I noticed that glibc has applied some fixes to canonicalize.c that we were missing; and sure enough, was able to enhance the testsuite to trip these bugs. They also applied some assert's proving that their optimization to avoid strcpy are safe; I left the asserts out, but copied their optimization. OK to commit?
I plan on porting the testsuite changes to test-canonicalize.c, and fixing any fallout there as a separate commit. From: Eric Blake <[email protected]> Date: Thu, 10 Sep 2009 12:12:16 -0600 Subject: [PATCH] canonicalize-lgpl: reject non-directory with trailing slash * tests/test-canonicalize-lgpl.c (main): Enhance test. * lib/canonicalize-lgpl.c (__realpath): Synchronize with glibc. Signed-off-by: Eric Blake <[email protected]> --- ChangeLog | 6 ++++++ lib/canonicalize-lgpl.c | 11 +++++++---- tests/test-canonicalize-lgpl.c | 16 +++++++++++++++- 3 files changed, 28 insertions(+), 5 deletions(-) diff --git a/ChangeLog b/ChangeLog index f9d9c1b..baeaf35 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,11 @@ 2009-09-10 Eric Blake <[email protected]> + canonicalize-lgpl: reject non-directory with trailing slash + * tests/test-canonicalize-lgpl.c (main): Enhance test. + * lib/canonicalize-lgpl.c (__realpath): Synchronize with glibc. + +2009-09-10 Eric Blake <[email protected]> + dirname: add library-safe mdir_name * lib/dirname.h (mdir_name): New prototype. * lib/dirname.c (dir_name): Move guts... diff --git a/lib/canonicalize-lgpl.c b/lib/canonicalize-lgpl.c index 6b5663a..c8f313e 100644 --- a/lib/canonicalize-lgpl.c +++ b/lib/canonicalize-lgpl.c @@ -298,6 +298,11 @@ __realpath (const char *name, char *resolved) while ((--dest)[-1] != '/'); } #endif + else if (!S_ISDIR (st.st_mode) && *end != '\0') + { + __set_errno (ENOTDIR); + goto error; + } } } if (dest > rpath + 1 && dest[-1] == '/') @@ -307,16 +312,14 @@ __realpath (const char *name, char *resolved) if (extra_buf) freea (extra_buf); - return resolved ? memcpy (resolved, rpath, dest - rpath + 1) : rpath; + return rpath; error: { int saved_errno = errno; if (extra_buf) freea (extra_buf); - if (resolved) - strcpy (resolved, rpath); - else + if (resolved == NULL) free (rpath); errno = saved_errno; } diff --git a/tests/test-canonicalize-lgpl.c b/tests/test-canonicalize-lgpl.c index 29b919d..87e5e46 100644 --- a/tests/test-canonicalize-lgpl.c +++ b/tests/test-canonicalize-lgpl.c @@ -1,5 +1,5 @@ /* Test of execution of program termination handlers. - Copyright (C) 2007-2008 Free Software Foundation, Inc. + Copyright (C) 2007-2009 Free Software Foundation, Inc. This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -79,6 +79,20 @@ main () ASSERT (result == NULL); } + /* Check that a non-directory with trailing slash yields NULL. */ + { + char *result = canonicalize_file_name ("t-can-lgpl.tmp/tra/"); + ASSERT (result == NULL); + result = canonicalize_file_name ("t-can-lgpl.tmp/huk/"); + ASSERT (result == NULL); + } + + /* Check that a missing directory yields NULL. */ + { + char *result = canonicalize_file_name ("t-can-lgpl.tmp/ouk/.."); + ASSERT (result == NULL); + } + /* Check that a loop of symbolic links is detected. */ { char *result = canonicalize_file_name ("ise"); -- 1.6.3.2
