Received: by 10.213.65.68 with SMTP id h4csp750020imn; Sat, 7 Apr 2018 08:45:37 -0700 (PDT) X-Google-Smtp-Source: AIpwx48dixsXa+ZvA3wHEhlzsGt9rnZcbZE4QFaoVyLcmIFOJdHIOY3Gl4F1hcw/IJrRUtMsAQU9 X-Received: by 2002:a17:902:be12:: with SMTP id r18-v6mr29461882pls.173.1523115937473; Sat, 07 Apr 2018 08:45:37 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1523115937; cv=none; d=google.com; s=arc-20160816; b=NrLBRzz7hExrPD5ziXEuybYX5xqLxAtOIjkc6YIP289pb0/mpndzBEnM0Q/gliWExu dHuarcGVy1rweUMzXBn+nMSJF/tPbo3EAlDYd0Ywh1qwC6CRv5NsKPnEBsEjT6rm0AiR JLjrzKF4l1QJlwifVdOM5AgHUK8Q97lzG9W3hvdGeJpL/8bnhxLBFuv6zVr7Cab6N+xK +Wj4eDPJ8fonDMJTYgxtKNb12Qk51UP5jV7OmjTWr4GKg4vS5aayczfm0XJf8Abxfa2S 0yNePbjmSVT0gR/12bdx80wpwiTzrFmfkXPQxhO1kWgdDCj8a+wiUBerWhBHr0O2/IV2 3o8w== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:user-agent:in-reply-to :content-disposition:mime-version:references:message-id:subject:to :from:date:arc-authentication-results; bh=3Q7FOn5BIzzK7kcHb2CC3gYWfVhUGP2dN8Z4io85q6Y=; b=WNGN100qnFugwRBJSlFtKy4h1esVdk+OfxdfFtH7Z/IkiwzmBYGVyt9fQnScr0TLAw /dJvA9T1bRxYcpbdT9YoiF+89+qCj+jOESkj6JdpYpn5z86EdFJ6WXCrx6OWTuaP01LA hbNjz3kTqatoSJxCNsifF5wFAF47/Gh9I0Ck9OdOz0tgbrkdFuE4DmbSVRpweCXF/+Et QxB3YbU/PkMdVzJoKUgNmrhrp6mas3dH63h10uQP2A6JsqoqzzublqqFszJqs9G2/5b7 N8o8ocKcaxsz4dqY0WZFQDIz1OBAw19pkbCqB77KyWcwUghFBQYeDRVjpJ3j3XFiYb98 WHnQ== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id be3-v6si4231094plb.75.2018.04.07.08.44.27; Sat, 07 Apr 2018 08:45:37 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752077AbeDGPkf (ORCPT + 99 others); Sat, 7 Apr 2018 11:40:35 -0400 Received: from la.guarana.org ([173.254.219.205]:58588 "EHLO la.guarana.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751965AbeDGPkd (ORCPT ); Sat, 7 Apr 2018 11:40:33 -0400 Received: by la.guarana.org (Postfix, from userid 1006) id 956943461157; Sat, 7 Apr 2018 11:40:33 -0400 (EDT) Date: Sat, 7 Apr 2018 11:40:33 -0400 From: Kevin Easton To: Steffen Klassert , Herbert Xu , "David S. Miller" , netdev@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH v2 1/2] af_key: Always verify length of provided sadb_key Message-ID: References: MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: User-Agent: Mutt/1.5.21 (2010-09-15) Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Key extensions (struct sadb_key) include a user-specified number of key bits. The kernel uses that number to determine how much key data to copy out of the message in pfkey_msg2xfrm_state(). The length of the sadb_key message must be verified to be long enough, even in the case of SADB_X_AALG_NULL. Furthermore, the sadb_key_len value must be long enough to include both the key data and the struct sadb_key itself. Introduce a helper function verify_key_len(), and call it from parse_exthdrs() where other exthdr types are similarly checked for correctness. Signed-off-by: Kevin Easton Reported-by: syzbot+5022a34ca5a3d49b84223653fab632dfb7b4cf37@syzkaller.appspotmail.com --- net/key/af_key.c | 45 +++++++++++++++++++++++++++++++++++---------- 1 file changed, 35 insertions(+), 10 deletions(-) diff --git a/net/key/af_key.c b/net/key/af_key.c index 7e2e718..e62e52e 100644 --- a/net/key/af_key.c +++ b/net/key/af_key.c @@ -437,6 +437,24 @@ static int verify_address_len(const void *p) return 0; } +static inline int sadb_key_len(const struct sadb_key *key) +{ + int key_bytes = DIV_ROUND_UP(key->sadb_key_bits, 8); + + return DIV_ROUND_UP(sizeof(struct sadb_key) + key_bytes, + sizeof(uint64_t)); +} + +static int verify_key_len(const void *p) +{ + const struct sadb_key *key = p; + + if (sadb_key_len(key) > key->sadb_key_len) + return -EINVAL; + + return 0; +} + static inline int pfkey_sec_ctx_len(const struct sadb_x_sec_ctx *sec_ctx) { return DIV_ROUND_UP(sizeof(struct sadb_x_sec_ctx) + @@ -533,16 +551,25 @@ static int parse_exthdrs(struct sk_buff *skb, const struct sadb_msg *hdr, void * return -EINVAL; if (ext_hdrs[ext_type-1] != NULL) return -EINVAL; - if (ext_type == SADB_EXT_ADDRESS_SRC || - ext_type == SADB_EXT_ADDRESS_DST || - ext_type == SADB_EXT_ADDRESS_PROXY || - ext_type == SADB_X_EXT_NAT_T_OA) { + switch (ext_type) { + case SADB_EXT_ADDRESS_SRC: + case SADB_EXT_ADDRESS_DST: + case SADB_EXT_ADDRESS_PROXY: + case SADB_X_EXT_NAT_T_OA: if (verify_address_len(p)) return -EINVAL; - } - if (ext_type == SADB_X_EXT_SEC_CTX) { + break; + case SADB_X_EXT_SEC_CTX: if (verify_sec_ctx_len(p)) return -EINVAL; + break; + case SADB_EXT_KEY_AUTH: + case SADB_EXT_KEY_ENCRYPT: + if (verify_key_len(p)) + return -EINVAL; + break; + default: + break; } ext_hdrs[ext_type-1] = (void *) p; } @@ -1104,14 +1131,12 @@ static struct xfrm_state * pfkey_msg2xfrm_state(struct net *net, key = ext_hdrs[SADB_EXT_KEY_AUTH - 1]; if (key != NULL && sa->sadb_sa_auth != SADB_X_AALG_NULL && - ((key->sadb_key_bits+7) / 8 == 0 || - (key->sadb_key_bits+7) / 8 > key->sadb_key_len * sizeof(uint64_t))) + key->sadb_key_bits == 0) return ERR_PTR(-EINVAL); key = ext_hdrs[SADB_EXT_KEY_ENCRYPT-1]; if (key != NULL && sa->sadb_sa_encrypt != SADB_EALG_NULL && - ((key->sadb_key_bits+7) / 8 == 0 || - (key->sadb_key_bits+7) / 8 > key->sadb_key_len * sizeof(uint64_t))) + key->sadb_key_bits == 0) return ERR_PTR(-EINVAL); x = xfrm_state_alloc(net); -- 2.8.1