@@ -, +, @@ - (par_mktmpdir) CVE-2011-4114: - create parent of cache directory (i.e. /tmp/par-USER) with mode 0700 - if it already exists, check that (and bail out if not) - it's not a symlink - it's mode 0700 - it's owned by USER myldr/mktmpdir.c | 38 +++++++++++++++++++++++++++++++++++--- 1 files changed, 35 insertions(+), 3 deletions(-) --- a/myldr/mktmpdir.c +++ a/myldr/mktmpdir.c @@ -161,10 +161,42 @@ char *par_mktmpdir ( char **argv ) { stmpdir2 is the top $TEMP/par-$USER, needed to build stmpdir. We need 2 buffers because snprintf() can't write to a buffer it's reading from. */ - stmpdir = malloc( stmp_len ); stmpdir2 = malloc( stmp_len ); sprintf(stmpdir2, "%s%s%s%s", tmpdir, dir_sep, subdirbuf_prefix, username); - my_mkdir(stmpdir2, 0755); +#ifdef WIN32 + _mkdir(stmpdir2); /* FIXME bail if error (other than EEXIST) */ +#else + { + struct stat st; + + if (mkdir(stmpdir2, 0700) == -1 && errno != EEXIST) { + fprintf(stderr, "%s: creation of private subdirectory %s failed (errno=%i)\n", + argv[0], stmpdir2, errno); + return NULL; + } + + /* now check that: + * - stmpdir2 is a directory (and not a symlink) + * - stmpdir2 is owned by the user + * - stmpdir2 has mode 0700 + */ + if (lstat(stmpdir2, &st) == -1) { + fprintf(stderr, "%s: stat of private subdirectory %s failed (errno=%i)\n", + argv[0], stmpdir2, errno); + return NULL; + } + + if (!S_ISDIR(st.st_mode) + || st.st_uid != getuid() + || (st.st_mode & 0777) != 0700 ) { + fprintf(stderr, "%s: private subdirectory %s is unsafe (please remove it and retry your operation)\n", + argv[0], stmpdir2); + return NULL; + } + } +#endif + + stmpdir = malloc( stmp_len ); /* Doesn't really work - XXX */ val = par_getenv( "PATH" ); @@ -250,7 +282,7 @@ char *par_mktmpdir ( char **argv ) { a prior invocation crashed leaving garbage in a temp directory that might interfere. */ - while (my_mkdir(stmpdir, 0755) == -1 && errno == EEXIST) { + while (my_mkdir(stmpdir, 0700) == -1 && errno == EEXIST) { sprintf( stmpdir, "%s%stemp-%u-%u%s",