diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index c0f4c8b7..7cad3818 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -36,8 +36,7 @@ jobs: - name: Build elf loader, proot, and care run: | - build-wrapper-linux-x86-64 --out-dir ${{ env.BUILD_WRAPPER_OUT_DIR }} make -C src loader.elf loader-m32.elf build.h - build-wrapper-linux-x86-64 --out-dir ${{ env.BUILD_WRAPPER_OUT_DIR }} env CFLAGS=--coverage LDFLAGS=--coverage make -C src proot care V=1 + build-wrapper-linux-x86-64 --out-dir ${{ env.BUILD_WRAPPER_OUT_DIR }} make -C src clean loader.elf loader-m32.elf build.h proot care - name: Execute test suite continue-on-error: true @@ -53,6 +52,8 @@ jobs: - name: Run sonar-scanner env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - SONAR_TOKEN: ${{ secrets.SONARCLOUD_TOKEN }} + SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }} run: | + find /home/runner/work/proot/proot/test/ -type d -exec chmod 755 {} \; + find /home/runner/work/proot/proot/test/ -type f -exec chmod 644 {} \; sonar-scanner --define sonar.cfamily.build-wrapper-output="${{ env.BUILD_WRAPPER_OUT_DIR }}" diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 00000000..d9924b28 --- /dev/null +++ b/.gitmodules @@ -0,0 +1,3 @@ +[submodule "lib/uthash"] + path = lib/uthash + url = https://github.com/proot-me/uthash diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 6b15b975..8c8e15f9 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -11,6 +11,29 @@ Unreleased Please see `Unreleased Changes`_ for more information. +5.4.0 - 2023-05-13 +------------------ + +Added +~~~~~ + +- faccessat2 syscall +- Enable SonarCloud for GitHub Actions +- Include uthash v2.3.0 as submodule +- Disable mixed execution with new --mixed-mode option + +Changed +~~~~~~~ + +- Rename test-0cf405b0.c to fix_memory_corruption_execve_proc_self_exe.c + +Fixed +~~~~~ + +- Android compatibility with cwd +- Running test-0cf405b0 for newer versions of glibc +- Running test-25069c12 and test-25069c13 on newer kernels + 5.3.1 - 2022-04-24 ------------------ @@ -221,6 +244,6 @@ Fixed - Non-executable stack for binaries. -.. _Unreleased Changes: https://github.com/proot-me/proot/compare/v5.3.1...master +.. _Unreleased Changes: https://github.com/proot-me/proot/compare/v5.4.0...master .. _Keep a Changelog: https://keepachangelog.com/en/1.0.0 .. _Semantic Versioning: https://semver.org/spec/v2.0.0.html diff --git a/doc/care/manual.rst b/doc/care/manual.rst index 137b8906..1c19a078 100644 --- a/doc/care/manual.rst +++ b/doc/care/manual.rst @@ -6,8 +6,8 @@ Comprehensive Archiver for Reproducible Execution ------------------------------------------------- -:Date: 2014-09-15 -:Version: 2.2 +:Date: 2023-05-13 +:Version: 2.3.0 :Manual section: 1 @@ -442,7 +442,7 @@ Colophon ======== Visit https://proot-me.github.io/care for help, bug reports, suggestions, patches, ... -Copyright (C) 2022 PRoot Developers, licensed under GPL v2 or later. +Copyright (C) 2023 PRoot Developers, licensed under GPL v2 or later. :: diff --git a/doc/howto-release.rst b/doc/howto-release.rst index c41dfc5f..6f624e13 100644 --- a/doc/howto-release.rst +++ b/doc/howto-release.rst @@ -41,8 +41,8 @@ Static Binaries The following commands will generate statically-linked binaries which can be optionally distributed for each release:: - make -C src loader.elf loader-m32.elf build.h - LDFLAGS="${LDFLAGS} -static" make -C src proot + make -C src clean loader.elf loader-m32.elf build.h + LDFLAGS="${LDFLAGS} -static" make -C src proot care Documentation Update -------------------- diff --git a/doc/proot/manual.rst b/doc/proot/manual.rst index d9b4131c..65dd4085 100644 --- a/doc/proot/manual.rst +++ b/doc/proot/manual.rst @@ -6,8 +6,8 @@ ``chroot``, ``mount --bind``, and ``binfmt_misc`` without privilege/setup ------------------------------------------------------------------------- -:Date: 2022-01-04 -:Version: 5.3.0 +:Date: 2023-05-13 +:Version: 5.4.0 :Manual section: 1 @@ -671,7 +671,7 @@ Colophon ======== Visit https://proot-me.github.io for help, bug reports, suggestions, patches, ... -Copyright (C) 2022 PRoot Developers, licensed under GPL v2 or later. +Copyright (C) 2023 PRoot Developers, licensed under GPL v2 or later. :: diff --git a/lib/uthash b/lib/uthash new file mode 160000 index 00000000..e493aa90 --- /dev/null +++ b/lib/uthash @@ -0,0 +1 @@ +Subproject commit e493aa90a2833b4655927598f169c31cfcdf7861 diff --git a/sonar-project.properties b/sonar-project.properties index 7e4651bf..e20ebdb2 100644 --- a/sonar-project.properties +++ b/sonar-project.properties @@ -6,7 +6,9 @@ sonar.organization=proot-me #sonar.projectVersion=1.0 # Path is relative to the sonar-project.properties file. Replace "\" by "/" on Windows. -#sonar.sources=. +sonar.sources=src +#sonar.cfamily.compile-commands=compile_commands.json # Encoding of the source code. Default is default system encoding #sonar.sourceEncoding=UTF-8 +sonar.host.url=https://sonarcloud.io diff --git a/src/GNUmakefile b/src/GNUmakefile index 38d89a95..168a044a 100644 --- a/src/GNUmakefile +++ b/src/GNUmakefile @@ -20,7 +20,7 @@ PYTHON_MAJOR_VERSION = $(shell ${PYTHON} -c "import sys; print(sys.version_info. PYTHON_EMBED = $(shell ${PYTHON} -c "import sys; print('--embed' if sys.hexversion > 0x03080000 else '')" 2>/dev/null) HAS_PYTHON_CONFIG := $(shell ${PYTHON}-config --ldflags ${PYTHON_EMBED} 2>/dev/null) -CPPFLAGS += -D_FILE_OFFSET_BITS=64 -D_GNU_SOURCE -I. -I$(VPATH) +CPPFLAGS += -D_FILE_OFFSET_BITS=64 -D_GNU_SOURCE -I. -I$(VPATH) -I$(VPATH)/../lib/uthash/include CFLAGS += -g -Wall -Wextra -O2 CFLAGS += $(shell pkg-config --cflags talloc) LDFLAGS += -Wl,-z,noexecstack @@ -184,7 +184,7 @@ care: $(OBJECTS) $(CARE_OBJECTS) # Special case to compute which files depend on the auto-generated # file "build.h". -USE_BUILD_H := $(patsubst $(SRC)%.c,%.o,$(shell egrep -sl 'include[[:space:]]+"build.h"' $(patsubst %.o,$(SRC)%.c,$(OBJECTS) $(CARE_OBJECTS)))) +USE_BUILD_H := $(patsubst $(SRC)%.c,%.o,$(shell grep -E -sl 'include[[:space:]]+"build.h"' $(patsubst %.o,$(SRC)%.c,$(OBJECTS) $(CARE_OBJECTS)))) $(USE_BUILD_H): build.h %.o: %.c diff --git a/src/cli/care.h b/src/cli/care.h index 69f3645a..4cbf69f2 100644 --- a/src/cli/care.h +++ b/src/cli/care.h @@ -6,7 +6,7 @@ #include "cli/cli.h" #ifndef VERSION -#define VERSION "2.2" +#define VERSION "2.3.0" #endif #define CARE_MAX_SIZE 1024 diff --git a/src/cli/proot.c b/src/cli/proot.c index 1e2fa66e..429be4c5 100644 --- a/src/cli/proot.c +++ b/src/cli/proot.c @@ -143,6 +143,12 @@ static int handle_option_q(Tracee *tracee, const Cli *cli UNUSED, const char *va return 0; } +static int handle_option_mixed_mode(Tracee *tracee, const Cli *cli UNUSED, const char *value UNUSED) +{ + tracee->mixed_mode = value; + return 0; +} + static int handle_option_w(Tracee *tracee, const Cli *cli UNUSED, const char *value) { tracee->fs->cwd = talloc_strdup(tracee->fs, value); diff --git a/src/cli/proot.h b/src/cli/proot.h index 0ac57977..85366b6f 100644 --- a/src/cli/proot.h +++ b/src/cli/proot.h @@ -6,7 +6,7 @@ #include "cli/cli.h" #ifndef VERSION -#define VERSION "5.3.0" +#define VERSION "5.4.0" #endif static const char *recommended_bindings[] = { @@ -51,6 +51,7 @@ static const char *recommended_su_bindings[] = { static int handle_option_r(Tracee *tracee, const Cli *cli, const char *value); static int handle_option_b(Tracee *tracee, const Cli *cli, const char *value); static int handle_option_q(Tracee *tracee, const Cli *cli, const char *value); +static int handle_option_mixed_mode(Tracee *tracee, const Cli *cli, const char *value); static int handle_option_w(Tracee *tracee, const Cli *cli, const char *value); static int handle_option_v(Tracee *tracee, const Cli *cli, const char *value); static int handle_option_V(Tracee *tracee, const Cli *cli, const char *value); @@ -77,7 +78,7 @@ static Cli proot_cli = { .subtitle = "chroot, mount --bind, and binfmt_misc without privilege/setup", .synopsis = "proot [option] ... [command]", .colophon = "Visit https://proot-me.github.io for help, bug reports, suggestions, patches, ...\n\ -Copyright (C) 2022 PRoot Developers, licensed under GPL v2 or later.", +Copyright (C) 2023 PRoot Developers, licensed under GPL v2 or later.", .logo = "\ _____ _____ ___\n\ | __ \\ __ \\_____ _____| |_\n\ @@ -137,6 +138,15 @@ Copyright (C) 2022 PRoot Developers, licensed under GPL v2 or later.", \temulated by QEMU user-mode. The native execution of host programs\n\ \tis still effective and the whole host rootfs is bound to\n\ \t/host-rootfs in the guest environment.", + }, + { .class = "Regular options", + .arguments = { + { .name = "--mixed-mode", .separator = ' ', .value = "value" }, + { .name = NULL, .separator = '\0', .value = NULL } }, + .handler = handle_option_mixed_mode, + .description = "Disable the mixed-execution feature.", + .detail = "\tDo not treat ELF executables specially when they appear to be\n\ +\tnative executables of the host system.", }, { .class = "Regular options", .arguments = { diff --git a/src/execve/enter.c b/src/execve/enter.c index 0ae86d55..4ddb5295 100644 --- a/src/execve/enter.c +++ b/src/execve/enter.c @@ -382,7 +382,7 @@ static int expand_runner(Tracee* tracee, char host_path[PATH_MAX], char user_pat /* No need to adjust argv[] if it's a host binary (a.k.a * mixed-mode). */ - if (!is_host_elf(tracee, host_path)) { + if (tracee->mixed_mode || !is_host_elf(tracee, host_path)) { ArrayOfXPointers *argv; size_t nb_qemu_args; size_t i; diff --git a/src/extension/care/care.c b/src/extension/care/care.c index ea15f8dc..cae1b28a 100644 --- a/src/extension/care/care.c +++ b/src/extension/care/care.c @@ -29,11 +29,11 @@ #include /* time(2), localtime(3), */ #include /* offsetof(3), */ #include /* talloc*, */ -#include /* ut*, UT*, HASH*, */ #include /* STAILQ_*, */ #include /* PRI*, */ #include /* AT_*, */ +#include "uthash.h" /* ut*, UT*, HASH*, */ #include "extension/care/care.h" #include "extension/care/final.h" #include "extension/care/archive.h" diff --git a/src/path/temp.c b/src/path/temp.c index 1cfb6747..998024fd 100644 --- a/src/path/temp.c +++ b/src/path/temp.c @@ -198,7 +198,12 @@ static int remove_temp_directory2(const char *path) int status; char *cwd; +#ifdef __ANDROID__ + cwd = malloc(PATH_MAX); + getcwd(cwd, PATH_MAX); +#else cwd = get_current_dir_name(); +#endif status = chmod(path, 0700); if (status < 0) { diff --git a/src/tracee/tracee.h b/src/tracee/tracee.h index 1e40a38d..3e71e7da 100644 --- a/src/tracee/tracee.h +++ b/src/tracee/tracee.h @@ -204,6 +204,8 @@ typedef struct tracee { * execve sysexit. */ struct load_info *load_info; + /* Disable mixed-execution (native host) check */ + bool mixed_mode; /********************************************************************** * Private but inherited resources * diff --git a/test/test-0cf405b0.c b/test/fix_memory_corruption_execve_proc_self_exe.c similarity index 59% rename from test/test-0cf405b0.c rename to test/fix_memory_corruption_execve_proc_self_exe.c index 2566409e..00fc1b14 100644 --- a/test/test-0cf405b0.c +++ b/test/fix_memory_corruption_execve_proc_self_exe.c @@ -1,12 +1,13 @@ #include /* execlp(2), */ -#include /* exit(3), */ +#include /* exit(3), getenv(3), setenv(3)*/ #include /* strcmp(3), */ int main(int argc, char *argv[]) { - if (argc == 0) //strcmp(argv[0], "/proc/self/exe") == 0) + if (getenv("PROC_SELF_EXE") != NULL) exit(EXIT_SUCCESS); + setenv("PROC_SELF_EXE", "1", 1); execlp("/proc/self/exe", NULL); exit(EXIT_FAILURE); } diff --git a/test/test-25069c12.c b/test/test-25069c12.c index 1f6cd52b..b9f27fa8 100644 --- a/test/test-25069c12.c +++ b/test/test-25069c12.c @@ -1,14 +1,15 @@ -#include /* execve(2), */ -#include /* exit(3), */ +#include /* execv(2), */ +#include /* exit(3), getenv(3), setenv(3), */ #include /* strcmp(3), */ int main(int argc, char *argv[]) { char *void_array[] = { NULL }; - if (argc == 0) + if (getenv("PROC_SELF_EXE") != NULL) exit(EXIT_SUCCESS); - execve("/proc/self/exe", void_array, void_array); + setenv("PROC_SELF_EXE", "1", 1); + execv("/proc/self/exe", void_array); exit(EXIT_FAILURE); } diff --git a/test/test-25069c13.c b/test/test-25069c13.c index dc14733b..af8b8d83 100644 --- a/test/test-25069c13.c +++ b/test/test-25069c13.c @@ -1,12 +1,13 @@ -#include /* execve(2), */ -#include /* exit(3), */ +#include /* execv(2), */ +#include /* exit(3), getenv(3), setenv(3), */ #include /* strcmp(3), */ int main(int argc, char *argv[]) { - if (argc == 0) + if (getenv("PROC_SELF_EXE") != NULL) exit(EXIT_SUCCESS); - execve("/proc/self/exe", NULL, NULL); + setenv("PROC_SELF_EXE", "1", 1); + execv("/proc/self/exe", NULL); exit(EXIT_FAILURE); }