libbb.h cleanup.
[oweals/opkg-lede.git] / libbb / make_directory.c
index 797ce270c436e3d486cb92ba7a8a93600c3c0acc..cff2e5185b763c818859cb29176ce1b62e5ab93f 100644 (file)
@@ -26,6 +26,7 @@
 #include <sys/types.h>
 #include <unistd.h>
 #include <stdlib.h>
+#include <libgen.h>
 
 #include "libbb.h"
 
@@ -50,17 +51,25 @@ int make_directory (const char *path, long mode, int flags)
 
                if (stat (path, &st) < 0 && errno == ENOENT) {
                        int status;
-                       char *buf, *parent;
+                       char *pathcopy, *parent, *parentcopy;
                        mode_t mask;
 
                        mask = umask (0);
                        umask (mask);
 
-                       buf = xstrdup (path);
-                       parent = dirname (buf);
-                       status = make_directory (parent, (0777 & ~mask) | 0300,
-                                       FILEUTILS_RECUR);
-                       free (buf);
+                       /* dirname is unsafe, it may both modify the
+                          memory of the path argument and may return
+                          a pointer to static memory, which can then
+                          be modified by consequtive calls to dirname */
+                       
+                       pathcopy = xstrdup (path);
+                       parent = dirname (pathcopy);
+                       parentcopy = xstrdup (parent);
+                       status = make_directory (parentcopy, (0777 & ~mask)
+                                                                        | 0300, FILEUTILS_RECUR);
+                       free (pathcopy);
+                       free (parentcopy);
+
 
                        if (status < 0 || make_directory (path, mode, 0) < 0)
                                return -1;