From patchwork Fri Dec 1 16:07:15 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Kleber Sacilotto de Souza X-Patchwork-Id: 843570 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=lists.ubuntu.com (client-ip=91.189.94.19; helo=huckleberry.canonical.com; envelope-from=kernel-team-bounces@lists.ubuntu.com; receiver=) Received: from huckleberry.canonical.com (huckleberry.canonical.com [91.189.94.19]) by ozlabs.org (Postfix) with ESMTP id 3ypK0w2xswz9ryv; Sat, 2 Dec 2017 03:07:28 +1100 (AEDT) Received: from localhost ([127.0.0.1] helo=huckleberry.canonical.com) by huckleberry.canonical.com with esmtp (Exim 4.86_2) (envelope-from ) id 1eKnqW-0003b9-W4; Fri, 01 Dec 2017 16:07:24 +0000 Received: from youngberry.canonical.com ([91.189.89.112]) by huckleberry.canonical.com with esmtps (TLS1.0:DHE_RSA_AES_128_CBC_SHA1:128) (Exim 4.86_2) (envelope-from ) id 1eKnqU-0003aE-Cm for kernel-team@lists.ubuntu.com; Fri, 01 Dec 2017 16:07:22 +0000 Received: from mail-wr0-f199.google.com ([209.85.128.199]) by youngberry.canonical.com with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.76) (envelope-from ) id 1eKnqU-0006AG-5S for kernel-team@lists.ubuntu.com; Fri, 01 Dec 2017 16:07:22 +0000 Received: by mail-wr0-f199.google.com with SMTP id w95so6085240wrc.20 for ; Fri, 01 Dec 2017 08:07:22 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:subject:date:message-id:in-reply-to :references; bh=wfC32EdKO9fPGglAO8NBneuOUXoX1W/Yjny4vMdscnM=; b=D0ryhYIuqtzySaTOHynvWtVWqX1EZ6D1pJWpOhkdaE8XGiyTUxFFbMAgfYuapoqMPc 8+ewLOERBtICTp8bPPITES5HYQ9i4O+pH9H/YhxDYBs7g8heSMWEEntTtznpGHqZy1b7 2WuO1ISMrnKp3rMKEC1K1wRpzFBApUg/xhPG3LH/Se6jbvs6Tgm5pLjmWX3yeUgS6zPv MNZnfpg6bxEwwow5YS10iChTeseu7zXwCohgK0xxxoY2n9aaWBIp+W/Sk/F+z8ONLszY V/g43XJZ1ehh4wuYZOkK8XTwvoTwcNOB0SpYdxjvHHBxRfh2W0/6mATaCASNGXZFZ9GU AMJg== X-Gm-Message-State: AJaThX5OVl0w7s1GFlEVnyis4HAB7PlJoEjYSuaDZzFRMiSlyWtzcuJf dMCTdiLU6ujya+8b+4ejAC0E7C89EVFxdx+DOve20LbrFnYdOwxZ0i6Qgu6pxHIjjgEgTbZsmeG itamVyuy9J2kV6gEkSBx7hi6XTBrFvOoBZEsNuRyCXQ== X-Received: by 10.80.180.18 with SMTP id b18mr18733257edh.136.1512144441529; Fri, 01 Dec 2017 08:07:21 -0800 (PST) X-Google-Smtp-Source: AGs4zMZItIcujPvQ2wCGo9EwL3Jp3/+WT6S6TWPFDu9ITacA1yvQRNnd7dWX02TENYOz239/yyhUJg== X-Received: by 10.80.180.18 with SMTP id b18mr18733236edh.136.1512144441286; Fri, 01 Dec 2017 08:07:21 -0800 (PST) Received: from localhost ([2a02:8109:98c0:1604:d93c:6a88:7e3b:ea29]) by smtp.gmail.com with ESMTPSA id m48sm4692375edd.7.2017.12.01.08.07.20 for (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Fri, 01 Dec 2017 08:07:20 -0800 (PST) From: Kleber Sacilotto de Souza To: kernel-team@lists.ubuntu.com Subject: [SRU][Xenial][PATCH 1/2] netlink: add a start callback for starting a netlink dump Date: Fri, 1 Dec 2017 17:07:15 +0100 Message-Id: <20171201160716.30552-2-kleber.souza@canonical.com> X-Mailer: git-send-email 2.14.1 In-Reply-To: <20171201160716.30552-1-kleber.souza@canonical.com> References: <20171201160716.30552-1-kleber.souza@canonical.com> X-BeenThere: kernel-team@lists.ubuntu.com X-Mailman-Version: 2.1.20 Precedence: list List-Id: Kernel team discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Errors-To: kernel-team-bounces@lists.ubuntu.com Sender: "kernel-team" From: Tom Herbert The start callback allows the caller to set up a context for the dump callbacks. Presumably, the context can then be destroyed in the done callback. Signed-off-by: Tom Herbert Signed-off-by: David S. Miller CVE-2017-16939 (cherry picked from commit fc9e50f5a5a4e1fa9ba2756f745a13e693cf6a06) Signed-off-by: Kleber Sacilotto de Souza --- include/linux/netlink.h | 2 ++ include/net/genetlink.h | 2 ++ net/netlink/af_netlink.c | 4 ++++ net/netlink/genetlink.c | 16 ++++++++++++++++ 4 files changed, 24 insertions(+) diff --git a/include/linux/netlink.h b/include/linux/netlink.h index 639e9b8b0e4d..0b41959aab9f 100644 --- a/include/linux/netlink.h +++ b/include/linux/netlink.h @@ -131,6 +131,7 @@ netlink_skb_clone(struct sk_buff *skb, gfp_t gfp_mask) struct netlink_callback { struct sk_buff *skb; const struct nlmsghdr *nlh; + int (*start)(struct netlink_callback *); int (*dump)(struct sk_buff * skb, struct netlink_callback *cb); int (*done)(struct netlink_callback *cb); @@ -153,6 +154,7 @@ struct nlmsghdr * __nlmsg_put(struct sk_buff *skb, u32 portid, u32 seq, int type, int len, int flags); struct netlink_dump_control { + int (*start)(struct netlink_callback *); int (*dump)(struct sk_buff *skb, struct netlink_callback *); int (*done)(struct netlink_callback *); void *data; diff --git a/include/net/genetlink.h b/include/net/genetlink.h index 1b6b6dcb018d..43c0e771f417 100644 --- a/include/net/genetlink.h +++ b/include/net/genetlink.h @@ -114,6 +114,7 @@ static inline void genl_info_net_set(struct genl_info *info, struct net *net) * @flags: flags * @policy: attribute validation policy * @doit: standard command callback + * @start: start callback for dumps * @dumpit: callback for dumpers * @done: completion callback for dumps * @ops_list: operations list @@ -122,6 +123,7 @@ struct genl_ops { const struct nla_policy *policy; int (*doit)(struct sk_buff *skb, struct genl_info *info); + int (*start)(struct netlink_callback *cb); int (*dumpit)(struct sk_buff *skb, struct netlink_callback *cb); int (*done)(struct netlink_callback *cb); diff --git a/net/netlink/af_netlink.c b/net/netlink/af_netlink.c index acfb16fdcd55..b7b3578240fc 100644 --- a/net/netlink/af_netlink.c +++ b/net/netlink/af_netlink.c @@ -2199,6 +2199,7 @@ int __netlink_dump_start(struct sock *ssk, struct sk_buff *skb, cb = &nlk->cb; memset(cb, 0, sizeof(*cb)); + cb->start = control->start; cb->dump = control->dump; cb->done = control->done; cb->nlh = nlh; @@ -2211,6 +2212,9 @@ int __netlink_dump_start(struct sock *ssk, struct sk_buff *skb, mutex_unlock(nlk->cb_mutex); + if (cb->start) + cb->start(cb); + ret = netlink_dump(sk); sock_put(sk); diff --git a/net/netlink/genetlink.c b/net/netlink/genetlink.c index 521c3b951ea9..a6497a014015 100644 --- a/net/netlink/genetlink.c +++ b/net/netlink/genetlink.c @@ -513,6 +513,20 @@ void *genlmsg_put(struct sk_buff *skb, u32 portid, u32 seq, } EXPORT_SYMBOL(genlmsg_put); +static int genl_lock_start(struct netlink_callback *cb) +{ + /* our ops are always const - netlink API doesn't propagate that */ + const struct genl_ops *ops = cb->data; + int rc = 0; + + if (ops->start) { + genl_lock(); + rc = ops->start(cb); + genl_unlock(); + } + return rc; +} + static int genl_lock_dumpit(struct sk_buff *skb, struct netlink_callback *cb) { /* our ops are always const - netlink API doesn't propagate that */ @@ -581,6 +595,7 @@ static int genl_family_rcv_msg(struct genl_family *family, .module = family->module, /* we have const, but the netlink API doesn't */ .data = (void *)ops, + .start = genl_lock_start, .dump = genl_lock_dumpit, .done = genl_lock_done, }; @@ -592,6 +607,7 @@ static int genl_family_rcv_msg(struct genl_family *family, } else { struct netlink_dump_control c = { .module = family->module, + .start = ops->start, .dump = ops->dumpit, .done = ops->done, }; From patchwork Fri Dec 1 16:07:16 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Kleber Sacilotto de Souza X-Patchwork-Id: 843571 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=lists.ubuntu.com (client-ip=91.189.94.19; helo=huckleberry.canonical.com; envelope-from=kernel-team-bounces@lists.ubuntu.com; receiver=) Received: from huckleberry.canonical.com (huckleberry.canonical.com [91.189.94.19]) by ozlabs.org (Postfix) with ESMTP id 3ypK0y5ZTFz9ryv; Sat, 2 Dec 2017 03:07:30 +1100 (AEDT) Received: from localhost ([127.0.0.1] helo=huckleberry.canonical.com) by huckleberry.canonical.com with esmtp (Exim 4.86_2) (envelope-from ) id 1eKnqZ-0003ce-7F; Fri, 01 Dec 2017 16:07:27 +0000 Received: from youngberry.canonical.com ([91.189.89.112]) by huckleberry.canonical.com with esmtps (TLS1.0:DHE_RSA_AES_128_CBC_SHA1:128) (Exim 4.86_2) (envelope-from ) id 1eKnqW-0003av-Ie for kernel-team@lists.ubuntu.com; Fri, 01 Dec 2017 16:07:24 +0000 Received: from mail-wm0-f72.google.com ([74.125.82.72]) by youngberry.canonical.com with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.76) (envelope-from ) id 1eKnqW-0006AR-BQ for kernel-team@lists.ubuntu.com; Fri, 01 Dec 2017 16:07:24 +0000 Received: by mail-wm0-f72.google.com with SMTP id i71so1162411wmd.9 for ; Fri, 01 Dec 2017 08:07:24 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:subject:date:message-id:in-reply-to :references; bh=2H7SNiVroNRkt67tu+IiOU6YqtPu/QW1BSLeRUTW8rc=; b=CwnPdgyoGXpdVndSrgfTNhVgUz6kwjxPu497Xw4QpXl0u7dXe9tsxMA07c6BxENDRR xnqXHwYVY+lSmy0oc1iJKQtYpOWm48sNQBDMCTiol/JPXOuhxiVOvPpsPwdiK3b3mfvF 0MLkn3Rh5ld67C9TQA0NB8pHn5NYy5wy4MYv3HwVEQMcD5JfcrfBtFQwIqNgrJBt2or9 +8HBvgcJ+1H5T+EwmBUf4Jdc4/4xs5+14OHsBwon8SPXXJeOScCqwzZKLHuRqvySKZ9w xO6X875XTIdnRSLVT91qFCWF5OLxmqqqpmR0UXgISpcnXuJCYIHBhpWR7aEoBvUxQ1wE kAqw== X-Gm-Message-State: AJaThX7r160D8bsQpHfRQqlR4nNBdtb/7yB7MSjRsawIV59JKAxHQm9B xj/f/pZCkDwvfvF2oy5TcsXS094F2cx4hN5emJC9NzSWA+D6Qg5/Hl121RbagTmjhPBA3WLfE4T u+CRs2xTX3xmaa+t94vybXn6yiQatt3FTQKLqgQY27w== X-Received: by 10.80.243.136 with SMTP id g8mr18781608edm.42.1512144443749; Fri, 01 Dec 2017 08:07:23 -0800 (PST) X-Google-Smtp-Source: AGs4zMaFOjDNOrxIgP+NHUem3EmjyxCC6x4q8xIkOZmgi1+VyJL0Ev+TeU31XD8dvNQsa8qkVJ9ubA== X-Received: by 10.80.243.136 with SMTP id g8mr18781580edm.42.1512144443523; Fri, 01 Dec 2017 08:07:23 -0800 (PST) Received: from localhost ([2a02:8109:98c0:1604:d93c:6a88:7e3b:ea29]) by smtp.gmail.com with ESMTPSA id d58sm5717232ede.62.2017.12.01.08.07.22 for (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Fri, 01 Dec 2017 08:07:22 -0800 (PST) From: Kleber Sacilotto de Souza To: kernel-team@lists.ubuntu.com Subject: [SRU][Zesty][Xenial][PATCH 2/2] ipsec: Fix aborted xfrm policy dump crash Date: Fri, 1 Dec 2017 17:07:16 +0100 Message-Id: <20171201160716.30552-3-kleber.souza@canonical.com> X-Mailer: git-send-email 2.14.1 In-Reply-To: <20171201160716.30552-1-kleber.souza@canonical.com> References: <20171201160716.30552-1-kleber.souza@canonical.com> X-BeenThere: kernel-team@lists.ubuntu.com X-Mailman-Version: 2.1.20 Precedence: list List-Id: Kernel team discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Errors-To: kernel-team-bounces@lists.ubuntu.com Sender: "kernel-team" From: Herbert Xu An independent security researcher, Mohamed Ghannam, has reported this vulnerability to Beyond Security's SecuriTeam Secure Disclosure program. The xfrm_dump_policy_done function expects xfrm_dump_policy to have been called at least once or it will crash. This can be triggered if a dump fails because the target socket's receive buffer is full. This patch fixes it by using the cb->start mechanism to ensure that the initialisation is always done regardless of the buffer situation. Fixes: 12a169e7d8f4 ("ipsec: Put dumpers on the dump list") Signed-off-by: Herbert Xu Signed-off-by: Steffen Klassert CVE-2017-16939 (cherry picked from commit 1137b5e2529a8f5ca8ee709288ecba3e68044df2) Signed-off-by: Kleber Sacilotto de Souza --- net/xfrm/xfrm_user.c | 25 +++++++++++++++---------- 1 file changed, 15 insertions(+), 10 deletions(-) diff --git a/net/xfrm/xfrm_user.c b/net/xfrm/xfrm_user.c index 7a5a64e70b4d..76944a4839a5 100644 --- a/net/xfrm/xfrm_user.c +++ b/net/xfrm/xfrm_user.c @@ -1652,32 +1652,34 @@ static int dump_one_policy(struct xfrm_policy *xp, int dir, int count, void *ptr static int xfrm_dump_policy_done(struct netlink_callback *cb) { - struct xfrm_policy_walk *walk = (struct xfrm_policy_walk *) &cb->args[1]; + struct xfrm_policy_walk *walk = (struct xfrm_policy_walk *)cb->args; struct net *net = sock_net(cb->skb->sk); xfrm_policy_walk_done(walk, net); return 0; } +static int xfrm_dump_policy_start(struct netlink_callback *cb) +{ + struct xfrm_policy_walk *walk = (struct xfrm_policy_walk *)cb->args; + + BUILD_BUG_ON(sizeof(*walk) > sizeof(cb->args)); + + xfrm_policy_walk_init(walk, XFRM_POLICY_TYPE_ANY); + return 0; +} + static int xfrm_dump_policy(struct sk_buff *skb, struct netlink_callback *cb) { struct net *net = sock_net(skb->sk); - struct xfrm_policy_walk *walk = (struct xfrm_policy_walk *) &cb->args[1]; + struct xfrm_policy_walk *walk = (struct xfrm_policy_walk *)cb->args; struct xfrm_dump_info info; - BUILD_BUG_ON(sizeof(struct xfrm_policy_walk) > - sizeof(cb->args) - sizeof(cb->args[0])); - info.in_skb = cb->skb; info.out_skb = skb; info.nlmsg_seq = cb->nlh->nlmsg_seq; info.nlmsg_flags = NLM_F_MULTI; - if (!cb->args[0]) { - cb->args[0] = 1; - xfrm_policy_walk_init(walk, XFRM_POLICY_TYPE_ANY); - } - (void) xfrm_policy_walk(net, walk, dump_one_policy, &info); return skb->len; @@ -2415,6 +2417,7 @@ static const struct nla_policy xfrma_spd_policy[XFRMA_SPD_MAX+1] = { static const struct xfrm_link { int (*doit)(struct sk_buff *, struct nlmsghdr *, struct nlattr **); + int (*start)(struct netlink_callback *); int (*dump)(struct sk_buff *, struct netlink_callback *); int (*done)(struct netlink_callback *); const struct nla_policy *nla_pol; @@ -2428,6 +2431,7 @@ static const struct xfrm_link { [XFRM_MSG_NEWPOLICY - XFRM_MSG_BASE] = { .doit = xfrm_add_policy }, [XFRM_MSG_DELPOLICY - XFRM_MSG_BASE] = { .doit = xfrm_get_policy }, [XFRM_MSG_GETPOLICY - XFRM_MSG_BASE] = { .doit = xfrm_get_policy, + .start = xfrm_dump_policy_start, .dump = xfrm_dump_policy, .done = xfrm_dump_policy_done }, [XFRM_MSG_ALLOCSPI - XFRM_MSG_BASE] = { .doit = xfrm_alloc_userspi }, @@ -2479,6 +2483,7 @@ static int xfrm_user_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh) { struct netlink_dump_control c = { + .start = link->start, .dump = link->dump, .done = link->done, };