From patchwork Tue Jul 25 20:45:26 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Amit Pundir X-Patchwork-Id: 108710 Delivered-To: patch@linaro.org Received: by 10.140.101.44 with SMTP id t41csp29364qge; Tue, 25 Jul 2017 13:46:32 -0700 (PDT) X-Received: by 10.84.206.37 with SMTP id f34mr22965018ple.262.1501015592680; Tue, 25 Jul 2017 13:46:32 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1501015592; cv=none; d=google.com; s=arc-20160816; b=EIv5j8B/hy1rnftdLbS3ae6P4HV1lG2r4vU5fGqVdxqN4TNzGtTy7qmjoIZ+Zk3keE VR5MWG7CiPoR4H6eY09EFmDHl34GCFKEsf7hu88th2id7zsMuprlpDbk2ZboiBAl+KB+ N0a776XvELKTMtspCkWXsYJ07HB3MOzy2bqVznsdb/xwKNDdJYsxm1wjoL9cn2oUWIWY O3P/0svRCwtpmt4VOnTGWQBK57aYUpkNVmmEJfg5+bfVCUrELdQ2j/H5sRtY5qxNYOr4 XDTK5KnzXkMxxaaY0KFoFWZtkouYnhnSXnB7eaj4PsqlAXOf1F5WVVhe0h1k2zkSfawp oVmw== 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=q59IIL4YUrHEAiENd2Wnr3b7p74SUmV2hUWsSt53eNc=; b=0Ca5OY9qJANtZbLmhiAKRwsFzgLf/xxECb+W1TI7DVgDQXPg7Vm/IGH5FMENVEmrmE Qp9jpd4AbDsWNtVcVgljh4jt5AENBxo1aI8NJjCfYNo6jY8nUweipl+4RsmPAV1JhRSJ +oHnR2QCeLboi5Z8PzP4xgvjPkDZ66AtKnJdRpLTA1cu06p/UiuJV9BbpVUPzvSRkn25 e27T2ggL0hWDFS75Hjev7DUG2ol1sKUDS/nmEmMX1dUdHoYXJ5GXeprbkTnPlTQnZVIM DuEgJZho69vSCC5WnotNHXNgzSHhqrkT7vunqIrRoVxwkuIxzae+g5OYNpFgQxow0tN/ AZ7g== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.b=RIGXOQFK; 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 m1si8985184plb.340.2017.07.25.13.46.32; Tue, 25 Jul 2017 13:46:32 -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=RIGXOQFK; 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 S1752745AbdGYUqS (ORCPT + 6 others); Tue, 25 Jul 2017 16:46:18 -0400 Received: from mail-pg0-f45.google.com ([74.125.83.45]:37400 "EHLO mail-pg0-f45.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752433AbdGYUqQ (ORCPT ); Tue, 25 Jul 2017 16:46:16 -0400 Received: by mail-pg0-f45.google.com with SMTP id y129so74745737pgy.4 for ; Tue, 25 Jul 2017 13:46:16 -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=q59IIL4YUrHEAiENd2Wnr3b7p74SUmV2hUWsSt53eNc=; b=RIGXOQFKuu1LpbRjGtuWBE/Dt5Qt21V2ySqmXQ+1K1SDmiN24klp6jNt7f0OvEQ/Ta aTVZOFVlLPZkt0kAaEDREHYYqE7AKoCvLQ7o4lGq6lz8EcTJmTMRxwdHjBQBp47hGicC cRuV22ApQ21k1V1rn9QmKus4I7VmpbckpNWIc= 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=q59IIL4YUrHEAiENd2Wnr3b7p74SUmV2hUWsSt53eNc=; b=dUOqg0YaCIzsn6SJAXIX/42+Glgj5BJUUkMNW7AZsBW+Nk7JnJyHWEtjT0lFQGdwvI rdDh6eSO0LTTabvk17b/n2zLVHqY1kP7b7ndMHChi3KmJghTopy8SaobY1A4Joh+xq4p t5KaeC/c+rTluv1U1XOrDvi8Wvgw0SAxiN9trk8vljz23MWdheJf2oIhZmM+SKH9PdPc AUUxyBiGZnJ6DJPk2EicwUpaio8Fx9iwVfezMp5w8qavc7lCTH9z3pFwgdvqmQCrxhWm CafUCAm+bJ6wN4MLylg9U7syJoRTb+9B0Wn+Bz382kr0IfMIJB0vQdWJhTP/e6c7GXVB wChQ== X-Gm-Message-State: AIVw110R63aj9SL9Sqw/u32XxbdQW5/BndRgCcwOCOvmcF1/dZZnjg74 Q6uWnejdEoB9iKzh X-Received: by 10.84.128.102 with SMTP id 93mr22467753pla.21.1501015575913; Tue, 25 Jul 2017 13:46:15 -0700 (PDT) Received: from localhost.localdomain ([106.51.135.235]) by smtp.gmail.com with ESMTPSA id d4sm532125pfj.59.2017.07.25.13.46.13 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Tue, 25 Jul 2017 13:46:14 -0700 (PDT) From: Amit Pundir To: Greg KH Cc: Stable , Herbert Xu , Steffen Klassert Subject: [PATCH for-3.18 15/15] af_key: Fix sadb_x_ipsecrequest parsing Date: Wed, 26 Jul 2017 02:15:26 +0530 Message-Id: <1501015526-32178-16-git-send-email-amit.pundir@linaro.org> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1501015526-32178-1-git-send-email-amit.pundir@linaro.org> References: <1501015526-32178-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 d49fa0dd2634..08e2c6159e03 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; @@ -1921,19 +1925,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; @@ -1953,7 +1952,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; @@ -2416,7 +2419,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); @@ -2428,7 +2430,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); @@ -2444,6 +2446,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) { @@ -2451,13 +2454,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) @@ -2466,13 +2470,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)