From patchwork Wed May 9 12:01:46 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Michal Kubecek X-Patchwork-Id: 910810 X-Patchwork-Delegate: linville@tuxdriver.com 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=none (p=none dis=none) header.from=suse.cz Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 40gw2816z8z9s47 for ; Wed, 9 May 2018 22:01:51 +1000 (AEST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S934813AbeEIMBt (ORCPT ); Wed, 9 May 2018 08:01:49 -0400 Received: from mx2.suse.de ([195.135.220.15]:50456 "EHLO mx2.suse.de" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S934447AbeEIMBs (ORCPT ); Wed, 9 May 2018 08:01:48 -0400 X-Virus-Scanned: by amavisd-new at test-mx.suse.de Received: from relay1.suse.de (charybdis-ext.suse.de [195.135.220.254]) by mx2.suse.de (Postfix) with ESMTP id 35F80AD69; Wed, 9 May 2018 12:01:47 +0000 (UTC) Received: by unicorn.suse.cz (Postfix, from userid 1000) id C7408A0C6F; Wed, 9 May 2018 14:01:46 +0200 (CEST) From: Michal Kubecek Subject: [PATCH ethtool] ethtool: fix stack clash in do_get_phy_tunable and do_set_phy_tunable To: "John W. Linville" Cc: netdev@vger.kernel.org, Raju Lakkaraju , "Allan W. Nielsen" Message-Id: <20180509120146.C7408A0C6F@unicorn.suse.cz> Date: Wed, 9 May 2018 14:01:46 +0200 (CEST) Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org Users reported stack clash detected when using --get-phy-tunable on ppc64le. Problem is caused by local variable ds of type struct ethtool_tunable which has last member "void *data[0]". Accessing data[0] (as do_get_phy_tunable() does) or adding requested value at the end (which is what kernel ioctl does) writes past allocated space for the variable. Make ds part of an anonymous structure to make sure there is enough space for tunable value and drop the (pointless) access to ds.data[0]. The same problem also exists in do_set_phy_tunable(). Fixes: b0fe96dec90f ("Ethtool: Implements ETHTOOL_PHY_GTUNABLE/ETHTOOL_PHY_STUNABLE and PHY downshift") Signed-off-by: Michal Kubecek --- ethtool.c | 39 +++++++++++++++++++++------------------ 1 file changed, 21 insertions(+), 18 deletions(-) diff --git a/ethtool.c b/ethtool.c index 3289e0f6e8ec..2e873848eb4e 100644 --- a/ethtool.c +++ b/ethtool.c @@ -4740,20 +4740,22 @@ static int do_get_phy_tunable(struct cmd_context *ctx) } if (downshift_changed) { - struct ethtool_tunable ds; + struct { + struct ethtool_tunable ds; + u8 __count; + } cont; u8 count = 0; - ds.cmd = ETHTOOL_PHY_GTUNABLE; - ds.id = ETHTOOL_PHY_DOWNSHIFT; - ds.type_id = ETHTOOL_TUNABLE_U8; - ds.len = 1; - ds.data[0] = &count; - err = send_ioctl(ctx, &ds); + cont.ds.cmd = ETHTOOL_PHY_GTUNABLE; + cont.ds.id = ETHTOOL_PHY_DOWNSHIFT; + cont.ds.type_id = ETHTOOL_TUNABLE_U8; + cont.ds.len = 1; + err = send_ioctl(ctx, &cont.ds); if (err < 0) { perror("Cannot Get PHY downshift count"); return 87; } - count = *((u8 *)&ds.data[0]); + count = *((u8 *)&cont.ds.data[0]); if (count) fprintf(stdout, "Downshift count: %d\n", count); else @@ -4931,16 +4933,17 @@ static int do_set_phy_tunable(struct cmd_context *ctx) /* Do it */ if (ds_changed) { - struct ethtool_tunable ds; - u8 count; - - ds.cmd = ETHTOOL_PHY_STUNABLE; - ds.id = ETHTOOL_PHY_DOWNSHIFT; - ds.type_id = ETHTOOL_TUNABLE_U8; - ds.len = 1; - ds.data[0] = &count; - *((u8 *)&ds.data[0]) = ds_cnt; - err = send_ioctl(ctx, &ds); + struct { + struct ethtool_tunable ds; + u8 __count; + } cont; + + cont.ds.cmd = ETHTOOL_PHY_STUNABLE; + cont.ds.id = ETHTOOL_PHY_DOWNSHIFT; + cont.ds.type_id = ETHTOOL_TUNABLE_U8; + cont.ds.len = 1; + *((u8 *)&cont.ds.data[0]) = ds_cnt; + err = send_ioctl(ctx, &cont.ds); if (err < 0) { perror("Cannot Set PHY downshift count"); err = 87;