From patchwork Sat May 21 16:22:48 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Baozeng Ding X-Patchwork-Id: 624857 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 3rBqpv6bd4z9t3s for ; Sun, 22 May 2016 02:23:03 +1000 (AEST) Authentication-Results: ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b=PnlM2+f6; dkim-atps=neutral Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752166AbcEUQXA (ORCPT ); Sat, 21 May 2016 12:23:00 -0400 Received: from mail-pa0-f68.google.com ([209.85.220.68]:33744 "EHLO mail-pa0-f68.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752104AbcEUQW5 (ORCPT ); Sat, 21 May 2016 12:22:57 -0400 Received: by mail-pa0-f68.google.com with SMTP id f8so1879174pag.0 for ; Sat, 21 May 2016 09:22:57 -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=pxAKIQZg+wjHv+mc9KXYtMKmYb7mRjNhHudu6NlBhic=; b=PnlM2+f66PUA5ZAO5S6DyWILWtTwRXXR7WlVnixCJ+h2IeiLax19LWBVk+rY0uHHs4 cQWck+k/4MSjvKxnmyiIMF2ZwPPW/N5JGyQhSSKjRGNy5ymRU2sFAo8wtoEj4L/41FZR 1xNzP5ZayCjWnF2A4ZarNy8vSAyYbG/JmRmOCKaHJQOhhdaxdKoWHqwAQi4of1C/IhDP oDdvqocZt1K/b5rDTB+4d9BRr29Fl/BpjQHpDjB3e8P9bZFbgmXHp9X72oda8c0+5GIW XSsJDpMc69unOr7xZvE8egnggUQnciInXU9AYF4FjVn4MEbtW8gt383lvW8I5arjsNHo QT1A== 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=pxAKIQZg+wjHv+mc9KXYtMKmYb7mRjNhHudu6NlBhic=; b=gSuO4KaI+NI9MeNfLALffjq41cGB5I7VF/vB/VF8bSBj0et55Rd5JVKzSqbBO+YURD j0X+Mn95XW6Bg7oqw9WIbl+dhnMo1nLrrAQOLlUOxHD3jxLS1ijnPyWF5KSjQQ/vw3Ub 2v6tcw+4o5yzTGAeGmDJJw+MgWTMSftjqZYqbT3gW94J8ptcAik+bAFJ17Q7D+pgMFZG 85tJJm0KekrI23ET1bUoYL4wNS1QuFgYKYnJct9qVUkGIzkyTcq1rDOy683V/t7gJCW8 ZZni4NGJD2N5qKKcIvE1ISsmG6etRcvi5mZ3Omqh9SPbQWTMyNdHwLG6IYImAit2O1ml g2eQ== X-Gm-Message-State: AOPr4FXzUr2tkxeWBGLa82cugn5lxH5lWumwEnbOguSxy3Ugrb7WrWBio2tUugLGiJ872Q== X-Received: by 10.66.183.69 with SMTP id ek5mr13857967pac.153.1463847776586; Sat, 21 May 2016 09:22:56 -0700 (PDT) Received: from [10.8.0.16] ([104.156.239.137]) by smtp.gmail.com with ESMTPSA id vw1sm20892252pab.35.2016.05.21.09.22.53 (version=TLSv1/SSLv3 cipher=OTHER); Sat, 21 May 2016 09:22:56 -0700 (PDT) To: jon.maloy@ericsson.com, ying.xue@windriver.com, davem@davemloft.net Cc: netdev@vger.kernel.org, tipc-discussion@lists.sourceforge.net From: Baozeng Ding Subject: [PATCH] net/tipc: fix potential null pointer dereference in several tipc netlink compat functions Message-ID: <6eb20dd0-0241-71d5-ee9e-0001db0301ba@gmail.com> Date: Sun, 22 May 2016 00:22:48 +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 funciton, its third argument should be checked to make sure it is not null. This patch fixes several potential null pointer dereference vulnerability in the tipc netlink functions. Signed-off-by: Baozeng Ding --- net/tipc/netlink_compat.c | 111 ++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 93 insertions(+), 18 deletions(-) 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 (!attrs[TIPC_NLA_NAME_TABLE]) + 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)); diff --git a/net/tipc/netlink_compat.c b/net/tipc/netlink_compat.c index 4dfc5c1..959e989 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,