Have get_parent_directory() handle "/foo" and "/" correctly.

The parent of "/foo" is "/"; and "/" is its own parent.

This would cause Tor to fail if you tried to have a PF_UNIX control
socket in the root directory.  That would be a stupid thing to do
for other reasons, but there's no reason to fail like _this_.

Bug found by Esteban Manchado Velázquez. Fix for bug 5089; bugfix on
Tor 0.2.2.26-beta.  Unit test included.
This commit is contained in:
Nick Mathewson 2012-05-24 12:56:31 -04:00
parent 75fc4dbbca
commit 254504fc14
3 changed files with 19 additions and 4 deletions

5
changes/bug5089 Normal file
View File

@ -0,0 +1,5 @@
o Minor bugfixes:
- Correctly handle checking the permissions on the parent
directory of a control socket in the root directory. Bug found
by Esteban Manchado Velázquez. Fix for bug 5089; bugfix on Tor
0.2.2.26-beta.

View File

@ -1481,7 +1481,11 @@ get_user_homedir(const char *username)
} }
#endif #endif
/** Modify <b>fname</b> to contain the name of the directory */ /** Modify <b>fname</b> to contain the name of its parent directory. Doesn't
* actually examine the filesystem; does a purely syntactic modification.
*
* The parent of the root director is considered to be iteself.
* */
int int
get_parent_directory(char *fname) get_parent_directory(char *fname)
{ {
@ -1503,13 +1507,18 @@ get_parent_directory(char *fname)
*/ */
cp = fname + strlen(fname); cp = fname + strlen(fname);
at_end = 1; at_end = 1;
while (--cp > fname) { while (--cp >= fname) {
int is_sep = (*cp == '/' int is_sep = (*cp == '/'
#ifdef MS_WINDOWS #ifdef MS_WINDOWS
|| *cp == '\\' || *cp == '\\'
#endif #endif
); );
if (is_sep) { if (is_sep) {
if (cp == fname) {
/* This is the first separator in the file name; don't remove it! */
cp[1] = '\0';
return 0;
}
*cp = '\0'; *cp = '\0';
if (! at_end) if (! at_end)
return 0; return 0;

View File

@ -1299,11 +1299,12 @@ test_util_parent_dir(void *ptr)
T("/home/wombat/knish", 0, "/home/wombat"); T("/home/wombat/knish", 0, "/home/wombat");
T("/home/wombat/knish/", 0, "/home/wombat"); T("/home/wombat/knish/", 0, "/home/wombat");
T("/home", 0, "/");
T("./home/wombat/knish/", 0, "./home/wombat"); T("./home/wombat/knish/", 0, "./home/wombat");
T("./wombat", 0, "."); T("./wombat", 0, ".");
T("", -1, ""); T("", -1, "");
T("/", -1, ""); T("/", 0, "/");
T("////", -1, ""); T("////", 0, "/");
done: done:
tor_free(cp); tor_free(cp);