Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions THIRD_PARTY_NOTICES.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,11 @@ third-party components.
## PRoot

- Project: <https://github.com/termux/proot>
- Version: `5.1.107.86`
- Version: `5.1.107.101`
- Source archive SHA-256:
`692da7f952ac390eb65c4117d360cad23a052525eea4eb110ae42f8a4a7d7bb8`
`a66743f50c7b0bac1913b83bf55e139d679c80a0ca2808eec76432a65640017f`
- License: GNU General Public License version 2
- Local modification: `tools/proot-ndk28.patch`
- Local patch set: `patches/proot`

## talloc

Expand All @@ -21,7 +21,7 @@ third-party components.
- License: GNU Lesser General Public License version 3 or later

`tools/build-proot-assets.sh` downloads the pinned source archives, verifies
the hashes, applies the recorded patch, and builds the checked-in binaries.
the hashes, applies the recorded patches, and builds the checked-in binaries.
Release packaging must provide the applicable full license texts and complete
corresponding source alongside binary downloads.

Expand Down
Binary file modified app/src/main/assets/runtime/arm64-v8a/proot
Binary file not shown.
Binary file modified app/src/main/assets/runtime/armeabi-v7a/proot
Binary file not shown.
Binary file modified app/src/main/assets/runtime/x86_64/proot
Binary file not shown.
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ data class ProotRuntime(
)

object ProotRuntimeInstaller {
private const val PROOT_VERSION = "5.1.107.101-1"
private const val PROOT_VERSION = "5.1.107.101-3"
private const val TAR_VERSION = "1.35-1"
private val supportedAbis = setOf("arm64-v8a", "armeabi-v7a", "x86_64")

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,8 @@ object ProotApplicationLaunchBuilder {
androidHome = context.filesDir.absolutePath,
loaderPath = runtime.loader.absolutePath,
temporaryDirectory = temporaryDirectory.absolutePath,
shmHelperLauncher = AndroidExecutableCommand.systemLinkerPath(),
prootPath = runtime.executable.absolutePath,
).associate {
val separator = it.indexOf('=')
it.substring(0, separator) to it.substring(separator + 1)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,8 @@ object ProotDesktopLaunchBuilder {
androidHome = context.filesDir.absolutePath,
loaderPath = runtime.loader.absolutePath,
temporaryDirectory = temporaryDirectory.absolutePath,
shmHelperLauncher = AndroidExecutableCommand.systemLinkerPath(),
prootPath = runtime.executable.absolutePath,
).associate {
val separator = it.indexOf('=')
it.substring(0, separator) to it.substring(separator + 1)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,8 @@ object ProotTerminalLaunchBuilder {
androidHome = context.filesDir.absolutePath,
loaderPath = runtime.loader.absolutePath,
temporaryDirectory = temporaryDirectory.absolutePath,
shmHelperLauncher = linker,
prootPath = runtime.executable.absolutePath,
)

return ProotTerminalLaunch(
Expand Down Expand Up @@ -170,6 +172,8 @@ object ProotTerminalLaunchBuilder {
androidHome: String,
loaderPath: String,
temporaryDirectory: String,
shmHelperLauncher: String,
prootPath: String,
): Array<String> =
arrayOf(
"ANDROID_DATA=/data",
Expand All @@ -180,6 +184,8 @@ object ProotTerminalLaunchBuilder {
"PATH=/system/bin",
"PROOT_LOADER=$loaderPath",
"PROOT_TMP_DIR=$temporaryDirectory",
"PROOT_SHM_HELPER_LAUNCHER=$shmHelperLauncher",
"PROOT_SHM_HELPER_EXECUTABLE=$prootPath",
"TMPDIR=$temporaryDirectory",
)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -366,13 +366,19 @@ class ProotTerminalLaunchTest {
androidHome = "/data/user/0/udroid/files",
loaderPath = "/data/user/0/udroid/files/runtime/libproot-loader.so",
temporaryDirectory = "/data/user/0/udroid/cache/proot",
shmHelperLauncher = "/system/bin/linker64",
prootPath = "/data/user/0/udroid/files/runtime/proot",
)

assertTrue("ANDROID_ROOT=/system" in environment)
assertTrue(
"PROOT_LOADER=/data/user/0/udroid/files/runtime/libproot-loader.so" in environment,
)
assertTrue("PROOT_TMP_DIR=/data/user/0/udroid/cache/proot" in environment)
assertTrue("PROOT_SHM_HELPER_LAUNCHER=/system/bin/linker64" in environment)
assertTrue(
"PROOT_SHM_HELPER_EXECUTABLE=/data/user/0/udroid/files/runtime/proot" in environment,
)
assertTrue("TMPDIR=/data/user/0/udroid/cache/proot" in environment)
}
}
21 changes: 21 additions & 0 deletions patches/proot/0001-android-runtime.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
--- a/src/extension/ashmem_memfd/ashmem_memfd.c
+++ b/src/extension/ashmem_memfd/ashmem_memfd.c
@@ -3,4 +3,5 @@
#include <stdlib.h>
+#include <string.h>
#include <signal.h>
#include <unistd.h>
#include <sys/syscall.h> /* __NR_memfd_create, */
--- a/src/extension/sysvipc/sysvipc_shm.c
+++ b/src/extension/sysvipc/sysvipc_shm.c
@@ -14,0 +15 @@
+#include <stdlib.h> /* getenv */
@@ -156 +157,7 @@
- execl("/proc/self/exe", "proot", "--shm-helper", NULL);
+ const char *launcher = getenv("PROOT_SHM_HELPER_LAUNCHER");
+ const char *executable = getenv("PROOT_SHM_HELPER_EXECUTABLE");
+ if (launcher != NULL && launcher[0] == '/'
+ && executable != NULL && executable[0] == '/') {
+ execl(launcher, launcher, executable, "--shm-helper", NULL);
+ }
+ execl("/proc/self/exe", "proot", "--shm-helper", NULL);
166 changes: 166 additions & 0 deletions patches/proot/0002-selective-android-ioctl-tracing.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,166 @@
--- a/src/syscall/seccomp.c
+++ b/src/syscall/seccomp.c
@@ -38,6 +38,10 @@
#include <stddef.h> /* offsetof(3), */
#include <stdint.h> /* uint*_t, UINT*_MAX, */
#include <assert.h> /* assert(3), */
+#ifdef __ANDROID__
+#include <linux/ioctl.h> /* _IOW, */
+#include <termios.h> /* TCGETS2, TCSETS*, */
+#endif

#include "syscall/seccomp.h"
#include "tracee/tracee.h"
@@ -117,9 +121,56 @@
status = add_statements(program, LENGTH_TRACE_SYSCALL, statements);
if (status < 0)
return status;
+
+ return 0;
+}
+
+#ifdef __ANDROID__
+#define LENGTH_TRACE_ANDROID_IOCTL 14
+
+/* Only requests rewritten in enter.c or exit.c need the ptrace round trip. */
+static int add_trace_android_ioctl(struct sock_fprog *program, word_t syscall)
+{
+ const uint32_t requests[] = {
+ TCSETS + 2,
+ TCGETS2,
+ TCSETS2,
+ TCSETSW2,
+ TCSETSF2,
+ _IOW(0x94, 9, int), /* FICLONE */
+ };
+ const size_t request_offset = offsetof(struct seccomp_data, args[1]);
+ struct sock_filter start[] = {
+ BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, syscall, 0,
+ LENGTH_TRACE_ANDROID_IOCTL - 1),
+ BPF_STMT(BPF_LD + BPF_W + BPF_ABS, request_offset),
+ };
+ size_t i;
+ int status;
+
+ if (syscall > UINT32_MAX || request_offset > UINT32_MAX)
+ return -ERANGE;
+
+ status = add_statements(program, sizeof(start) / sizeof(start[0]), start);
+ if (status < 0)
+ return status;
+
+ for (i = 0; i < sizeof(requests) / sizeof(requests[0]); i++) {
+ struct sock_filter request[] = {
+ BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, requests[i], 0, 1),
+ BPF_STMT(BPF_RET + BPF_K,
+ SECCOMP_RET_TRACE + FILTER_SYSEXIT),
+ };
+
+ status = add_statements(program,
+ sizeof(request) / sizeof(request[0]), request);
+ if (status < 0)
+ return status;
+ }

return 0;
}
+#endif

/**
* Append to @program->filter the statements that allow anything (if
@@ -127,7 +178,8 @@
* sanity check. This function returns -errno if an error occurred,
* otherwise 0.
*/
-static int end_arch_section(struct sock_fprog *program, size_t nb_traced_syscalls)
+static int end_arch_section(struct sock_fprog *program, size_t nb_traced_syscalls,
+ size_t extra_length)
{
int status;

@@ -144,7 +196,8 @@

/* Sanity check, see start_arch_section(). */
if ( talloc_array_length(program->filter) - program->len
- != LENGTH_END_SECTION + nb_traced_syscalls * LENGTH_TRACE_SYSCALL)
+ != LENGTH_END_SECTION + nb_traced_syscalls * LENGTH_TRACE_SYSCALL
+ + extra_length)
return -ERANGE;

return 0;
@@ -156,12 +209,14 @@
* sanity check. This function returns -errno if an error occurred,
* otherwise 0.
*/
-static int start_arch_section(struct sock_fprog *program, uint32_t arch, size_t nb_traced_syscalls)
+static int start_arch_section(struct sock_fprog *program, uint32_t arch,
+ size_t nb_traced_syscalls, size_t extra_length)
{
const size_t arch_offset = offsetof(struct seccomp_data, arch);
const size_t syscall_offset = offsetof(struct seccomp_data, nr);
const size_t section_length = LENGTH_END_SECTION +
- nb_traced_syscalls * LENGTH_TRACE_SYSCALL;
+ nb_traced_syscalls * LENGTH_TRACE_SYSCALL +
+ extra_length;
int status;

/* Sanity checks. */
@@ -267,6 +322,7 @@
/* For each handled architectures */
for (i = 0; i < nb_archs; i++) {
word_t syscall;
+ size_t extra_length = 0;

nb_traced_syscalls = 0;

@@ -279,8 +335,17 @@
}
}

+#ifdef __ANDROID__
+ for (j = 0; j < seccomp_archs[i].nb_abis; j++) {
+ syscall = detranslate_sysnum(seccomp_archs[i].abis[j], PR_ioctl);
+ if (syscall != SYSCALL_AVOIDER)
+ extra_length += LENGTH_TRACE_ANDROID_IOCTL;
+ }
+#endif
+
/* Filter: if handled architecture */
- status = start_arch_section(&program, seccomp_archs[i].value, nb_traced_syscalls);
+ status = start_arch_section(&program, seccomp_archs[i].value,
+ nb_traced_syscalls, extra_length);
if (status < 0)
goto end;

@@ -298,8 +363,20 @@
}
}

+#ifdef __ANDROID__
+ for (j = 0; j < seccomp_archs[i].nb_abis; j++) {
+ syscall = detranslate_sysnum(seccomp_archs[i].abis[j], PR_ioctl);
+ if (syscall == SYSCALL_AVOIDER)
+ continue;
+
+ status = add_trace_android_ioctl(&program, syscall);
+ if (status < 0)
+ goto end;
+ }
+#endif
+
/* Filter: allow untraced syscalls for this architecture */
- status = end_arch_section(&program, nb_traced_syscalls);
+ status = end_arch_section(&program, nb_traced_syscalls, extra_length);
if (status < 0)
goto end;
}
@@ -356,9 +433,6 @@
{ PR_getsockname, FILTER_SYSEXIT },
{ PR_getxattr, 0 },
{ PR_inotify_add_watch, 0 },
-#ifdef __ANDROID__
- { PR_ioctl, FILTER_SYSEXIT },
-#endif
{ PR_lchown, 0 },
{ PR_lchown32, 0 },
{ PR_lgetxattr, 0 },
5 changes: 3 additions & 2 deletions tools/build-proot-assets.sh
Original file line number Diff line number Diff line change
Expand Up @@ -57,8 +57,9 @@ build_abi() {
ln -s "$TOOLCHAIN/llvm-readelf" "$wrappers/readelf"
unzip -q "$WORK/proot.zip" -d "$abi_work/proot-source"
tar -xzf "$WORK/talloc.tar.gz" -C "$abi_work/talloc" --strip-components=1
patch -d "$abi_work/proot-source/proot-${PROOT_VERSION}" -p1 \
< "$ROOT/tools/proot-ndk28.patch"
for patch_file in "$ROOT"/patches/proot/*.patch; do
patch -d "$abi_work/proot-source/proot-${PROOT_VERSION}" -p1 < "$patch_file"
done

(
cd "$abi_work/talloc"
Expand Down
8 changes: 0 additions & 8 deletions tools/proot-ndk28.patch

This file was deleted.

Loading