Received: by 2002:a25:8b91:0:0:0:0:0 with SMTP id j17csp1163528ybl; Wed, 4 Dec 2019 18:31:32 -0800 (PST) X-Google-Smtp-Source: APXvYqyNr9fFkHf3/L1l4U6oluXYMMPGCjWNcfIKpv3QrtvDHf5hl+3xo62Tgp7/+jkgJHCgAfhE X-Received: by 2002:a05:6808:3b3:: with SMTP id n19mr5560006oie.23.1575513092441; Wed, 04 Dec 2019 18:31:32 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1575513092; cv=none; d=google.com; s=arc-20160816; b=RLfqey3gLmVnQwkcdq8kDe2krzfCvPtIYDcBGv0KydgQPovOUcsQDldiBziMRVUpp+ 87z8ltJJw7r6VwBq5/inghRF0TNBnvOJphASHMaa/h2eyll//In7N+1GBs50ylDGZE5E QN+75Pt6oajqrYjBVwNIX53MXrM9EUGhBowCEzYStZxlPwD1zpetNoaho4cEk+dknSgK +UJ2Xh0IDXayXK9IsjH/05jpRTs7KUZq5SAKtCjebiUZWbL2fzrcScNXHWlbnfqpeo9I d5U+m6XQ4gK7gRttahAUMlzO4pJU21F7EzN7D5C/A5N9PBZGSovuv/T+n+GIS4pypLtN Xq8Q== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:content-transfer-encoding:mime-version :message-id:date:subject:cc:to:from:dkim-signature; bh=Y7Ee+dNHq54/7afYHD+UmtJjTH9smfXBulTry9R0FkI=; b=sIpfBbJvNOETr/kaD0pSog+FQlpa4rPs2y+Nia26Y5Y1avluQoKXfzRICnkVHYjvyu 9WFbm09luBm7Jdgxl3HiPuitTAHSX/KrEnvlDZAcg+cq1SdWq0QicfbeNK46/ieOcycn YmCMxVAGUwY4EccPvPk0yAaxHjI6hyu3gTqxvqD40RmrJfdXAkjd1tHx5MgTH0FUzK8H wW9AYAEC8f4uZtDI2CZ7+Hqlvu7teiq9CIPlXC7zV1LKhM1ZBs+Ku3gY2owz2yY644gd 6t9YzHg5KHyJhbiz7yIuscVCbkjsxeDHDSlPKO0btZkiv4Hmj7vQ2OALQOnacKNKLfqi 0DTQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@chromium.org header.s=google header.b=Thn+k6tk; spf=pass (google.com: best guess record for domain of linux-bluetooth-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-bluetooth-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=chromium.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id x32si4303721otb.24.2019.12.04.18.31.03; Wed, 04 Dec 2019 18:31:32 -0800 (PST) Received-SPF: pass (google.com: best guess record for domain of linux-bluetooth-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=pass header.i=@chromium.org header.s=google header.b=Thn+k6tk; spf=pass (google.com: best guess record for domain of linux-bluetooth-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-bluetooth-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=chromium.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728490AbfLECbB (ORCPT + 99 others); Wed, 4 Dec 2019 21:31:01 -0500 Received: from mail-pf1-f194.google.com ([209.85.210.194]:38554 "EHLO mail-pf1-f194.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728321AbfLECbB (ORCPT ); Wed, 4 Dec 2019 21:31:01 -0500 Received: by mail-pf1-f194.google.com with SMTP id x185so826710pfc.5 for ; Wed, 04 Dec 2019 18:31:00 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=chromium.org; s=google; h=from:to:cc:subject:date:message-id:mime-version :content-transfer-encoding; bh=Y7Ee+dNHq54/7afYHD+UmtJjTH9smfXBulTry9R0FkI=; b=Thn+k6tk3XAXYITVNqhSJ+4N0+izNtsGUvABmDpnSR1IwTELS0KwBKxwk7UQ7rn6Ty umt/AFtjgw5HG9B1Vw5DmFkBfGUkjk8NsxXQToq4x2kCW+9zWH0YSahqVuvqketU9cGI mOwVSN3cP20uwpDuB0kELiE7Rc/YkC5xwws+s= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:mime-version :content-transfer-encoding; bh=Y7Ee+dNHq54/7afYHD+UmtJjTH9smfXBulTry9R0FkI=; b=Er5bFbaI0FM1D3K2JILsc7xkbBugKWVSVA99dO//eVoyEsLePC4zRLxC02gtF3Qz00 JiKNRzaQDfHUdVxHizwgmi4fMyHz2s6O7aQaCfpR3hKdyln3Tmxyu/vC+K2sXkGbPzkW drCDSqosu7FS3ACQA1vd5KWgos8dwLY4jmpPD6Ss7PfP+x1JA94azfDRKnclaea+RyJG fuHmH4Xvg+Y6TxL4EsjNDmWOe//KbA+5yILie65Wt58C8Yb9JbPcvBbTK/c7LD5kvEH8 4AdJ8DHeQtThmP2JxqWKWPkBRLNfwop6dJ555Ul6V5/v8cklQfQzaueKfy5+pW3al44R MCuw== X-Gm-Message-State: APjAAAWGLv2c/OLXDzmrES53gnl4rJ/vZkC7ow6CHUx1JD4YaP+ieo+c y18xss1B2hBR6h+9Y/xWOAM6vA== X-Received: by 2002:a62:7b46:: with SMTP id w67mr6732042pfc.113.1575513060108; Wed, 04 Dec 2019 18:31:00 -0800 (PST) Received: from apsdesk.mtv.corp.google.com ([2620:15c:202:1:e09a:8d06:a338:aafb]) by smtp.gmail.com with ESMTPSA id x12sm9174425pfm.130.2019.12.04.18.30.58 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 04 Dec 2019 18:30:59 -0800 (PST) From: Abhishek Pandit-Subedi To: Dmitry Torokhov , =?UTF-8?q?Pali=20Roh=C3=A1r?= , linux-input@vger.kernel.org Cc: linux-bluetooth@vger.kernel.org, Luiz Augusto von Dentz , Abhishek Pandit-Subedi , Bjorn Helgaas , linux-kernel@vger.kernel.org, Thomas Gleixner , Greg Kroah-Hartman , Andrey Smirnov , Kirill Smelkov Subject: [PATCH v4] Input: uinput - Add UI_SET_PHYS_STR and UI_SET_UNIQ_STR Date: Wed, 4 Dec 2019 18:30:54 -0800 Message-Id: <20191204182942.v4.1.Ib53f70556ffe94d9a1903632ee9b0dc929f94557@changeid> X-Mailer: git-send-email 2.24.0.393.g34dc348eaf-goog MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Sender: linux-bluetooth-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-bluetooth@vger.kernel.org The ioctl definition for UI_SET_PHYS is ambiguous because it is defined with size = sizeof(char*) but is expected to be given a variable length string. Add a deprecation notice for UI_SET_PHYS and provide UI_SET_PHYS_STR(len) which expects a size from the user. Also support setting the uniq attribute of the input device. The uniq attribute is used as a unique identifier for the connected device. For example, uinput devices created by BlueZ will store the address of the connected device as the uniq property. Signed-off-by: Abhishek Pandit-Subedi --- Hi input maintainers, Here is an updated patch that refactors the ioctl handlers (properly allowing the size to be set from userspace). When calling the new ioctls, the call signature will look like this: ``` ioctl(fd, UI_SET_PHYS_STR(18), "00:11:22:33:44:55"); ``` I've tested this on a Chromebook running kernel v4.19 with a sample program compiled for both 32-bit (i.e. gcc -m32 test.c) and 64-bit. The final uinput device looks like this: ``` udevadm info -a -p /devices/virtual/input/input18 Udevadm info starts with the device specified by the devpath and then walks up the chain of parent devices. It prints for every device found, all possible attributes in the udev rules key format. A rule to match, can be composed by the attributes of the device and the attributes from one single parent device. looking at device '/devices/virtual/input/input18': KERNEL=="input18" SUBSYSTEM=="input" DRIVER=="" ATTR{inhibited}=="0" ATTR{name}=="Test" ATTR{phys}=="00:00:00:33:44:55" ATTR{properties}=="0" ATTR{uniq}=="00:11:22:00:00:00" ``` Changes in v4: - Added uinput_get_user_str Changes in v3: - Added UI_SET_PHYS_STR(len) and UI_SET_UNIQ_STR(len) and added deprecation notice for UI_SET_PHYS Changes in v2: - Added compat handling for UI_SET_UNIQ drivers/input/misc/uinput.c | 48 +++++++++++++++++++++++++------------ include/uapi/linux/uinput.h | 5 ++++ 2 files changed, 38 insertions(+), 15 deletions(-) diff --git a/drivers/input/misc/uinput.c b/drivers/input/misc/uinput.c index 84051f20b18a..2c3180370a02 100644 --- a/drivers/input/misc/uinput.c +++ b/drivers/input/misc/uinput.c @@ -20,6 +20,7 @@ */ #include #include +#include #include #include #include @@ -280,7 +281,7 @@ static int uinput_dev_flush(struct input_dev *dev, struct file *file) static void uinput_destroy_device(struct uinput_device *udev) { - const char *name, *phys; + const char *name, *phys, *uniq; struct input_dev *dev = udev->dev; enum uinput_state old_state = udev->state; @@ -289,6 +290,7 @@ static void uinput_destroy_device(struct uinput_device *udev) if (dev) { name = dev->name; phys = dev->phys; + uniq = dev->uniq; if (old_state == UIST_CREATED) { uinput_flush_requests(udev); input_unregister_device(dev); @@ -297,6 +299,7 @@ static void uinput_destroy_device(struct uinput_device *udev) } kfree(name); kfree(phys); + kfree(uniq); udev->dev = NULL; } } @@ -831,6 +834,24 @@ static int uinput_str_to_user(void __user *dest, const char *str, return ret ? -EFAULT : len; } +static int uinput_get_user_str(struct uinput_device *udev, const char **kptr, + const char *uptr, unsigned int size) +{ + char *tmp; + + if (udev->state == UIST_CREATED) + return -EINVAL; + + tmp = strndup_user(uptr, size); + if (IS_ERR(tmp)) + return PTR_ERR(tmp); + + kfree(*kptr); + *kptr = tmp; + + return 0; +} + static long uinput_ioctl_handler(struct file *file, unsigned int cmd, unsigned long arg, void __user *p) { @@ -839,7 +860,6 @@ static long uinput_ioctl_handler(struct file *file, unsigned int cmd, struct uinput_ff_upload ff_up; struct uinput_ff_erase ff_erase; struct uinput_request *req; - char *phys; const char *name; unsigned int size; @@ -916,19 +936,8 @@ static long uinput_ioctl_handler(struct file *file, unsigned int cmd, goto out; case UI_SET_PHYS: - if (udev->state == UIST_CREATED) { - retval = -EINVAL; - goto out; - } - - phys = strndup_user(p, 1024); - if (IS_ERR(phys)) { - retval = PTR_ERR(phys); - goto out; - } - - kfree(udev->dev->phys); - udev->dev->phys = phys; + pr_warn_once("uinput: UI_SET_PHYS is deprecated. Use UI_SET_PHYS_STR"); + retval = uinput_get_user_str(udev, &udev->dev->phys, p, 1024); goto out; case UI_BEGIN_FF_UPLOAD: @@ -1023,6 +1032,15 @@ static long uinput_ioctl_handler(struct file *file, unsigned int cmd, case UI_ABS_SETUP & ~IOCSIZE_MASK: retval = uinput_abs_setup(udev, p, size); goto out; + + case UI_SET_PHYS_STR(0): + retval = uinput_get_user_str(udev, &udev->dev->phys, p, size); + goto out; + + case UI_SET_UNIQ_STR(0): + retval = uinput_get_user_str(udev, &udev->dev->uniq, p, size); + goto out; + } retval = -EINVAL; diff --git a/include/uapi/linux/uinput.h b/include/uapi/linux/uinput.h index c9e677e3af1d..84d4fa142830 100644 --- a/include/uapi/linux/uinput.h +++ b/include/uapi/linux/uinput.h @@ -142,9 +142,14 @@ struct uinput_abs_setup { #define UI_SET_LEDBIT _IOW(UINPUT_IOCTL_BASE, 105, int) #define UI_SET_SNDBIT _IOW(UINPUT_IOCTL_BASE, 106, int) #define UI_SET_FFBIT _IOW(UINPUT_IOCTL_BASE, 107, int) + +/* DEPRECATED: Data size is ambiguous. Use UI_SET_PHYS_STR instead. */ #define UI_SET_PHYS _IOW(UINPUT_IOCTL_BASE, 108, char*) + #define UI_SET_SWBIT _IOW(UINPUT_IOCTL_BASE, 109, int) #define UI_SET_PROPBIT _IOW(UINPUT_IOCTL_BASE, 110, int) +#define UI_SET_PHYS_STR(len) _IOC(_IOC_WRITE, UINPUT_IOCTL_BASE, 111, len) +#define UI_SET_UNIQ_STR(len) _IOC(_IOC_WRITE, UINPUT_IOCTL_BASE, 112, len) #define UI_BEGIN_FF_UPLOAD _IOWR(UINPUT_IOCTL_BASE, 200, struct uinput_ff_upload) #define UI_END_FF_UPLOAD _IOW(UINPUT_IOCTL_BASE, 201, struct uinput_ff_upload) -- 2.24.0.393.g34dc348eaf-goog