@cryptotaxi247 / netdata-1 / commits / 563ff0138

Fix file permissions under directory (#15208)

* Fix health crash * Revert "Fix health crash" This reverts commit 2057e6f4216c5a10b25dcf56276ecb7da88079ca. * Fix file permissions * Fix registry directory permissions * Recursively process directories as needed to fix permissions * Fix recursion properly. * Fix recursion properly (part 2) * Fix recursion properly (part 3) * Exclude www directories * Fix recursion properly (part 4) * Make systemd not touch directory permissions * Info message if running as root * Improve message * Set CAP_CHOWN capability

Stelios Fragkakis committed Jun 16, 2023 at 16:11 UTC 563ff0138d64864e85664d5d12b52d8f500cf446
3 files changed +44 -14
daemon/daemon.c
+42 -6
@@ -43,10 +43,39 @@ static void chown_open_file(int fd, uid_t uid, gid_t gid) {
43 }
44 }
45
46 -void change_dir_ownership(const char *dir, uid_t uid, gid_t gid)
46 +static void fix_directory_file_permissions(const char *dirname, uid_t uid, gid_t gid, bool recursive)
47 +{
48 + char filename[FILENAME_MAX + 1];
49 +
50 + DIR *dir = opendir(dirname);
51 + if (!dir)
52 + return;
53 +
54 + struct dirent *de = NULL;
55 +
56 + while ((de = readdir(dir))) {
57 + if (de->d_type == DT_DIR && (!strcmp(de->d_name, ".") || !strcmp(de->d_name, "..")))
58 + continue;
59 +
60 + (void) snprintfz(filename, FILENAME_MAX, "%s/%s", dirname, de->d_name);
61 + if (de->d_type == DT_REG || recursive) {
62 + if (chown(filename, uid, gid) == -1)
63 + error("Cannot chown %s '%s' to %u:%u", de->d_type == DT_DIR ? "directory" : "file", filename, (unsigned int)uid, (unsigned int)gid);
64 + }
65 +
66 + if (de->d_type == DT_DIR && recursive)
67 + fix_directory_file_permissions(filename, uid, gid, recursive);
68 + }
69 +
70 + closedir(dir);
71 +}
72 +
73 +void change_dir_ownership(const char *dir, uid_t uid, gid_t gid, bool recursive)
74 {
75 if (chown(dir, uid, gid) == -1)
76 error("Cannot chown directory '%s' to %u:%u", dir, (unsigned int)uid, (unsigned int)gid);
77 +
78 + fix_directory_file_permissions(dir, uid, gid, recursive);
79 }
80
81 void clean_directory(char *dirname)
@@ -66,11 +95,15 @@ void clean_directory(char *dirname)
95 }
96
97 void prepare_required_directories(uid_t uid, gid_t gid) {
69 - change_dir_ownership(netdata_configured_cache_dir, uid, gid);
70 - change_dir_ownership(netdata_configured_varlib_dir, uid, gid);
71 - change_dir_ownership(netdata_configured_lock_dir, uid, gid);
72 - change_dir_ownership(netdata_configured_log_dir, uid, gid);
73 - change_dir_ownership(claimingdirectory, uid, gid);
98 + change_dir_ownership(netdata_configured_cache_dir, uid, gid, true);
99 + change_dir_ownership(netdata_configured_varlib_dir, uid, gid, false);
100 + change_dir_ownership(netdata_configured_lock_dir, uid, gid, false);
101 + change_dir_ownership(netdata_configured_log_dir, uid, gid, false);
102 + change_dir_ownership(claimingdirectory, uid, gid, false);
103 +
104 + char filename[FILENAME_MAX + 1];
105 + snprintfz(filename, FILENAME_MAX, "%s/registry", netdata_configured_varlib_dir);
106 + change_dir_ownership(filename, uid, gid, false);
107
108 clean_directory(netdata_configured_lock_dir);
109 }
@@ -87,6 +120,9 @@ int become_user(const char *username, int pid_fd) {
120 uid_t uid = pw->pw_uid;
121 gid_t gid = pw->pw_gid;
122
123 + if (am_i_root)
124 + info("I am root, so checking permissions");
125 +
126 prepare_required_directories(uid, gid);
127
128 if(pidfile[0]) {
system/systemd/netdata.service.in
+2
@@ -59,6 +59,8 @@ CapabilityBoundingSet=CAP_SYS_CHROOT
59 CapabilityBoundingSet=CAP_NET_ADMIN
60 # is required for plugins that use sudo
61 CapabilityBoundingSet=CAP_SETGID CAP_SETUID
62 +# is required to change file ownership
63 +CapabilityBoundingSet=CAP_CHOWN
64
65 # Sandboxing
66 ProtectSystem=full
system/systemd/netdata.service.v235.in
-8
@@ -8,14 +8,6 @@ After=network.target httpd.service squid.service nfs-server.service mysqld.servi
8 [Service]
9 Type=simple
10 User=root
11 -RuntimeDirectory=netdata
12 -CacheDirectory=netdata
13 -StateDirectory=netdata
14 -LogsDirectory=netdata
15 -RuntimeDirectoryMode=0775
16 -StateDirectoryMode=0755
17 -CacheDirectoryMode=0755
18 -LogsDirectoryMode=2750
11 EnvironmentFile=-/etc/default/netdata
12 ExecStart=@sbindir_POST@/netdata -D $EXTRA_OPTS
13