bwrap replacement - part 1

This commit is contained in:
netblue30 2025-12-18 08:04:12 -05:00
parent 411b97fdc9
commit 33d07c2320
3 changed files with 151 additions and 1 deletions

View file

@ -26,7 +26,7 @@ endif
COMPLETIONDIRS = src/zsh_completion src/bash_completion
APPS = src/firecfg/firecfg src/firejail/firejail src/firemon/firemon src/profstats/profstats src/jailcheck/jailcheck src/etc-cleanup/etc-cleanup
APPS = src/firecfg/firecfg src/firejail/firejail src/firemon/firemon src/profstats/profstats src/jailcheck/jailcheck src/etc-cleanup/etc-cleanup src/fbwrap/fbwrap
SBOX_APPS = src/fbuilder/fbuilder src/ftee/ftee
SBOX_APPS_NON_DUMPABLE = src/fcopy/fcopy src/fldd/fldd src/fnet/fnet src/fnetfilter/fnetfilter src/fzenity/fzenity
SBOX_APPS_NON_DUMPABLE += src/fsec-optimize/fsec-optimize src/fsec-print/fsec-print src/fseccomp/fseccomp
@ -221,6 +221,7 @@ endif
$(INSTALL) -m 0755 -t $(DESTDIR)$(libdir)/firejail $(SBOX_APPS)
$(INSTALL) -m 0755 -t $(DESTDIR)$(libdir)/firejail src/profstats/profstats
$(INSTALL) -m 0755 -t $(DESTDIR)$(libdir)/firejail src/etc-cleanup/etc-cleanup
$(INSTALL) -m 0755 -t $(DESTDIR)$(libdir)/firejail src/fbwrap/fbwrap
# plugins w/o read permission (non-dumpable)
$(INSTALL) -m 0711 -t $(DESTDIR)$(libdir)/firejail $(SBOX_APPS_NON_DUMPABLE)
$(INSTALL) -m 0711 -t $(DESTDIR)$(libdir)/firejail src/fshaper/fshaper.sh

12
src/fbwrap/Makefile Normal file
View file

@ -0,0 +1,12 @@
.SUFFIXES:
ROOT = ../..
-include $(ROOT)/config.mk
MOD = fbwrap
MOD_DIR = $(ROOT)/src/$(MOD)
PROG = $(MOD_DIR)/$(MOD)
TARGET = $(PROG)
#EXTRA_OBJS = ../lib/common.o ../lib/pid.o
include $(ROOT)/src/prog.mk

137
src/fbwrap/main.c Normal file
View file

@ -0,0 +1,137 @@
/*
* Copyright (C) 2014-2025 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.
*/
#define _GNU_SOURCE
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/stat.h>
//#define DEBUG
// checking the file is in the regular executable path or in /usr/lib*
// fname: full path required!!!
static int check_env_path(const char *fname) {
#ifdef DEBUG
printf("%s:%s():%d %s\n", __FILE__, __PRETTY_FUNCTION__, __LINE__, fname);
#endif
if (strncmp(fname, "/usr/lib", 8) == 0)
return 0;
const char *path1 = secure_getenv("PATH");
if (path1) {
char *path2 = strdup(path1);
if (!path2) {
fprintf(stderr, "Error: strdup failed in fbwrap\n");
return 1;
}
// use path2 to count the entries
char *ptr = strtok(path2, ":");
while (ptr) {
if (strncmp(fname, ptr, strlen(ptr)) == 0) {
free(path2);
printf("INFO: full path provided for %s\n", fname);
return 0;
}
ptr = strtok(NULL, ":");
}
free(path2);
}
return 1;
}
// fname: full path required!!!
static int ok_to_run(const char *fname) {
#ifdef DEBUG
printf("%s:%s():%d %s\n", __FILE__, __PRETTY_FUNCTION__, __LINE__, fname);
#endif
if (check_env_path(fname))
return 0;
struct stat s;
int rv = stat(fname, &s);
if (rv == 0 && S_ISREG(s.st_mode) && access(fname, X_OK) == 0)
return 1;
return 0;
}
static void usage(void) {
printf("fbwrap - bwrap replacement for Firejail sandbox.\n"
"Usage: fbwrap bwrap-program-and-arguments\n"
"\n"
"This program does nothing! It just starts the application\n"
"bwrap was supposed to sandbox, without any sandboxing features.\n"
"\n"
"fbwrap is installed automatically inside Firejail sandbox\n"
"replacing the real bwrap. The real bwrap is still available\n"
"outside the sandbox.\n\n");
}
int main(int argc, char **argv) {
int i;
#ifdef DEBUG
printf("%s:%s():%d\n", __FILE__, __PRETTY_FUNCTION__, __LINE__);
#endif
if (strcmp(argv[1], "-h") == 0 ||
strcmp(argv[1], "-?") == 0 ||
strcmp(argv[1], "-v") == 0 ||
strcmp(argv[1], "--help") == 0 ||
strcmp(argv[1], "--version") == 0) {
usage();
return 0;
}
for (i = 1; i < argc; i++) {
#ifdef DEBUG
printf("%s:%s():%d %s\n", __FILE__, __PRETTY_FUNCTION__, __LINE__, argv[i]);
#endif
if (*argv[i] != '/') // enforcing $(PATH) for our target
continue;
if (ok_to_run(argv[i])) {
fprintf(stderr, "Info: fbwrap target program %s found\n", argv[i]);
break;
}
}
if (i == argc) {
fprintf(stderr, "Error: fbwrap target program not found. Please use a full path for your target.\n");
usage();
exit(1);
}
#define MAX_ARGLIST 64
char *arglist[MAX_ARGLIST] = {NULL};
int j;
for (j = 0; i < argc && j < MAX_ARGLIST; i++, j++)
arglist[j] = argv[i];
if (j >= (MAX_ARGLIST - 1)) {
fprintf(stderr, "Error: fbwrap target program has an argument list larger than %d\n", MAX_ARGLIST - 1);
exit(1);
}
execvp(arglist[0], arglist);
return 0;
}