summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/shared/device-nodes.c1
-rw-r--r--src/shared/label.c20
-rw-r--r--src/shared/label.h1
-rw-r--r--src/shared/mkdir-label.c23
-rw-r--r--src/shared/mkdir.c24
-rw-r--r--src/shared/mkdir.h1
-rw-r--r--src/shared/time-util.c1
7 files changed, 50 insertions, 21 deletions
diff --git a/src/shared/device-nodes.c b/src/shared/device-nodes.c
index f03fbd9d8c..28d7664da4 100644
--- a/src/shared/device-nodes.c
+++ b/src/shared/device-nodes.c
@@ -20,6 +20,7 @@
#include <stdlib.h>
#include <stdio.h>
#include <stdint.h>
+#include <string.h>
#include <sys/types.h>
#include "device-nodes.h"
diff --git a/src/shared/label.c b/src/shared/label.c
index 6c0e96f970..59b49ecc70 100644
--- a/src/shared/label.c
+++ b/src/shared/label.c
@@ -34,6 +34,26 @@ int label_fix(const char *path, bool ignore_enoent, bool ignore_erofs) {
return 0;
}
+int mkdir_label(const char *path, mode_t mode) {
+ int r;
+
+ assert(path);
+
+ r = mac_selinux_create_file_prepare(path, S_IFDIR);
+ if (r < 0)
+ return r;
+
+ if (mkdir(path, mode) < 0)
+ r = -errno;
+
+ mac_selinux_create_file_clear();
+
+ if (r < 0)
+ return r;
+
+ return mac_smack_fix(path, false, false);
+}
+
int symlink_label(const char *old_path, const char *new_path) {
int r;
diff --git a/src/shared/label.h b/src/shared/label.h
index ba1e2559e9..f8fd69411f 100644
--- a/src/shared/label.h
+++ b/src/shared/label.h
@@ -24,4 +24,5 @@
int label_fix(const char *path, bool ignore_enoent, bool ignore_erofs);
+int mkdir_label(const char *path, mode_t mode);
int symlink_label(const char *old_path, const char *new_path);
diff --git a/src/shared/mkdir-label.c b/src/shared/mkdir-label.c
index 832e3df4d9..95b4a9a1ed 100644
--- a/src/shared/mkdir-label.c
+++ b/src/shared/mkdir-label.c
@@ -30,27 +30,10 @@
#include "path-util.h"
#include "mkdir.h"
-static int label_mkdir(const char *path, mode_t mode) {
- int r;
-
- if (mac_selinux_use())
- return mac_selinux_mkdir(path, mode);
-
- if (mac_smack_use()) {
- r = mkdir(path, mode);
- if (r < 0)
- return -errno;
-
- return mac_smack_fix(path, false, false);
- }
-
- r = mkdir(path, mode);
- if (r < 0)
- return -errno;
-
- return 0;
+int mkdir_safe_label(const char *path, mode_t mode, uid_t uid, gid_t gid) {
+ return mkdir_safe_internal(path, mode, uid, gid, mkdir_label);
}
int mkdir_parents_label(const char *path, mode_t mode) {
- return mkdir_parents_internal(NULL, path, mode, label_mkdir);
+ return mkdir_parents_internal(NULL, path, mode, mkdir_label);
}
diff --git a/src/shared/mkdir.c b/src/shared/mkdir.c
index 0c2a6cfe4d..3bc5131e40 100644
--- a/src/shared/mkdir.c
+++ b/src/shared/mkdir.c
@@ -23,13 +23,35 @@
#include <errno.h>
#include <stdlib.h>
#include <stdio.h>
-#include <limits.h>
#include "label.h"
#include "util.h"
#include "path-util.h"
#include "mkdir.h"
+int mkdir_safe_internal(const char *path, mode_t mode, uid_t uid, gid_t gid, mkdir_func_t _mkdir) {
+ struct stat st;
+
+ if (_mkdir(path, mode) >= 0)
+ if (chmod_and_chown(path, mode, uid, gid) < 0)
+ return -errno;
+
+ if (lstat(path, &st) < 0)
+ return -errno;
+
+ if ((st.st_mode & 0007) > (mode & 0007) ||
+ (st.st_mode & 0070) > (mode & 0070) ||
+ (st.st_mode & 0700) > (mode & 0700) ||
+ (uid != (uid_t) -1 && st.st_uid != uid) ||
+ (gid != (gid_t) -1 && st.st_gid != gid) ||
+ !S_ISDIR(st.st_mode)) {
+ errno = EEXIST;
+ return -errno;
+ }
+
+ return 0;
+}
+
int mkdir_parents_internal(const char *prefix, const char *path, mode_t mode, mkdir_func_t _mkdir) {
const char *p, *e;
int r;
diff --git a/src/shared/mkdir.h b/src/shared/mkdir.h
index baa2df58b4..7d37c89230 100644
--- a/src/shared/mkdir.h
+++ b/src/shared/mkdir.h
@@ -28,5 +28,6 @@ int mkdir_parents_label(const char *path, mode_t mode);
/* internally used */
typedef int (*mkdir_func_t)(const char *pathname, mode_t mode);
+int mkdir_safe_internal(const char *path, mode_t mode, uid_t uid, gid_t gid, mkdir_func_t _mkdir);
int mkdir_parents_internal(const char *prefix, const char *path, mode_t mode, mkdir_func_t _mkdir);
int mkdir_p_internal(const char *prefix, const char *path, mode_t mode, mkdir_func_t _mkdir);
diff --git a/src/shared/time-util.c b/src/shared/time-util.c
index 3f72fdd5b2..ccd3d9562c 100644
--- a/src/shared/time-util.c
+++ b/src/shared/time-util.c
@@ -19,6 +19,7 @@
#include <stdlib.h>
#include <stdio.h>
+#include <string.h>
#include <stdbool.h>
#include <time.h>