Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 11 Aug 2008 19:47:02 GMT
From:      Hans Petter Selasky <hselasky@FreeBSD.org>
To:        Perforce Change Reviews <perforce@FreeBSD.org>
Subject:   PERFORCE change 147174 for review
Message-ID:  <200808111947.m7BJl2w7065893@repoman.freebsd.org>

next in thread | raw e-mail | index | archive | help
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)



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200808111947.m7BJl2w7065893>