mirror of
https://github.com/netblue30/firejail.git
synced 2026-07-19 07:47:51 -06:00
deprecated --private-home
Some checks failed
Build-extra / build-gcc (push) Has been cancelled
Build-extra / build-clang (push) Has been cancelled
Build / build (push) Has been cancelled
Check-C / scan-build (push) Has been cancelled
Check-C / cppcheck (push) Has been cancelled
Check-C / codeql-cpp (push) Has been cancelled
Check-Profiles / profile-checks (push) Has been cancelled
Codespell / codespell (push) Has been cancelled
Test / test-main (push) Has been cancelled
Test / test-fs (push) Has been cancelled
Test / test-environment (push) Has been cancelled
Test / test-utils (push) Has been cancelled
Test / test-network (push) Has been cancelled
Some checks failed
Build-extra / build-gcc (push) Has been cancelled
Build-extra / build-clang (push) Has been cancelled
Build / build (push) Has been cancelled
Check-C / scan-build (push) Has been cancelled
Check-C / cppcheck (push) Has been cancelled
Check-C / codeql-cpp (push) Has been cancelled
Check-Profiles / profile-checks (push) Has been cancelled
Codespell / codespell (push) Has been cancelled
Test / test-main (push) Has been cancelled
Test / test-fs (push) Has been cancelled
Test / test-environment (push) Has been cancelled
Test / test-utils (push) Has been cancelled
Test / test-network (push) Has been cancelled
This commit is contained in:
parent
a55ce9e1ae
commit
e5eefcf5f7
11 changed files with 4 additions and 307 deletions
|
|
@ -39,7 +39,6 @@ HAVE_LANDLOCK=@HAVE_LANDLOCK@
|
|||
HAVE_NETWORK=@HAVE_NETWORK@
|
||||
HAVE_ONLY_SYSCFG_PROFILES=@HAVE_ONLY_SYSCFG_PROFILES@
|
||||
HAVE_OUTPUT=@HAVE_OUTPUT@
|
||||
HAVE_PRIVATE_HOME=@HAVE_PRIVATE_HOME@
|
||||
HAVE_PRIVATE_LIB=@HAVE_PRIVATE_LIB@
|
||||
HAVE_SANDBOX_CHECK=@HAVE_SANDBOX_CHECK@
|
||||
HAVE_SELINUX=@HAVE_SELINUX@
|
||||
|
|
|
|||
|
|
@ -129,14 +129,6 @@ AS_IF([test "x$enable_output" != "xno"], [
|
|||
HAVE_OUTPUT="-DHAVE_OUTPUT"
|
||||
])
|
||||
|
||||
HAVE_PRIVATE_HOME=""
|
||||
AC_SUBST([HAVE_PRIVATE_HOME])
|
||||
AC_ARG_ENABLE([private-home],
|
||||
[AS_HELP_STRING([--disable-private-home], [disable private home feature])])
|
||||
AS_IF([test "x$enable_private_home" != "xno"], [
|
||||
HAVE_PRIVATE_HOME="-DHAVE_PRIVATE_HOME"
|
||||
])
|
||||
|
||||
HAVE_PRIVATE_LIB=""
|
||||
AC_SUBST([HAVE_PRIVATE_LIB])
|
||||
AC_ARG_ENABLE([private-lib],
|
||||
|
|
@ -275,7 +267,6 @@ Features:
|
|||
file transfer support: $HAVE_FILE_TRANSFER
|
||||
Landlock support: $HAVE_LANDLOCK
|
||||
network: $HAVE_NETWORK
|
||||
private home support: $HAVE_PRIVATE_HOME
|
||||
private lib support: $HAVE_PRIVATE_LIB
|
||||
sandbox check: $HAVE_SANDBOX_CHECK
|
||||
SELinux labeling support: $HAVE_SELINUX
|
||||
|
|
|
|||
|
|
@ -113,7 +113,7 @@
|
|||
# Enable or disable private-etc feature, default enabled.
|
||||
# private-etc yes
|
||||
|
||||
# Enable or disable private-home feature, default enabled
|
||||
# private-home feature was deprecated in firejail version 0.9.81
|
||||
# private-home yes
|
||||
|
||||
# Enable or disable private-lib feature, default disabled
|
||||
|
|
|
|||
|
|
@ -65,7 +65,6 @@ const char *const cfgstr[] = {
|
|||
[CFG_PRIVATE_BIN_NO_LOCAL] = "private-bin-no-local",
|
||||
[CFG_PRIVATE_CACHE] = "private-cache",
|
||||
[CFG_PRIVATE_ETC] = "private-etc",
|
||||
[CFG_PRIVATE_HOME] = "private-home",
|
||||
[CFG_PRIVATE_LIB] = "private-lib",
|
||||
[CFG_PRIVATE_OPT] = "private-opt",
|
||||
[CFG_PRIVATE_SRV] = "private-srv",
|
||||
|
|
@ -173,7 +172,6 @@ int checkcfg(int val) {
|
|||
PARSE_YESNO(CFG_PRIVATE_BIN_NO_LOCAL, "private-bin-no-local")
|
||||
PARSE_YESNO(CFG_PRIVATE_CACHE, "private-cache")
|
||||
PARSE_YESNO(CFG_PRIVATE_ETC, "private-etc")
|
||||
PARSE_YESNO(CFG_PRIVATE_HOME, "private-home")
|
||||
PARSE_YESNO(CFG_PRIVATE_LIB, "private-lib")
|
||||
PARSE_YESNO(CFG_PRIVATE_OPT, "private-opt")
|
||||
PARSE_YESNO(CFG_PRIVATE_SRV, "private-srv")
|
||||
|
|
@ -187,6 +185,8 @@ int checkcfg(int val) {
|
|||
#undef PARSE_YESNO
|
||||
else if (strncmp(ptr, "tracelog", 8) == 0)
|
||||
; // tracelog feature was deprecated in firejail version 0.9.81
|
||||
else if (strncmp(ptr, "private-home", 12) == 0)
|
||||
; // tracelog feature was deprecated in firejail version 0.9.81
|
||||
|
||||
// netfilter
|
||||
else if (strncmp(ptr, "netfilter-default ", 18) == 0) {
|
||||
|
|
@ -466,13 +466,6 @@ static const char *const compiletime_support =
|
|||
"disabled"
|
||||
#endif
|
||||
|
||||
"\n\t- private-home support is "
|
||||
#ifdef HAVE_PRIVATE_HOME
|
||||
"enabled"
|
||||
#else
|
||||
"disabled"
|
||||
#endif
|
||||
|
||||
"\n\t- private-lib support is "
|
||||
#ifdef HAVE_PRIVATE_LIB
|
||||
"enabled"
|
||||
|
|
|
|||
|
|
@ -178,7 +178,6 @@ typedef struct config_t {
|
|||
char *keep_fd; // inherit file descriptors to sandbox
|
||||
char *chrootdir; // chroot directory
|
||||
char *home_private; // private home directory
|
||||
char *home_private_keep; // keep list for private home directory
|
||||
char *etc_private_keep; // keep list for private etc directory
|
||||
char *opt_private_keep; // keep list for private opt directory
|
||||
char *srv_private_keep; // keep list for private srv directory
|
||||
|
|
@ -658,7 +657,6 @@ void fs_private_homedir(void);
|
|||
void fs_check_private_dir(void);
|
||||
// check new private working directory (--private-cwd= option) - exit if it fails
|
||||
void fs_check_private_cwd(const char *dir);
|
||||
void fs_private_home_list(void);
|
||||
|
||||
|
||||
// seccomp.c
|
||||
|
|
@ -849,7 +847,6 @@ enum {
|
|||
CFG_PRIVATE_BIN_NO_LOCAL,
|
||||
CFG_PRIVATE_CACHE,
|
||||
CFG_PRIVATE_ETC,
|
||||
CFG_PRIVATE_HOME,
|
||||
CFG_PRIVATE_LIB,
|
||||
CFG_PRIVATE_OPT,
|
||||
CFG_PRIVATE_SRV,
|
||||
|
|
|
|||
|
|
@ -483,211 +483,3 @@ errout:
|
|||
exit(1);
|
||||
}
|
||||
|
||||
//***********************************************************************************
|
||||
// --private-home
|
||||
//***********************************************************************************
|
||||
static char *check_dir_or_file(const char *name) {
|
||||
EUID_ASSERT();
|
||||
assert(name);
|
||||
|
||||
// basic checks
|
||||
invalid_filename(name, 0); // no globbing
|
||||
if (arg_debug)
|
||||
printf("Private home: checking %s\n", name);
|
||||
|
||||
// expand home directory
|
||||
char *fname = expand_macros(name);
|
||||
assert(fname);
|
||||
|
||||
// If it doesn't start with '/', it must be relative to homedir
|
||||
if (fname[0] != '/') {
|
||||
char* tmp;
|
||||
if (asprintf(&tmp, "%s/%s", cfg.homedir, fname) == -1)
|
||||
errExit("asprintf");
|
||||
free(fname);
|
||||
fname = tmp;
|
||||
}
|
||||
|
||||
// we allow only files in user home directory or symbolic links to files or directories owned by the user
|
||||
struct stat s;
|
||||
if (lstat(fname, &s) == 0 && S_ISLNK(s.st_mode)) {
|
||||
if (strncmp(fname, cfg.homedir, strlen(cfg.homedir)) != 0 || fname[strlen(cfg.homedir)] != '/')
|
||||
goto errexit;
|
||||
if (stat(fname, &s) == 0) {
|
||||
if (s.st_uid != getuid()) {
|
||||
fprintf(stderr, "Error: symbolic link %s to file or directory not owned by the user\n", fname);
|
||||
exit(1);
|
||||
}
|
||||
return fname;
|
||||
}
|
||||
else // dangling link
|
||||
goto errexit;
|
||||
}
|
||||
else {
|
||||
// check the file is in user home directory
|
||||
char *rname = realpath(fname, NULL);
|
||||
if (!rname || strncmp(rname, cfg.homedir, strlen(cfg.homedir)) != 0)
|
||||
goto errexit;
|
||||
// a full home directory is not allowed
|
||||
char *ptr = rname + strlen(cfg.homedir);
|
||||
if (*ptr != '/')
|
||||
goto errexit;
|
||||
// only top files and directories in user home are allowed
|
||||
ptr = strchr(++ptr, '/');
|
||||
if (ptr) {
|
||||
fprintf(stderr, "Error: only top files and directories in user home are allowed\n");
|
||||
exit(1);
|
||||
}
|
||||
free(fname);
|
||||
return rname;
|
||||
}
|
||||
|
||||
errexit:
|
||||
fprintf(stderr, "Error: invalid file %s\n", name);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
static void duplicate(char *name) {
|
||||
EUID_ASSERT();
|
||||
char *fname = check_dir_or_file(name);
|
||||
|
||||
if (arg_debug)
|
||||
printf("Private home: duplicating %s\n", fname);
|
||||
assert(strncmp(fname, cfg.homedir, strlen(cfg.homedir)) == 0);
|
||||
|
||||
struct stat s;
|
||||
if (lstat(fname, &s) == -1) {
|
||||
free(fname);
|
||||
return;
|
||||
}
|
||||
else if (S_ISDIR(s.st_mode)) {
|
||||
// create the directory in RUN_HOME_DIR
|
||||
char *path;
|
||||
char *ptr = strrchr(fname, '/');
|
||||
ptr++;
|
||||
if (asprintf(&path, "%s/%s", RUN_HOME_DIR, ptr) == -1)
|
||||
errExit("asprintf");
|
||||
create_empty_dir_as_user(path, 0755);
|
||||
sbox_run(SBOX_USER| SBOX_CAPS_NONE | SBOX_SECCOMP, 3, PATH_FCOPY, fname, path);
|
||||
free(path);
|
||||
}
|
||||
else
|
||||
sbox_run(SBOX_USER| SBOX_CAPS_NONE | SBOX_SECCOMP, 3, PATH_FCOPY, fname, RUN_HOME_DIR);
|
||||
fs_logger2("clone", fname);
|
||||
fs_logger_print(); // save the current log
|
||||
|
||||
free(fname);
|
||||
}
|
||||
|
||||
// private mode (--private-home=list):
|
||||
// mount homedir on top of /home/user,
|
||||
// tmpfs on top of /root in nonroot mode,
|
||||
// tmpfs on top of /tmp in root mode,
|
||||
// set skel files,
|
||||
// restore .Xauthority
|
||||
void fs_private_home_list(void) {
|
||||
char *homedir = cfg.homedir;
|
||||
char *private_list = cfg.home_private_keep;
|
||||
assert(homedir);
|
||||
assert(private_list);
|
||||
EUID_ASSERT();
|
||||
|
||||
timetrace_start();
|
||||
|
||||
uid_t uid = getuid();
|
||||
gid_t gid = getgid();
|
||||
|
||||
int xflag = store_xauthority();
|
||||
int aflag = store_asoundrc();
|
||||
|
||||
EUID_ROOT();
|
||||
// create /run/firejail/mnt/home directory
|
||||
mkdir_attr(RUN_HOME_DIR, 0755, uid, gid);
|
||||
selinux_relabel_path(RUN_HOME_DIR, homedir);
|
||||
|
||||
// save the current log
|
||||
fs_logger_print();
|
||||
EUID_USER();
|
||||
|
||||
// copy the list of files in the new home directory
|
||||
if (arg_debug)
|
||||
printf("Copying files in the new home:\n");
|
||||
char *dlist = strdup(cfg.home_private_keep);
|
||||
if (!dlist)
|
||||
errExit("strdup");
|
||||
|
||||
char *ptr = strtok(dlist, ",");
|
||||
if (!ptr) {
|
||||
fprintf(stderr, "Error: invalid private-home argument\n");
|
||||
exit(1);
|
||||
}
|
||||
duplicate(ptr);
|
||||
while ((ptr = strtok(NULL, ",")) != NULL)
|
||||
duplicate(ptr);
|
||||
|
||||
fs_logger_print(); // save the current log
|
||||
free(dlist);
|
||||
|
||||
if (arg_debug)
|
||||
printf("Mount-bind %s on top of %s\n", RUN_HOME_DIR, homedir);
|
||||
|
||||
int fd = safer_openat(-1, homedir, O_PATH|O_DIRECTORY|O_NOFOLLOW|O_CLOEXEC);
|
||||
if (fd == -1)
|
||||
errExit("opening home directory");
|
||||
// home directory should be owned by the user
|
||||
struct stat s;
|
||||
if (fstat(fd, &s) == -1)
|
||||
errExit("fstat");
|
||||
if (s.st_uid != uid) {
|
||||
fprintf(stderr, "Error: cannot mount private directory:\n"
|
||||
"Home directory is not owned by the current user\n");
|
||||
exit(1);
|
||||
}
|
||||
// mount using the file descriptor
|
||||
EUID_ROOT();
|
||||
if (bind_mount_path_to_fd(RUN_HOME_DIR, fd))
|
||||
errExit("mount bind");
|
||||
EUID_USER();
|
||||
close(fd);
|
||||
|
||||
// check /proc/self/mountinfo to confirm the mount is ok
|
||||
MountData *mptr = get_last_mount();
|
||||
if (strcmp(mptr->dir, homedir) != 0 || strcmp(mptr->fstype, "tmpfs") != 0)
|
||||
errLogExit("invalid private-home mount");
|
||||
fs_logger2("tmpfs", homedir);
|
||||
|
||||
EUID_ROOT();
|
||||
if (uid != 0) {
|
||||
// mask /root
|
||||
if (arg_debug)
|
||||
printf("Mounting a new /root directory\n");
|
||||
if (mount("tmpfs", "/root", "tmpfs", MS_NOSUID | MS_NODEV | MS_STRICTATIME, "mode=700,gid=0") < 0)
|
||||
errExit("mounting /root directory");
|
||||
selinux_relabel_path("/root", "/root");
|
||||
fs_logger("tmpfs /root");
|
||||
}
|
||||
if (uid == 0 && !arg_allusers) {
|
||||
// mask /home
|
||||
if (arg_debug)
|
||||
printf("Mounting a new /home directory\n");
|
||||
if (mount("tmpfs", "/home", "tmpfs", MS_NOSUID | MS_NODEV | MS_STRICTATIME, "mode=755,gid=0") < 0)
|
||||
errExit("mounting /home directory");
|
||||
selinux_relabel_path("/home", "/home");
|
||||
fs_logger("tmpfs /home");
|
||||
}
|
||||
|
||||
// mask RUN_HOME_DIR, it is writable and not noexec
|
||||
if (mount("tmpfs", RUN_HOME_DIR, "tmpfs", MS_NOSUID | MS_NODEV | MS_STRICTATIME, "mode=755,gid=0") < 0)
|
||||
errExit("mounting tmpfs");
|
||||
EUID_USER();
|
||||
|
||||
if (!arg_keep_shell_rc)
|
||||
skel(homedir);
|
||||
if (xflag)
|
||||
copy_xauthority();
|
||||
if (aflag)
|
||||
copy_asoundrc();
|
||||
|
||||
if (!arg_quiet)
|
||||
fprintf(stderr, "Home directory installed in %0.2f ms\n", timetrace_end());
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1865,11 +1865,6 @@ int main(int argc, char **argv, char **envp) {
|
|||
arg_private = 1;
|
||||
}
|
||||
else if (strncmp(argv[i], "--private=", 10) == 0) {
|
||||
if (cfg.home_private_keep) {
|
||||
fprintf(stderr, "Error: a private list of files was already defined with --private-home option.\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
// extract private home dirname
|
||||
cfg.home_private = argv[i] + 10;
|
||||
if (*cfg.home_private == '\0') {
|
||||
|
|
@ -1885,30 +1880,6 @@ int main(int argc, char **argv, char **envp) {
|
|||
}
|
||||
arg_private = 1;
|
||||
}
|
||||
#ifdef HAVE_PRIVATE_HOME
|
||||
else if (strncmp(argv[i], "--private-home=", 15) == 0) {
|
||||
if (checkcfg(CFG_PRIVATE_HOME)) {
|
||||
if (cfg.home_private) {
|
||||
fprintf(stderr, "Error: a private home directory was already defined with --private option.\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
// extract private home dirname
|
||||
if (*(argv[i] + 15) == '\0') {
|
||||
fprintf(stderr, "Error: invalid private-home option\n");
|
||||
exit(1);
|
||||
}
|
||||
if (cfg.home_private_keep) {
|
||||
if ( asprintf(&cfg.home_private_keep, "%s,%s", cfg.home_private_keep, argv[i] + 15) < 0 )
|
||||
errExit("asprintf");
|
||||
} else
|
||||
cfg.home_private_keep = argv[i] + 15;
|
||||
arg_private = 1;
|
||||
}
|
||||
else
|
||||
exit_err_feature(argv[i], CFG_PRIVATE_HOME);
|
||||
}
|
||||
#endif
|
||||
else if (strcmp(argv[i], "--private-dev") == 0) {
|
||||
arg_private_dev = 1;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -384,18 +384,7 @@ int profile_check_line(char *ptr, int lineno, const char *fname) {
|
|||
return 0;
|
||||
}
|
||||
else if (strncmp(ptr, "private-home ", 13) == 0) {
|
||||
#ifdef HAVE_PRIVATE_HOME
|
||||
if (checkcfg(CFG_PRIVATE_HOME)) {
|
||||
if (cfg.home_private_keep) {
|
||||
if ( asprintf(&cfg.home_private_keep, "%s,%s", cfg.home_private_keep, ptr + 13) < 0 )
|
||||
errExit("asprintf");
|
||||
} else
|
||||
cfg.home_private_keep = ptr + 13;
|
||||
arg_private = 1;
|
||||
}
|
||||
else
|
||||
warning_feature_disabled(fname, lineno, ptr, CFG_PRIVATE_HOME);
|
||||
#endif
|
||||
fprintf(stderr, "Warning: \"private-home\" feature was deprecated in firejail version 0.9.81\n");
|
||||
return 0;
|
||||
}
|
||||
else if (strcmp(ptr, "tab") == 0) {
|
||||
|
|
|
|||
|
|
@ -893,12 +893,6 @@ int sandbox(void* sandbox_arg) {
|
|||
else
|
||||
fs_private_homedir();
|
||||
}
|
||||
else if (cfg.home_private_keep) { // --private-home=
|
||||
if (cfg.chrootdir)
|
||||
fwarning("private-home= feature is disabled in chroot\n");
|
||||
else
|
||||
fs_private_home_list();
|
||||
}
|
||||
else // --private
|
||||
fs_private();
|
||||
EUID_ROOT();
|
||||
|
|
|
|||
|
|
@ -411,17 +411,6 @@ the /etc directory, and must not contain the / character
|
|||
expressed as foo/bar -- is disallowed).
|
||||
All modifications are discarded when the sandbox is closed.
|
||||
Multiple private-etc commands are allowed and they accumulate.
|
||||
#ifdef HAVE_PRIVATE_HOME
|
||||
.TP
|
||||
\fBprivate\-home file,directory
|
||||
Build a new user home in a temporary
|
||||
filesystem, and copy the files and directories in the list in the
|
||||
new home.
|
||||
The files and directories in the list must be expressed as relative to
|
||||
the current user's home directory.
|
||||
All modifications are discarded when the sandbox is
|
||||
closed.
|
||||
#endif
|
||||
#ifdef HAVE_PRIVATE_LIB
|
||||
.TP
|
||||
\fBprivate\-lib file,directory
|
||||
|
|
|
|||
|
|
@ -2321,23 +2321,6 @@ $ firejail \-\-allow\-debuggers \-\-profile=/etc/firejail/transmission\-qt.profi
|
|||
strace \-f \-\-trace=%file /usr/bin/transmission-qt 2>&1 | grep etc
|
||||
|
||||
See also \fB\-\-allow-debuggers\fR and \fB\-\-trace\fR.
|
||||
#ifdef HAVE_PRIVATE_HOME
|
||||
.TP
|
||||
\fB\-\-private\-home=file,directory
|
||||
Build a new user home in a temporary
|
||||
filesystem, and copy the files and directories in the list in the
|
||||
new home.
|
||||
The files and directories in the list must be expressed as relative to
|
||||
the current user's home directory.
|
||||
All modifications are discarded when the sandbox is
|
||||
closed.
|
||||
.br
|
||||
|
||||
.br
|
||||
Example:
|
||||
.br
|
||||
$ firejail \-\-private\-home=.mozilla /usr/bin/firefox
|
||||
#endif
|
||||
#ifdef HAVE_PRIVATE_LIB
|
||||
.TP
|
||||
\fB\-\-private\-lib=file,directory
|
||||
|
|
@ -3275,7 +3258,6 @@ Compile time support:
|
|||
- file transfer support is enabled
|
||||
- firetunnel support is enabled
|
||||
- networking support is enabled
|
||||
- private-home support is enabled
|
||||
- seccomp-bpf support is enabled
|
||||
- user namespace support is enabled
|
||||
- X11 sandboxing support is enabled
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue