From patchwork Sun May 22 04:22:03 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Baozeng Ding X-Patchwork-Id: 624898 X-Patchwork-Delegate: davem@davemloft.net Return-Path: X-Original-To: patchwork-incoming@ozlabs.org Delivered-To: patchwork-incoming@ozlabs.org Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 3rC7n35Tdtz9t3v for ; Sun, 22 May 2016 14:22:31 +1000 (AEST) Authentication-Results: ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b=MUxE26gl; dkim-atps=neutral Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751545AbcEVEWV (ORCPT ); Sun, 22 May 2016 00:22:21 -0400 Received: from mail-pa0-f65.google.com ([209.85.220.65]:36815 "EHLO mail-pa0-f65.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751383AbcEVEWN (ORCPT ); Sun, 22 May 2016 00:22:13 -0400 Received: by mail-pa0-f65.google.com with SMTP id xm6so14606037pab.3 for ; Sat, 21 May 2016 21:22:13 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=to:cc:from:subject:message-id:date:user-agent:mime-version :content-transfer-encoding; bh=C1Epu1s2+uqTlCArdVU491ikToShWgakTE8tQtlc1aM=; b=MUxE26gljqmx/8lkODTKe9dWfCkXfFEcG61mPmUc3rvFfD7qKsdDjNHAYSNt4CD9D6 KGdF79R6osBnv3UIUfJlTmEsoakUPsuY1zBvXp10MWutP7NAG0FO+Yfv36Q+/o9nv3Xr mkkz6blKlxPkXKJSaKGdoM2fiIkzyFiF8l/ueQ6hmQnlr0mmBDZUXxQ7veIDsp1zLy44 QgGo6EQLXjv8v7C7rFOlgEV93U4uiDo/sHW2B1Z22V57Vu5VsTQvH/Tf9HBtcRhRDdpA TcaSYtJiKy8SljCwyDrnW57jnX+XdtmrSHy2w3VY3QBbNF+AG/WaF1o/S4u7pq2vfBkG DX1g== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:to:cc:from:subject:message-id:date:user-agent :mime-version:content-transfer-encoding; bh=C1Epu1s2+uqTlCArdVU491ikToShWgakTE8tQtlc1aM=; b=j3FyZwrPshY6SRIksba6A1WpGRMsr4xY28S7AOC/o01hHcTCXIrCzsV8ccJS+w0T9d zwUfXWWMVF99rHdhZ4x/a2cVvzdRhDENV12Iyk/56q+4welZkFNIr/P6PBB/SMCEOin6 3Zbyoyrh3rUzvTNmLkACeQvB9wMFfBqeP/zGss2iBPfeOt/rAdUQ/nSDAlZs1c8zBm6s nMhShiKEq1Z+nw51erpzqNPdujX+/hFzed9s9CWlHKXwbCnN2ArJzpNdSfEUVfwUZe6j Vurjux435AavDN8ow/225v2r4RdXz7yeOLwySayOypol9uFWATNghkywAKn/JaV5pW6L dqeQ== X-Gm-Message-State: AOPr4FUhRynPmHUfI2jWyxpsa9DSne6BRuLjMMkDlssrM+y6Sb7MUK1InsKmsJ4rPARmTw== X-Received: by 10.66.66.42 with SMTP id c10mr16974236pat.119.1463890932336; Sat, 21 May 2016 21:22:12 -0700 (PDT) Received: from [10.8.0.2] ([104.156.239.137]) by smtp.gmail.com with ESMTPSA id o7sm37179510pfb.76.2016.05.21.21.22.08 (version=TLSv1/SSLv3 cipher=OTHER); Sat, 21 May 2016 21:22:11 -0700 (PDT) To: jon.maloy@ericsson.com, ying.xue@windriver.com, davem@davemloft.net, sploving1@gmail.com Cc: netdev@vger.kernel.org, tipc-discussion@lists.sourceforge.net From: Baozeng Ding Subject: [PATCH net] tipc: fix potential null pointer dereference in some compat, functions Message-ID: Date: Sun, 22 May 2016 12:22:03 +0800 User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:45.0) Gecko/20100101 Thunderbird/45.1.0 MIME-Version: 1.0 Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org Before calling the nla_parse_nested function, make sure the pointer to the attribute is not null. This patch fixes several potential null pointer dereference vulnerabilities in the tipc netlink functions. Signed-off-by: Baozeng Ding --- net/tipc/netlink_compat.c | 111 ++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 93 insertions(+), 18 deletions(-) diff --git a/net/tipc/netlink_compat.c b/net/tipc/netlink_compat.c index 4dfc5c1..1e18b78 100644 --- a/net/tipc/netlink_compat.c +++ b/net/tipc/netlink_compat.c @@ -345,10 +345,16 @@ static int tipc_nl_compat_doit(struct tipc_nl_compat_cmd_doit *cmd, static int tipc_nl_compat_bearer_dump(struct tipc_nl_compat_msg *msg, struct nlattr **attrs) { + int err; struct nlattr *bearer[TIPC_NLA_BEARER_MAX + 1]; - nla_parse_nested(bearer, TIPC_NLA_BEARER_MAX, attrs[TIPC_NLA_BEARER], - NULL); + if (!attrs[TIPC_NLA_BEARER]) + return -EINVAL; + + err = nla_parse_nested(bearer, TIPC_NLA_BEARER_MAX, + attrs[TIPC_NLA_BEARER], NULL); + if (err) + return err; return tipc_add_tlv(msg->rep, TIPC_TLV_BEARER_NAME, nla_data(bearer[TIPC_NLA_BEARER_NAME]), @@ -456,18 +462,35 @@ static void __fill_bc_link_stat(struct tipc_nl_compat_msg *msg, static int tipc_nl_compat_link_stat_dump(struct tipc_nl_compat_msg *msg, struct nlattr **attrs) { + int err; char *name; struct nlattr *link[TIPC_NLA_LINK_MAX + 1]; struct nlattr *prop[TIPC_NLA_PROP_MAX + 1]; struct nlattr *stats[TIPC_NLA_STATS_MAX + 1]; - nla_parse_nested(link, TIPC_NLA_LINK_MAX, attrs[TIPC_NLA_LINK], NULL); + if (!attrs[TIPC_NLA_LINK]) + return -EINVAL; - nla_parse_nested(prop, TIPC_NLA_PROP_MAX, link[TIPC_NLA_LINK_PROP], - NULL); + err = nla_parse_nested(link, TIPC_NLA_LINK_MAX, + attrs[TIPC_NLA_LINK], NULL); + if (err) + return err; + + if (!link[TIPC_NLA_LINK_PROP]) + return -EINVAL; - nla_parse_nested(stats, TIPC_NLA_STATS_MAX, link[TIPC_NLA_LINK_STATS], - NULL); + err = nla_parse_nested(prop, TIPC_NLA_PROP_MAX, + link[TIPC_NLA_LINK_PROP], NULL); + if (err) + return err; + + if (!link[TIPC_NLA_LINK_STATS]) + return -EINVAL; + + err = nla_parse_nested(stats, TIPC_NLA_STATS_MAX, + link[TIPC_NLA_LINK_STATS], NULL); + if (err) + return err; name = (char *)TLV_DATA(msg->req); if (strcmp(name, nla_data(link[TIPC_NLA_LINK_NAME])) != 0) @@ -567,10 +590,17 @@ static int tipc_nl_compat_link_stat_dump(struct tipc_nl_compat_msg *msg, static int tipc_nl_compat_link_dump(struct tipc_nl_compat_msg *msg, struct nlattr **attrs) { + int err; struct nlattr *link[TIPC_NLA_LINK_MAX + 1]; struct tipc_link_info link_info; - nla_parse_nested(link, TIPC_NLA_LINK_MAX, attrs[TIPC_NLA_LINK], NULL); + if (!attrs[TIPC_NLA_LINK]) + return -EINVAL; + + err = nla_parse_nested(link, TIPC_NLA_LINK_MAX, + attrs[TIPC_NLA_LINK], NULL); + if (err) + return err; link_info.dest = nla_get_flag(link[TIPC_NLA_LINK_DEST]); link_info.up = htonl(nla_get_flag(link[TIPC_NLA_LINK_UP])); @@ -751,6 +781,7 @@ static int tipc_nl_compat_name_table_dump_header(struct tipc_nl_compat_msg *msg) static int tipc_nl_compat_name_table_dump(struct tipc_nl_compat_msg *msg, struct nlattr **attrs) { + int err; char port_str[27]; struct tipc_name_table_query *ntq; struct nlattr *nt[TIPC_NLA_NAME_TABLE_MAX + 1]; @@ -759,11 +790,21 @@ static int tipc_nl_compat_name_table_dump(struct tipc_nl_compat_msg *msg, static const char * const scope_str[] = {"", " zone", " cluster", " node"}; - nla_parse_nested(nt, TIPC_NLA_NAME_TABLE_MAX, - attrs[TIPC_NLA_NAME_TABLE], NULL); + if (!attrs[TIPC_NLA_NAME_TABLE]) + return -EINVAL; - nla_parse_nested(publ, TIPC_NLA_PUBL_MAX, nt[TIPC_NLA_NAME_TABLE_PUBL], - NULL); + err = nla_parse_nested(nt, TIPC_NLA_NAME_TABLE_MAX, + attrs[TIPC_NLA_NAME_TABLE], NULL); + if (err) + return err; + + if (!nt[TIPC_NLA_NAME_TABLE_PUBL]) + return -EINVAL; + + err = nla_parse_nested(publ, TIPC_NLA_PUBL_MAX, + nt[TIPC_NLA_NAME_TABLE_PUBL], NULL); + if (err) + return err; ntq = (struct tipc_name_table_query *)TLV_DATA(msg->req); @@ -813,10 +854,17 @@ out: static int __tipc_nl_compat_publ_dump(struct tipc_nl_compat_msg *msg, struct nlattr **attrs) { + int err; u32 type, lower, upper; struct nlattr *publ[TIPC_NLA_PUBL_MAX + 1]; - nla_parse_nested(publ, TIPC_NLA_PUBL_MAX, attrs[TIPC_NLA_PUBL], NULL); + if (!attrs[TIPC_NLA_PUBL]) + return -EINVAL; + + err = nla_parse_nested(publ, TIPC_NLA_PUBL_MAX, + attrs[TIPC_NLA_PUBL], NULL); + if (err) + return err; type = nla_get_u32(publ[TIPC_NLA_PUBL_TYPE]); lower = nla_get_u32(publ[TIPC_NLA_PUBL_LOWER]); @@ -876,7 +924,13 @@ static int tipc_nl_compat_sk_dump(struct tipc_nl_compat_msg *msg, u32 sock_ref; struct nlattr *sock[TIPC_NLA_SOCK_MAX + 1]; - nla_parse_nested(sock, TIPC_NLA_SOCK_MAX, attrs[TIPC_NLA_SOCK], NULL); + if (!attrs[TIPC_NLA_SOCK]) + return -EINVAL; + + err = nla_parse_nested(sock, TIPC_NLA_SOCK_MAX, + attrs[TIPC_NLA_SOCK], NULL); + if (err) + return err; sock_ref = nla_get_u32(sock[TIPC_NLA_SOCK_REF]); tipc_tlv_sprintf(msg->rep, "%u:", sock_ref); @@ -916,10 +970,16 @@ static int tipc_nl_compat_sk_dump(struct tipc_nl_compat_msg *msg, static int tipc_nl_compat_media_dump(struct tipc_nl_compat_msg *msg, struct nlattr **attrs) { + int err; struct nlattr *media[TIPC_NLA_MEDIA_MAX + 1]; - nla_parse_nested(media, TIPC_NLA_MEDIA_MAX, attrs[TIPC_NLA_MEDIA], - NULL); + if (!attrs[TIPC_NLA_MEDIA]) + return -EINVAL; + + err = nla_parse_nested(media, TIPC_NLA_MEDIA_MAX, attrs[TIPC_NLA_MEDIA], + NULL); + if (err) + return err; return tipc_add_tlv(msg->rep, TIPC_TLV_MEDIA_NAME, nla_data(media[TIPC_NLA_MEDIA_NAME]), @@ -929,10 +989,17 @@ static int tipc_nl_compat_media_dump(struct tipc_nl_compat_msg *msg, static int tipc_nl_compat_node_dump(struct tipc_nl_compat_msg *msg, struct nlattr **attrs) { + int err; struct tipc_node_info node_info; struct nlattr *node[TIPC_NLA_NODE_MAX + 1]; - nla_parse_nested(node, TIPC_NLA_NODE_MAX, attrs[TIPC_NLA_NODE], NULL); + if (!attrs[TIPC_NLA_NODE]) + return -EINVAL; + + err = nla_parse_nested(node, TIPC_NLA_NODE_MAX, + attrs[TIPC_NLA_NODE], NULL); + if (err) + return err; node_info.addr = htonl(nla_get_u32(node[TIPC_NLA_NODE_ADDR])); node_info.up = htonl(nla_get_flag(node[TIPC_NLA_NODE_UP])); @@ -969,10 +1036,18 @@ static int tipc_nl_compat_net_set(struct tipc_nl_compat_cmd_doit *cmd, static int tipc_nl_compat_net_dump(struct tipc_nl_compat_msg *msg, struct nlattr **attrs) { + int err; __be32 id; struct nlattr *net[TIPC_NLA_NET_MAX + 1]; - nla_parse_nested(net, TIPC_NLA_NET_MAX, attrs[TIPC_NLA_NET], NULL); + if (!attrs[TIPC_NLA_NET]) + return -EINVAL; + + err = nla_parse_nested(net, TIPC_NLA_NET_MAX, + attrs[TIPC_NLA_NET], NULL); + if (err) + return err; + id = htonl(nla_get_u32(net[TIPC_NLA_NET_ID])); return tipc_add_tlv(msg->rep, TIPC_TLV_UNSIGNED, &id, sizeof(id));