git » libjio » commit 0ec2422

If not initialized properly, error paths will close fds where it shouldn't. This can easily happen in a normal path, like jfsck() when the jdir doesn't exist.

author Alberto Bertogli
2004-08-29 00:22:57 UTC
committer Alberto Bertogli
2007-07-15 13:17:16 UTC
parent 6f2cd048bc9e1a06b53de41db234415ecb07b8c3

If not initialized properly, error paths will close fds where it shouldn't. This can easily happen in a normal path, like jfsck() when the jdir doesn't exist.

If not initialized properly, error paths will close fds where it shouldn't.
This can easily happen in a normal path, like jfsck() when the jdir doesn't
exist.

This patch initialize values properly so error paths work as expected.

Thanks to Pieter Grimmerink for the report and the fix.

check.c +9 -8
trans.c +7 -1

diff --git a/check.c b/check.c
index f0ce63e..4c5a2f8 100644
--- a/check.c
+++ b/check.c
@@ -95,7 +95,7 @@ error:
 /* check the journal and rollback incomplete transactions */
 int jfsck(const char *name, struct jfsck_result *res)
 {
-	int fd, tfd, rv, i, ret;
+	int tfd, rv, i, ret;
 	unsigned int maxtid;
 	uint32_t csum1, csum2;
 	char jdir[PATH_MAX], jlockfile[PATH_MAX], tname[PATH_MAX];
@@ -108,20 +108,22 @@ int jfsck(const char *name, struct jfsck_result *res)
 	unsigned char *map;
 	off_t filelen;
 
-	fd = tfd = -1;
+	tfd = -1;
 	filelen = 0;
 	dir = NULL;
-	fs.jmap = NULL;
+	fs.fd = -1;
+	fs.jfd = -1;
+	fs.jdirfd = -1;
+	fs.jmap = MAP_FAILED;
 	map = NULL;
 	ret = 0;
 
-	fd = open(name, O_RDWR | O_SYNC | O_LARGEFILE);
-	if (fd < 0) {
+	fs.fd = open(name, O_RDWR | O_SYNC | O_LARGEFILE);
+	if (fs.fd < 0) {
 		ret = J_ENOENT;
 		goto exit;
 	}
 
-	fs.fd = fd;
 	fs.name = (char *) name;
 
 	if (!get_jdir(name, jdir)) {
@@ -154,7 +156,6 @@ int jfsck(const char *name, struct jfsck_result *res)
 			PROT_READ | PROT_WRITE, MAP_SHARED, fs.jfd, 0);
 	if (fs.jmap == MAP_FAILED) {
 		ret = J_ENOJOURNAL;
-		fs.jmap = NULL;
 		goto exit;
 	}
 
@@ -283,7 +284,7 @@ exit:
 		close(fs.jdirfd);
 	if (dir != NULL)
 		closedir(dir);
-	if (fs.jmap != NULL)
+	if (fs.jmap != MAP_FAILED)
 		munmap(fs.jmap, sizeof(unsigned int));
 
 	return ret;
diff --git a/trans.c b/trans.c
index fbbba10..799da40 100644
--- a/trans.c
+++ b/trans.c
@@ -506,6 +506,11 @@ int jopen(struct jfs *fs, const char *name, int flags, int mode, int jflags)
 	char jdir[PATH_MAX], jlockfile[PATH_MAX];
 	struct stat sinfo;
 
+	fs->fd = -1;
+	fs->jfd = -1;
+	fs->jdirfd = -1;
+	fs->jmap = MAP_FAILED;
+
 	/* we always need read and write access, because when we commit a
 	 * transaction we read the current contents before applying, and write
 	 * access is needed for locking with fcntl */
@@ -627,7 +632,8 @@ int jclose(struct jfs *fs)
 	if (fs->name)
 		/* allocated by strdup() in jopen() */
 		free(fs->name);
-	munmap(fs->jmap, sizeof(unsigned int));
+	if (fs->jmap != MAP_FAILED)
+		munmap(fs->jmap, sizeof(unsigned int));
 
 	pthread_mutex_unlock(&(fs->lock));
 	pthread_mutex_destroy(&(fs->lock));