From patchwork Tue Jul 20 14:46:12 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Arnd Bergmann X-Patchwork-Id: 481529 Delivered-To: patch@linaro.org Received: by 2002:a02:c94a:0:0:0:0:0 with SMTP id u10csp5228746jao; Tue, 20 Jul 2021 08:17:07 -0700 (PDT) X-Google-Smtp-Source: ABdhPJwyhnga0o/WrOHhzSdCky/JTTL50gr+3Wv+i/V3ruzYIky++qc47aNhro/n3MThY2UP8dE4 X-Received: by 2002:a19:700d:: with SMTP id h13mr22705839lfc.109.1626794226931; Tue, 20 Jul 2021 08:17:06 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1626794226; cv=none; d=google.com; s=arc-20160816; b=xTNjK+iepDVtKLFUdE4r495qnaET5ebRkDg5YeZR150TbsHfppO5CIpe+jucMFXS10 06PssNXmXdaKEO1v6ZB2HwUv9CFilc3S71S4j+7fIvTKDjuAlPRsGmJD8EUXMiiaoZMV iGIAx+BkAHUVxO6rG9GRLEWy053RKxCw1T35IRlVoV3OVfgqYX5/XdIaZU1EX6Q0Q3j6 wHJedXLdXxcYtIjtXkI4+vscorEh+w4wBRcHiFr0P0h1A8WfUbVguUtis45ZvwJr/CNC PcaRFoI2E73XZ8P21ra95J9WxUlpRKkGL8rIfpaRrsO3tfy3vjn2dYGfapbGa/LR5d+J xh8g== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :references:in-reply-to:message-id:date:subject:cc:to:from :dkim-signature; bh=8U0pqnr7MF6CGYDx79kk5qcz4nht5VAiHMG+uHN9OwQ=; b=mdyeEhlIIo/ez/3rSZjkLsPe9VD4NpMIPq04glof6YkPDU958d6/CDa6HIHvKJJ5Dc nF80rxfSpFbdk8Z4KX+N6w+Scs0GmEqxiW6Cd1nssUGGizyb4AzpWAVI//Wm0v34a4ku atxlElFZo5mnP1IvU0uUPJ/AdtHIo/JDNL8ZQ9we06qkBPrrrQacSQkIr9OLkLVBeu1D o/LaF2Y60qCa9iuGcMm8wxQMm/xqDCNtfHooDSiFk4mXt+XRBBWNi2clnOJzXMbRtJ5U 504YLEy1aVvlIUacrYnz+mBwNKOrwtrh9z15JF/rkDxhNuJxsaX157nkyY64MfNu6pwu BGiQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@kernel.org header.s=k20201202 header.b=ta0W+irw; spf=pass (google.com: domain of netdev-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=netdev-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id j8si24247821ljq.554.2021.07.20.08.17.06; Tue, 20 Jul 2021 08:17:06 -0700 (PDT) Received-SPF: pass (google.com: domain of netdev-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) client-ip=23.128.96.18; Authentication-Results: mx.google.com; dkim=pass header.i=@kernel.org header.s=k20201202 header.b=ta0W+irw; spf=pass (google.com: domain of netdev-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=netdev-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S240204AbhGTOgR (ORCPT + 8 others); Tue, 20 Jul 2021 10:36:17 -0400 Received: from mail.kernel.org ([198.145.29.99]:55712 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S237402AbhGTORU (ORCPT ); Tue, 20 Jul 2021 10:17:20 -0400 Received: by mail.kernel.org (Postfix) with ESMTPSA id A3E8B61221; Tue, 20 Jul 2021 14:46:57 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1626792418; bh=+coq0b+Vy2SEWu1iJCM3uM8qyxI2AS4K0Q/yOhzMxBQ=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=ta0W+irwAATFq3juKQ4iehdLf5gXVXnXdBzvy6Mc44ibj5fEmdieMzw2Vu9yn23dE zw1HG+NJniW51jUQUUOQGw9BYws2YI7IAcz2gry27Bybu/07yfD8XkQNQPqLKML/Bb 0A/IWOK0DsPXrkFQy4euqyPb0LR57llfVKsXITGPWHabW39R7LYoTOz83H90cv1zms dYa1bjesQt/jeOZkWq7XMAsCfi/MFWZW6TbqEUhMNNDUi6PtBLQ1fQxieifa82fCNq nS4vt/zeVTWqHunZma95qJ1PAdrecHFrN1AxFSgjbLdkMilR0npo3GOahceQ7qh3v8 b80EHKuPbbeXQ== From: Arnd Bergmann To: netdev@vger.kernel.org Cc: Christoph Hellwig , Arnd Bergmann Subject: [PATCH net-next v2 05/31] bridge: use ndo_siocdevprivate Date: Tue, 20 Jul 2021 16:46:12 +0200 Message-Id: <20210720144638.2859828-6-arnd@kernel.org> X-Mailer: git-send-email 2.29.2 In-Reply-To: <20210720144638.2859828-1-arnd@kernel.org> References: <20210720144638.2859828-1-arnd@kernel.org> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org From: Arnd Bergmann The bridge driver has an old set of ioctls using the SIOCDEVPRIVATE namespace that have never worked in compat mode and are explicitly forbidden already. Move them over to ndo_siocdevprivate and fix compat mode for these, because we can. Signed-off-by: Arnd Bergmann --- net/bridge/br_device.c | 1 + net/bridge/br_ioctl.c | 37 +++++++++++++++++++++++++------------ net/bridge/br_private.h | 2 ++ 3 files changed, 28 insertions(+), 12 deletions(-) -- 2.29.2 diff --git a/net/bridge/br_device.c b/net/bridge/br_device.c index e8b626cc6bfd..b57ff551caba 100644 --- a/net/bridge/br_device.c +++ b/net/bridge/br_device.c @@ -451,6 +451,7 @@ static const struct net_device_ops br_netdev_ops = { .ndo_change_rx_flags = br_dev_change_rx_flags, .ndo_change_mtu = br_change_mtu, .ndo_do_ioctl = br_dev_ioctl, + .ndo_siocdevprivate = br_dev_siocdevprivate, #ifdef CONFIG_NET_POLL_CONTROLLER .ndo_netpoll_setup = br_netpoll_setup, .ndo_netpoll_cleanup = br_netpoll_cleanup, diff --git a/net/bridge/br_ioctl.c b/net/bridge/br_ioctl.c index 2db800fc27ca..9f924fe43641 100644 --- a/net/bridge/br_ioctl.c +++ b/net/bridge/br_ioctl.c @@ -106,15 +106,32 @@ static int add_del_if(struct net_bridge *br, int ifindex, int isadd) * This interface is deprecated because it was too difficult * to do the translation for 32/64bit ioctl compatibility. */ -static int old_dev_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) +int br_dev_siocdevprivate(struct net_device *dev, struct ifreq *rq, void __user *data, int cmd) { struct net_bridge *br = netdev_priv(dev); struct net_bridge_port *p = NULL; unsigned long args[4]; + void __user *argp; int ret = -EOPNOTSUPP; - if (copy_from_user(args, rq->ifr_data, sizeof(args))) - return -EFAULT; + if (in_compat_syscall()) { + unsigned int cargs[4]; + + if (copy_from_user(cargs, data, sizeof(cargs))) + return -EFAULT; + + args[0] = cargs[0]; + args[1] = cargs[1]; + args[2] = cargs[2]; + args[3] = cargs[3]; + + argp = compat_ptr(args[1]); + } else { + if (copy_from_user(args, data, sizeof(args))) + return -EFAULT; + + argp = (void __user *)args[1]; + } switch (args[0]) { case BRCTL_ADD_IF: @@ -171,7 +188,7 @@ static int old_dev_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) return -ENOMEM; get_port_ifindices(br, indices, num); - if (copy_to_user((void __user *)args[1], indices, num*sizeof(int))) + if (copy_to_user(argp, indices, num * sizeof(int))) num = -EFAULT; kfree(indices); return num; @@ -232,7 +249,7 @@ static int old_dev_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) rcu_read_unlock(); - if (copy_to_user((void __user *)args[1], &p, sizeof(p))) + if (copy_to_user(argp, &p, sizeof(p))) return -EFAULT; return 0; @@ -282,8 +299,7 @@ static int old_dev_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) } case BRCTL_GET_FDB_ENTRIES: - return get_fdb_entries(br, (void __user *)args[1], - args[2], args[3]); + return get_fdb_entries(br, argp, args[2], args[3]); } if (!ret) { @@ -320,7 +336,7 @@ static int old_deviceless(struct net *net, void __user *uarg) args[2] = get_bridge_ifindices(net, indices, args[2]); - ret = copy_to_user((void __user *)args[1], indices, args[2]*sizeof(int)) + ret = copy_to_user(uarg, indices, args[2]*sizeof(int)) ? -EFAULT : args[2]; kfree(indices); @@ -335,7 +351,7 @@ static int old_deviceless(struct net *net, void __user *uarg) if (!ns_capable(net->user_ns, CAP_NET_ADMIN)) return -EPERM; - if (copy_from_user(buf, (void __user *)args[1], IFNAMSIZ)) + if (copy_from_user(buf, uarg, IFNAMSIZ)) return -EFAULT; buf[IFNAMSIZ-1] = 0; @@ -383,9 +399,6 @@ int br_dev_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) struct net_bridge *br = netdev_priv(dev); switch (cmd) { - case SIOCDEVPRIVATE: - return old_dev_ioctl(dev, rq, cmd); - case SIOCBRADDIF: case SIOCBRDELIF: return add_del_if(br, rq->ifr_ifindex, cmd == SIOCBRADDIF); diff --git a/net/bridge/br_private.h b/net/bridge/br_private.h index 2b48b204205e..3f90be8c9ce0 100644 --- a/net/bridge/br_private.h +++ b/net/bridge/br_private.h @@ -791,6 +791,8 @@ br_port_get_check_rtnl(const struct net_device *dev) /* br_ioctl.c */ int br_dev_ioctl(struct net_device *dev, struct ifreq *rq, int cmd); +int br_dev_siocdevprivate(struct net_device *dev, struct ifreq *rq, + void __user *data, int cmd); int br_ioctl_deviceless_stub(struct net *net, unsigned int cmd, void __user *arg);