From 561eb836a30ce70988814b80dc2e9dc5bad90e6d Mon Sep 17 00:00:00 2001 From: Alistair Delva Date: Thu, 5 Nov 2020 08:49:49 -0800 Subject: [PATCH] ANDROID: Temporarily disable XFRM_USER_COMPAT filtering Before 5.10-rc1, the upstream kernel blocked any compat calls into XFRM code with EOPNOTSUPP, however Android kernels had been patching this check out and made userspace match the 64-bit kernel netlink format instead. When the new XFRM_USER_COMPAT feature landed, it added a similar check in two places which returns EOPNOTSUPP only if the XFRM_USER_COMPAT feature is disabled, however that is currently always the case for Android kernels and we do not want to filter these callers. While we work to remove the userspace compatibility mess, disable the filtering of compat calls when XFRM_USER_COMPAT is disabled. If the XFRM_USER_COMPAT feature is enabled, nothing changes. Bug: 163141236 Bug: 172541864 Signed-off-by: Alistair Delva Change-Id: Ifbea109070650dfcb4f93a3cc692c18a8d11ab44 --- net/xfrm/xfrm_state.c | 21 ++++++++++++--------- net/xfrm/xfrm_user.c | 25 ++++++++++++++----------- 2 files changed, 26 insertions(+), 20 deletions(-) diff --git a/net/xfrm/xfrm_state.c b/net/xfrm/xfrm_state.c index bbd4643d7e82..01a51421b754 100644 --- a/net/xfrm/xfrm_state.c +++ b/net/xfrm/xfrm_state.c @@ -2377,17 +2377,20 @@ int xfrm_user_policy(struct sock *sk, int optname, sockptr_t optval, int optlen) if (IS_ERR(data)) return PTR_ERR(data); - if (in_compat_syscall()) { - struct xfrm_translator *xtr = xfrm_get_translator(); + /* Use the 64-bit / untranslated format on Android, even for compat */ + if (!IS_ENABLED(CONFIG_ANDROID) || IS_ENABLED(CONFIG_XFRM_USER_COMPAT)) { + if (in_compat_syscall()) { + struct xfrm_translator *xtr = xfrm_get_translator(); - if (!xtr) - return -EOPNOTSUPP; + if (!xtr) + return -EOPNOTSUPP; - err = xtr->xlate_user_policy_sockptr(&data, optlen); - xfrm_put_translator(xtr); - if (err) { - kfree(data); - return err; + err = xtr->xlate_user_policy_sockptr(&data, optlen); + xfrm_put_translator(xtr); + if (err) { + kfree(data); + return err; + } } } diff --git a/net/xfrm/xfrm_user.c b/net/xfrm/xfrm_user.c index d0c32a8fcc4a..49687429adf2 100644 --- a/net/xfrm/xfrm_user.c +++ b/net/xfrm/xfrm_user.c @@ -2705,19 +2705,22 @@ static int xfrm_user_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh, if (!netlink_net_capable(skb, CAP_NET_ADMIN)) return -EPERM; - if (in_compat_syscall()) { - struct xfrm_translator *xtr = xfrm_get_translator(); + /* Use the 64-bit / untranslated format on Android, even for compat */ + if (!IS_ENABLED(CONFIG_ANDROID) || IS_ENABLED(CONFIG_XFRM_USER_COMPAT)) { + if (in_compat_syscall()) { + struct xfrm_translator *xtr = xfrm_get_translator(); - if (!xtr) - return -EOPNOTSUPP; + if (!xtr) + return -EOPNOTSUPP; - nlh64 = xtr->rcv_msg_compat(nlh, link->nla_max, - link->nla_pol, extack); - xfrm_put_translator(xtr); - if (IS_ERR(nlh64)) - return PTR_ERR(nlh64); - if (nlh64) - nlh = nlh64; + nlh64 = xtr->rcv_msg_compat(nlh, link->nla_max, + link->nla_pol, extack); + xfrm_put_translator(xtr); + if (IS_ERR(nlh64)) + return PTR_ERR(nlh64); + if (nlh64) + nlh = nlh64; + } } if ((type == (XFRM_MSG_GETSA - XFRM_MSG_BASE) ||