commit: ac63593feec203a38fccf1189ba0fe3e304f4f8b Author: John Helmert III <ajak <AT> gentoo <DOT> org> AuthorDate: Mon Dec 25 19:47:55 2023 +0000 Commit: John Helmert III <ajak <AT> gentoo <DOT> org> CommitDate: Mon Dec 25 19:55:26 2023 +0000 URL: https://gitweb.gentoo.org/repo/gentoo.git/commit/?id=ac63593f
net-vpn/tor: add 0.4.7.16-r1 for arm64 test patch Closes: https://bugs.gentoo.org/920063 Signed-off-by: John Helmert III <ajak <AT> gentoo.org> net-vpn/tor/files/tor-0.4.7.16-arm64-sandbox.patch | 337 +++++++++++++++++++++ net-vpn/tor/tor-0.4.7.16-r1.ebuild | 168 ++++++++++ 2 files changed, 505 insertions(+) diff --git a/net-vpn/tor/files/tor-0.4.7.16-arm64-sandbox.patch b/net-vpn/tor/files/tor-0.4.7.16-arm64-sandbox.patch new file mode 100644 index 000000000000..2b473bf981b6 --- /dev/null +++ b/net-vpn/tor/files/tor-0.4.7.16-arm64-sandbox.patch @@ -0,0 +1,337 @@ +From https://gitlab.torproject.org/tpo/core/tor/-/merge_requests/574 +Gentoo Bug: https://bugs.gentoo.org/920063 +From: Pierre Bourdon <delr...@gmail.com> +Date: Sat, 30 Apr 2022 11:52:59 +0200 +Subject: [PATCH 1/4] sandbox: fix openat filtering on AArch64 + +New glibc versions not sign-extending 32 bit negative constants seems to +not be a thing on AArch64. I suspect that this might not be the only +architecture where the sign-extensions is happening, and the correct fix +might be instead to use a proper 32 bit comparison for the first openat +parameter. For now, band-aid fix this so the sandbox can work again on +AArch64. +--- a/src/lib/sandbox/sandbox.c ++++ b/src/lib/sandbox/sandbox.c +@@ -518,7 +518,12 @@ libc_uses_openat_for_opendir(void) + static int + libc_negative_constant_needs_cast(void) + { ++#if defined(__aarch64__) && defined(__LP64__) ++ /* Existing glibc versions always sign-extend to 64 bits on AArch64. */ ++ return 0; ++#else + return is_libc_at_least(2, 27); ++#endif + } + + /** Allow a single file to be opened. If <b>use_openat</b> is true, +-- +GitLab + + +From 8fd13f7a7bfd4efc02d888ce9d10bcb6a80a03c8 Mon Sep 17 00:00:00 2001 +From: Pierre Bourdon <delr...@gmail.com> +Date: Sat, 30 Apr 2022 13:02:16 +0200 +Subject: [PATCH 2/4] sandbox: filter {chown,chmod,rename} via their *at + variant on Aarch64 + +The chown/chmod/rename syscalls have never existed on AArch64, and libc +implements the POSIX functions via the fchownat/fchmodat/renameat +syscalls instead. + +Add new filter functions for fchownat/fchmodat/renameat, not made +architecture specific since the syscalls exists everywhere else too. +However, in order to limit seccomp filter space usage, we only insert +rules for one of {chown, chown32, fchownat} depending on the +architecture (resp. {chmod, fchmodat}, {rename, renameat}). +--- a/src/lib/sandbox/sandbox.c ++++ b/src/lib/sandbox/sandbox.c +@@ -614,6 +614,32 @@ sb_chmod(scmp_filter_ctx ctx, sandbox_cfg_t *filter) + return 0; + } + ++static int ++sb_fchmodat(scmp_filter_ctx ctx, sandbox_cfg_t *filter) ++{ ++ int rc; ++ sandbox_cfg_t *elem = NULL; ++ ++ // for each dynamic parameter filters ++ for (elem = filter; elem != NULL; elem = elem->next) { ++ smp_param_t *param = elem->param; ++ ++ if (param != NULL && param->prot == 1 && param->syscall ++ == SCMP_SYS(fchmodat)) { ++ rc = seccomp_rule_add_2(ctx, SCMP_ACT_ALLOW, SCMP_SYS(fchmodat), ++ SCMP_CMP_NEG(0, SCMP_CMP_EQ, AT_FDCWD), ++ SCMP_CMP_STR(1, SCMP_CMP_EQ, param->value)); ++ if (rc != 0) { ++ log_err(LD_BUG,"(Sandbox) failed to add fchmodat syscall, received " ++ "libseccomp error %d", rc); ++ return rc; ++ } ++ } ++ } ++ ++ return 0; ++} ++ + #ifdef __i386__ + static int + sb_chown32(scmp_filter_ctx ctx, sandbox_cfg_t *filter) +@@ -666,6 +692,32 @@ sb_chown(scmp_filter_ctx ctx, sandbox_cfg_t *filter) + } + #endif /* defined(__i386__) */ + ++static int ++sb_fchownat(scmp_filter_ctx ctx, sandbox_cfg_t *filter) ++{ ++ int rc; ++ sandbox_cfg_t *elem = NULL; ++ ++ // for each dynamic parameter filters ++ for (elem = filter; elem != NULL; elem = elem->next) { ++ smp_param_t *param = elem->param; ++ ++ if (param != NULL && param->prot == 1 && param->syscall ++ == SCMP_SYS(fchownat)) { ++ rc = seccomp_rule_add_2(ctx, SCMP_ACT_ALLOW, SCMP_SYS(fchownat), ++ SCMP_CMP_NEG(0, SCMP_CMP_EQ, AT_FDCWD), ++ SCMP_CMP_STR(1, SCMP_CMP_EQ, param->value)); ++ if (rc != 0) { ++ log_err(LD_BUG,"(Sandbox) failed to add fchownat syscall, received " ++ "libseccomp error %d", rc); ++ return rc; ++ } ++ } ++ } ++ ++ return 0; ++} ++ + /** + * Function responsible for setting up the rename syscall for + * the seccomp filter sandbox. +@@ -697,6 +749,39 @@ sb_rename(scmp_filter_ctx ctx, sandbox_cfg_t *filter) + return 0; + } + ++/** ++ * Function responsible for setting up the renameat syscall for ++ * the seccomp filter sandbox. ++ */ ++static int ++sb_renameat(scmp_filter_ctx ctx, sandbox_cfg_t *filter) ++{ ++ int rc; ++ sandbox_cfg_t *elem = NULL; ++ ++ // for each dynamic parameter filters ++ for (elem = filter; elem != NULL; elem = elem->next) { ++ smp_param_t *param = elem->param; ++ ++ if (param != NULL && param->prot == 1 && ++ param->syscall == SCMP_SYS(renameat)) { ++ ++ rc = seccomp_rule_add_4(ctx, SCMP_ACT_ALLOW, SCMP_SYS(renameat), ++ SCMP_CMP_NEG(0, SCMP_CMP_EQ, AT_FDCWD), ++ SCMP_CMP_STR(1, SCMP_CMP_EQ, param->value), ++ SCMP_CMP_NEG(2, SCMP_CMP_EQ, AT_FDCWD), ++ SCMP_CMP_STR(3, SCMP_CMP_EQ, param->value2)); ++ if (rc != 0) { ++ log_err(LD_BUG,"(Sandbox) failed to add renameat syscall, received " ++ "libseccomp error %d", rc); ++ return rc; ++ } ++ } ++ } ++ ++ return 0; ++} ++ + /** + * Function responsible for setting up the openat syscall for + * the seccomp filter sandbox. +@@ -1317,7 +1402,9 @@ static sandbox_filter_func_t filter_func[] = { + #else + sb_chown, + #endif ++ sb_fchownat, + sb_chmod, ++ sb_fchmodat, + sb_open, + sb_openat, + sb_opendir, +@@ -1325,6 +1412,7 @@ static sandbox_filter_func_t filter_func[] = { + sb_ptrace, + #endif + sb_rename, ++ sb_renameat, + #ifdef __NR_fcntl64 + sb_fcntl64, + #endif +@@ -1592,10 +1680,24 @@ new_element(int syscall, char *value) + + #ifdef __i386__ + #define SCMP_chown SCMP_SYS(chown32) ++#elif defined(__aarch64__) && defined(__LP64__) ++#define SCMP_chown SCMP_SYS(fchownat) + #else + #define SCMP_chown SCMP_SYS(chown) + #endif + ++#if defined(__aarch64__) && defined(__LP64__) ++#define SCMP_chmod SCMP_SYS(fchmodat) ++#else ++#define SCMP_chmod SCMP_SYS(chmod) ++#endif ++ ++#if defined(__aarch64__) && defined(__LP64__) ++#define SCMP_rename SCMP_SYS(renameat) ++#else ++#define SCMP_rename SCMP_SYS(rename) ++#endif ++ + #ifdef __NR_stat64 + #define SCMP_stat SCMP_SYS(stat64) + #else +@@ -1633,7 +1735,7 @@ sandbox_cfg_allow_chmod_filename(sandbox_cfg_t **cfg, char *file) + { + sandbox_cfg_t *elem = NULL; + +- elem = new_element(SCMP_SYS(chmod), file); ++ elem = new_element(SCMP_chmod, file); + + elem->next = *cfg; + *cfg = elem; +@@ -1659,7 +1761,7 @@ sandbox_cfg_allow_rename(sandbox_cfg_t **cfg, char *file1, char *file2) + { + sandbox_cfg_t *elem = NULL; + +- elem = new_element2(SCMP_SYS(rename), file1, file2); ++ elem = new_element2(SCMP_rename, file1, file2); + + elem->next = *cfg; + *cfg = elem; +-- +GitLab + + +From eb0749d64917fee6ff74c3810dbec8cd063f546c Mon Sep 17 00:00:00 2001 +From: Pierre Bourdon <delr...@gmail.com> +Date: Wed, 4 May 2022 07:19:40 +0200 +Subject: [PATCH 3/4] sandbox: replace SCMP_CMP_NEG with masked equality checks + +For some syscalls the kernel ABI uses 32 bit signed integers. Whether +these 32 bit integer values are sign extended or zero extended to the +native 64 bit register sizes is undefined and dependent on the {arch, +compiler, libc} being used. Instead of trying to detect which cases +zero-extend and which cases sign-extend, this commit uses a masked +equality check on the lower 32 bits of the value. +--- a/src/lib/sandbox/sandbox.c ++++ b/src/lib/sandbox/sandbox.c +@@ -141,10 +141,12 @@ static sandbox_cfg_t *filter_dynamic = NULL; + * the high bits of the value might get masked out improperly. */ + #define SCMP_CMP_MASKED(a,b,c) \ + SCMP_CMP4((a), SCMP_CMP_MASKED_EQ, ~(scmp_datum_t)(b), (c)) +-/* For negative constants, the rule to add depends on the glibc version. */ +-#define SCMP_CMP_NEG(a,op,b) (libc_negative_constant_needs_cast() ? \ +- (SCMP_CMP((a), (op), (unsigned int)(b))) : \ +- (SCMP_CMP_STR((a), (op), (b)))) ++/* Negative constants aren't consistently sign extended or zero extended. ++ * Different compilers, libc, and architectures behave differently. For cases ++ * where the kernel ABI uses a 32 bit integer, this macro can be used to ++ * mask-compare only the lower 32 bits of the value. */ ++#define SCMP_CMP_LOWER32_EQ(a,b) \ ++ SCMP_CMP4((a), SCMP_CMP_MASKED_EQ, 0xFFFFFFFF, (unsigned int)(b)) + + /** Variable used for storing all syscall numbers that will be allowed with the + * stage 1 general Tor sandbox. +@@ -513,19 +515,6 @@ libc_uses_openat_for_opendir(void) + (is_libc_at_least(2, 15) && !is_libc_at_least(2, 22)); + } + +-/* Return true if we think we're running with a libc that needs to cast +- * negative arguments like AT_FDCWD for seccomp rules. */ +-static int +-libc_negative_constant_needs_cast(void) +-{ +-#if defined(__aarch64__) && defined(__LP64__) +- /* Existing glibc versions always sign-extend to 64 bits on AArch64. */ +- return 0; +-#else +- return is_libc_at_least(2, 27); +-#endif +-} +- + /** Allow a single file to be opened. If <b>use_openat</b> is true, + * we're using a libc that remaps all the opens into openats. */ + static int +@@ -533,7 +522,7 @@ allow_file_open(scmp_filter_ctx ctx, int use_openat, const char *file) + { + if (use_openat) { + return seccomp_rule_add_2(ctx, SCMP_ACT_ALLOW, SCMP_SYS(openat), +- SCMP_CMP_NEG(0, SCMP_CMP_EQ, AT_FDCWD), ++ SCMP_CMP_LOWER32_EQ(0, AT_FDCWD), + SCMP_CMP_STR(1, SCMP_CMP_EQ, file)); + } else { + return seccomp_rule_add_1(ctx, SCMP_ACT_ALLOW, SCMP_SYS(open), +@@ -627,7 +616,7 @@ sb_fchmodat(scmp_filter_ctx ctx, sandbox_cfg_t *filter) + if (param != NULL && param->prot == 1 && param->syscall + == SCMP_SYS(fchmodat)) { + rc = seccomp_rule_add_2(ctx, SCMP_ACT_ALLOW, SCMP_SYS(fchmodat), +- SCMP_CMP_NEG(0, SCMP_CMP_EQ, AT_FDCWD), ++ SCMP_CMP_LOWER32_EQ(0, AT_FDCWD), + SCMP_CMP_STR(1, SCMP_CMP_EQ, param->value)); + if (rc != 0) { + log_err(LD_BUG,"(Sandbox) failed to add fchmodat syscall, received " +@@ -705,7 +694,7 @@ sb_fchownat(scmp_filter_ctx ctx, sandbox_cfg_t *filter) + if (param != NULL && param->prot == 1 && param->syscall + == SCMP_SYS(fchownat)) { + rc = seccomp_rule_add_2(ctx, SCMP_ACT_ALLOW, SCMP_SYS(fchownat), +- SCMP_CMP_NEG(0, SCMP_CMP_EQ, AT_FDCWD), ++ SCMP_CMP_LOWER32_EQ(0, AT_FDCWD), + SCMP_CMP_STR(1, SCMP_CMP_EQ, param->value)); + if (rc != 0) { + log_err(LD_BUG,"(Sandbox) failed to add fchownat syscall, received " +@@ -767,9 +756,9 @@ sb_renameat(scmp_filter_ctx ctx, sandbox_cfg_t *filter) + param->syscall == SCMP_SYS(renameat)) { + + rc = seccomp_rule_add_4(ctx, SCMP_ACT_ALLOW, SCMP_SYS(renameat), +- SCMP_CMP_NEG(0, SCMP_CMP_EQ, AT_FDCWD), ++ SCMP_CMP_LOWER32_EQ(0, AT_FDCWD), + SCMP_CMP_STR(1, SCMP_CMP_EQ, param->value), +- SCMP_CMP_NEG(2, SCMP_CMP_EQ, AT_FDCWD), ++ SCMP_CMP_LOWER32_EQ(2, AT_FDCWD), + SCMP_CMP_STR(3, SCMP_CMP_EQ, param->value2)); + if (rc != 0) { + log_err(LD_BUG,"(Sandbox) failed to add renameat syscall, received " +@@ -799,7 +788,7 @@ sb_openat(scmp_filter_ctx ctx, sandbox_cfg_t *filter) + if (param != NULL && param->prot == 1 && param->syscall + == SCMP_SYS(openat)) { + rc = seccomp_rule_add_3(ctx, SCMP_ACT_ALLOW, SCMP_SYS(openat), +- SCMP_CMP_NEG(0, SCMP_CMP_EQ, AT_FDCWD), ++ SCMP_CMP_LOWER32_EQ(0, AT_FDCWD), + SCMP_CMP_STR(1, SCMP_CMP_EQ, param->value), + SCMP_CMP(2, SCMP_CMP_EQ, O_RDONLY|O_NONBLOCK|O_LARGEFILE|O_DIRECTORY| + O_CLOEXEC)); +-- +GitLab + + +From 42034ae9da2866c67ce8cb8522d6a619d8b21170 Mon Sep 17 00:00:00 2001 +From: Pierre Bourdon <delr...@gmail.com> +Date: Wed, 4 May 2022 07:31:06 +0200 +Subject: [PATCH 4/4] changes: add entry for MR !574 + +--- /dev/null ++++ b/changes/aarch64_sandbox +@@ -0,0 +1,5 @@ ++ o Minor bugfixes (sandbox): ++ - Fix sandbox support on AArch64 systems. More "*at" variants of syscalls ++ are now supported. Signed 32 bit syscall parameters are checked more ++ precisely, which should lead to lower likelihood of breakages with future ++ compiler and libc releases. Fixes bug 40599; bugfix on 0.4.4.3-alpha. +-- +GitLab + diff --git a/net-vpn/tor/tor-0.4.7.16-r1.ebuild b/net-vpn/tor/tor-0.4.7.16-r1.ebuild new file mode 100644 index 000000000000..1c40fca5fb09 --- /dev/null +++ b/net-vpn/tor/tor-0.4.7.16-r1.ebuild @@ -0,0 +1,168 @@ +# Copyright 1999-2023 Gentoo Authors +# Distributed under the terms of the GNU General Public License v2 + +EAPI=8 + +PYTHON_COMPAT=( python3_{10..12} ) +VERIFY_SIG_OPENPGP_KEY_PATH=/usr/share/openpgp-keys/torproject.org.asc +inherit edo python-any-r1 readme.gentoo-r1 systemd verify-sig + +MY_PV="$(ver_rs 4 -)" +MY_PF="${PN}-${MY_PV}" +DESCRIPTION="Anonymizing overlay network for TCP" +HOMEPAGE="https://www.torproject.org/ https://gitlab.torproject.org/tpo/core/tor/" + +if [[ ${PV} == 9999 ]] ; then + EGIT_REPO_URI="https://gitlab.torproject.org/tpo/core/tor" + inherit autotools git-r3 +else + SRC_URI=" + https://www.torproject.org/dist/${MY_PF}.tar.gz + https://archive.torproject.org/tor-package-archive/${MY_PF}.tar.gz + verify-sig? ( + https://dist.torproject.org/${MY_PF}.tar.gz.sha256sum + https://dist.torproject.org/${MY_PF}.tar.gz.sha256sum.asc + ) + " + + S="${WORKDIR}/${MY_PF}" + + if [[ ${PV} != *_alpha* && ${PV} != *_beta* && ${PV} != *_rc* ]]; then + KEYWORDS="~amd64 ~arm ~arm64 ~hppa ~mips ~ppc ~ppc64 ~riscv ~sparc ~x86 ~ppc-macos" + fi + + BDEPEND="verify-sig? ( >=sec-keys/openpgp-keys-tor-20230727 )" +fi + +LICENSE="BSD GPL-2" +SLOT="0" +IUSE="caps doc lzma +man scrypt seccomp selinux +server systemd tor-hardening test zstd" +RESTRICT="!test? ( test )" + +DEPEND=" + >=dev-libs/libevent-2.1.12-r1:=[ssl] + dev-libs/openssl:=[-bindist(-)] + sys-libs/zlib + caps? ( sys-libs/libcap ) + man? ( app-text/asciidoc ) + lzma? ( app-arch/xz-utils ) + scrypt? ( app-crypt/libscrypt ) + seccomp? ( >=sys-libs/libseccomp-2.4.1 ) + systemd? ( sys-apps/systemd:= ) + zstd? ( app-arch/zstd:= ) +" +RDEPEND=" + acct-user/tor + acct-group/tor + ${DEPEND} + selinux? ( sec-policy/selinux-tor ) +" +DEPEND+=" + test? ( + ${DEPEND} + ${PYTHON_DEPS} + ) +" + +DOCS=() + +PATCHES=( + "${FILESDIR}"/${PN}-0.2.7.4-torrc.sample.patch + "${FILESDIR}"/${P}-arm64-sandbox.patch +) + +pkg_setup() { + use test && python-any-r1_pkg_setup +} + +src_unpack() { + if [[ ${PV} == 9999 ]] ; then + git-r3_src_unpack + else + if use verify-sig; then + cd "${DISTDIR}" || die + verify-sig_verify_detached ${MY_PF}.tar.gz.sha256sum{,.asc} + verify-sig_verify_unsigned_checksums \ + ${MY_PF}.tar.gz.sha256sum sha256 ${MY_PF}.tar.gz + cd "${WORKDIR}" || die + fi + + default + fi +} + +src_prepare() { + default + + # Running shellcheck automagically isn't useful for ebuild testing. + echo "exit 0" > scripts/maint/checkShellScripts.sh || die + + if [[ ${PV} == 9999 ]] ; then + eautoreconf + fi +} + +src_configure() { + use doc && DOCS+=( README.md ChangeLog ReleaseNotes doc/HACKING ) + + export ac_cv_lib_cap_cap_init=$(usex caps) + export tor_cv_PYTHON="${EPYTHON}" + + local myeconfargs=( + --localstatedir="${EPREFIX}/var" + --disable-all-bugs-are-fatal + --enable-system-torrc + --disable-android + --disable-coverage + --disable-html-manual + --disable-libfuzzer + --enable-missing-doc-warnings + --disable-module-dirauth + --enable-pic + --disable-restart-debugging + + $(use_enable man asciidoc) + $(use_enable man manpage) + $(use_enable lzma) + $(use_enable scrypt libscrypt) + $(use_enable seccomp) + $(use_enable server module-relay) + $(use_enable systemd) + $(use_enable tor-hardening gcc-hardening) + $(use_enable tor-hardening linker-hardening) + $(use_enable test unittests) + $(use_enable zstd) + ) + + econf "${myeconfargs[@]}" +} + +src_test() { + local skip_tests=( + # Fails in sandbox + :sandbox/open_filename + :sandbox/openat_filename + ) + + # The makefile runs these by parallel by chunking them with a script + # but that means we lose verbosity and can't skip individual tests easily + # either. + edo ./src/test/test --verbose "${skip_tests[@]}" +} + +src_install() { + default + readme.gentoo_create_doc + + newconfd "${FILESDIR}"/tor.confd tor + newinitd "${FILESDIR}"/tor.initd-r9 tor + systemd_dounit "${FILESDIR}"/tor.service + + keepdir /var/lib/tor + + fperms 750 /var/lib/tor + fowners tor:tor /var/lib/tor + + insinto /etc/tor/ + newins "${FILESDIR}"/torrc-r2 torrc +}