make --private-lib a compile time option, disabled by default

This commit is contained in:
netblue30 2023-03-09 12:46:11 -05:00
parent 18765f2358
commit b689b69f6c
11 changed files with 89 additions and 30 deletions

18
configure vendored
View file

@ -641,6 +641,7 @@ HAVE_USERNS
HAVE_NETWORK HAVE_NETWORK
HAVE_GLOBALCFG HAVE_GLOBALCFG
HAVE_CHROOT HAVE_CHROOT
HAVE_PRIVATE_LIB
HAVE_PRIVATE_HOME HAVE_PRIVATE_HOME
HAVE_FIRETUNNEL HAVE_FIRETUNNEL
HAVE_GAWK HAVE_GAWK
@ -719,6 +720,7 @@ enable_usertmpfs
enable_man enable_man
enable_firetunnel enable_firetunnel
enable_private_home enable_private_home
enable_private_lib
enable_chroot enable_chroot
enable_globalcfg enable_globalcfg
enable_network enable_network
@ -1380,6 +1382,7 @@ Optional Features:
--disable-man disable man pages --disable-man disable man pages
--enable-firetunnel enable firetunnel --enable-firetunnel enable firetunnel
--disable-private-home disable private home feature --disable-private-home disable private home feature
--disable-private-lib disable private lib feature
--disable-chroot disable chroot --disable-chroot disable chroot
--disable-globalcfg if the global config file firejail.config is not --disable-globalcfg if the global config file firejail.config is not
present, continue the program using defaults present, continue the program using defaults
@ -3485,6 +3488,19 @@ if test "x$enable_private_home" != "xno"; then :
fi fi
HAVE_PRIVATE_LIB=""
# Check whether --enable-private-lib was given.
if test "${enable_private_lib+set}" = set; then :
enableval=$enable_private_lib;
fi
if test "x$enable_private_lib" = "xyes"; then :
HAVE_PRIVATE_LIB="-DHAVE_PRIVATE_LIB"
fi
HAVE_CHROOT="" HAVE_CHROOT=""
# Check whether --enable-chroot was given. # Check whether --enable-chroot was given.
@ -3674,6 +3690,7 @@ if test "x$enable_lts" = "xyes"; then :
HAVE_MAN="-DHAVE_MAN" HAVE_MAN="-DHAVE_MAN"
HAVE_FIRETUNNEL="" HAVE_FIRETUNNEL=""
HAVE_PRIVATE_HOME="" HAVE_PRIVATE_HOME=""
HAVE_PRIVATE_LIB=""
HAVE_CHROOT="" HAVE_CHROOT=""
HAVE_GLOBALCFG="" HAVE_GLOBALCFG=""
HAVE_USERNS="" HAVE_USERNS=""
@ -5291,6 +5308,7 @@ Features:
network: $HAVE_NETWORK network: $HAVE_NETWORK
overlayfs support: $HAVE_OVERLAYFS overlayfs support: $HAVE_OVERLAYFS
private home support: $HAVE_PRIVATE_HOME private home support: $HAVE_PRIVATE_HOME
private lib support: $HAVE_PRIVATE_LIB
SELinux labeling support: $HAVE_SELINUX SELinux labeling support: $HAVE_SELINUX
user namespace: $HAVE_USERNS user namespace: $HAVE_USERNS
X11 sandboxing support: $HAVE_X11 X11 sandboxing support: $HAVE_X11

View file

@ -147,6 +147,14 @@ AS_IF([test "x$enable_private_home" != "xno"], [
HAVE_PRIVATE_HOME="-DHAVE_PRIVATE_HOME" HAVE_PRIVATE_HOME="-DHAVE_PRIVATE_HOME"
]) ])
HAVE_PRIVATE_LIB=""
AC_SUBST([HAVE_PRIVATE_LIB])
AC_ARG_ENABLE([private-lib],
[AS_HELP_STRING([--disable-private-lib], [disable private lib feature])])
AS_IF([test "x$enable_private_lib" = "xyes"], [
HAVE_PRIVATE_LIB="-DHAVE_PRIVATE_LIB"
])
HAVE_CHROOT="" HAVE_CHROOT=""
AC_SUBST([HAVE_CHROOT]) AC_SUBST([HAVE_CHROOT])
AC_ARG_ENABLE([chroot], AC_ARG_ENABLE([chroot],
@ -268,6 +276,7 @@ AS_IF([test "x$enable_lts" = "xyes"], [
HAVE_MAN="-DHAVE_MAN" HAVE_MAN="-DHAVE_MAN"
HAVE_FIRETUNNEL="" HAVE_FIRETUNNEL=""
HAVE_PRIVATE_HOME="" HAVE_PRIVATE_HOME=""
HAVE_PRIVATE_LIB=""
HAVE_CHROOT="" HAVE_CHROOT=""
HAVE_GLOBALCFG="" HAVE_GLOBALCFG=""
HAVE_USERNS="" HAVE_USERNS=""
@ -324,6 +333,7 @@ Features:
network: $HAVE_NETWORK network: $HAVE_NETWORK
overlayfs support: $HAVE_OVERLAYFS overlayfs support: $HAVE_OVERLAYFS
private home support: $HAVE_PRIVATE_HOME private home support: $HAVE_PRIVATE_HOME
private lib support: $HAVE_PRIVATE_LIB
SELinux labeling support: $HAVE_SELINUX SELinux labeling support: $HAVE_SELINUX
user namespace: $HAVE_USERNS user namespace: $HAVE_USERNS
X11 sandboxing support: $HAVE_X11 X11 sandboxing support: $HAVE_X11

View file

@ -5,7 +5,7 @@
# GCOV test setup # GCOV test setup
# required: sudo, lcov (apt-get install lcov) # required: sudo, lcov (apt-get install lcov)
# setup: make distclean && ./configure --prefix=/usr --enable-apparmor --enable-gcov && make -j4 && sudo make install # setup: modify ./configure line below if necessary
# run as regular user: ./gcov.sh # run as regular user: ./gcov.sh
# result in gcov-dir/index.html # result in gcov-dir/index.html
@ -17,6 +17,7 @@ gcov_generate() {
genhtml -q gcov-file --output-directory gcov-dir genhtml -q gcov-file --output-directory gcov-dir
} }
make distclean && ./configure --prefix=/usr --enable-apparmor --enable-gcov --enable-fatal-warnings && make -j4 && sudo make install
rm -fr gcov-dir gcov-file rm -fr gcov-dir gcov-file
firejail --version firejail --version
gcov_generate gcov_generate

View file

@ -409,6 +409,14 @@ void print_compiletime_support(void) {
#endif #endif
); );
printf("\t- private-lib support is %s\n",
#ifdef HAVE_PRIVATE_LIB
"enabled"
#else
"disabled"
#endif
);
printf("\t- private-cache and tmpfs as user %s\n", printf("\t- private-cache and tmpfs as user %s\n",
#ifdef HAVE_USERTMPFS #ifdef HAVE_USERTMPFS
"enabled" "enabled"

View file

@ -32,35 +32,6 @@ extern void fslib_install_stdc(void);
extern void fslib_install_firejail(void); extern void fslib_install_firejail(void);
extern void fslib_install_system(void); extern void fslib_install_system(void);
static int lib_cnt = 0;
static int dir_cnt = 0;
static const char *masked_lib_dirs[] = {
"/usr/lib64",
"/lib64",
"/usr/lib",
"/lib",
"/usr/local/lib64",
"/usr/local/lib",
NULL,
};
// return 1 if the file is in masked_lib_dirs[]
static int valid_full_path(const char *full_path) {
if (strstr(full_path, ".."))
return 0;
int i = 0;
while (masked_lib_dirs[i]) {
size_t len = strlen(masked_lib_dirs[i]);
if (strncmp(full_path, masked_lib_dirs[i], len) == 0 &&
full_path[len] == '/')
return 1;
i++;
}
return 0;
}
// return 1 if symlink to firejail executable // return 1 if symlink to firejail executable
int is_firejail_link(const char *fname) { int is_firejail_link(const char *fname) {
EUID_ASSERT(); EUID_ASSERT();
@ -116,6 +87,36 @@ char *find_in_path(const char *program) {
return NULL; return NULL;
} }
#ifdef HAVE_PRIVATE_LIB
static int lib_cnt = 0;
static int dir_cnt = 0;
static const char *masked_lib_dirs[] = {
"/usr/lib64",
"/lib64",
"/usr/lib",
"/lib",
"/usr/local/lib64",
"/usr/local/lib",
NULL,
};
// return 1 if the file is in masked_lib_dirs[]
static int valid_full_path(const char *full_path) {
if (strstr(full_path, ".."))
return 0;
int i = 0;
while (masked_lib_dirs[i]) {
size_t len = strlen(masked_lib_dirs[i]);
if (strncmp(full_path, masked_lib_dirs[i], len) == 0 &&
full_path[len] == '/')
return 1;
i++;
}
return 0;
}
static char *build_dest_dir(const char *full_path) { static char *build_dest_dir(const char *full_path) {
assert(full_path); assert(full_path);
if (strstr(full_path, "/x86_64-linux-gnu/")) if (strstr(full_path, "/x86_64-linux-gnu/"))
@ -465,3 +466,4 @@ void fs_private_lib(void) {
// mount lib filesystem // mount lib filesystem
mount_directories(); mount_directories();
} }
#endif

View file

@ -36,6 +36,7 @@ typedef struct liblist_t {
int len; int len;
} LibList; } LibList;
#ifdef HAVE_PRIVATE_LIB
static LibList libc_list[] = { static LibList libc_list[] = {
{ "libselinux.so.", 0 }, { "libselinux.so.", 0 },
{ "libpcre2-8.so.", 0 }, { "libpcre2-8.so.", 0 },
@ -356,3 +357,4 @@ void fslib_install_system(void) {
ptr++; ptr++;
} }
} }
#endif

View file

@ -1355,8 +1355,10 @@ int main(int argc, char **argv, char **envp) {
arg_debug_blacklists = 1; arg_debug_blacklists = 1;
else if (strcmp(argv[i], "--debug-whitelists") == 0) else if (strcmp(argv[i], "--debug-whitelists") == 0)
arg_debug_whitelists = 1; arg_debug_whitelists = 1;
#ifdef HAVE_PRIVATE_LIB
else if (strcmp(argv[i], "--debug-private-lib") == 0) else if (strcmp(argv[i], "--debug-private-lib") == 0)
arg_debug_private_lib = 1; arg_debug_private_lib = 1;
#endif
else if (strcmp(argv[i], "--quiet") == 0) { else if (strcmp(argv[i], "--quiet") == 0) {
if (!arg_debug) if (!arg_debug)
arg_quiet = 1; arg_quiet = 1;
@ -2137,6 +2139,7 @@ int main(int argc, char **argv, char **envp) {
else else
exit_err_feature("private-bin"); exit_err_feature("private-bin");
} }
#ifdef HAVE_PRIVATE_LIB
else if (strncmp(argv[i], "--private-lib", 13) == 0) { else if (strncmp(argv[i], "--private-lib", 13) == 0) {
if (checkcfg(CFG_PRIVATE_LIB)) { if (checkcfg(CFG_PRIVATE_LIB)) {
// extract private lib list (if any) // extract private lib list (if any)
@ -2152,6 +2155,7 @@ int main(int argc, char **argv, char **envp) {
else else
exit_err_feature("private-lib"); exit_err_feature("private-lib");
} }
#endif
else if (strcmp(argv[i], "--private-tmp") == 0) { else if (strcmp(argv[i], "--private-tmp") == 0) {
arg_private_tmp = 1; arg_private_tmp = 1;
} }

View file

@ -949,6 +949,7 @@ int sandbox(void* sandbox_arg) {
} }
} }
#ifdef HAVE_PRIVATE_LIB
// private-lib is disabled for appimages // private-lib is disabled for appimages
if (arg_private_lib && !arg_appimage) { if (arg_private_lib && !arg_appimage) {
if (cfg.chrootdir) if (cfg.chrootdir)
@ -959,6 +960,7 @@ int sandbox(void* sandbox_arg) {
fs_private_lib(); fs_private_lib();
} }
} }
#endif
#ifdef HAVE_USERTMPFS #ifdef HAVE_USERTMPFS
if (arg_private_cache) { if (arg_private_cache) {

View file

@ -81,7 +81,9 @@ static char *usage_str =
" --debug-blacklists - debug blacklisting.\n" " --debug-blacklists - debug blacklisting.\n"
" --debug-caps - print all recognized capabilities.\n" " --debug-caps - print all recognized capabilities.\n"
" --debug-errnos - print all recognized error numbers.\n" " --debug-errnos - print all recognized error numbers.\n"
#ifdef HAVE_PRIVATE_LIB
" --debug-private-lib - debug for --private-lib option.\n" " --debug-private-lib - debug for --private-lib option.\n"
#endif
" --debug-protocols - print all recognized protocols.\n" " --debug-protocols - print all recognized protocols.\n"
" --debug-syscalls - print all recognized system calls.\n" " --debug-syscalls - print all recognized system calls.\n"
" --debug-syscalls32 - print all recognized 32 bit system calls.\n" " --debug-syscalls32 - print all recognized 32 bit system calls.\n"
@ -208,6 +210,9 @@ static char *usage_str =
"\tcommon device files.\n" "\tcommon device files.\n"
" --private-etc=file,directory - build a new /etc in a temporary\n" " --private-etc=file,directory - build a new /etc in a temporary\n"
"\tfilesystem, and copy the files and directories in the list.\n" "\tfilesystem, and copy the files and directories in the list.\n"
#ifdef HAVE_PRIVATE_LIB
" --private-lib - create a private /lib directory\n"
#endif
" --private-tmp - mount a tmpfs on top of /tmp directory.\n" " --private-tmp - mount a tmpfs on top of /tmp directory.\n"
" --private-cwd - do not inherit working directory inside jail.\n" " --private-cwd - do not inherit working directory inside jail.\n"
" --private-cwd=directory - set working directory inside jail.\n" " --private-cwd=directory - set working directory inside jail.\n"

View file

@ -407,12 +407,14 @@ the current user's home directory.
All modifications are discarded when the sandbox is All modifications are discarded when the sandbox is
closed. closed.
#endif #endif
#ifdef HAVE_PRIVATE_LIB
.TP .TP
\fBprivate-lib file,directory \fBprivate-lib file,directory
Build a new /lib directory and bring in the libraries required by the application to run. Build a new /lib directory and bring in the libraries required by the application to run.
The files and directories in the list must be expressed as relative to The files and directories in the list must be expressed as relative to
the /lib directory. the /lib directory.
This feature is still under development, see \fBman 1 firejail\fR for some examples. This feature is still under development, see \fBman 1 firejail\fR for some examples.
#endif
.TP .TP
\fBprivate-opt file,directory \fBprivate-opt file,directory
Build a new /opt in a temporary Build a new /opt in a temporary

View file

@ -684,9 +684,11 @@ Print all recognized error numbers in the current Firejail software build and ex
Example: Example:
.br .br
$ firejail \-\-debug-errnos $ firejail \-\-debug-errnos
#ifdef HAVE_PRIVATE_LIB
.TP .TP
\fB\-\-debug-private-lib \fB\-\-debug-private-lib
Debug messages for --private-lib option. Debug messages for --private-lib option.
#endif
.TP .TP
\fB\-\-debug-protocols \fB\-\-debug-protocols
Print all recognized protocols in the current Firejail software build and exit. Print all recognized protocols in the current Firejail software build and exit.
@ -696,6 +698,7 @@ Print all recognized protocols in the current Firejail software build and exit.
Example: Example:
.br .br
$ firejail \-\-debug-protocols $ firejail \-\-debug-protocols
#endif
.TP .TP
\fB\-\-debug-syscalls \fB\-\-debug-syscalls
Print all recognized system calls in the current Firejail software build and exit. Print all recognized system calls in the current Firejail software build and exit.
@ -2179,6 +2182,7 @@ Example:
.br .br
$ firejail \-\-private-home=.mozilla firefox $ firejail \-\-private-home=.mozilla firefox
#endif #endif
#ifdef HAVE_PRIVATE_LIB
.TP .TP
\fB\-\-private-lib=file,directory \fB\-\-private-lib=file,directory
This feature is currently under heavy development. Only amd64 platforms are supported at this moment. This feature is currently under heavy development. Only amd64 platforms are supported at this moment.
@ -2234,6 +2238,7 @@ $
.br .br
Note: Support for this command is controlled in firejail.config with the Note: Support for this command is controlled in firejail.config with the
\fBprivate-lib\fR option. \fBprivate-lib\fR option.
#endif
.TP .TP
\fB\-\-private-opt=file,directory \fB\-\-private-opt=file,directory
Build a new /opt in a temporary Build a new /opt in a temporary