From owner-p4-projects@FreeBSD.ORG Mon Aug 11 19:47:02 2008 Return-Path: Delivered-To: p4-projects@freebsd.org Received: by hub.freebsd.org (Postfix, from userid 32767) id B30481065673; Mon, 11 Aug 2008 19:47:02 +0000 (UTC) Delivered-To: perforce@FreeBSD.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 76B1B106564A for ; Mon, 11 Aug 2008 19:47:02 +0000 (UTC) (envelope-from hselasky@FreeBSD.org) Received: from repoman.freebsd.org (repoman.freebsd.org [IPv6:2001:4f8:fff6::29]) by mx1.freebsd.org (Postfix) with ESMTP id 642268FC1A for ; Mon, 11 Aug 2008 19:47:02 +0000 (UTC) (envelope-from hselasky@FreeBSD.org) Received: from repoman.freebsd.org (localhost [127.0.0.1]) by repoman.freebsd.org (8.14.2/8.14.2) with ESMTP id m7BJl2EH065895 for ; Mon, 11 Aug 2008 19:47:02 GMT (envelope-from hselasky@FreeBSD.org) Received: (from perforce@localhost) by repoman.freebsd.org (8.14.2/8.14.1/Submit) id m7BJl2w7065893 for perforce@freebsd.org; Mon, 11 Aug 2008 19:47:02 GMT (envelope-from hselasky@FreeBSD.org) Date: Mon, 11 Aug 2008 19:47:02 GMT Message-Id: <200808111947.m7BJl2w7065893@repoman.freebsd.org> X-Authentication-Warning: repoman.freebsd.org: perforce set sender to hselasky@FreeBSD.org using -f From: Hans Petter Selasky To: Perforce Change Reviews Cc: Subject: PERFORCE change 147174 for review X-BeenThere: p4-projects@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: p4 projects tree changes List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 11 Aug 2008 19:47:03 -0000 http://perforce.freebsd.org/chv.cgi?CH=147174 Change 147174 by hselasky@hselasky_laptop001 on 2008/08/11 19:46:17 Implement a set of IOCTLs that can change the permissions on the USB root, bus, device and interface. A permission is inactive when the mode is zero. Affected files ... .. //depot/projects/usb/src/sys/dev/usb2/core/usb2_core.h#16 edit .. //depot/projects/usb/src/sys/dev/usb2/core/usb2_dev.c#23 edit .. //depot/projects/usb/src/sys/dev/usb2/core/usb2_device.c#20 edit .. //depot/projects/usb/src/sys/dev/usb2/include/usb2_ioctl.h#11 edit Differences ... ==== //depot/projects/usb/src/sys/dev/usb2/core/usb2_core.h#16 (text+ko) ==== @@ -156,7 +156,6 @@ uint32_t uid; uint32_t gid; uint16_t mode; - uint8_t active; }; /* ==== //depot/projects/usb/src/sys/dev/usb2/core/usb2_dev.c#23 (text+ko) ==== @@ -111,7 +111,6 @@ .uid = UID_ROOT, .gid = GID_OPERATOR, .mode = 0660, - .active = 1, }; static struct cdevsw usb2_devsw = { @@ -238,7 +237,6 @@ iface->perm.uid = uid; iface->perm.gid = gid; iface->perm.mode = mode; - iface->perm.active = 1; mtx_unlock(&usb2_ref_lock); } @@ -246,6 +244,168 @@ } /*------------------------------------------------------------------------* + * usb2_set_perm + * + * This function will set the permissions at the given level. + * + * Return values: + * 0: Success. + * Else: Failure. + *------------------------------------------------------------------------*/ +static int +usb2_set_perm(struct usb2_dev_perm *psrc, uint8_t level) +{ + struct usb2_location loc; + struct usb2_perm *pdst; + uint32_t devloc; + int error; + + /* only super-user can set permissions */ + error = suser(curthread); + if (error) { + return (error); + } + if ((psrc->bus_index >= USB_BUS_MAX) || + (psrc->dev_index >= USB_DEV_MAX) || + (psrc->iface_index >= USB_IFACE_MAX)) { + return (EINVAL); + } + devloc = 0; + switch (level) { + case 3: + devloc += psrc->iface_index * + USB_DEV_MAX * USB_BUS_MAX; + /* FALLTHROUGH */ + case 2: + devloc += psrc->dev_index * + USB_BUS_MAX; + /* FALLTHROUGH */ + case 1: + devloc += psrc->bus_index; + break; + default: + break; + } + + if ((level > 0) && (level < 4)) { + error = usb2_ref_device(NULL, &loc, devloc); + if (error) { + return (error); + } + } + switch (level) { + case 3: + pdst = &loc.iface->perm; + break; + case 2: + pdst = &loc.udev->perm; + break; + case 1: + pdst = &loc.bus->perm; + break; + default: + pdst = &usb2_perm; + break; + } + + /* all permissions are protected by "usb2_ref_lock" */ + mtx_lock(&usb2_ref_lock); + pdst->uid = psrc->user_id; + pdst->gid = psrc->group_id; + pdst->mode = psrc->mode; + mtx_unlock(&usb2_ref_lock); + + if ((level > 0) && (level < 4)) { + usb2_unref_device(&loc); + } + return (0); /* success */ +} + +/*------------------------------------------------------------------------* + * usb2_get_perm + * + * This function will get the permissions at the given level. + * + * Return values: + * 0: Success. + * Else: Failure. + *------------------------------------------------------------------------*/ +static int +usb2_get_perm(struct usb2_dev_perm *pdst, uint8_t level) +{ + struct usb2_location loc; + struct usb2_perm *psrc; + uint32_t devloc; + int error; + + if ((pdst->bus_index >= USB_BUS_MAX) || + (pdst->dev_index >= USB_DEV_MAX) || + (pdst->iface_index >= USB_IFACE_MAX)) { + return (EINVAL); + } +retry: + devloc = 0; + switch (level) { + case 3: + devloc += pdst->iface_index * + USB_DEV_MAX * USB_BUS_MAX; + /* FALLTHROUGH */ + case 2: + devloc += pdst->dev_index * + USB_BUS_MAX; + /* FALLTHROUGH */ + case 1: + devloc += pdst->bus_index; + break; + default: + break; + } + + if ((level > 0) && (level < 4)) { + error = usb2_ref_device(NULL, &loc, devloc); + if (error) { + return (error); + } + } + switch (level) { + case 3: + psrc = &loc.iface->perm; + break; + case 2: + psrc = &loc.udev->perm; + break; + case 1: + psrc = &loc.bus->perm; + break; + default: + psrc = &usb2_perm; + break; + } + + /* all permissions are protected by "usb2_ref_lock" */ + mtx_lock(&usb2_ref_lock); + if (psrc->mode != 0) { + pdst->user_id = psrc->uid; + pdst->group_id = psrc->gid; + pdst->mode = psrc->mode; + error = 0; + } else { + error = EINVAL; + } + mtx_unlock(&usb2_ref_lock); + + if ((level > 0) && (level < 4)) { + usb2_unref_device(&loc); + if (error) { + /* try to find the permission one level down */ + level--; + goto retry; + } + } + return (error); +} + +/*------------------------------------------------------------------------* * usb2_match_perm * * This function will compare two permission structures and see if @@ -260,7 +420,7 @@ { uint16_t mode; - if (psystem->active && puser->active) { + if ((psystem->mode != 0) && (puser->mode != 0)) { /* continue */ } else { return (0); /* no access */ @@ -962,9 +1122,6 @@ perm.mode |= 0444; if (fflags & FWRITE) perm.mode |= 0222; - perm.active = 1; - - mtx_lock(udev->default_mtx); /* scan down the permissions tree */ if ((ep_index != 0) && iface && @@ -984,7 +1141,6 @@ /* no access */ err = EPERM; } - mtx_unlock(udev->default_mtx); return (err); } @@ -1108,16 +1264,44 @@ usb2_ioctl(struct cdev *dev, u_long cmd, caddr_t data, int fflag, struct thread *td) { + union { + struct usb2_read_dir *urd; + struct usb2_dev_perm *udp; + void *data; + } u; int err; + u.data = data; + switch (cmd) { - case USB_READ_DIR:{ - struct usb2_read_dir *urd = (void *)data; - - err = usb2_read_symlink(urd->urd_data, - urd->urd_startentry, urd->urd_maxlen); - break; - } + case USB_READ_DIR: + err = usb2_read_symlink(u.urd->urd_data, + u.urd->urd_startentry, u.urd->urd_maxlen); + break; + case USB_SET_IFACE_PERM: + err = usb2_set_perm(u.udp, 3); + break; + case USB_SET_DEVICE_PERM: + err = usb2_set_perm(u.udp, 2); + break; + case USB_SET_BUS_PERM: + err = usb2_set_perm(u.udp, 1); + break; + case USB_SET_ROOT_PERM: + err = usb2_set_perm(u.udp, 0); + break; + case USB_GET_IFACE_PERM: + err = usb2_get_perm(u.udp, 3); + break; + case USB_GET_DEVICE_PERM: + err = usb2_get_perm(u.udp, 2); + break; + case USB_GET_BUS_PERM: + err = usb2_get_perm(u.udp, 1); + break; + case USB_GET_ROOT_PERM: + err = usb2_get_perm(u.udp, 0); + break; default: err = ENOTTY; break; ==== //depot/projects/usb/src/sys/dev/usb2/core/usb2_device.c#20 (text+ko) ==== @@ -470,7 +470,7 @@ iface->idesc = NULL; iface->alt_index = 0; iface->parent_iface_index = USB_IFACE_INDEX_ANY; - iface->perm.active = 0; /* disable permissions */ + iface->perm.mode = 0; /* disable permissions */ iface++; } ==== //depot/projects/usb/src/sys/dev/usb2/include/usb2_ioctl.h#11 (text+ko) ==== @@ -180,6 +180,18 @@ uint8_t ep_index; }; +struct usb2_dev_perm { + /* Permissions */ + uint16_t user_id; + uint16_t group_id; + uint16_t mode; + + /* Device location */ + uint16_t bus_index; + uint16_t dev_index; + uint16_t iface_index; +}; + /* USB controller */ #define USB_REQUEST _IOWR('U', 1, struct usb2_ctl_request) #define USB_SETDEBUG _IOW ('U', 2, int) @@ -222,10 +234,18 @@ #define USB_IFACE_DRIVER_DETACH _IOW ('U', 125, int) #define USB_GET_PLUGTIME _IOR ('U', 126, uint32_t) #define USB_READ_DIR _IOW ('U', 127, struct usb2_read_dir) +#define USB_SET_ROOT_PERM _IOW ('U', 128, struct usb2_dev_perm) +#define USB_SET_BUS_PERM _IOW ('U', 129, struct usb2_dev_perm) +#define USB_SET_DEVICE_PERM _IOW ('U', 130, struct usb2_dev_perm) +#define USB_SET_IFACE_PERM _IOW ('U', 131, struct usb2_dev_perm) +#define USB_GET_ROOT_PERM _IOW ('U', 132, struct usb2_dev_perm) +#define USB_GET_BUS_PERM _IOW ('U', 133, struct usb2_dev_perm) +#define USB_GET_DEVICE_PERM _IOW ('U', 134, struct usb2_dev_perm) +#define USB_GET_IFACE_PERM _IOW ('U', 135, struct usb2_dev_perm) /* Modem device */ -#define USB_GET_CM_OVER_DATA _IOR ('U', 130, int) -#define USB_SET_CM_OVER_DATA _IOW ('U', 131, int) +#define USB_GET_CM_OVER_DATA _IOR ('U', 160, int) +#define USB_SET_CM_OVER_DATA _IOW ('U', 161, int) /* USB file system interface */ #define USB_FS_START _IOW ('U', 192, struct usb2_fs_start)