Received: by 2002:a05:6902:102b:0:0:0:0 with SMTP id x11csp1279834ybt; Thu, 9 Jul 2020 03:12:28 -0700 (PDT) X-Google-Smtp-Source: ABdhPJwjKIw7hgPbw8CyQ8Y9lpfbqC/JGVemY4f9WE47GKsntyQVr7fpKPRfP3QrooAbEMTPFJ7k X-Received: by 2002:a17:906:66d0:: with SMTP id k16mr57326746ejp.293.1594289548773; Thu, 09 Jul 2020 03:12:28 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1594289548; cv=none; d=google.com; s=arc-20160816; b=BfSyd6f2+GjySRORXvvPUHIuyI52rVcwnmCTAaYdPCLJPGVULeSpjNSylErGTeSAIR lqzRa/Xw0q4/EBBP14hNGS/h6DNdnYq/ktUqoc5pZYiJF+ZTUusf+xilh1hWSa5AtkFH Cj/m1z6hviKz3wCoiXgBpWZi+gtNlwLgEme+Kq/FqRS7pkIO7vtXZg45qG+ii+N4mJmo c7wPOf6IiZcLF4NzDFcxdikddv8bleoKaPvuros5v9G4sHh7SGNBJpNOatrhH0+eKSzm JUvlAxLFciH2/a2sEhDtLoTFIeumHIxYIQFgeGCINCB1Df1WYmpN0TtnMzbuRsN//Bm1 A+AQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:date:message-id:cc:to:subject:from; bh=zkSr8dzmd6dEIK4rKcJpGEnpddRaLpsEu5MdOXl+g+s=; b=TM75sdpPNaiz8Iykt4Rhr1nZ65xwxs+MhAsI8zLm/oJyyAzf9+JoAR/nZZwBYjK5V/ Ji3jYzNcT9aDmVzzG324guFVnHw+k5EJXTQvcE2sACgU8tt2vnVqbJv4Kher/K8Ph0Fc yJWIc9FHp1UxUHDfiqFSTALwU6B/eodwDo9SumYjLtUtBXlMtps8Ilb0etK84ler7Wm0 ImT2MbHuUlQqGhYwG2+bXxPMw8THyRsnzYP+lVNxR1fDrXHN8MVYJxo4DPAvG68gHAGN 5DYWUphuz5+lTFhL4dN00el8LLaxdqITpW+stmMOXfoEQD/JcuNHmsN2Ogxgnho+AbIL Qg+Q== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id bc14si1593643edb.368.2020.07.09.03.12.05; Thu, 09 Jul 2020 03:12:28 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) client-ip=23.128.96.18; Authentication-Results: mx.google.com; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726443AbgGIKLx (ORCPT + 99 others); Thu, 9 Jul 2020 06:11:53 -0400 Received: from mx2.suse.de ([195.135.220.15]:58286 "EHLO mx2.suse.de" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726327AbgGIKLw (ORCPT ); Thu, 9 Jul 2020 06:11:52 -0400 X-Virus-Scanned: by amavisd-new at test-mx.suse.de Received: from relay2.suse.de (unknown [195.135.221.27]) by mx2.suse.de (Postfix) with ESMTP id 738F3B04C; Thu, 9 Jul 2020 10:11:50 +0000 (UTC) Received: by lion.mk-sys.cz (Postfix, from userid 1000) id 65DBB60567; Thu, 9 Jul 2020 12:11:50 +0200 (CEST) From: Michal Kubecek Subject: [PATCH net] ethtool: fix genlmsg_put() failure handling in ethnl_default_dumpit() To: "David S. Miller" , Jakub Kicinski , netdev@vger.kernel.org Cc: linux-kernel@vger.kernel.org Message-Id: <20200709101150.65DBB60567@lion.mk-sys.cz> Date: Thu, 9 Jul 2020 12:11:50 +0200 (CEST) Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org If the genlmsg_put() call in ethnl_default_dumpit() fails, we bail out without checking if we already have some messages in current skb like we do with ethnl_default_dump_one() failure later. Therefore if existing messages almost fill up the buffer so that there is not enough space even for netlink and genetlink header, we lose all prepared messages and return and error. Rather than duplicating the skb->len check, move the genlmsg_put(), genlmsg_cancel() and genlmsg_end() calls into ethnl_default_dump_one(). This is also more logical as all message composition will be in ethnl_default_dump_one() and only iteration logic will be left in ethnl_default_dumpit(). Fixes: 728480f12442 ("ethtool: default handlers for GET requests") Reported-by: Jakub Kicinski Signed-off-by: Michal Kubecek --- net/ethtool/netlink.c | 27 +++++++++++++-------------- 1 file changed, 13 insertions(+), 14 deletions(-) diff --git a/net/ethtool/netlink.c b/net/ethtool/netlink.c index 88fd07f47040..dd8a1c1dc07d 100644 --- a/net/ethtool/netlink.c +++ b/net/ethtool/netlink.c @@ -376,10 +376,17 @@ static int ethnl_default_doit(struct sk_buff *skb, struct genl_info *info) } static int ethnl_default_dump_one(struct sk_buff *skb, struct net_device *dev, - const struct ethnl_dump_ctx *ctx) + const struct ethnl_dump_ctx *ctx, + struct netlink_callback *cb) { + void *ehdr; int ret; + ehdr = genlmsg_put(skb, NETLINK_CB(cb->skb).portid, cb->nlh->nlmsg_seq, + ðtool_genl_family, 0, ctx->ops->reply_cmd); + if (!ehdr) + return -EMSGSIZE; + ethnl_init_reply_data(ctx->reply_data, ctx->ops, dev); rtnl_lock(); ret = ctx->ops->prepare_data(ctx->req_info, ctx->reply_data, NULL); @@ -395,6 +402,10 @@ static int ethnl_default_dump_one(struct sk_buff *skb, struct net_device *dev, if (ctx->ops->cleanup_data) ctx->ops->cleanup_data(ctx->reply_data); ctx->reply_data->dev = NULL; + if (ret < 0) + genlmsg_cancel(skb, ehdr); + else + genlmsg_end(skb, ehdr); return ret; } @@ -411,7 +422,6 @@ static int ethnl_default_dumpit(struct sk_buff *skb, int s_idx = ctx->pos_idx; int h, idx = 0; int ret = 0; - void *ehdr; rtnl_lock(); for (h = ctx->pos_hash; h < NETDEV_HASHENTRIES; h++, s_idx = 0) { @@ -431,26 +441,15 @@ static int ethnl_default_dumpit(struct sk_buff *skb, dev_hold(dev); rtnl_unlock(); - ehdr = genlmsg_put(skb, NETLINK_CB(cb->skb).portid, - cb->nlh->nlmsg_seq, - ðtool_genl_family, 0, - ctx->ops->reply_cmd); - if (!ehdr) { - dev_put(dev); - ret = -EMSGSIZE; - goto out; - } - ret = ethnl_default_dump_one(skb, dev, ctx); + ret = ethnl_default_dump_one(skb, dev, ctx, cb); dev_put(dev); if (ret < 0) { - genlmsg_cancel(skb, ehdr); if (ret == -EOPNOTSUPP) goto lock_and_cont; if (likely(skb->len)) ret = skb->len; goto out; } - genlmsg_end(skb, ehdr); lock_and_cont: rtnl_lock(); if (net->dev_base_seq != seq) { -- 2.27.0