aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlistair Delva <adelva@google.com>2020-01-21 12:30:39 -0800
committerAlistair Delva <adelva@google.com>2020-01-21 12:30:45 -0800
commit4d571430604bc13c65f46a323333e387a110a9ed (patch)
tree1d8c3da5bf4d7e9d7e208ba2232ab2bf3308c6b4
parentab7379dd97e0d46fc84407a86de7397e0106a424 (diff)
downloadiproute2-4d571430604bc13c65f46a323333e387a110a9ed.tar.gz
ANDROID: Fix 32-bit x86 iproute2 on 64-bit kernel
Fix VtsKernelNetTest / xfrm_test.XfrmFunctionalTest testAddSa and other system users of iproute2 binaries on 32-bit x86 userspaces. The upstream XFRM netlink interface does not use packed structures, so it depends on architecture-specific alignment of XFRM structures. In upstream kernels, the workaround was to disallow 32-bit applications to use this netlink interface on 64-bit kernels, but on Android we want to support this, and so the check was removed from the kernel. Other changes had already been made to netd and various C++ unittests to mitigate this incompatibility, however these workarounds were not applied / cannot work with the C binaries from the iproute2 package. Apply the same workaround again here. NOTE: This explicitly breaks running iproute2 on a 32-bit x86 kernel. However, we don't think this will affect any device in the Android ecosystem. Bug: 138147164 Change-Id: Ibc6aa966f7f114d75c46078e5675ba2a44836a7d
l---------include/linux/xfrm.h1
-rw-r--r--include/uapi/linux/xfrm.h12
-rw-r--r--ip/xfrm.h13
3 files changed, 24 insertions, 2 deletions
diff --git a/include/linux/xfrm.h b/include/linux/xfrm.h
new file mode 120000
index 00000000..f43ae1b4
--- /dev/null
+++ b/include/linux/xfrm.h
@@ -0,0 +1 @@
+../uapi/linux/xfrm.h \ No newline at end of file
diff --git a/include/uapi/linux/xfrm.h b/include/uapi/linux/xfrm.h
index 93fb1920..8312d3d1 100644
--- a/include/uapi/linux/xfrm.h
+++ b/include/uapi/linux/xfrm.h
@@ -381,7 +381,11 @@ struct xfrm_usersa_info {
#define XFRM_STATE_AF_UNSPEC 32
#define XFRM_STATE_ALIGN4 64
#define XFRM_STATE_ESN 128
-};
+}
+#ifdef __i386__
+__attribute__((aligned(8))) /* b/138147164 */
+#endif
+;
#define XFRM_SA_XFLAG_DONT_ENCAP_DSCP 1
@@ -420,7 +424,11 @@ struct xfrm_userpolicy_info {
/* Automatically expand selector to include matching ICMP payloads. */
#define XFRM_POLICY_ICMP 2
__u8 share;
-};
+}
+#ifdef __i386__
+__attribute__((aligned(8))) /* b/138147164 */
+#endif
+;
struct xfrm_userpolicy_id {
struct xfrm_selector sel;
diff --git a/ip/xfrm.h b/ip/xfrm.h
index 71be574d..f1d3d0e7 100644
--- a/ip/xfrm.h
+++ b/ip/xfrm.h
@@ -30,6 +30,19 @@
#include <linux/xfrm.h>
#include <linux/ipsec.h>
+#ifdef __i386__
+/* b/138147164 */
+/* Adapted from checks in system/netd/server/XfrmController.h */
+_Static_assert(sizeof(struct xfrm_usersa_info) - offsetof(struct xfrm_usersa_info, flags) == 8,
+ "struct xfrm_usersa_info probably misaligned with kernel struct.");
+_Static_assert(sizeof(struct xfrm_usersa_info) % 8 == 0,
+ "struct xfrm_usersa_info is not 64-bit aligned.");
+_Static_assert(sizeof(struct xfrm_userpolicy_info) - offsetof(struct xfrm_userpolicy_info, share) == 5,
+ "struct xfrm_userpolicy_info probably misaligned with kernel struct.");
+_Static_assert(sizeof(struct xfrm_userpolicy_info) % 8 == 0,
+ "struct xfrm_userpolicy_info is not 64-bit aligned.");
+#endif /* __i386__ */
+
#ifndef IPPROTO_MH
#define IPPROTO_MH 135
#endif