aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLibravatar netblue30 <netblue30@yahoo.com>2018-04-09 09:43:13 -0400
committerLibravatar netblue30 <netblue30@yahoo.com>2018-04-09 09:43:13 -0400
commitbbaba69f23ae9e181677044b5afb8c29b3eb83b5 (patch)
tree23218ae24f5ab2969ec6d817754a0b1aa71326e7
parentuid test utility (diff)
downloadfirejail-bbaba69f23ae9e181677044b5afb8c29b3eb83b5.tar.gz
firejail-bbaba69f23ae9e181677044b5afb8c29b3eb83b5.tar.zst
firejail-bbaba69f23ae9e181677044b5afb8c29b3eb83b5.zip
noroot uid/gid/supplementary group fixes; problems found by smitsohu
-rw-r--r--src/firejail/sandbox.c10
-rw-r--r--src/firejail/util.c85
2 files changed, 62 insertions, 33 deletions
diff --git a/src/firejail/sandbox.c b/src/firejail/sandbox.c
index 1e60b6477..709ce96b6 100644
--- a/src/firejail/sandbox.c
+++ b/src/firejail/sandbox.c
@@ -1022,19 +1022,17 @@ int sandbox(void* sandbox_arg) {
1022#endif 1022#endif
1023 1023
1024 //**************************************** 1024 //****************************************
1025 // drop privileges or create a new user namespace 1025 // create a new user namespace
1026 // - too early to drop privileges
1026 //**************************************** 1027 //****************************************
1027 save_nogroups(); 1028 save_nogroups();
1028 if (arg_noroot) { 1029 if (arg_noroot) {
1029 int rv = unshare(CLONE_NEWUSER); 1030 int rv = unshare(CLONE_NEWUSER);
1030 if (rv == -1) { 1031 if (rv == -1) {
1031 fwarning("cannot create a new user namespace, going forward without it...\n"); 1032 fwarning("cannot create a new user namespace, going forward without it...\n");
1032 drop_privs(arg_nogroups);
1033 arg_noroot = 0; 1033 arg_noroot = 0;
1034 } 1034 }
1035 } 1035 }
1036 else
1037 drop_privs(arg_nogroups);
1038 1036
1039 // notify parent that new user namespace has been created so a proper 1037 // notify parent that new user namespace has been created so a proper
1040 // UID/GID map can be setup 1038 // UID/GID map can be setup
@@ -1066,8 +1064,9 @@ int sandbox(void* sandbox_arg) {
1066 } 1064 }
1067 1065
1068 //**************************************** 1066 //****************************************
1069 // fork the application and monitor it 1067 // drop privileges, fork the application and monitor it
1070 //**************************************** 1068 //****************************************
1069 drop_privs(arg_nogroups);
1071 pid_t app_pid = fork(); 1070 pid_t app_pid = fork();
1072 if (app_pid == -1) 1071 if (app_pid == -1)
1073 errExit("fork"); 1072 errExit("fork");
@@ -1085,6 +1084,7 @@ int sandbox(void* sandbox_arg) {
1085 printf("AppArmor enabled\n"); 1084 printf("AppArmor enabled\n");
1086 } 1085 }
1087#endif 1086#endif
1087
1088 prctl(PR_SET_PDEATHSIG, SIGKILL, 0, 0, 0); // kill the child in case the parent died 1088 prctl(PR_SET_PDEATHSIG, SIGKILL, 0, 0, 0); // kill the child in case the parent died
1089 start_application(0); // start app 1089 start_application(0); // start app
1090 } 1090 }
diff --git a/src/firejail/util.c b/src/firejail/util.c
index c644f83a8..14e9f6440 100644
--- a/src/firejail/util.c
+++ b/src/firejail/util.c
@@ -32,6 +32,61 @@
32#include <sys/wait.h> 32#include <sys/wait.h>
33 33
34#define MAX_GROUPS 1024 34#define MAX_GROUPS 1024
35
36static void clean_supplementary_groups(gid_t gid) {
37 assert(cfg.username);
38 gid_t groups[MAX_GROUPS];
39 int ngroups = MAX_GROUPS;
40
41 int rv = getgrouplist(cfg.username, gid, groups, &ngroups);
42 if (rv == -1)
43 goto clean_all;
44
45 // clean supplementary group list
46 // allow only tty, audio, video, games
47 gid_t new_groups[MAX_GROUPS];
48 int new_ngroups = 0;
49 char *allowed[] = {
50 "tty",
51 "audio",
52 "video",
53 "games",
54 NULL
55 };
56
57 int i = 0;
58 while (allowed[i]) {
59 gid_t g = get_group_id(allowed[i]);
60 if (g) {
61 int j;
62 for (j = 0; j < ngroups; j++) {
63 if (g == groups[j]) {
64 new_groups[new_ngroups] = g;
65 new_ngroups++;
66 break;
67 }
68 }
69 }
70 i++;
71 }
72
73 if (new_ngroups) {
74 rv = setgroups(new_ngroups, new_groups);
75 if (rv)
76 goto clean_all;
77 }
78 else
79 goto clean_all;
80
81 return;
82
83clean_all:
84 fwarning("cleaning all supplementary groups\n");
85 if (setgroups(0, NULL) < 0)
86 errExit("setgroups");
87}
88
89
35// drop privileges 90// drop privileges
36// - for root group or if nogroups is set, supplementary groups are not configured 91// - for root group or if nogroups is set, supplementary groups are not configured
37void drop_privs(int nogroups) { 92void drop_privs(int nogroups) {
@@ -45,34 +100,8 @@ void drop_privs(int nogroups) {
45 if (arg_debug) 100 if (arg_debug)
46 printf("Username %s, no supplementary groups\n", cfg.username); 101 printf("Username %s, no supplementary groups\n", cfg.username);
47 } 102 }
48 else { 103 else if (arg_noroot)
49 assert(cfg.username); 104 clean_supplementary_groups(gid);
50 gid_t groups[MAX_GROUPS];
51 int ngroups = MAX_GROUPS;
52 int rv = getgrouplist(cfg.username, gid, groups, &ngroups);
53
54 if (arg_debug && rv) {
55 printf("Username %s, groups ", cfg.username);
56 int i;
57 for (i = 0; i < ngroups; i++)
58 printf("%u, ", groups[i]);
59 printf("\n");
60 }
61
62 if (rv == -1) {
63 fwarning("cannot extract supplementary group list, dropping them\n");
64 if (setgroups(0, NULL) < 0)
65 errExit("setgroups");
66 }
67 else {
68 rv = setgroups(ngroups, groups);
69 if (rv) {
70 fwarning("cannot set supplementary group list, dropping them\n");
71 if (setgroups(0, NULL) < 0)
72 errExit("setgroups");
73 }
74 }
75 }
76 105
77 // set uid/gid 106 // set uid/gid
78 if (setgid(getgid()) < 0) 107 if (setgid(getgid()) < 0)