Messages in this thread Patch in this message | | | Date | Wed, 9 Jun 1999 18:07:15 -0400 (EDT) | From | Alexander Viro <> | Subject | [PATCH] Oopsable bug in __prefix_lookup_dentry() on mips and sparc* |
| |
__mips_lookup_dentry() (and its relatives on sparc) pass LOOKUP_SLASHOK to lookup_dentry(). It has no effect unless * /usr/gnuemul/ exist and * /usr/gnuemul/{irix,sunos,solaris}/ doesn't. Assume that it is the case. Now, any lookup on /foo will give an oops: 1) we are calling lookup_dentry("/foo", whatever, whatever). name == "/foo". 2) we see that *name=='/'. Trimming the leading slashes leaves us with name == "foo". 3) __prefix_lookup_dentry happens. It's a macro, expanding to dentry = __mips_lookup_dentry(name, lookup_flags); if (!IS_ERR(dentry)) return dentry; 4) we are calling __mips_lookup_dentry("foo", whatever); which does base = lookup_dentry("usr/gnuemul/irix/", dget(current->fs->root), LOOKUP_FOLLOW|LOOKUP_DIRECTORY|LOOKUP_SLASHOK); if (IS_ERR(base)) return base; base = lookup_dentry(name, base, lookup_flags); 5) First lookup_dentry gives us a negative dentry of /usr/gnuemul/irix (if we didn't pass LOOKUP_SLASHOK we would get ERR_PTR(-ENOENT);) and we are calling lookup_dentry("foo", negative_dentry, whatever); 6) ... which calls permission(NULL, MAY_EXEC). Oops.
Proposed fix: remove LOOKUP_SLASHOK from the __mips_lookup_dentry().
Results:
* If the process is not running with PER_IRIX32 - no changes, relevant call never happens. * If /usr/gnuemul/irix exists or is unreachable - no changes, LOOKUP_SLASHOK has no effect. * If the name doesn't start from / - no changes, relevant call never happens. * If the name consists of several slashes - new variant will give us the root, current one gives the (negative) dentry of /usr/gnuemul/irix. * If the name consists of several slashes followed by something else - new variant will give us expected result (lookup of the rest of name from root), current one gives an oops.
In other words, removing LOOKUP_SLASHOK from __mips_lookup_dentry() is the right thing - in all cases when it changes behaviour of lookup_dentry() it fixes a bug.
The same applies to __sparc_lookup_dentry() and __sparc64_lookup_dentry().
Patch follows: diff -urN linux-2.3.6-pre2/include/asm-mips/namei.h linux-bird.misc/include/asm-mips/namei.h --- linux-2.3.6-pre2/include/asm-mips/namei.h Thu May 13 07:03:14 1999 +++ linux-bird.misc/include/asm-mips/namei.h Wed Jun 9 18:00:02 1999 @@ -23,7 +23,7 @@ base = lookup_dentry (IRIX32_EMUL, dget (current->fs->root), - (LOOKUP_FOLLOW | LOOKUP_DIRECTORY | LOOKUP_SLASHOK)); + (LOOKUP_FOLLOW | LOOKUP_DIRECTORY)); if (IS_ERR (base)) return base; diff -urN linux-2.3.6-pre2/include/asm-sparc/namei.h linux-bird.misc/include/asm-sparc/namei.h --- linux-2.3.6-pre2/include/asm-sparc/namei.h Thu May 13 07:03:18 1999 +++ linux-bird.misc/include/asm-sparc/namei.h Wed Jun 9 18:00:42 1999 @@ -28,7 +28,7 @@ base = lookup_dentry (emul, dget (current->fs->root), - (LOOKUP_FOLLOW | LOOKUP_DIRECTORY | LOOKUP_SLASHOK)); + (LOOKUP_FOLLOW | LOOKUP_DIRECTORY)); if (IS_ERR (base)) return NULL; diff -urN linux-2.3.6-pre2/include/asm-sparc64/namei.h linux-bird.misc/include/asm-sparc64/namei.h --- linux-2.3.6-pre2/include/asm-sparc64/namei.h Thu May 13 07:03:20 1999 +++ linux-bird.misc/include/asm-sparc64/namei.h Wed Jun 9 18:01:24 1999 @@ -28,7 +28,7 @@ base = lookup_dentry (emul, dget (current->fs->root), - (LOOKUP_FOLLOW | LOOKUP_DIRECTORY | LOOKUP_SLASHOK)); + (LOOKUP_FOLLOW | LOOKUP_DIRECTORY)); if (IS_ERR (base)) return NULL;
- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.rutgers.edu Please read the FAQ at http://www.tux.org/lkml/
| |