From 9aa3d40e0b24bbd3dfa5d51198ffc289fa901c9f Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Petr=20P=C3=ADsa=C5=99?= <ppisar@redhat.com>
Date: Tue, 6 Dec 2011 14:22:04 +0100
Subject: [PATCH] Fix CVE-2011-4114 ported for 1.010.
From: r1296 | rschupp | 2011-11-14 21:01:18 +0100 (Po, 14 lis 2011) | 11 lines
myldr/mktmpdir.c:
- (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
NOTE: PAR contains a "copy" of par_mktmpdir (in Perl); this
must be fixed as well and we must require the fixed version.
Adjusted error message from r1313 is included.
---
myldr/mktmpdir.c | 38 +++++++++++++++++++++++++++++++++++---
1 files changed, 35 insertions(+), 3 deletions(-)
diff --git a/myldr/mktmpdir.c b/myldr/mktmpdir.c
index 6699831..2293268 100644
--- a/myldr/mktmpdir.c
+++ b/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",
--
1.7.7.4