Re: [PATCH] mount: pointer used after free

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Sun, Sep 02, 2007 at 02:11:42PM -0600, LaMont Jones wrote:
> As reported in http://bugs.debian.org/440562
> 
> A chain of symlinks to /etc/fstab results in using a pointer after
> freeing it.

 Uf.. stupid bug. util-linux 2.12h:

$ git diff d26aa358^..d26aa358 mount/realpath.c

diff --git a/mount/realpath.c b/mount/realpath.c
index 988d923..373dbe8 100644
--- a/mount/realpath.c
+++ b/mount/realpath.c
@@ -32,17 +32,13 @@
 
 #define MAX_READLINKS 32
 
-/* this leaks some memory - unimportant for mount */
 char *
 myrealpath(const char *path, char *resolved_path, int maxreslth) {
 	int readlinks = 0;
 	char *npath;
 	char link_path[PATH_MAX+1];
 	int n;
-#ifdef resolve_symlinks
-	char *buf;
-	int m;
-#endif
+	char *buf = NULL;
 
 	npath = resolved_path;
 
@@ -83,7 +79,7 @@ myrealpath(const char *path, char *resolved_path, int maxreslth) {
 		while (*path != '\0' && *path != '/') {
 			if (npath-resolved_path > maxreslth-2) {
 				errno = ENAMETOOLONG;
-				return NULL;
+				goto err;
 			}
 			*npath++ = *path++;
 		}
@@ -91,7 +87,7 @@ myrealpath(const char *path, char *resolved_path, int maxreslth) {
 		/* Protect against infinite loops. */
 		if (readlinks++ > MAX_READLINKS) {
 			errno = ELOOP;
-			return NULL;
+			goto err;
 		}
 
 		/* See if last pathname component is a symlink. */
@@ -100,9 +96,11 @@ myrealpath(const char *path, char *resolved_path, int maxreslth) {
 		if (n < 0) {
 			/* EINVAL means the file exists but isn't a symlink. */
 			if (errno != EINVAL)
-				return NULL;
+				goto err;
 		} else {
 #ifdef resolve_symlinks		/* Richard Gooch dislikes sl resolution */
+			int m;
+
 			/* Note: readlink doesn't add the null byte. */
 			link_path[n] = '\0';
 			if (*link_path == '/')
@@ -115,6 +113,8 @@ myrealpath(const char *path, char *resolved_path, int maxreslth) {
 
 			/* Insert symlink contents into path. */
 			m = strlen(path);
+			if (buf)
+				free(buf);
 			buf = xmalloc(m + n + 1);
 			memcpy(buf, link_path, n);
 			memcpy(buf + n, path, m + 1);
@@ -128,5 +128,13 @@ myrealpath(const char *path, char *resolved_path, int maxreslth) {
 		npath--;
 	/* Make sure it's null terminated. */
 	*npath = '\0';
+
+	if (buf)
+		free(buf);
 	return resolved_path;
+
+ err:
+	if (buf)
+		free(buf);
+	return NULL;
 }


-- 
 Karel Zak  <kzak@xxxxxxxxxx>
-
To unsubscribe from this list: send the line "unsubscribe util-linux-ng" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html

[Index of Archives]     [Netdev]     [Ethernet Bridging]     [Linux Wireless]     [Kernel Newbies]     [Security]     [Linux for Hams]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux RAID]     [Linux Admin]     [Samba]

  Powered by Linux