From bea0a444852659a7ed48a212042b80148006769f Mon Sep 17 00:00:00 2001 From: Drew DeVault Date: Fri, 8 May 2020 16:43:07 -0400 Subject: [PATCH] Update qemu-minimal-static --- sr.ht/pixman/APKBUILD | 43 ++++ sr.ht/pixman/stacksize-reduction.patch | 35 ++++ sr.ht/qemu-minimal-static/APKBUILD | 14 +- sr.ht/qemu-minimal-static/qemu-chroot.c | 196 ++++++++++++++++-- .../qemu-minimal-static/xattr_size_max.patch | 15 ++ 5 files changed, 282 insertions(+), 21 deletions(-) create mode 100644 sr.ht/pixman/APKBUILD create mode 100644 sr.ht/pixman/stacksize-reduction.patch create mode 100644 sr.ht/qemu-minimal-static/xattr_size_max.patch diff --git a/sr.ht/pixman/APKBUILD b/sr.ht/pixman/APKBUILD new file mode 100644 index 0000000..2ad13b7 --- /dev/null +++ b/sr.ht/pixman/APKBUILD @@ -0,0 +1,43 @@ +# Maintainer: Natanael Copa +pkgname=pixman +pkgver=0.40.0 +pkgrel=0 +pkgdesc="Low-level pixel manipulation library" +url="http://xorg.freedesktop.org" +arch="all" +license="MIT" +subpackages="$pkgname-static $pkgname-dev $pkgname-dbg" +makedepends="perl linux-headers autoconf automake libtool" +source="https://gitlab.freedesktop.org/pixman/pixman/-/archive/pixman-$pkgver/pixman-pixman-$pkgver.tar.gz" +builddir="$srcdir/$pkgname-$pkgname-$pkgver" + +build() { + cd "$builddir" + ./autogen.sh + ./configure \ + --build=$CBUILD \ + --host=$CHOST \ + --prefix=/usr \ + --enable-static \ + --disable-openmp \ + --disable-arm-iwmmxt + make +} + +check() { + cd "$builddir" + make check +} + +package() { + cd "$builddir" + make DESTDIR="$pkgdir" install +} + +static() { + pkgdesc="Static libraries for pixman" + mkdir -p "$subpkgdir"/usr/lib + mv "$pkgdir"/usr/lib/*.a "$subpkgdir"/usr/lib/ +} + +sha512sums="18774e22add5c5442edede5467fa07234c2b9e57a79d88110f25424e4253c6ab0c2921e951c5686cefebf4724ff19ad053d0c28f4d2f8d642bbcf6fc71764ef6 pixman-pixman-0.40.0.tar.gz" diff --git a/sr.ht/pixman/stacksize-reduction.patch b/sr.ht/pixman/stacksize-reduction.patch new file mode 100644 index 0000000..38da9b3 --- /dev/null +++ b/sr.ht/pixman/stacksize-reduction.patch @@ -0,0 +1,35 @@ +Reduce the stack footprint of pixman's function +general_composite_rect() which allocates a large buffer +`stack_scanline_buffer`. Make it `static __thread` instead. + +--- a/pixman/pixman-general.c 2015-12-27 21:37:37.000000000 +0100 ++++ b/pixman/pixman-general.c 2016-05-05 12:24:47.346661080 +0200 +@@ -128,8 +128,8 @@ + pixman_composite_info_t *info) + { + PIXMAN_COMPOSITE_ARGS (info); +- uint8_t stack_scanline_buffer[3 * SCANLINE_BUFFER_LENGTH]; +- uint8_t *scanline_buffer = (uint8_t *) stack_scanline_buffer; ++ static __thread uint8_t static_scanline_buffer[3 * SCANLINE_BUFFER_LENGTH]; ++ uint8_t *scanline_buffer = (uint8_t *) static_scanline_buffer; + uint8_t *src_buffer, *mask_buffer, *dest_buffer; + pixman_iter_t src_iter, mask_iter, dest_iter; + pixman_combine_32_func_t compose; +@@ -158,7 +158,7 @@ + if (width <= 0 || _pixman_multiply_overflows_int (width, Bpp * 3)) + return; + +- if (width * Bpp * 3 > sizeof (stack_scanline_buffer) - 15 * 3) ++ if (width * Bpp * 3 > sizeof (static_scanline_buffer) - 15 * 3) + { + scanline_buffer = pixman_malloc_ab_plus_c (width, Bpp * 3, 15 * 3); + +@@ -232,7 +232,7 @@ + if (dest_iter.fini) + dest_iter.fini (&dest_iter); + +- if (scanline_buffer != (uint8_t *) stack_scanline_buffer) ++ if (scanline_buffer != (uint8_t *) static_scanline_buffer) + free (scanline_buffer); + } + diff --git a/sr.ht/qemu-minimal-static/APKBUILD b/sr.ht/qemu-minimal-static/APKBUILD index 92a73e1..0c28826 100644 --- a/sr.ht/qemu-minimal-static/APKBUILD +++ b/sr.ht/qemu-minimal-static/APKBUILD @@ -1,6 +1,6 @@ # Maintainer: Drew DeVault pkgname=qemu-minimal-static -pkgver=4.2.0 +pkgver=5.0.0 pkgrel=0 pkgdesc="A stripped down, chrooted version of qemu for untrusted guests" url="https://qemu.org/" @@ -30,6 +30,7 @@ source=" https://wiki.qemu-project.org/download/qemu-$pkgver.tar.xz 80-kvm.rules qemu-chroot.c + xattr_size_max.patch " builddir="$srcdir/qemu-$pkgver" @@ -52,7 +53,6 @@ build() { --disable-vte \ --disable-gtk \ --disable-sdl \ - --disable-bluez \ --disable-spice \ --disable-vnc \ --disable-curses \ @@ -69,6 +69,11 @@ build() { package() { make DESTDIR="$pkgdir/usr/lib/qemu-minimal-static" install + mkdir -p "$pkgdir"/usr/lib/qemu-minimal-static/dev + mkdir -p "$pkgdir"/usr/lib/qemu-minimal-static/base + mkdir -p "$pkgdir"/usr/lib/qemu-minimal-static/var/tmp + touch "$pkgdir"/usr/lib/qemu-minimal-static/dev/null + touch "$pkgdir"/usr/lib/qemu-minimal-static/dev/kvm install -Dm644 "$srcdir"/80-kvm.rules \ "$pkgdir"/lib/udev/rules.d/80-kvm.rules mkdir -p "$pkgdir"/usr/bin @@ -77,6 +82,7 @@ package() { rm "$pkgdir"/usr/lib/qemu-minimal-static/libexec/qemu-bridge-helper } -sha512sums="2a79973c2b07c53e8c57a808ea8add7b6b2cbca96488ed5d4b669ead8c9318907dec2b6109f180fc8ca8f04c0f73a56e82b3a527b5626b799d7e849f2474ec56 qemu-4.2.0.tar.xz +sha512sums="21ef0cbe107c468a40f0fa2635db2a40048c8790b629dfffca5cd62bb1b502ea8eb133bfc40df5ecf1489e2bffe87f6829aee041cb8a380ff04a8afa23b39fcf qemu-5.0.0.tar.xz 9b7a89b20fcf737832cb7b4d5dc7d8301dd88169cbe5339eda69fbb51c2e537d8cb9ec7cf37600899e734209e63410d50d0821bce97e401421db39c294d97be2 80-kvm.rules -731b946f0c2fe188b8c4f7c96758359d86995d6ea45a8476c0e741268d03c7b65c0507f9298309224810558c825ee03bba13e8ebef0ee7d6dbd9e8194990312b qemu-chroot.c" +996d78a60d4283b31400a808916c774e7dd80ae5827aa25966a19a8134710bf4a010f1eccc680dc6a4fdbaef953323e50674d6b857f4197d32d266ff106904c7 qemu-chroot.c +4b1e26ba4d53f9f762cbd5cea8ef6f8062d827ae3ae07bc36c5b0c0be4e94fc1856ad2477e8e791b074b8a25d51ed6d0ddd75e605e54600e5dd0799143793ce4 xattr_size_max.patch" diff --git a/sr.ht/qemu-minimal-static/qemu-chroot.c b/sr.ht/qemu-minimal-static/qemu-chroot.c index 6ee9814..87bba28 100644 --- a/sr.ht/qemu-minimal-static/qemu-chroot.c +++ b/sr.ht/qemu-minimal-static/qemu-chroot.c @@ -1,16 +1,29 @@ #define _XOPEN_SOURCE #include -#include +#include +#include +#include #include +#include #include #include #include +#include #include #include int chroot(char *path); -void check(int p, char *ctx) { +struct userbind { + char *src, *dest; + struct userbind *next; +}; + +pid_t child; +char *pidpath = NULL, *root = NULL; +struct userbind *binds = NULL; + +static void check(int p, char *ctx) { if (p) { return; } @@ -18,24 +31,173 @@ void check(int p, char *ctx) { exit(1); } +static void usage(void) { + fprintf(stderr, "Usage: qemu-chroot [-b :] [-p ] " + "/bin/qemu-system- [args...]\n"); +} + +static void cleanup() { + int r; + char path[PATH_MAX + 1] = ""; + char *paths[] = { + "/dev/null", + "/dev/kvm", + }; + for (size_t i = 0; i < sizeof(paths) / sizeof(paths[0]); ++i) { + snprintf(path, sizeof(path), "%s%s", root, paths[i]); + r = umount2(path, 0); + if (r != 0) { + fprintf(stderr, "umount %s: %s\n", path, strerror(errno)); + } + } + + while (binds) { + snprintf(path, sizeof(path), "%s%s", root, binds->dest); + r = umount2(path, 0); + if (r != 0) { + fprintf(stderr, "umount %s: %s\n", path, strerror(errno)); + } + struct userbind *next = binds->next; + free(binds); + binds = next; + } + + r = umount2(root, 0); + if (r != 0) { + fprintf(stderr, "umount %s: %s\n", root, strerror(errno)); + } + remove(root); + + remove(pidpath); +} + +static void sig(int s) { + kill(child, s); +} + int main(int argc, char *argv[]) { + FILE *pidfile = NULL; + + char c; + while ((c = getopt(argc, argv, "b:p:h")) != -1) { + switch (c) { + case 'b':; + char *src = strtok(optarg, ":"); + char *dest = strtok(NULL, ":"); + struct userbind *bind = calloc(1, sizeof(struct userbind)); + bind->src = src; + bind->dest = dest; + bind->next = binds; + binds = bind; + break; + case 'p': + if (pidfile != NULL) { + fprintf(stderr, "-p may only be specified once"); + return 1; + } + pidpath = optarg; + pidfile = fopen(pidpath, "w"); + check(pidfile != NULL, "open pid file for write"); + break; + case 'h': + usage(); + return 0; + default: + usage(); + return 1; + } + } + + argc -= optind; + argv += optind; + + char tmp[] = "/tmp/qemu-chroot.XXXXXX"; + root = mkdtemp(tmp); + check(root != NULL, "mkdtemp"); + struct passwd *nobody = getpwnam("nobody"); check(nobody != NULL, "getpwnam"); int r; - r = chroot("/usr/lib/qemu-minimal-static"); - check(r == 0, "chroot"); - - r = setgid(nobody->pw_gid); - check(r == 0, "setgid"); - r = setegid(nobody->pw_gid); - check(r == 0, "setegid"); - r = setuid(nobody->pw_uid); - check(r == 0, "setuid"); - r = seteuid(nobody->pw_uid); - check(r == 0, "seteuid"); - - r = execv(argv[1], &argv[1]); - check(r == 0, "execv"); - return 1; + r = mount("/usr/lib/qemu-minimal-static", root, "", MS_BIND, NULL); + check(r == 0, "bind mount /usr/lib/qemu-minimal-static"); + + char *paths[] = { + "/dev/null", + "/dev/kvm", + }; + char path[PATH_MAX + 1] = ""; + for (size_t i = 0; i < sizeof(paths) / sizeof(paths[0]); ++i) { + snprintf(path, sizeof(path), "%s%s", root, paths[i]); + r = mount(paths[i], path, "", MS_BIND, NULL); + if (r != 0) { + fprintf(stderr, "bind mount %s: %s\n", paths[i], strerror(errno)); + return 1; + } + } + + struct userbind *b = binds; + while (b) { + snprintf(path, sizeof(path), "%s%s", root, b->dest); + r = mount(b->src, path, "", MS_BIND, NULL); + if (r != 0) { + fprintf(stderr, "bind mount %s: %s\n", b->src, strerror(errno)); + return 1; + } + b = b->next; + } + + struct sigaction sa = {0}; + sigemptyset(&sa.sa_mask); + sa.sa_handler = sig; + sa.sa_flags = SA_RESTART; + + r = sigaction(SIGINT, &sa, NULL); + check(r != -1, "sigaction"); + + r = sigaction(SIGTERM, &sa, NULL); + check(r != -1, "sigaction"); + + child = fork(); + check(child != -1, "fork"); + if (child == 0) { + if (pidfile != NULL) { + fclose(pidfile); + } + + r = chroot(root); + check(r == 0, "chroot"); + + r = setgid(nobody->pw_gid); + check(r == 0, "setgid"); + r = setegid(nobody->pw_gid); + check(r == 0, "setegid"); + r = setuid(nobody->pw_uid); + check(r == 0, "setuid"); + r = seteuid(nobody->pw_uid); + check(r == 0, "seteuid"); + + if (setuid(0) != -1) { + fprintf(stderr, "Unable to drop root, bailing out\n"); + return 1; + } + + r = execv(argv[0], &argv[0]); + check(r == 0, "execv"); + } + + if (pidfile != NULL) { + fprintf(pidfile, "%d\n", child); + fclose(pidfile); + } + + int status; + do { + pid_t wpid = waitpid(child, &status, WUNTRACED | WCONTINUED); + check(wpid != -1, "waitpid"); + } while (!WIFEXITED(status) && !WIFSIGNALED(status)); + + cleanup(); + + return WEXITSTATUS(status); } diff --git a/sr.ht/qemu-minimal-static/xattr_size_max.patch b/sr.ht/qemu-minimal-static/xattr_size_max.patch new file mode 100644 index 0000000..1a33cbf --- /dev/null +++ b/sr.ht/qemu-minimal-static/xattr_size_max.patch @@ -0,0 +1,15 @@ +diff --git a/hw/9pfs/9p.c b/hw/9pfs/9p.c +index faebd91..a0f15b6 100644 +--- a/hw/9pfs/9p.c ++++ b/hw/9pfs/9p.c +@@ -25,6 +25,10 @@ + #include "trace.h" + #include "migration/migration.h" + ++#ifdef __linux__ ++#include /* for XATTR_SIZE_MAX */ ++#endif ++ + int open_fd_hw; + int total_open_fd; + static int open_fd_rc; -- 2.45.2