Workarounds for Android host glibc toolchain
When minijail is built against the Android host glibc toolchain, its
syscall and ioctl coverage becomes limited by the very old Linux C
headers the toolchain is using. Because crosvm jails subprocesses
that can load e.g. GL libraries or FUSE which may be built with much
newer glibc versions, we need support for some newer syscalls and
ioctls added to Linux.
Minijail will throw parse errors for any syscall or ioctl in .policy
files that it doesn't understand; and anyway, it wouldn't be meaningful
to strip these, as .policy files are inclusion (not exclusion) based.
This change isn't very nice, but it does unblock us from running crosvm
built by the Android host toolchain with sandboxing enabled.
Change-Id: Iab7f2e7abac0f5e154e300833b8d91d7b8500aff
(cherry picked from commit 3b58ccb3072c5908c79d65339e886b344f49c5d1)
diff --git a/gen_constants-inl.h b/gen_constants-inl.h
index 1248254..686ec5e 100644
--- a/gen_constants-inl.h
+++ b/gen_constants-inl.h
@@ -1,6 +1,11 @@
+/* Copyright (c) 2014 The Chromium OS Authors. All rights reserved.
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
#if defined(__i386__) || defined(__x86_64__)
#include <asm/prctl.h>
-#endif // __i386__ || __x86_64__
+#endif /* __i386__ || __x86_64__ */
#include <errno.h>
#include <fcntl.h>
#include <linux/fd.h>
@@ -23,8 +28,45 @@
#include "arch.h"
-// These defines use C structures that are not defined in the same headers which
-// cause our CPP logic to fail w/undefined identifiers. Remove them to avoid
-// build errors on such broken systems.
+/* These defines use C structures that are not defined in the same headers which
+ * cause our CPP logic to fail w/undefined identifiers. Remove them to avoid
+ * build errors on such broken systems.
+ */
#undef BLKTRACESETUP
#undef FS_IOC_FIEMAP
+
+/* The old glibc bundled with the Android host toolchain is missing some ioctl
+ * definitions used by minijail policy in crosvm and other projects. Locally
+ * define them below.
+ * This UAPI is taken from sanitized bionic headers.
+ */
+
+/* <linux/fs.h> */
+#if !defined(FS_IOC_FSGETXATTR) && !defined(FS_IOC_FSSETXATTR)
+struct fsxattr {
+ __u32 fsx_xflags;
+ __u32 fsx_extsize;
+ __u32 fsx_nextents;
+ __u32 fsx_projid;
+ __u32 fsx_cowextsize;
+ unsigned char fsx_pad[8];
+};
+#define FS_IOC_FSGETXATTR _IOR('X', 31, struct fsxattr)
+#define FS_IOC_FSSETXATTR _IOW('X', 32, struct fsxattr)
+#endif /* !FS_IOC_FSGETXATTR && !FS_IOC_FSSETXATTR */
+
+/* <linux/fscrypt.h> */
+#if !defined(FS_IOC_SET_ENCRYPTION_POLICY) && \
+ !defined(FS_IOC_GET_ENCRYPTION_POLICY)
+#define FSCRYPT_KEY_DESCRIPTOR_SIZE 8
+struct fscrypt_policy_v1 {
+ __u8 version;
+ __u8 contents_encryption_mode;
+ __u8 filenames_encryption_mode;
+ __u8 flags;
+ __u8 master_key_descriptor[FSCRYPT_KEY_DESCRIPTOR_SIZE];
+};
+#define fscrypt_policy fscrypt_policy_v1
+#define FS_IOC_SET_ENCRYPTION_POLICY _IOR('f', 19, struct fscrypt_policy)
+#define FS_IOC_GET_ENCRYPTION_POLICY _IOW('f', 21, struct fscrypt_policy)
+#endif /* !FS_IOC_SET_ENCRYPTION_POLICY && !FS_IOC_GET_ENCRYPTION_POLICY */
diff --git a/gen_syscalls-inl.h b/gen_syscalls-inl.h
new file mode 100644
index 0000000..6203ae4
--- /dev/null
+++ b/gen_syscalls-inl.h
@@ -0,0 +1,63 @@
+/* Copyright (c) 2014 The Chromium OS Authors. All rights reserved.
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#include <asm/unistd.h>
+
+/* Ideally minijail is compiled against a modern libc, which has modern copies
+ * of Linux uapi for ioctls, and unistd.h for syscalls. However, sometimes this
+ * isn't possible - such as when building with the Android host toolchain - so
+ * locally define the system calls in use in active seccomp policy files.
+ * This UAPI is taken from sanitized bionic headers.
+ */
+
+#ifndef __NR_copy_file_range
+#ifdef __x86_64__
+#define __NR_copy_file_range 326
+#elif __i386__
+#define __NR_copy_file_range 377
+#elif __arm64__
+#define __NR_copy_file_range 285
+#endif
+#endif /* __NR_copy_file_range */
+
+#ifndef __NR_getrandom
+#ifdef __x86_64__
+#define __NR_getrandom 318
+#elif __i386__
+#define __NR_getrandom 355
+#elif __arm64__
+#define __NR_getrandom 278
+#endif
+#endif /* __NR_getrandom */
+
+#ifndef __NR_memfd_create
+#ifdef __x86_64__
+#define __NR_memfd_create 319
+#elif __i386__
+#define __NR_memfd_create 356
+#elif __arm64__
+#define __NR_memfd_create 279
+#endif
+#endif /* __NR_memfd_create */
+
+#ifndef __NR_renameat2
+#ifdef __x86_64__
+#define __NR_renameat2 316
+#elif __i386__
+#define __NR_renameat2 353
+#elif __arm64__
+#define __NR_renameat2 276
+#endif
+#endif /* __NR_renameat2 */
+
+#ifndef __NR_statx
+#ifdef __x86_64__
+#define __NR_statx 332
+#elif __i386__
+#define __NR_statx 383
+#elif __arm64__
+#define __NR_statx 291
+#endif
+#endif /* __NR_statx */
diff --git a/gen_syscalls.sh b/gen_syscalls.sh
index 43e39b7..ca26322 100755
--- a/gen_syscalls.sh
+++ b/gen_syscalls.sh
@@ -48,7 +48,7 @@
cat <<-EOF > "${OUTFILE}"
/* GENERATED BY MAKEFILE */
#include <stddef.h>
-#include <asm/unistd.h>
+#include "gen_syscalls-inl.h"
#include "libsyscalls.h"
const struct syscall_entry syscall_table[] = {
$(${BUILD} | sed -Ene "${SED_MULTILINE}")
diff --git a/linux-x86/libsyscalls.gen.c b/linux-x86/libsyscalls.gen.c
index c33e124..34af6ca 100644
--- a/linux-x86/libsyscalls.gen.c
+++ b/linux-x86/libsyscalls.gen.c
@@ -1,6 +1,6 @@
/* GENERATED BY MAKEFILE */
#include <stddef.h>
-#include <asm/unistd.h>
+#include "gen_syscalls-inl.h"
#include "libsyscalls.h"
const struct syscall_entry syscall_table[] = {
#ifdef __NR_read