From patchwork Tue Jul 25 19:29:16 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Amit Pundir X-Patchwork-Id: 108674 Delivered-To: patch@linaro.org Received: by 10.140.101.44 with SMTP id t41csp939577qge; Tue, 25 Jul 2017 12:29:55 -0700 (PDT) X-Received: by 10.84.232.135 with SMTP id i7mr22356933plk.193.1501010995724; Tue, 25 Jul 2017 12:29:55 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1501010995; cv=none; d=google.com; s=arc-20160816; b=BM2q0ATRdffsx7FshRes7ZIRrYpRFy023RmMwUmryvRdmFasYwb1BnKsSRjp9ri1rj 8g3Ot/8w9owa/RZbf/2fP0sDp8mB/c7OONFLI0ch5KwhrAUATgH0YtkIg7Wck/loBTyU 1Da/wDqEhBL2ELfD8CKqYBw/3R5iH+FKylMdGqGxrqIRT82/UzJfrXXr1G1cO1MxIrHi pyM+vQ0jFxEOkYPKqNbInsxzwPj1DNvHHEKX15ZW48poDY6NMtMFhRW2AXSL6wErRWz8 vkP/5wxdjuDuYJNiV6Np0hD0pvi+lpYk4UsWvQVkwFInjjxditOvRmCdFN7oE0vOA+UX A+BA== 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=NZU+wft7CbEO9JpYDeYAk3wtG0OrN9MuE4DoaJIf3Qs=; b=fOQqPyGt7z+mAs1d2VOwYIPLWWdl1irCeI2aJtKKUX2BK6hVDz4lw5j3Wpt4uxyXx4 gokII9Ab/Q105nCZ2XhVNjRAo4kRLIQxLAZ9hkCdLN/0togISyCn//wVD9l0yfJkSMRx SQx/WSlyhpVu5UVqA+McATI+6rIjPHVgIM2O7X+3gfD5ufqhqV6Tx0UePxSIr6m9F3Xj jzKpOYseYklHVU81YINRotvvjov3kNdGxf1W6nSHit53Kadt/68b1a27p29mp0/t1i2n Z7K5QX8een2U3/xYeQN8ndKiMnuB87JAMk+mYjBUBRYMr+Bza8Us6Yg0plsNxXTYlbYI +Rcw== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.b=gcgFaZGS; 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 o128si5866746pga.856.2017.07.25.12.29.55; Tue, 25 Jul 2017 12:29:55 -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=gcgFaZGS; 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 S1753034AbdGYT3w (ORCPT + 6 others); Tue, 25 Jul 2017 15:29:52 -0400 Received: from mail-pf0-f181.google.com ([209.85.192.181]:36769 "EHLO mail-pf0-f181.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1754251AbdGYT3u (ORCPT ); Tue, 25 Jul 2017 15:29:50 -0400 Received: by mail-pf0-f181.google.com with SMTP id z129so22420988pfb.3 for ; Tue, 25 Jul 2017 12:29:49 -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=NZU+wft7CbEO9JpYDeYAk3wtG0OrN9MuE4DoaJIf3Qs=; b=gcgFaZGSOkfHCBY42I/9jLXNt0WJu6rVazZuMCXEKfybTx4n7yrcFtvOBEDo1OPVXU eKNBSSDb310FNGCJFjBBKdKVneOMEOXZoDCfqseoPdbgPjU5G1MZ/Q1Mp2HMdJbXHxnI ZCtXKZS1X1Ql42JXBBVhKP+VyolmPC5TbcLh0= 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=NZU+wft7CbEO9JpYDeYAk3wtG0OrN9MuE4DoaJIf3Qs=; b=C91lGW93QqKjB7ZXeBe/3aLpG/NQ9YQUEclN8PrLfheSs+Ao4uzSyF92sAK+nC7odu l5g/SsFuc1dRMFdSigjrBuX98M30fEeN6b1qciNk4tLOwR2DLFeZ4IvQLtm30U8E3s5b TTrlGkotWGswzzYA6y6CA9ug/Bj+3KfjpMavp8hp4CSn7rR4kbgHSm3W7VmmIsCO9rmj kpjZehvd+VJ2wlcepcf6Qu50FgOb06wLWkEjh/N+LMwajXJIv07rgtkNNKQJ8HrnfewD QVXMOxkjqB7SvjGuOhfpSFVlwinxA9br+WH70G/qsMWmKjZldhzDFVNt2DiL8J5E3mrB F2SQ== X-Gm-Message-State: AIVw111binEekm11VOytpZ6gQ92q7R/lxwDkY2PaboW/0oc9q0voOJic iAi8g1sLzcO+c+1psmj0tA== X-Received: by 10.99.55.79 with SMTP id g15mr20511601pgn.28.1501010989468; Tue, 25 Jul 2017 12:29:49 -0700 (PDT) Received: from localhost.localdomain ([106.51.135.235]) by smtp.gmail.com with ESMTPSA id 85sm30371425pfr.90.2017.07.25.12.29.46 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Tue, 25 Jul 2017 12:29:48 -0700 (PDT) From: Amit Pundir To: Greg KH Cc: Stable , Herbert Xu , Steffen Klassert Subject: [PATCH for-4.9 10/10] af_key: Fix sadb_x_ipsecrequest parsing Date: Wed, 26 Jul 2017 00:59:16 +0530 Message-Id: <1501010956-27944-11-git-send-email-amit.pundir@linaro.org> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1501010956-27944-1-git-send-email-amit.pundir@linaro.org> References: <1501010956-27944-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 @@ static int key_pol_get_resp(struct sock *sk, struct xfrm_policy *xp, const struc 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)