diff options
author | netblue30 <netblue30@yahoo.com> | 2018-06-04 15:45:56 -0400 |
---|---|---|
committer | netblue30 <netblue30@yahoo.com> | 2018-06-04 15:45:56 -0400 |
commit | ac9283365224ed46ab2087c050ae1e2916a0dbf5 (patch) | |
tree | ecc9d148454b06e928a242ff5037462239e1a28d /src/lib/firejail_user.c | |
parent | add private-cache option (diff) | |
download | firejail-ac9283365224ed46ab2087c050ae1e2916a0dbf5.tar.gz firejail-ac9283365224ed46ab2087c050ae1e2916a0dbf5.tar.zst firejail-ac9283365224ed46ab2087c050ae1e2916a0dbf5.zip |
evaluate UID_MIN/GID_MID at runtime, remove compile time evaluation - fixes #1964
Diffstat (limited to 'src/lib/firejail_user.c')
-rw-r--r-- | src/lib/firejail_user.c | 66 |
1 files changed, 64 insertions, 2 deletions
diff --git a/src/lib/firejail_user.c b/src/lib/firejail_user.c index 0cc0ac6c1..c7af14254 100644 --- a/src/lib/firejail_user.c +++ b/src/lib/firejail_user.c | |||
@@ -26,11 +26,70 @@ | |||
26 | // One username per line in the file | 26 | // One username per line in the file |
27 | 27 | ||
28 | #include "../include/common.h" | 28 | #include "../include/common.h" |
29 | #include "../include/firejail_user.h" | ||
29 | #include <sys/types.h> | 30 | #include <sys/types.h> |
30 | #include <pwd.h> | 31 | #include <pwd.h> |
31 | #include "../../uids.h" | ||
32 | 32 | ||
33 | #define MAXBUF 4098 | 33 | #define MAXBUF 4098 |
34 | |||
35 | // minimum values for uid and gid extracted from /etc/login.defs | ||
36 | int uid_min = 0; | ||
37 | int gid_min = 0; | ||
38 | |||
39 | static void init_uid_gid_min(void) { | ||
40 | if (uid_min != 0 && gid_min != 0) | ||
41 | return; | ||
42 | |||
43 | // read the real values from login.def | ||
44 | FILE *fp = fopen("/etc/login.defs", "r"); | ||
45 | if (!fp) | ||
46 | goto errexit; | ||
47 | |||
48 | char buf[MAXBUF]; | ||
49 | while (fgets(buf, MAXBUF, fp)) { | ||
50 | // comments | ||
51 | if (*buf == '#') | ||
52 | continue; | ||
53 | // skip empty space | ||
54 | char *ptr = buf; | ||
55 | while (*ptr == ' ' || *ptr == '\t') | ||
56 | ptr++; | ||
57 | |||
58 | if (strncmp(ptr, "UID_MIN", 7) == 0) { | ||
59 | int rv = sscanf(ptr + 7, "%d", &uid_min); | ||
60 | if (rv != 1 || uid_min < 0) { | ||
61 | fclose(fp); | ||
62 | goto errexit; | ||
63 | } | ||
64 | } | ||
65 | else if (strncmp(ptr, "GID_MIN", 7) == 0) { | ||
66 | int rv = sscanf(ptr + 7, "%d", &gid_min); | ||
67 | if (rv != 1 || gid_min < 0) { | ||
68 | fclose(fp); | ||
69 | goto errexit; | ||
70 | } | ||
71 | } | ||
72 | |||
73 | if (uid_min != 0 && gid_min != 0) | ||
74 | break; | ||
75 | |||
76 | } | ||
77 | fclose(fp); | ||
78 | |||
79 | if (uid_min == 0 || gid_min == 0) | ||
80 | goto errexit; | ||
81 | //printf("uid_min %d, gid_min %d\n", uid_min, gid_min); | ||
82 | |||
83 | return; | ||
84 | |||
85 | errexit: | ||
86 | fprintf(stderr, "Error: cannot read UID_MIN and/or GID_MIN from /etc/login.defs, using 1000 by default\n"); | ||
87 | uid_min = 1000; | ||
88 | gid_min = 1000; | ||
89 | } | ||
90 | |||
91 | |||
92 | |||
34 | static inline char *get_fname(void) { | 93 | static inline char *get_fname(void) { |
35 | char *fname; | 94 | char *fname; |
36 | if (asprintf(&fname, "%s/firejail.users", SYSCONFDIR) == -1) | 95 | if (asprintf(&fname, "%s/firejail.users", SYSCONFDIR) == -1) |
@@ -38,9 +97,11 @@ static inline char *get_fname(void) { | |||
38 | return fname; | 97 | return fname; |
39 | } | 98 | } |
40 | 99 | ||
100 | |||
41 | // returns 1 if the user is found in the database or if the database was not created | 101 | // returns 1 if the user is found in the database or if the database was not created |
42 | int firejail_user_check(const char *name) { | 102 | int firejail_user_check(const char *name) { |
43 | assert(name); | 103 | assert(name); |
104 | init_uid_gid_min(); | ||
44 | 105 | ||
45 | // root is allowed to run firejail by default | 106 | // root is allowed to run firejail by default |
46 | if (strcmp(name, "root") == 0) | 107 | if (strcmp(name, "root") == 0) |
@@ -48,7 +109,8 @@ int firejail_user_check(const char *name) { | |||
48 | 109 | ||
49 | // other system users will run the program as is | 110 | // other system users will run the program as is |
50 | uid_t uid = getuid(); | 111 | uid_t uid = getuid(); |
51 | if ((uid < UID_MIN && uid != 0) || strcmp(name, "nobody") == 0) | 112 | assert(uid_min > 0); |
113 | if (((int) uid < uid_min && uid != 0) || strcmp(name, "nobody") == 0) | ||
52 | return 0; | 114 | return 0; |
53 | 115 | ||
54 | // check file existence | 116 | // check file existence |