From patchwork Tue Jul 25 20:07:21 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Amit Pundir X-Patchwork-Id: 108695 Delivered-To: patch@linaro.org Received: by 10.182.45.195 with SMTP id p3csp14577obm; Tue, 25 Jul 2017 13:08:08 -0700 (PDT) X-Received: by 10.84.236.4 with SMTP id q4mr17599986plk.423.1501013288481; Tue, 25 Jul 2017 13:08:08 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1501013288; cv=none; d=google.com; s=arc-20160816; b=CHQAUFDQW4pYN/ffNwPK9uPRJMpfJlkWqyUyhZPu+u5KqEEW0tG6OeB2i24N2Q5/f6 zH03qxFVk+tg114Z08d4gg65zGeyi+44jqJYYYqXpHfNLzhMuoElVdq7a9q2uEw9rW6i WAuXDeBR1vHiIinn2MX1FZH+ZJRhQPesMit6ngHZcw8xvAagynKtD1vGJF36IwYND7fA NjK/0GDxuv+VG/QFBDrGYChaWGF7x3rHdb01uKOl+fhT02srwAOVWcp6PD0af7GAKCAe EMhRg0/O3x9X0C26D61A3r3Ym5392lrWxpwOAJ7MIkVighXyEB18ypXiC4DWO4JC5SUk hw6A== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:references:in-reply-to:message-id:date :subject:cc:to:from:dkim-signature:arc-authentication-results; bh=Xp4WifqjzjwUt0y7XmZv+/gI8WGVN4bsftaJ3WdKqGc=; b=VWnqnkVD2Se0XGatHe4SpDm0gt7LRawkHQfo3pA7UUp/uxwOCpVx5WPQ/3Lh4ayQEm vEi3Y7wTK/rnd3E57qUoD4diJHneZibRGo6PpglQwXX4kwLP4yiOmzAB6lIzgtsEvg/H Q5KA6McVCPP9EoaX6E7Dj18rC+b9iHV7eDlqq9Y1BMRLpcdLpYiApQvzVJdQpvx5P+H4 Y/Zy5RGFTSk5ihiti04H/G2WYUmO4eIoK3Jwj0kx5caDejSEJRP5HTGQNvZ2XHRPdN3p 3qInMF9645ovonyl/GXjn2xT63jtCEfJGhLS10zbMTaq0UGBnns6xKQtgH67VFeNHZ5b Fmmw== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.b=FFser2pB; spf=pass (google.com: best guess record for domain of stable-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=stable-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id h10si8970990plk.237.2017.07.25.13.08.08; Tue, 25 Jul 2017 13:08:08 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of stable-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=pass header.i=@linaro.org header.b=FFser2pB; spf=pass (google.com: best guess record for domain of stable-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=stable-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753450AbdGYUIG (ORCPT + 6 others); Tue, 25 Jul 2017 16:08:06 -0400 Received: from mail-pf0-f171.google.com ([209.85.192.171]:35668 "EHLO mail-pf0-f171.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752220AbdGYUIF (ORCPT ); Tue, 25 Jul 2017 16:08:05 -0400 Received: by mail-pf0-f171.google.com with SMTP id h29so27237128pfd.2 for ; Tue, 25 Jul 2017 13:08:05 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=Xp4WifqjzjwUt0y7XmZv+/gI8WGVN4bsftaJ3WdKqGc=; b=FFser2pBM3TgnrVooe/jzLY1Lbma/r+6AHJ7O4xRLWEcJwxMjrDLXpU8BfRRsKR+BD e4kP04MBmjn2/WggpX9QFkV3iA02zWAKHO8/3gItNeUtpUBium05GvnY9jZ7PKHQMHlb DD2QLVoGZT0UbOjIl5QqU1gjamPG4EgRR+WPY= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=Xp4WifqjzjwUt0y7XmZv+/gI8WGVN4bsftaJ3WdKqGc=; b=knBHeTD/fOsOOwk82mybF9CzqpjvTtOPhXnH27nE/LTGqaBA1ZsFT4KnvfkHGZey6T N997ApTiBpzRNgsLEA4xEZIiReKAfhnztCbfkPaUTvxN2zKK9cbsXLn++hiPRvJLXdT+ 7Wh0uOS7cdInbNqnS2rXinN1AVZb1xLy24M2Xf2lS80hJSuNSJn3q+CKxndWxiwtWkxS 3OiJ8lNY1EeQw4ZTICE0O9FVL9z8mjOkDgoTZXOLoMIDjgubXQDJfksHH45N3+3yfL5y jbTH7o/X1mUkhP6tGCrTex2/tUUwssxDUBIb1bzXneRegD++dNA04c8YTmriicgedjIc j68g== X-Gm-Message-State: AIVw113liE8buUvV4vmwPUHViyaK0+N4rfEryTTPWNQVyB6J47JR4FEK AzoD3K2SnY13p2tv X-Received: by 10.84.237.15 with SMTP id s15mr23681950plk.100.1501013284612; Tue, 25 Jul 2017 13:08:04 -0700 (PDT) Received: from localhost.localdomain ([106.51.135.235]) by smtp.gmail.com with ESMTPSA id c76sm27684356pfj.91.2017.07.25.13.08.02 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Tue, 25 Jul 2017 13:08:03 -0700 (PDT) From: Amit Pundir To: Greg KH Cc: Stable , Herbert Xu , Steffen Klassert Subject: [PATCH for-4.4 13/13] af_key: Fix sadb_x_ipsecrequest parsing Date: Wed, 26 Jul 2017 01:37:21 +0530 Message-Id: <1501013241-31961-14-git-send-email-amit.pundir@linaro.org> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1501013241-31961-1-git-send-email-amit.pundir@linaro.org> References: <1501013241-31961-1-git-send-email-amit.pundir@linaro.org> Sender: stable-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: stable@vger.kernel.org From: Herbert Xu commit 096f41d3a8fcbb8dde7f71379b1ca85fe213eded upstream. The parsing of sadb_x_ipsecrequest is broken in a number of ways. First of all we're not verifying sadb_x_ipsecrequest_len. This is needed when the structure carries addresses at the end. Worse we don't even look at the length when we parse those optional addresses. The migration code had similar parsing code that's better but it also has some deficiencies. The length is overcounted first of all as it includes the header itself. It also fails to check the length before dereferencing the sa_family field. This patch fixes those problems in parse_sockaddr_pair and then uses it in parse_ipsecrequest. Reported-by: Andrey Konovalov Signed-off-by: Herbert Xu Signed-off-by: Steffen Klassert Signed-off-by: Amit Pundir --- net/key/af_key.c | 47 ++++++++++++++++++++++++++--------------------- 1 file changed, 26 insertions(+), 21 deletions(-) -- 2.7.4 diff --git a/net/key/af_key.c b/net/key/af_key.c index e67c28e614b9..d8d95b6415e4 100644 --- a/net/key/af_key.c +++ b/net/key/af_key.c @@ -65,6 +65,10 @@ struct pfkey_sock { } dump; }; +static int parse_sockaddr_pair(struct sockaddr *sa, int ext_len, + xfrm_address_t *saddr, xfrm_address_t *daddr, + u16 *family); + static inline struct pfkey_sock *pfkey_sk(struct sock *sk) { return (struct pfkey_sock *)sk; @@ -1922,19 +1926,14 @@ parse_ipsecrequest(struct xfrm_policy *xp, struct sadb_x_ipsecrequest *rq) /* addresses present only in tunnel mode */ if (t->mode == XFRM_MODE_TUNNEL) { - u8 *sa = (u8 *) (rq + 1); - int family, socklen; + int err; - family = pfkey_sockaddr_extract((struct sockaddr *)sa, - &t->saddr); - if (!family) - return -EINVAL; - - socklen = pfkey_sockaddr_len(family); - if (pfkey_sockaddr_extract((struct sockaddr *)(sa + socklen), - &t->id.daddr) != family) - return -EINVAL; - t->encap_family = family; + err = parse_sockaddr_pair( + (struct sockaddr *)(rq + 1), + rq->sadb_x_ipsecrequest_len - sizeof(*rq), + &t->saddr, &t->id.daddr, &t->encap_family); + if (err) + return err; } else t->encap_family = xp->family; @@ -1954,7 +1953,11 @@ parse_ipsecrequests(struct xfrm_policy *xp, struct sadb_x_policy *pol) if (pol->sadb_x_policy_len * 8 < sizeof(struct sadb_x_policy)) return -EINVAL; - while (len >= sizeof(struct sadb_x_ipsecrequest)) { + while (len >= sizeof(*rq)) { + if (len < rq->sadb_x_ipsecrequest_len || + rq->sadb_x_ipsecrequest_len < sizeof(*rq)) + return -EINVAL; + if ((err = parse_ipsecrequest(xp, rq)) < 0) return err; len -= rq->sadb_x_ipsecrequest_len; @@ -2417,7 +2420,6 @@ out: return err; } -#ifdef CONFIG_NET_KEY_MIGRATE static int pfkey_sockaddr_pair_size(sa_family_t family) { return PFKEY_ALIGN8(pfkey_sockaddr_len(family) * 2); @@ -2429,7 +2431,7 @@ static int parse_sockaddr_pair(struct sockaddr *sa, int ext_len, { int af, socklen; - if (ext_len < pfkey_sockaddr_pair_size(sa->sa_family)) + if (ext_len < 2 || ext_len < pfkey_sockaddr_pair_size(sa->sa_family)) return -EINVAL; af = pfkey_sockaddr_extract(sa, saddr); @@ -2445,6 +2447,7 @@ static int parse_sockaddr_pair(struct sockaddr *sa, int ext_len, return 0; } +#ifdef CONFIG_NET_KEY_MIGRATE static int ipsecrequests_to_migrate(struct sadb_x_ipsecrequest *rq1, int len, struct xfrm_migrate *m) { @@ -2452,13 +2455,14 @@ static int ipsecrequests_to_migrate(struct sadb_x_ipsecrequest *rq1, int len, struct sadb_x_ipsecrequest *rq2; int mode; - if (len <= sizeof(struct sadb_x_ipsecrequest) || - len < rq1->sadb_x_ipsecrequest_len) + if (len < sizeof(*rq1) || + len < rq1->sadb_x_ipsecrequest_len || + rq1->sadb_x_ipsecrequest_len < sizeof(*rq1)) return -EINVAL; /* old endoints */ err = parse_sockaddr_pair((struct sockaddr *)(rq1 + 1), - rq1->sadb_x_ipsecrequest_len, + rq1->sadb_x_ipsecrequest_len - sizeof(*rq1), &m->old_saddr, &m->old_daddr, &m->old_family); if (err) @@ -2467,13 +2471,14 @@ static int ipsecrequests_to_migrate(struct sadb_x_ipsecrequest *rq1, int len, rq2 = (struct sadb_x_ipsecrequest *)((u8 *)rq1 + rq1->sadb_x_ipsecrequest_len); len -= rq1->sadb_x_ipsecrequest_len; - if (len <= sizeof(struct sadb_x_ipsecrequest) || - len < rq2->sadb_x_ipsecrequest_len) + if (len <= sizeof(*rq2) || + len < rq2->sadb_x_ipsecrequest_len || + rq2->sadb_x_ipsecrequest_len < sizeof(*rq2)) return -EINVAL; /* new endpoints */ err = parse_sockaddr_pair((struct sockaddr *)(rq2 + 1), - rq2->sadb_x_ipsecrequest_len, + rq2->sadb_x_ipsecrequest_len - sizeof(*rq2), &m->new_saddr, &m->new_daddr, &m->new_family); if (err)