From cbbc90381b41156c16bcb30934a10c843c8298c0 Mon Sep 17 00:00:00 2001 From: netblue30 Date: Tue, 19 Sep 2017 09:47:26 -0400 Subject: add private-bin support to profile builder --- README.md | 9 ++-- etc/whitelist-var-common.inc | 1 + smtube.profile | 37 ------------- src/fbuilder/build_bin.c | 121 +++++++++++++++++++++++++++++++++++++++++++ src/fbuilder/build_profile.c | 4 +- src/fbuilder/fbuilder.h | 3 ++ src/libtrace/libtrace.c | 12 +++++ 7 files changed, 144 insertions(+), 43 deletions(-) delete mode 100644 smtube.profile create mode 100644 src/fbuilder/build_bin.c diff --git a/README.md b/README.md index 91bba52d2..c694bc8db 100644 --- a/README.md +++ b/README.md @@ -114,12 +114,12 @@ in order to allow strace to run. Chromium and Chromium-based browsers will not w Example: ````` -$ firejail --build vlc ~/Videos/test.mp4 +$ firejail --build /usr/bin/vlc ~/Videos/test.mp4 [...] ############################################ -# vlc profile +# /usr/bin/vlc profile ############################################ # Persistent global definitions # include /etc/firejail/globals.local @@ -141,13 +141,14 @@ private-tmp private-dev private-etc vdpau_wrapper.cfg,udev,drirc,fonts,xdg,gtk-3.0,machine-id,selinux, whitelist /var/lib/menu-xdg +# private-bin vlc, ### security filters caps.drop all nonewprivs seccomp -# seccomp.keep futex,poll,rt_sigtimedwait,ioctl,fdatasync,stat,writev,read,recvmsg,mprotect,write,sendto,clock_nanosleep,open,dup3,mmap,rt_sigprocmask,close,fstat,lstat,lseek,munmap,brk,rt_sigaction,rt_sigreturn,access,madvise,shmget,shmat,shmctl,alarm,getpid,socket,connect,recvfrom,sendmsg,shutdown,getsockname,getpeername,setsockopt,getsockopt,clone,execve,uname,shmdt,fcntl,flock,ftruncate,getdents,rename,mkdir,unlink,readlink,chmod,getrlimit,sysinfo,getuid,getgid,setuid,setgid,geteuid,getegid,getppid,getpgrp,setresuid,getresuid,setresgid,getresgid,statfs,fstatfs,prctl,arch_prctl,sched_getaffinity,set_tid_address,fadvise64,clock_getres,tgkill,set_robust_list,eventfd2,pipe2,getrandom,memfd_create -# 82 syscalls total +# seccomp.keep futex,poll,rt_sigtimedwait,ioctl,fdatasync,read,writev,sendmsg,sendto,write,recvmsg,mmap,mprotect,getpid,stat,clock_nanosleep,munmap,close,access,lseek,fcntl,open,fstat,lstat,brk,rt_sigaction,rt_sigprocmask,rt_sigreturn,madvise,shmget,shmat,shmctl,alarm,socket,connect,recvfrom,shutdown,getsockname,getpeername,setsockopt,getsockopt,clone,execve,uname,shmdt,flock,ftruncate,getdents,rename,mkdir,unlink,readlink,chmod,getrlimit,sysinfo,getuid,getgid,geteuid,getegid,getresuid,getresgid,statfs,fstatfs,prctl,arch_prctl,sched_getaffinity,set_tid_address,fadvise64,clock_getres,tgkill,set_robust_list,eventfd2,dup3,pipe2,getrandom,memfd_create +# 76 syscalls total # Probably you will need to add more syscalls to seccomp.keep. Look for # seccomp errors in /var/log/syslog or /var/log/audit/audit.log while # running your sandbox. diff --git a/etc/whitelist-var-common.inc b/etc/whitelist-var-common.inc index bd3473acc..024995f20 100644 --- a/etc/whitelist-var-common.inc +++ b/etc/whitelist-var-common.inc @@ -8,3 +8,4 @@ whitelist /var/lib/menu-xdg whitelist /var/cache/fontconfig whitelist /var/tmp whitelist /var/run +whitelist /var/lock diff --git a/smtube.profile b/smtube.profile deleted file mode 100644 index 2694dd5b0..000000000 --- a/smtube.profile +++ /dev/null @@ -1,37 +0,0 @@ -# Firejail profile for smtube -# This file is overwritten after every install/update -# Persistent local customizations -include /etc/firejail/smtube.local -# Persistent global definitions -include /etc/firejail/globals.local - -noblacklist ${HOME}/.config/smplayer -noblacklist ${HOME}/.config/smtube -noblacklist ${HOME}/.config/mpv -noblacklist ${HOME}/.mplayer -noblacklist ${HOME}/.config/vlc -noblacklist ${HOME}/.local/share/vlc - -include /etc/firejail/disable-common.inc -include /etc/firejail/disable-devel.inc -include /etc/firejail/disable-passwdmgr.inc -include /etc/firejail/disable-programs.inc - -caps.drop all -netfilter -nodvd -notv -novideo -nogroups -nonewprivs -noroot -protocol unix,inet,inet6,netlink -seccomp -shell none - -#no private-bin because users can add their own players to smtube and that would prevent that -private-dev -private-tmp - -noexec ${HOME} -noexec /tmp diff --git a/src/fbuilder/build_bin.c b/src/fbuilder/build_bin.c new file mode 100644 index 000000000..7d0e2cb7c --- /dev/null +++ b/src/fbuilder/build_bin.c @@ -0,0 +1,121 @@ +/* + * Copyright (C) 2014-2017 Firejail Authors + * + * This file is part of firejail project + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ +#include "fbuilder.h" + +static FileDB *bin_out = NULL; + +static void process_bin(const char *fname) { + assert(fname); + + // process trace file + FILE *fp = fopen(fname, "r"); + if (!fp) { + fprintf(stderr, "Error: cannot open %s\n", fname); + exit(1); + } + + char buf[MAX_BUF]; + while (fgets(buf, MAX_BUF, fp)) { + // remove \n + char *ptr = strchr(buf, '\n'); + if (ptr) + *ptr = '\0'; + + // parse line: 4:galculator:access /etc/fonts/conf.d:0 + // number followed by : + ptr = buf; + if (!isdigit(*ptr)) + continue; + while (isdigit(*ptr)) + ptr++; + if (*ptr != ':') + continue; + ptr++; + + // next : + ptr = strchr(ptr, ':'); + if (!ptr) + continue; + ptr++; + if (strncmp(ptr, "exec ", 5) == 0) + ptr += 5; + else + continue; + if (strncmp(ptr, "/bin/", 5) == 0) + ptr += 5; + else if (strncmp(ptr, "/sbin/", 6) == 0) + ptr += 6; + else if (strncmp(ptr, "/usr/bin/", 9) == 0) + ptr += 9; + else if (strncmp(ptr, "/usr/sbin/", 10) == 0) + ptr += 10; + else if (strncmp(ptr, "/usr/local/bin/", 15) == 0) + ptr += 15; + else if (strncmp(ptr, "/usr/local/sbin/", 16) == 0) + ptr += 16; + else if (strncmp(ptr, "/usr/games/", 11) == 0) + ptr += 12; + else if (strncmp(ptr, "/usr/local/games/", 17) == 0) + ptr += 17; + else + continue; + + // end of filename + char *ptr2 = strchr(ptr, ':'); + if (!ptr2) + continue; + *ptr2 = '\0'; + + bin_out = filedb_add(bin_out, ptr); + } + + fclose(fp); +} + + +// process fname, fname.1, fname.2, fname.3, fname.4, fname.5 +void build_bin(const char *fname) { + assert(fname); + + // run fname + process_bin(fname); + + // run all the rest + struct stat s; + int i; + for (i = 1; i <= 5; i++) { + char *newname; + if (asprintf(&newname, "%s.%d", fname, i) == -1) + errExit("asprintf"); + if (stat(newname, &s) == 0) + process_bin(newname); + free(newname); + } + + if (bin_out) { + printf("# private-bin "); + FileDB *ptr = bin_out; + while (ptr) { + printf("%s,", ptr->fname); + ptr = ptr->next; + } + printf("\n"); + } +} diff --git a/src/fbuilder/build_profile.c b/src/fbuilder/build_profile.c index 5fca22648..3f5fe48ca 100644 --- a/src/fbuilder/build_profile.c +++ b/src/fbuilder/build_profile.c @@ -33,6 +33,7 @@ static char *cmdlist[] = { "--caps.drop=all", "--nonewprivs", "--trace", + "--shell=none", "/usr/bin/strace", // also used as a marker in build_profile() "-c", "-f", @@ -56,8 +57,6 @@ static void clear_tmp_files(void) { } void build_profile(int argc, char **argv, int index) { - unlink("/tmp/strace-output"); - // next index is the application name if (index >= argc) { fprintf(stderr, "Error: application name missing\n"); @@ -136,6 +135,7 @@ void build_profile(int argc, char **argv, int index) { build_dev(TRACE_OUTPUT); build_etc(TRACE_OUTPUT); build_var(TRACE_OUTPUT); + build_bin(TRACE_OUTPUT); printf("\n"); printf("### security filters\n"); diff --git a/src/fbuilder/fbuilder.h b/src/fbuilder/fbuilder.h index a9049ea2d..c448f3e06 100644 --- a/src/fbuilder/fbuilder.h +++ b/src/fbuilder/fbuilder.h @@ -44,6 +44,9 @@ void build_var(const char *fname); void build_tmp(const char *fname); void build_dev(const char *fname); +// build_bin.c +void build_bin(const char *fname); + // build_home.c void build_home(const char *fname); diff --git a/src/libtrace/libtrace.c b/src/libtrace/libtrace.c index 5cdb254a3..04cf64997 100644 --- a/src/libtrace/libtrace.c +++ b/src/libtrace/libtrace.c @@ -673,3 +673,15 @@ int setresgid(gid_t rgid, gid_t egid, gid_t sgid) { return rv; } + +// every time a new process is started, this gets called +// it can be used to build things like private-bin +__attribute__((constructor)) +static void log_exec(int argc, char** argv) { + static char buf[PATH_MAX + 1]; + int rv = readlink("/proc/self/exe", buf, PATH_MAX); + if (rv != -1) { + buf[rv] = '\0'; // readlink does not add a '\0' at the end + printf("%u:%s:exec %s:0\n", pid(), name(), buf); + } +} -- cgit v1.2.3-54-g00ecf