Module Name: src Committed By: kre Date: Wed Jun 1 05:10:41 UTC 2016
Modified Files: src/bin/sh: eval.c Log Message: PR bin/43639 Redo earlier fix to only prohibit sourcing directories and block special files. char specials (/dev/tty, /dev/null, ... incl /dev/rwd0a) and fifos are OK. Posix actually requires that we find only readable files - that is not yet implemented (doing it sanely, without opening the file twice, is going to take some more modifications to code elsewhere). To generate a diff of this commit: cvs rdiff -u -r1.127 -r1.128 src/bin/sh/eval.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/bin/sh/eval.c diff -u src/bin/sh/eval.c:1.127 src/bin/sh/eval.c:1.128 --- src/bin/sh/eval.c:1.127 Fri May 13 10:32:52 2016 +++ src/bin/sh/eval.c Wed Jun 1 05:10:41 2016 @@ -1,4 +1,4 @@ -/* $NetBSD: eval.c,v 1.127 2016/05/13 10:32:52 kre Exp $ */ +/* $NetBSD: eval.c,v 1.128 2016/06/01 05:10:41 kre Exp $ */ /*- * Copyright (c) 1993 @@ -37,7 +37,7 @@ #if 0 static char sccsid[] = "@(#)eval.c 8.9 (Berkeley) 6/8/95"; #else -__RCSID("$NetBSD: eval.c,v 1.127 2016/05/13 10:32:52 kre Exp $"); +__RCSID("$NetBSD: eval.c,v 1.128 2016/06/01 05:10:41 kre Exp $"); #endif #endif /* not lint */ @@ -1266,18 +1266,40 @@ find_dot_file(char *basename) /* don't try this for absolute or relative paths */ if (strchr(basename, '/')) { if (stat(basename, &statb) == 0) { - if (S_ISREG(statb.st_mode)) - return basename; - error("%s: not a regular file", basename); - /* NOTREACHED */ + if (S_ISDIR(statb.st_mode)) + error("%s: is a directory", basename); + if (S_ISBLK(statb.st_mode)) + error("%s: is a block device", basename); + return basename; } } else while ((fullname = padvance(&path, basename)) != NULL) { - if ((stat(fullname, &statb) == 0) && S_ISREG(statb.st_mode)) { - /* - * Don't bother freeing here, since it will - * be freed by the caller. - */ - return fullname; + if ((stat(fullname, &statb) == 0)) { + /* weird format is to ease future code... */ + if (S_ISDIR(statb.st_mode) || S_ISBLK(statb.st_mode)) + ; +#if notyet + else if (unreadable()) { + /* + * testing this via st_mode is ugly to get + * correct (and would ignore ACLs). + * better way is just to open the file. + * But doing that here would (currently) + * mean opening the file twice, which + * might not be safe. So, defer this + * test until code is restructures so + * we can return a fd. Then we also + * get to fix the mem leak just below... + */ + } +#endif + else { + /* + * Don't bother freeing here, since + * it will be freed by the caller. + * XXX no it won't - a bug for later. + */ + return fullname; + } } stunalloc(fullname); }