summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Makefile.in10
-rw-r--r--src/firejail/restrict_users.c14
-rw-r--r--src/include/firejail_user.h2
-rw-r--r--src/lib/firejail_user.c66
4 files changed, 79 insertions, 13 deletions
diff --git a/Makefile.in b/Makefile.in
index fef544267..cbcf252df 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -22,16 +22,14 @@ HAVE_CONTRIB_INSTALL=@HAVE_CONTRIB_INSTALL@
22BUSYBOX_WORKAROUND=@BUSYBOX_WORKAROUND@ 22BUSYBOX_WORKAROUND=@BUSYBOX_WORKAROUND@
23HAVE_SUID=@HAVE_SUID@ 23HAVE_SUID=@HAVE_SUID@
24 24
25uids.h:; ./mkuid.sh
26
27.PHONY: mylibs $(MYLIBS) 25.PHONY: mylibs $(MYLIBS)
28mylibs: $(MYLIBS) 26mylibs: $(MYLIBS)
29$(MYLIBS): uids.h 27$(MYLIBS):
30 $(MAKE) -C $@ 28 $(MAKE) -C $@
31 29
32.PHONY: apps $(APPS) 30.PHONY: apps $(APPS)
33apps: $(APPS) 31apps: $(APPS)
34$(APPS): $(MYLIBS) uids.h 32$(APPS): $(MYLIBS)
35 $(MAKE) -C $@ 33 $(MAKE) -C $@
36 34
37$(MANPAGES): $(wildcard src/man/*.txt) 35$(MANPAGES): $(wildcard src/man/*.txt)
@@ -73,7 +71,7 @@ distclean: clean
73 for dir in $(APPS) $(MYLIBS); do \ 71 for dir in $(APPS) $(MYLIBS); do \
74 $(MAKE) -C $$dir distclean; \ 72 $(MAKE) -C $$dir distclean; \
75 done 73 done
76 rm -fr Makefile autom4te.cache config.log config.status config.h uids.h dummy.o src/common.mk 74 rm -fr Makefile autom4te.cache config.log config.status config.h dummy.o src/common.mk
77 75
78realinstall: 76realinstall:
79 # firejail executable 77 # firejail executable
@@ -192,7 +190,7 @@ uninstall:
192 rm -f $(DESTDIR)/$(datarootdir)/bash-completion/completions/firemon 190 rm -f $(DESTDIR)/$(datarootdir)/bash-completion/completions/firemon
193 rm -f $(DESTDIR)/$(datarootdir)/bash-completion/completions/firecfg 191 rm -f $(DESTDIR)/$(datarootdir)/bash-completion/completions/firecfg
194 192
195DISTFILES = "src etc platform contrib configure configure.ac dummy.c Makefile.in install.sh mkman.sh mketc.sh mkdeb.sh mkuid.sh COPYING README RELNOTES" 193DISTFILES = "src etc platform contrib configure configure.ac dummy.c Makefile.in install.sh mkman.sh mketc.sh mkdeb.sh COPYING README RELNOTES"
196DISTFILES_TEST = "test/apps test/apps-x11 test/apps-x11-xorg test/root test/fcopy test/environment test/profiles test/utils test/compile test/filters test/network test/arguments test/fs test/sysutils test/chroot" 194DISTFILES_TEST = "test/apps test/apps-x11 test/apps-x11-xorg test/root test/fcopy test/environment test/profiles test/utils test/compile test/filters test/network test/arguments test/fs test/sysutils test/chroot"
197 195
198dist: 196dist:
diff --git a/src/firejail/restrict_users.c b/src/firejail/restrict_users.c
index 982dba5ac..d66deeb97 100644
--- a/src/firejail/restrict_users.c
+++ b/src/firejail/restrict_users.c
@@ -18,6 +18,7 @@
18 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 18 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19*/ 19*/
20#include "firejail.h" 20#include "firejail.h"
21#include "../include/firejail_user.h"
21#include <sys/mount.h> 22#include <sys/mount.h>
22#include <sys/stat.h> 23#include <sys/stat.h>
23#include <linux/limits.h> 24#include <linux/limits.h>
@@ -26,7 +27,6 @@
26#include <dirent.h> 27#include <dirent.h>
27#include <fcntl.h> 28#include <fcntl.h>
28#include <errno.h> 29#include <errno.h>
29#include "../../uids.h"
30 30
31#define MAXBUF 1024 31#define MAXBUF 1024
32 32
@@ -115,8 +115,9 @@ static void sanitize_passwd(void) {
115 struct stat s; 115 struct stat s;
116 if (stat("/etc/passwd", &s) == -1) 116 if (stat("/etc/passwd", &s) == -1)
117 return; 117 return;
118 assert(uid_min);
118 if (arg_debug) 119 if (arg_debug)
119 printf("Sanitizing /etc/passwd, UID_MIN %d\n", UID_MIN); 120 printf("Sanitizing /etc/passwd, UID_MIN %d\n", uid_min);
120 if (is_link("/etc/passwd")) { 121 if (is_link("/etc/passwd")) {
121 fprintf(stderr, "Error: invalid /etc/passwd\n"); 122 fprintf(stderr, "Error: invalid /etc/passwd\n");
122 exit(1); 123 exit(1);
@@ -167,7 +168,8 @@ static void sanitize_passwd(void) {
167 int rv = sscanf(ptr, "%d:", &uid); 168 int rv = sscanf(ptr, "%d:", &uid);
168 if (rv == 0 || uid < 0) 169 if (rv == 0 || uid < 0)
169 goto errout; 170 goto errout;
170 if (uid < UID_MIN || uid == 65534) { // on Debian platforms user nobody is 65534 171 assert(uid_min);
172 if (uid < uid_min || uid == 65534) { // on Debian platforms user nobody is 65534
171 fprintf(fpout, "%s", buf); 173 fprintf(fpout, "%s", buf);
172 continue; 174 continue;
173 } 175 }
@@ -248,8 +250,9 @@ static void sanitize_group(void) {
248 struct stat s; 250 struct stat s;
249 if (stat("/etc/group", &s) == -1) 251 if (stat("/etc/group", &s) == -1)
250 return; 252 return;
253 assert(gid_min);
251 if (arg_debug) 254 if (arg_debug)
252 printf("Sanitizing /etc/group, GID_MIN %d\n", GID_MIN); 255 printf("Sanitizing /etc/group, GID_MIN %d\n", gid_min);
253 if (is_link("/etc/group")) { 256 if (is_link("/etc/group")) {
254 fprintf(stderr, "Error: invalid /etc/group\n"); 257 fprintf(stderr, "Error: invalid /etc/group\n");
255 exit(1); 258 exit(1);
@@ -299,7 +302,8 @@ static void sanitize_group(void) {
299 int rv = sscanf(ptr, "%d:", &gid); 302 int rv = sscanf(ptr, "%d:", &gid);
300 if (rv == 0 || gid < 0) 303 if (rv == 0 || gid < 0)
301 goto errout; 304 goto errout;
302 if (gid < GID_MIN || gid == 65534) { // on Debian platforms 65534 is group nogroup 305 assert(gid_min);
306 if (gid < gid_min || gid == 65534) { // on Debian platforms 65534 is group nogroup
303 if (copy_line(fpout, buf, ptr)) 307 if (copy_line(fpout, buf, ptr))
304 goto errout; 308 goto errout;
305 continue; 309 continue;
diff --git a/src/include/firejail_user.h b/src/include/firejail_user.h
index a7d30225e..66e618fbe 100644
--- a/src/include/firejail_user.h
+++ b/src/include/firejail_user.h
@@ -20,6 +20,8 @@
20#ifndef FIREJAIL_USER_H 20#ifndef FIREJAIL_USER_H
21#define FIREJAIL_USER_H 21#define FIREJAIL_USER_H
22 22
23extern int uid_min;
24extern int gid_min;
23 25
24// returns 1 if the user is found in the database or if the database was not created 26// returns 1 if the user is found in the database or if the database was not created
25int firejail_user_check(const char *name); 27int firejail_user_check(const char *name);
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
36int uid_min = 0;
37int gid_min = 0;
38
39static 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
85errexit:
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
34static inline char *get_fname(void) { 93static 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
42int firejail_user_check(const char *name) { 102int 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