From owner-dev-commits-src-main@freebsd.org Wed Jan 20 20:10:48 2021 Return-Path: Delivered-To: dev-commits-src-main@mailman.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mailman.nyi.freebsd.org (Postfix) with ESMTP id 5AADE4D8A49; Wed, 20 Jan 2021 20:10:48 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256 client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "mxrelay.nyi.freebsd.org", Issuer "R3" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 4DLc8l4dl6z3mXs; Wed, 20 Jan 2021 20:10:47 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from gitrepo.freebsd.org (gitrepo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:5]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (Client did not present a certificate) by mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id AA6E31F513; Wed, 20 Jan 2021 20:10:46 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from gitrepo.freebsd.org ([127.0.1.44]) by gitrepo.freebsd.org (8.16.1/8.16.1) with ESMTP id 10KKAk3U045104; Wed, 20 Jan 2021 20:10:46 GMT (envelope-from git@gitrepo.freebsd.org) Received: (from git@localhost) by gitrepo.freebsd.org (8.16.1/8.16.1/Submit) id 10KKAklL045103; Wed, 20 Jan 2021 20:10:46 GMT (envelope-from git) Date: Wed, 20 Jan 2021 20:10:46 GMT Message-Id: <202101202010.10KKAklL045103@gitrepo.freebsd.org> To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org From: Vladimir Kondratyev Subject: git: 7a810290b8f6 - main - evdev: Make variable-size ioctls return actual length of copyouted data MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit X-Git-Committer: wulf X-Git-Repository: src X-Git-Refname: refs/heads/main X-Git-Reftype: branch X-Git-Commit: 7a810290b8f6c6885fdb9917cf590d46fa270a61 Auto-Submitted: auto-generated X-BeenThere: dev-commits-src-main@freebsd.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: Commit messages for the main branch of the src repository List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 20 Jan 2021 20:10:48 -0000 The branch main has been updated by wulf: URL: https://cgit.FreeBSD.org/src/commit/?id=7a810290b8f6c6885fdb9917cf590d46fa270a61 commit 7a810290b8f6c6885fdb9917cf590d46fa270a61 Author: Vladimir Kondratyev AuthorDate: 2021-01-20 20:10:07 +0000 Commit: Vladimir Kondratyev CommitDate: 2021-01-20 20:10:07 +0000 evdev: Make variable-size ioctls return actual length of copyouted data on success instead of 0 to match Linux. Imprivata binary depends on this. Submitted by: Shunchao Hu Reviewed by: wulf Differential revision: https://reviews.freebsd.org/D28218 --- sys/dev/evdev/cdev.c | 29 +++++++++++++++++++++++------ 1 file changed, 23 insertions(+), 6 deletions(-) diff --git a/sys/dev/evdev/cdev.c b/sys/dev/evdev/cdev.c index 91536c119fb4..66d00ad16aee 100644 --- a/sys/dev/evdev/cdev.c +++ b/sys/dev/evdev/cdev.c @@ -78,7 +78,8 @@ static d_kqfilter_t evdev_kqfilter; static int evdev_kqread(struct knote *kn, long hint); static void evdev_kqdetach(struct knote *kn); static void evdev_dtor(void *); -static int evdev_ioctl_eviocgbit(struct evdev_dev *, int, int, caddr_t); +static int evdev_ioctl_eviocgbit(struct evdev_dev *, int, int, caddr_t, + struct thread *); static void evdev_client_filter_queue(struct evdev_client *, uint16_t); static struct cdevsw evdev_cdevsw = { @@ -576,29 +577,38 @@ evdev_ioctl(struct cdev *dev, u_long cmd, caddr_t data, int fflag, /* evdev variable-length ioctls handling */ switch (IOCBASECMD(cmd)) { case EVIOCGNAME(0): - strlcpy(data, evdev->ev_name, len); + /* Linux evdev does not terminate truncated strings with 0 */ + limit = MIN(strlen(evdev->ev_name) + 1, len); + memcpy(data, evdev->ev_name, limit); + td->td_retval[0] = limit; return (0); case EVIOCGPHYS(0): if (evdev->ev_shortname[0] == 0) return (ENOENT); - strlcpy(data, evdev->ev_shortname, len); + limit = MIN(strlen(evdev->ev_shortname) + 1, len); + memcpy(data, evdev->ev_shortname, limit); + td->td_retval[0] = limit; return (0); case EVIOCGUNIQ(0): if (evdev->ev_serial[0] == 0) return (ENOENT); - strlcpy(data, evdev->ev_serial, len); + limit = MIN(strlen(evdev->ev_serial) + 1, len); + memcpy(data, evdev->ev_serial, limit); + td->td_retval[0] = limit; return (0); case EVIOCGPROP(0): limit = MIN(len, bitstr_size(INPUT_PROP_CNT)); memcpy(data, evdev->ev_prop_flags, limit); + td->td_retval[0] = limit; return (0); case EVIOCGMTSLOTS(0): + /* EVIOCGMTSLOTS always returns 0 on success */ if (evdev->ev_mt == NULL) return (EINVAL); if (len < sizeof(uint32_t)) @@ -620,6 +630,7 @@ evdev_ioctl(struct cdev *dev, u_long cmd, caddr_t data, int fflag, evdev_client_filter_queue(client, EV_KEY); memcpy(data, evdev->ev_key_states, limit); EVDEV_UNLOCK(evdev); + td->td_retval[0] = limit; return (0); case EVIOCGLED(0): @@ -628,6 +639,7 @@ evdev_ioctl(struct cdev *dev, u_long cmd, caddr_t data, int fflag, evdev_client_filter_queue(client, EV_LED); memcpy(data, evdev->ev_led_states, limit); EVDEV_UNLOCK(evdev); + td->td_retval[0] = limit; return (0); case EVIOCGSND(0): @@ -636,6 +648,7 @@ evdev_ioctl(struct cdev *dev, u_long cmd, caddr_t data, int fflag, evdev_client_filter_queue(client, EV_SND); memcpy(data, evdev->ev_snd_states, limit); EVDEV_UNLOCK(evdev); + td->td_retval[0] = limit; return (0); case EVIOCGSW(0): @@ -644,20 +657,22 @@ evdev_ioctl(struct cdev *dev, u_long cmd, caddr_t data, int fflag, evdev_client_filter_queue(client, EV_SW); memcpy(data, evdev->ev_sw_states, limit); EVDEV_UNLOCK(evdev); + td->td_retval[0] = limit; return (0); case EVIOCGBIT(0, 0) ... EVIOCGBIT(EV_MAX, 0): type_num = IOCBASECMD(cmd) - EVIOCGBIT(0, 0); debugf(client, "EVIOCGBIT(%d): data=%p, len=%d", type_num, data, len); - return (evdev_ioctl_eviocgbit(evdev, type_num, len, data)); + return (evdev_ioctl_eviocgbit(evdev, type_num, len, data, td)); } return (EINVAL); } static int -evdev_ioctl_eviocgbit(struct evdev_dev *evdev, int type, int len, caddr_t data) +evdev_ioctl_eviocgbit(struct evdev_dev *evdev, int type, int len, caddr_t data, + struct thread *td) { unsigned long *bitmap; int limit; @@ -701,6 +716,7 @@ evdev_ioctl_eviocgbit(struct evdev_dev *evdev, int type, int len, caddr_t data) * just fake it returning only zeros. */ bzero(data, len); + td->td_retval[0] = len; return (0); default: return (ENOTTY); @@ -715,6 +731,7 @@ evdev_ioctl_eviocgbit(struct evdev_dev *evdev, int type, int len, caddr_t data) limit = bitstr_size(limit); len = MIN(limit, len); memcpy(data, bitmap, len); + td->td_retval[0] = len; return (0); }