Received: by 2002:ac0:a581:0:0:0:0:0 with SMTP id m1-v6csp3080799imm; Sun, 1 Jul 2018 11:49:44 -0700 (PDT) X-Google-Smtp-Source: ADUXVKKdAMFp7RExr72l7moB7WgfwoaGbV7Bn6fWaq6a29MzbehD6q/GHWcQfM48hknCDV4m4cBp X-Received: by 2002:a17:902:c6b:: with SMTP id 98-v6mr22891762pls.37.1530470984272; Sun, 01 Jul 2018 11:49:44 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1530470984; cv=none; d=google.com; s=arc-20160816; b=vPVvAhJMwWIYfvzBCSHZpMkUf2sYvKYcz+xEUSf69JMfu7Zb1iMrN00YHo3FNlDqKI iW2xvI9Wllxn+90gAQ/xDM0f0KS4UdK5m4shVMFK+QT+kHV6fCajmvG183z+NfUJq0cO NwWK3hyg+mVcgtfQKgHLBAp0ud2W+3+weB2OrYqZ4wRXWJ7MVamR5Vdzx+vffYqqR96Z KkR2NlKiNoVmhuSLk2FVAeZx0DNtlABA42Iwfm0xpzBRbwronzdVXm0OM4K268DhlD1l 82jOTKnyeHSWtDecmoOrc8xYQbACmNJOYlYQZPTKNUOC+xTODcaG3ePxrVChH+9Scu47 t3yQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:mime-version:user-agent:references :in-reply-to:message-id:date:subject:cc:to:from :arc-authentication-results; bh=e4Yva95xlP5wdYLa7EQiqZU2KoxK+3KHvJeg2HpesUw=; b=e7EnrRlpBDHsZSR2nCLItRnAicMXBJmsNyix6yzFR9ZF0i2DJ1ocGQVYmwkcLDobUg 6LzAw4nKLx9vmxI0prubu2HFfBKr9DUb2NGaMAulHshq00Y+UwDt6Vrb5SYYwjMQk4XH YbHYvazpmqErQvjGBDa+cNk4++CUEG27YBzEFs5tdcp2VrOCYdP0cd5YV3d0+Fu5P7+h v/1E0E2lZuJ/fnUEIYOSCHL23uFMpRIDgCzSRG+lgmIQ208X98DzkVyApp5mjb6skFmi ddd6YkHfTh4gyX9T+HiwFSK2A6kimW2FYP08mPTHUeKf9cvS9EJX9kGMtQsh/AyUyz8m Q1tg== 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 v4-v6si12780559pgv.624.2018.07.01.11.49.29; Sun, 01 Jul 2018 11:49:44 -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 S1752653AbeGAQLb (ORCPT + 99 others); Sun, 1 Jul 2018 12:11:31 -0400 Received: from mail.linuxfoundation.org ([140.211.169.12]:59690 "EHLO mail.linuxfoundation.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752436AbeGAQLV (ORCPT ); Sun, 1 Jul 2018 12:11:21 -0400 Received: from localhost (LFbn-1-12247-202.w90-92.abo.wanadoo.fr [90.92.61.202]) by mail.linuxfoundation.org (Postfix) with ESMTPSA id 973B2AD8; Sun, 1 Jul 2018 16:11:20 +0000 (UTC) From: Greg Kroah-Hartman To: linux-kernel@vger.kernel.org Cc: Greg Kroah-Hartman , stable@vger.kernel.org, Kevin Easton , syzbot+5022a34ca5a3d49b84223653fab632dfb7b4cf37@syzkaller.appspotmail.com, Steffen Klassert , Zubin Mithra Subject: [PATCH 3.18 03/85] af_key: Always verify length of provided sadb_key Date: Sun, 1 Jul 2018 18:01:21 +0200 Message-Id: <20180701153122.502054724@linuxfoundation.org> X-Mailer: git-send-email 2.18.0 In-Reply-To: <20180701153122.365061142@linuxfoundation.org> References: <20180701153122.365061142@linuxfoundation.org> User-Agent: quilt/0.65 X-stable: review MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org 3.18-stable review patch. If anyone has any objections, please let me know. ------------------ From: Kevin Easton commit 4b66af2d6356a00e94bcdea3e7fea324e8b5c6f4 upstream. 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 Signed-off-by: Steffen Klassert Cc: Zubin Mithra Signed-off-by: Greg Kroah-Hartman --- net/key/af_key.c | 45 +++++++++++++++++++++++++++++++++++---------- 1 file changed, 35 insertions(+), 10 deletions(-) --- a/net/key/af_key.c +++ b/net/key/af_key.c @@ -437,6 +437,24 @@ static int verify_address_len(const void 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 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; } @@ -1111,14 +1138,12 @@ static struct xfrm_state * pfkey_msg2xfr 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);