From patchwork Mon May 14 00:01:30 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Eric Biggers X-Patchwork-Id: 912638 X-Patchwork-Delegate: davem@davemloft.net Return-Path: X-Original-To: patchwork-incoming-netdev@ozlabs.org Delivered-To: patchwork-incoming-netdev@ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=vger.kernel.org (client-ip=209.132.180.67; helo=vger.kernel.org; envelope-from=netdev-owner@vger.kernel.org; receiver=) Authentication-Results: ozlabs.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="F9eP5s6T"; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 40kgrD3J6yz9s1d for ; Mon, 14 May 2018 10:02:52 +1000 (AEST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751357AbeENACd (ORCPT ); Sun, 13 May 2018 20:02:33 -0400 Received: from mail-pf0-f193.google.com ([209.85.192.193]:36973 "EHLO mail-pf0-f193.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751093AbeENACb (ORCPT ); Sun, 13 May 2018 20:02:31 -0400 Received: by mail-pf0-f193.google.com with SMTP id e9-v6so5139217pfi.4; Sun, 13 May 2018 17:02:31 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=kGKR5pOU9Qt9jGZ25Owm1HRtZ+cKf8u5WtQ/ZORtsPE=; b=F9eP5s6TJ58kKHXiz93U7T0uj4DmnrPg8jJlEtbODXuQXwmo0xPjEahdBbldqiwZZS HWzMJrQDc11h7lx9KifSneJYEv4osjfh/PW3MzUmSrp++vyGYyoxhFtPGqEeXBY8Njpy Ge75Cl9In/tkE0MA94trE5PYlHJzuvIlz9QH2Du/kZ0p2fHNZ4zAjvFycWwc/i9QPZgb tXiMwkCSCD73l626hLZ7pf8K3MUUFJ0ESjNaSIUzdpFPujtm3619bVUT8HZQDdLMOuyW ubwUvKumjkDBlo1eaEjRvpIB0ZClZeZlo2ezVq1EY2SLz3vKKLdkTZbmlhC563d285q8 GjrA== 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=kGKR5pOU9Qt9jGZ25Owm1HRtZ+cKf8u5WtQ/ZORtsPE=; b=dYWntwa0ISwz4Bu2shwkxdS/Q2y4kN4QUxahtvUGzdmjqoSUVbcmUb/cOGV2hR5SzE Cq+R+YuNUPo7V1pjBMZJf5OhYNmarkD2Xo8F8/FTZUw9bQ8GvH44vx7HJ8Hy+o0ct5Qd aSva3vi1kCdlZrLV9q9V1KGYjPhZqIJdUYjuHcuBdjaVPVghGqs4p/IGYkdBqXmv8uNC 2McVt5kq3b0NL0sy11KUs8ZkIohpb/dYlXn6TgiHTTKMg+FTIZMM41Iyc+o4dSrkjktJ OVQIYjLHn7BvBuq/r4LEgMfmS9NEPYkOZFfNGCbfOltgTGYGJU3rsj8CoG4lyqRqo+YF Hv4A== X-Gm-Message-State: ALKqPwdbLoTBXez68JNA7VdhkAFtwj/zsoi47wPNjGQcG6X0tUNp3nr0 4Chx4ja6gJFl/TguRoruKyw9XMEFvr8= X-Google-Smtp-Source: AB8JxZp2CAZ0HUFlleUgiFVcvJOGXzlPqrD21iI5h2DLKZ+8WBQEKRLxEI2AW9BpB63FRUf0RUPaNg== X-Received: by 2002:a63:6ac6:: with SMTP id f189-v6mr6604447pgc.308.1526256151008; Sun, 13 May 2018 17:02:31 -0700 (PDT) Received: from sol.localdomain (c-67-185-97-198.hsd1.wa.comcast.net. [67.185.97.198]) by smtp.gmail.com with ESMTPSA id d23-v6sm13891046pfn.3.2018.05.13.17.02.29 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Sun, 13 May 2018 17:02:30 -0700 (PDT) From: Eric Biggers To: Ursula Braun , Thomas Richter , linux-s390@vger.kernel.org Cc: netdev@vger.kernel.org, syzkaller-bugs@googlegroups.com, linux-kernel@vger.kernel.org, Eric Biggers Subject: [PATCH] net/smc: check for missing nlattrs in SMC_PNETID messages Date: Sun, 13 May 2018 17:01:30 -0700 Message-Id: <20180514000130.13780-1-ebiggers3@gmail.com> X-Mailer: git-send-email 2.17.0 In-Reply-To: <001a113f9bb83e4d560568457853@google.com> References: <001a113f9bb83e4d560568457853@google.com> Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org From: Eric Biggers It's possible to crash the kernel in several different ways by sending messages to the SMC_PNETID generic netlink family that are missing the expected attributes: - Missing SMC_PNETID_NAME => null pointer dereference when comparing names. - Missing SMC_PNETID_ETHNAME => null pointer dereference accessing smc_pnetentry::ndev. - Missing SMC_PNETID_IBNAME => null pointer dereference accessing smc_pnetentry::smcibdev. - Missing SMC_PNETID_IBPORT => out of bounds array access to smc_ib_device::pattr[-1]. Fix it by validating that all expected attributes are present and that SMC_PNETID_IBPORT is nonzero. Reported-by: syzbot+5cd61039dc9b8bfa6e47@syzkaller.appspotmail.com Fixes: 6812baabf24d ("smc: establish pnet table management") Cc: # v4.11+ Signed-off-by: Eric Biggers --- net/smc/smc_pnet.c | 71 ++++++++++++++++++++++++++-------------------- 1 file changed, 40 insertions(+), 31 deletions(-) diff --git a/net/smc/smc_pnet.c b/net/smc/smc_pnet.c index 74568cdbca708..d7b88b2d1b224 100644 --- a/net/smc/smc_pnet.c +++ b/net/smc/smc_pnet.c @@ -245,40 +245,45 @@ static struct smc_ib_device *smc_pnet_find_ib(char *ib_name) static int smc_pnet_fill_entry(struct net *net, struct smc_pnetentry *pnetelem, struct nlattr *tb[]) { - char *string, *ibname = NULL; - int rc = 0; + char *string, *ibname; + int rc; memset(pnetelem, 0, sizeof(*pnetelem)); INIT_LIST_HEAD(&pnetelem->list); - if (tb[SMC_PNETID_NAME]) { - string = (char *)nla_data(tb[SMC_PNETID_NAME]); - if (!smc_pnetid_valid(string, pnetelem->pnet_name)) { - rc = -EINVAL; - goto error; - } - } - if (tb[SMC_PNETID_ETHNAME]) { - string = (char *)nla_data(tb[SMC_PNETID_ETHNAME]); - pnetelem->ndev = dev_get_by_name(net, string); - if (!pnetelem->ndev) - return -ENOENT; - } - if (tb[SMC_PNETID_IBNAME]) { - ibname = (char *)nla_data(tb[SMC_PNETID_IBNAME]); - ibname = strim(ibname); - pnetelem->smcibdev = smc_pnet_find_ib(ibname); - if (!pnetelem->smcibdev) { - rc = -ENOENT; - goto error; - } - } - if (tb[SMC_PNETID_IBPORT]) { - pnetelem->ib_port = nla_get_u8(tb[SMC_PNETID_IBPORT]); - if (pnetelem->ib_port > SMC_MAX_PORTS) { - rc = -EINVAL; - goto error; - } - } + + rc = -EINVAL; + if (!tb[SMC_PNETID_NAME]) + goto error; + string = (char *)nla_data(tb[SMC_PNETID_NAME]); + if (!smc_pnetid_valid(string, pnetelem->pnet_name)) + goto error; + + rc = -EINVAL; + if (!tb[SMC_PNETID_ETHNAME]) + goto error; + rc = -ENOENT; + string = (char *)nla_data(tb[SMC_PNETID_ETHNAME]); + pnetelem->ndev = dev_get_by_name(net, string); + if (!pnetelem->ndev) + goto error; + + rc = -EINVAL; + if (!tb[SMC_PNETID_IBNAME]) + goto error; + rc = -ENOENT; + ibname = (char *)nla_data(tb[SMC_PNETID_IBNAME]); + ibname = strim(ibname); + pnetelem->smcibdev = smc_pnet_find_ib(ibname); + if (!pnetelem->smcibdev) + goto error; + + rc = -EINVAL; + if (!tb[SMC_PNETID_IBPORT]) + goto error; + pnetelem->ib_port = nla_get_u8(tb[SMC_PNETID_IBPORT]); + if (pnetelem->ib_port < 1 || pnetelem->ib_port > SMC_MAX_PORTS) + goto error; + return 0; error: @@ -307,6 +312,8 @@ static int smc_pnet_get(struct sk_buff *skb, struct genl_info *info) void *hdr; int rc; + if (!info->attrs[SMC_PNETID_NAME]) + return -EINVAL; pnetelem = smc_pnet_find_pnetid( (char *)nla_data(info->attrs[SMC_PNETID_NAME])); if (!pnetelem) @@ -359,6 +366,8 @@ static int smc_pnet_add(struct sk_buff *skb, struct genl_info *info) static int smc_pnet_del(struct sk_buff *skb, struct genl_info *info) { + if (!info->attrs[SMC_PNETID_NAME]) + return -EINVAL; return smc_pnet_remove_by_pnetid( (char *)nla_data(info->attrs[SMC_PNETID_NAME])); }