mirror of
https://github.com/netblue30/firejail.git
synced 2026-05-15 14:16:14 -06:00
evaluate UID_MIN/GID_MID at runtime, remove compile time evaluation - fixes #1964
This commit is contained in:
parent
df5c9f035a
commit
ac92833652
4 changed files with 79 additions and 13 deletions
10
Makefile.in
10
Makefile.in
|
|
@ -22,16 +22,14 @@ HAVE_CONTRIB_INSTALL=@HAVE_CONTRIB_INSTALL@
|
|||
BUSYBOX_WORKAROUND=@BUSYBOX_WORKAROUND@
|
||||
HAVE_SUID=@HAVE_SUID@
|
||||
|
||||
uids.h:; ./mkuid.sh
|
||||
|
||||
.PHONY: mylibs $(MYLIBS)
|
||||
mylibs: $(MYLIBS)
|
||||
$(MYLIBS): uids.h
|
||||
$(MYLIBS):
|
||||
$(MAKE) -C $@
|
||||
|
||||
.PHONY: apps $(APPS)
|
||||
apps: $(APPS)
|
||||
$(APPS): $(MYLIBS) uids.h
|
||||
$(APPS): $(MYLIBS)
|
||||
$(MAKE) -C $@
|
||||
|
||||
$(MANPAGES): $(wildcard src/man/*.txt)
|
||||
|
|
@ -73,7 +71,7 @@ distclean: clean
|
|||
for dir in $(APPS) $(MYLIBS); do \
|
||||
$(MAKE) -C $$dir distclean; \
|
||||
done
|
||||
rm -fr Makefile autom4te.cache config.log config.status config.h uids.h dummy.o src/common.mk
|
||||
rm -fr Makefile autom4te.cache config.log config.status config.h dummy.o src/common.mk
|
||||
|
||||
realinstall:
|
||||
# firejail executable
|
||||
|
|
@ -192,7 +190,7 @@ uninstall:
|
|||
rm -f $(DESTDIR)/$(datarootdir)/bash-completion/completions/firemon
|
||||
rm -f $(DESTDIR)/$(datarootdir)/bash-completion/completions/firecfg
|
||||
|
||||
DISTFILES = "src etc platform contrib configure configure.ac dummy.c Makefile.in install.sh mkman.sh mketc.sh mkdeb.sh mkuid.sh COPYING README RELNOTES"
|
||||
DISTFILES = "src etc platform contrib configure configure.ac dummy.c Makefile.in install.sh mkman.sh mketc.sh mkdeb.sh COPYING README RELNOTES"
|
||||
DISTFILES_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"
|
||||
|
||||
dist:
|
||||
|
|
|
|||
|
|
@ -18,6 +18,7 @@
|
|||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
#include "firejail.h"
|
||||
#include "../include/firejail_user.h"
|
||||
#include <sys/mount.h>
|
||||
#include <sys/stat.h>
|
||||
#include <linux/limits.h>
|
||||
|
|
@ -26,7 +27,6 @@
|
|||
#include <dirent.h>
|
||||
#include <fcntl.h>
|
||||
#include <errno.h>
|
||||
#include "../../uids.h"
|
||||
|
||||
#define MAXBUF 1024
|
||||
|
||||
|
|
@ -115,8 +115,9 @@ static void sanitize_passwd(void) {
|
|||
struct stat s;
|
||||
if (stat("/etc/passwd", &s) == -1)
|
||||
return;
|
||||
assert(uid_min);
|
||||
if (arg_debug)
|
||||
printf("Sanitizing /etc/passwd, UID_MIN %d\n", UID_MIN);
|
||||
printf("Sanitizing /etc/passwd, UID_MIN %d\n", uid_min);
|
||||
if (is_link("/etc/passwd")) {
|
||||
fprintf(stderr, "Error: invalid /etc/passwd\n");
|
||||
exit(1);
|
||||
|
|
@ -167,7 +168,8 @@ static void sanitize_passwd(void) {
|
|||
int rv = sscanf(ptr, "%d:", &uid);
|
||||
if (rv == 0 || uid < 0)
|
||||
goto errout;
|
||||
if (uid < UID_MIN || uid == 65534) { // on Debian platforms user nobody is 65534
|
||||
assert(uid_min);
|
||||
if (uid < uid_min || uid == 65534) { // on Debian platforms user nobody is 65534
|
||||
fprintf(fpout, "%s", buf);
|
||||
continue;
|
||||
}
|
||||
|
|
@ -248,8 +250,9 @@ static void sanitize_group(void) {
|
|||
struct stat s;
|
||||
if (stat("/etc/group", &s) == -1)
|
||||
return;
|
||||
assert(gid_min);
|
||||
if (arg_debug)
|
||||
printf("Sanitizing /etc/group, GID_MIN %d\n", GID_MIN);
|
||||
printf("Sanitizing /etc/group, GID_MIN %d\n", gid_min);
|
||||
if (is_link("/etc/group")) {
|
||||
fprintf(stderr, "Error: invalid /etc/group\n");
|
||||
exit(1);
|
||||
|
|
@ -299,7 +302,8 @@ static void sanitize_group(void) {
|
|||
int rv = sscanf(ptr, "%d:", &gid);
|
||||
if (rv == 0 || gid < 0)
|
||||
goto errout;
|
||||
if (gid < GID_MIN || gid == 65534) { // on Debian platforms 65534 is group nogroup
|
||||
assert(gid_min);
|
||||
if (gid < gid_min || gid == 65534) { // on Debian platforms 65534 is group nogroup
|
||||
if (copy_line(fpout, buf, ptr))
|
||||
goto errout;
|
||||
continue;
|
||||
|
|
|
|||
|
|
@ -20,6 +20,8 @@
|
|||
#ifndef FIREJAIL_USER_H
|
||||
#define FIREJAIL_USER_H
|
||||
|
||||
extern int uid_min;
|
||||
extern int gid_min;
|
||||
|
||||
// returns 1 if the user is found in the database or if the database was not created
|
||||
int firejail_user_check(const char *name);
|
||||
|
|
|
|||
|
|
@ -26,11 +26,70 @@
|
|||
// One username per line in the file
|
||||
|
||||
#include "../include/common.h"
|
||||
#include "../include/firejail_user.h"
|
||||
#include <sys/types.h>
|
||||
#include <pwd.h>
|
||||
#include "../../uids.h"
|
||||
|
||||
#define MAXBUF 4098
|
||||
|
||||
// minimum values for uid and gid extracted from /etc/login.defs
|
||||
int uid_min = 0;
|
||||
int gid_min = 0;
|
||||
|
||||
static void init_uid_gid_min(void) {
|
||||
if (uid_min != 0 && gid_min != 0)
|
||||
return;
|
||||
|
||||
// read the real values from login.def
|
||||
FILE *fp = fopen("/etc/login.defs", "r");
|
||||
if (!fp)
|
||||
goto errexit;
|
||||
|
||||
char buf[MAXBUF];
|
||||
while (fgets(buf, MAXBUF, fp)) {
|
||||
// comments
|
||||
if (*buf == '#')
|
||||
continue;
|
||||
// skip empty space
|
||||
char *ptr = buf;
|
||||
while (*ptr == ' ' || *ptr == '\t')
|
||||
ptr++;
|
||||
|
||||
if (strncmp(ptr, "UID_MIN", 7) == 0) {
|
||||
int rv = sscanf(ptr + 7, "%d", &uid_min);
|
||||
if (rv != 1 || uid_min < 0) {
|
||||
fclose(fp);
|
||||
goto errexit;
|
||||
}
|
||||
}
|
||||
else if (strncmp(ptr, "GID_MIN", 7) == 0) {
|
||||
int rv = sscanf(ptr + 7, "%d", &gid_min);
|
||||
if (rv != 1 || gid_min < 0) {
|
||||
fclose(fp);
|
||||
goto errexit;
|
||||
}
|
||||
}
|
||||
|
||||
if (uid_min != 0 && gid_min != 0)
|
||||
break;
|
||||
|
||||
}
|
||||
fclose(fp);
|
||||
|
||||
if (uid_min == 0 || gid_min == 0)
|
||||
goto errexit;
|
||||
//printf("uid_min %d, gid_min %d\n", uid_min, gid_min);
|
||||
|
||||
return;
|
||||
|
||||
errexit:
|
||||
fprintf(stderr, "Error: cannot read UID_MIN and/or GID_MIN from /etc/login.defs, using 1000 by default\n");
|
||||
uid_min = 1000;
|
||||
gid_min = 1000;
|
||||
}
|
||||
|
||||
|
||||
|
||||
static inline char *get_fname(void) {
|
||||
char *fname;
|
||||
if (asprintf(&fname, "%s/firejail.users", SYSCONFDIR) == -1)
|
||||
|
|
@ -38,9 +97,11 @@ static inline char *get_fname(void) {
|
|||
return fname;
|
||||
}
|
||||
|
||||
|
||||
// returns 1 if the user is found in the database or if the database was not created
|
||||
int firejail_user_check(const char *name) {
|
||||
assert(name);
|
||||
init_uid_gid_min();
|
||||
|
||||
// root is allowed to run firejail by default
|
||||
if (strcmp(name, "root") == 0)
|
||||
|
|
@ -48,7 +109,8 @@ int firejail_user_check(const char *name) {
|
|||
|
||||
// other system users will run the program as is
|
||||
uid_t uid = getuid();
|
||||
if ((uid < UID_MIN && uid != 0) || strcmp(name, "nobody") == 0)
|
||||
assert(uid_min > 0);
|
||||
if (((int) uid < uid_min && uid != 0) || strcmp(name, "nobody") == 0)
|
||||
return 0;
|
||||
|
||||
// check file existence
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue