Received: by 2002:a05:6a10:2726:0:0:0:0 with SMTP id ib38csp684365pxb; Tue, 5 Apr 2022 18:41:39 -0700 (PDT) X-Google-Smtp-Source: ABdhPJwhCLy6z5Ta6i5Ae4vlLM7YYoPVygHQl1abZsPB8LIgQon8eekIflCFZwVA0Nb7SKy+/aYb X-Received: by 2002:a50:ee05:0:b0:419:39d9:ccd8 with SMTP id g5-20020a50ee05000000b0041939d9ccd8mr6371673eds.369.1649209298962; Tue, 05 Apr 2022 18:41:38 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1649209298; cv=none; d=google.com; s=arc-20160816; b=dolAYJaXMLmy0cUef9Hcu0+duniK7rUl7pGc4dy87aldEI3kFQFjFIWNzEz7Jof23e btHKriYJ/tXyCFeYseLDMT6Gez/FYvWzDAEyiqDlwT9y97yYzu/lgzmNX6mjMaG3qK5L 9hxcTz11JWBXfv9U+yiMoxTkpLlSD/SS5iEc9L/oPdoPlwBl7L+i9rHqR71LIH4+XJwo l8oP058Oz7V1WgDN63122guyszAN7/5IZQYHYFQohqsOF7vkOBjqkozUfb0uzMmJ/qLg S9/UllCIz4LdsDWAO7ItSUy/ZKRI4q7ExGDVJKllOfvrLD7frW1jOwcVksJ87AAk1NGm jdcQ== 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 :user-agent:references:in-reply-to:message-id:date:subject:cc:to :from:dkim-signature; bh=Fg2WkM68oxkp3gopn9i8fJvktC3dH+EVIM7E5dt/Im8=; b=oIXTnCoivmd23yvwh6wy9Fxm+rusAH4KxbsXA//o2xnbZfderSGljub+FmI3fHEC2x w05aSayy3ho38A/gFPerk8AE17pBO5HnxD2PdartgdpiLUsGRMcdT3L4ve79w8RZDQSk gR6QXBex5aSIAXaQedYWqOMioPi02TmHr3nPBuFq029F7Rfb1tJWlhATSgCXifUj9U4/ VD3wM+wp0HWeZRUVMzl1gl+cm/KoacxKDL9peQ4YBgtFkX6a3dODLjLxVtMk2E3fijm5 9oD3/qD3fvhrBTuiPO0cmFaedrmlrf0LP4S6PIEzgUyG2qkOkjnuAnOsJYFHYsrOmgyY Ac7g== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linuxfoundation.org header.s=korg header.b=bGnjLu2Q; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linuxfoundation.org Return-Path: Received: from out1.vger.email (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id k10-20020a50e18a000000b00418e692aa7dsi10580086edl.526.2022.04.05.18.41.11; Tue, 05 Apr 2022 18:41:38 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) client-ip=2620:137:e000::1:20; Authentication-Results: mx.google.com; dkim=pass header.i=@linuxfoundation.org header.s=korg header.b=bGnjLu2Q; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linuxfoundation.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1377216AbiDEL22 (ORCPT + 99 others); Tue, 5 Apr 2022 07:28:28 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:38350 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S243378AbiDEIuZ (ORCPT ); Tue, 5 Apr 2022 04:50:25 -0400 Received: from dfw.source.kernel.org (dfw.source.kernel.org [IPv6:2604:1380:4641:c500::1]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id ACC1C12609; Tue, 5 Apr 2022 01:38:44 -0700 (PDT) Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by dfw.source.kernel.org (Postfix) with ESMTPS id 9E0D661551; Tue, 5 Apr 2022 08:38:15 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id AB060C385A7; Tue, 5 Apr 2022 08:38:14 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=linuxfoundation.org; s=korg; t=1649147895; bh=uQMB6DRnrFezFKqAd+bYNqR+eGeLNyW5WRYA6+53Eu0=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=bGnjLu2QtPrLvi9PFSY2To4Fa63Xvc5p/CnbEo2PtxF2MxUPkUW/7BwRcJyc0cJJg VSaFP1QwVhA+uga9msAc8QabRwYGS/pqobIHwegnU8jE5YcgTtUwzvt2W89XlvGqh/ ljmh88O/L32SgvswtzD6sFoR7mpYFJj1NL11oXXI= From: Greg Kroah-Hartman To: linux-kernel@vger.kernel.org Cc: Greg Kroah-Hartman , stable@vger.kernel.org, Johannes Berg , Kalle Valo Subject: [PATCH 5.16 0153/1017] rfkill: make new event layout opt-in Date: Tue, 5 Apr 2022 09:17:46 +0200 Message-Id: <20220405070358.751749539@linuxfoundation.org> X-Mailer: git-send-email 2.35.1 In-Reply-To: <20220405070354.155796697@linuxfoundation.org> References: <20220405070354.155796697@linuxfoundation.org> User-Agent: quilt/0.66 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-Spam-Status: No, score=-7.1 required=5.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,RCVD_IN_DNSWL_HI, SPF_HELO_NONE,SPF_PASS,T_SCC_BODY_TEXT_LINE autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Johannes Berg commit 54f586a9153201c6cff55e1f561990c78bd99aa7 upstream. Again new complaints surfaced that we had broken the ABI here, although previously all the userspace tools had agreed that it was their mistake and fixed it. Yet now there are cases (e.g. RHEL) that want to run old userspace with newer kernels, and thus are broken. Since this is a bit of a whack-a-mole thing, change the whole extensibility scheme of rfkill to no longer just rely on the message lengths, but instead require userspace to opt in via a new ioctl to a given maximum event size that it is willing to understand. By default, set that to RFKILL_EVENT_SIZE_V1 (8), so that the behaviour for userspace not calling the ioctl will look as if it's just running on an older kernel. Fixes: 14486c82612a ("rfkill: add a reason to the HW rfkill state") Cc: stable@vger.kernel.org # 5.11+ Signed-off-by: Johannes Berg Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/20220316212749.16491491b270.Ifcb1950998330a596f29a2a162e00b7546a1d6d0@changeid Signed-off-by: Greg Kroah-Hartman --- include/uapi/linux/rfkill.h | 14 +++++++++++- net/rfkill/core.c | 48 +++++++++++++++++++++++++++++++------------- 2 files changed, 46 insertions(+), 16 deletions(-) --- a/include/uapi/linux/rfkill.h +++ b/include/uapi/linux/rfkill.h @@ -159,8 +159,16 @@ struct rfkill_event_ext { * old behaviour for all userspace, unless it explicitly opts in to the * rules outlined here by using the new &struct rfkill_event_ext. * - * Userspace using &struct rfkill_event_ext must adhere to the following - * rules + * Additionally, some other userspace (bluez, g-s-d) was reading with a + * large size but as streaming reads rather than message-based, or with + * too strict checks for the returned size. So eventually, we completely + * reverted this, and extended messages need to be opted in to by using + * an ioctl: + * + * ioctl(fd, RFKILL_IOCTL_MAX_SIZE, sizeof(struct rfkill_event_ext)); + * + * Userspace using &struct rfkill_event_ext and the ioctl must adhere to + * the following rules: * * 1. accept short writes, optionally using them to detect that it's * running on an older kernel; @@ -175,6 +183,8 @@ struct rfkill_event_ext { #define RFKILL_IOC_MAGIC 'R' #define RFKILL_IOC_NOINPUT 1 #define RFKILL_IOCTL_NOINPUT _IO(RFKILL_IOC_MAGIC, RFKILL_IOC_NOINPUT) +#define RFKILL_IOC_MAX_SIZE 2 +#define RFKILL_IOCTL_MAX_SIZE _IOW(RFKILL_IOC_MAGIC, RFKILL_IOC_EXT_SIZE, __u32) /* and that's all userspace gets */ --- a/net/rfkill/core.c +++ b/net/rfkill/core.c @@ -78,6 +78,7 @@ struct rfkill_data { struct mutex mtx; wait_queue_head_t read_wait; bool input_handler; + u8 max_size; }; @@ -1141,6 +1142,8 @@ static int rfkill_fop_open(struct inode if (!data) return -ENOMEM; + data->max_size = RFKILL_EVENT_SIZE_V1; + INIT_LIST_HEAD(&data->events); mutex_init(&data->mtx); init_waitqueue_head(&data->read_wait); @@ -1223,6 +1226,7 @@ static ssize_t rfkill_fop_read(struct fi list); sz = min_t(unsigned long, sizeof(ev->ev), count); + sz = min_t(unsigned long, sz, data->max_size); ret = sz; if (copy_to_user(buf, &ev->ev, sz)) ret = -EFAULT; @@ -1237,6 +1241,7 @@ static ssize_t rfkill_fop_read(struct fi static ssize_t rfkill_fop_write(struct file *file, const char __user *buf, size_t count, loff_t *pos) { + struct rfkill_data *data = file->private_data; struct rfkill *rfkill; struct rfkill_event_ext ev; int ret; @@ -1251,6 +1256,7 @@ static ssize_t rfkill_fop_write(struct f * our API version even in a write() call, if it cares. */ count = min(count, sizeof(ev)); + count = min_t(size_t, count, data->max_size); if (copy_from_user(&ev, buf, count)) return -EFAULT; @@ -1310,31 +1316,47 @@ static int rfkill_fop_release(struct ino return 0; } -#ifdef CONFIG_RFKILL_INPUT static long rfkill_fop_ioctl(struct file *file, unsigned int cmd, unsigned long arg) { struct rfkill_data *data = file->private_data; + int ret = -ENOSYS; + u32 size; if (_IOC_TYPE(cmd) != RFKILL_IOC_MAGIC) return -ENOSYS; - if (_IOC_NR(cmd) != RFKILL_IOC_NOINPUT) - return -ENOSYS; - mutex_lock(&data->mtx); - - if (!data->input_handler) { - if (atomic_inc_return(&rfkill_input_disabled) == 1) - printk(KERN_DEBUG "rfkill: input handler disabled\n"); - data->input_handler = true; + switch (_IOC_NR(cmd)) { +#ifdef CONFIG_RFKILL_INPUT + case RFKILL_IOC_NOINPUT: + if (!data->input_handler) { + if (atomic_inc_return(&rfkill_input_disabled) == 1) + printk(KERN_DEBUG "rfkill: input handler disabled\n"); + data->input_handler = true; + } + ret = 0; + break; +#endif + case RFKILL_IOC_MAX_SIZE: + if (get_user(size, (__u32 __user *)arg)) { + ret = -EFAULT; + break; + } + if (size < RFKILL_EVENT_SIZE_V1 || size > U8_MAX) { + ret = -EINVAL; + break; + } + data->max_size = size; + ret = 0; + break; + default: + break; } - mutex_unlock(&data->mtx); - return 0; + return ret; } -#endif static const struct file_operations rfkill_fops = { .owner = THIS_MODULE, @@ -1343,10 +1365,8 @@ static const struct file_operations rfki .write = rfkill_fop_write, .poll = rfkill_fop_poll, .release = rfkill_fop_release, -#ifdef CONFIG_RFKILL_INPUT .unlocked_ioctl = rfkill_fop_ioctl, .compat_ioctl = compat_ptr_ioctl, -#endif .llseek = no_llseek, };