Changing permissions of /dev/usb[n] to 664?
Craig Rodrigues
rodrigc at crodrigues.org
Mon Nov 29 22:48:43 PST 2004
On Sun, Nov 07, 2004 at 12:58:14PM -0700, M. Warner Losh wrote:
> This looks good, but we should audit all the ioctls to make sure the
> ones that modify anything have the proper checks to make sure the fd
> was opened for write.
OK. Here is another iteration of the patch.
It does the following:
- opens /dev/usb[n] as 664
- puts suser() permission checks in the following paths:
USB_REQUEST ioctl()
usbpoll()
usbread()
This is what a non-root user can and cannot do on /dev/usb[n]:
Allowed
=======
USB_DISCOVER
USB_DEVICEINFO
USB_DEVICESTATS
usbopen()
usbclose()
Forbidden
=========
USB_REQUEST
usbread()
usbpoll()
The result of this patch is that a non-root user can
run usbdevs without a problem.
I also have a small test program where I tried running
different ioctl's as non-root and this is the output I got:
Executing ioctl(): USB_REQUEST Operation not permitted
Executing ioctl(): USB_DISCOVER...OK
Executing ioctl(): USB_DEVICEINFO...OK
Executing ioctl(): USB_DEVICESTATS...OK
Comments?
--
Craig Rodrigues
rodrigc at crodrigues.org
-------------- next part --------------
--- usb.c.orig Mon Nov 29 23:27:20 2004
+++ usb.c Tue Nov 30 00:04:00 2004
@@ -320,11 +320,11 @@
/* The per controller devices (used for usb_discover) */
/* XXX This is redundant now, but old usbd's will want it */
sc->sc_usbdev = make_dev(&usb_cdevsw, device_get_unit(self), UID_ROOT,
- GID_OPERATOR, 0660, "usb%d", device_get_unit(self));
+ GID_OPERATOR, 0664, "usb%d", device_get_unit(self));
if (usb_ndevs++ == 0) {
/* The device spitting out events */
usb_dev = make_dev(&usb_cdevsw, USB_DEV_MINOR, UID_ROOT,
- GID_OPERATOR, 0660, "usb");
+ GID_OPERATOR, 0664, "usb");
}
#endif
@@ -515,13 +515,16 @@
int unit = USBUNIT(dev);
int s, error, n;
+ error = suser(curthread);
+ if (error)
+ return error;
+
if (unit != USB_DEV_MINOR)
return (ENODEV);
if (uio->uio_resid != sizeof(struct usb_event))
return (EINVAL);
- error = 0;
s = splusb();
for (;;) {
n = usb_get_next_event(&ue);
@@ -605,6 +608,10 @@
usbd_status err;
int error = 0;
+ error = suser(p);
+ if (error)
+ return error;
+
DPRINTF(("usbioctl: USB_REQUEST addr=%d len=%d\n", addr, len));
if (len < 0 || len > 32768)
return (EINVAL);
@@ -680,6 +687,10 @@
{
int revents, mask, s;
int unit = USBUNIT(dev);
+ int error = suser(p);
+
+ if (error)
+ return error;
if (unit == USB_DEV_MINOR) {
revents = 0;
-------------- next part --------------
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <dev/usb/usb.h>
#include <errno.h>
void
execute_ioctl(int fd, int cmd, void *arg, const char *name)
{
int e;
printf("Executing ioctl(): %s", name);
e = ioctl(fd, cmd, arg);
if (e == -1 ) {
printf(" %s\n", strerror(errno));
} else {
printf("...OK\n");
}
}
int
main(int argc, char *argv[])
{
struct usb_ctl_request ucr;
struct usb_device_stats uds;
struct usb_device_info udi;
int fd = open("/dev/usb1", O_RDONLY);
if (fd == -1 ) {
perror(":");
exit(1);
}
ucr.ucr_request.wLength[0] = 0x00;
ucr.ucr_request.wLength[1] = 0x80;
udi.udi_addr = 1;
execute_ioctl(fd, USB_REQUEST, &ucr, "USB_REQUEST");
execute_ioctl(fd, USB_DISCOVER, NULL, "USB_DISCOVER");
execute_ioctl(fd, USB_DEVICEINFO, &udi, "USB_DEVICEINFO");
execute_ioctl(fd, USB_DEVICESTATS, &uds, "USB_DEVICESTATS");
close(fd);
return 0;
}
More information about the freebsd-usb
mailing list