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 <[EMAIL PROTECTED]>
-
To unsubscribe from this list: send the line "unsubscribe util-linux-ng" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at http://vger.kernel.org/majordomo-info.html