0001 #include <sys/ioctl.h>
0002 #include <sys/types.h>
0003 #include <sys/stat.h>
0004 #include <fcntl.h>
0005 #include <stdio.h>
0006 #include <errno.h>
0007 #include <string.h>
0008 #include <inttypes.h>
0009 #include <unistd.h>
0010
0011 #include <linux/usbdevice_fs.h>
0012
0013
0014 #ifndef USBDEVFS_DROP_PRIVILEGES
0015 #define USBDEVFS_DROP_PRIVILEGES _IOW('U', 30, __u32)
0016 #define USBDEVFS_CAP_DROP_PRIVILEGES 0x40
0017 #endif
0018
0019 void drop_privileges(int fd, uint32_t mask)
0020 {
0021 int res;
0022
0023 res = ioctl(fd, USBDEVFS_DROP_PRIVILEGES, &mask);
0024 if (res)
0025 printf("ERROR: USBDEVFS_DROP_PRIVILEGES returned %d\n", res);
0026 else
0027 printf("OK: privileges dropped!\n");
0028 }
0029
0030 void reset_device(int fd)
0031 {
0032 int res;
0033
0034 res = ioctl(fd, USBDEVFS_RESET);
0035 if (!res)
0036 printf("OK: USBDEVFS_RESET succeeded\n");
0037 else
0038 printf("ERROR: reset failed! (%d - %s)\n",
0039 -res, strerror(-res));
0040 }
0041
0042 void claim_some_intf(int fd)
0043 {
0044 int i, res;
0045
0046 for (i = 0; i < 4; i++) {
0047 res = ioctl(fd, USBDEVFS_CLAIMINTERFACE, &i);
0048 if (!res)
0049 printf("OK: claimed if %d\n", i);
0050 else
0051 printf("ERROR claiming if %d (%d - %s)\n",
0052 i, -res, strerror(-res));
0053 }
0054 }
0055
0056 int main(int argc, char *argv[])
0057 {
0058 uint32_t mask, caps;
0059 int c, fd;
0060
0061 fd = open(argv[1], O_RDWR);
0062 if (fd < 0) {
0063 printf("Failed to open file\n");
0064 goto err_fd;
0065 }
0066
0067
0068
0069
0070
0071 ioctl(fd, USBDEVFS_GET_CAPABILITIES, &caps);
0072 if (!(caps & USBDEVFS_CAP_DROP_PRIVILEGES)) {
0073 printf("DROP_PRIVILEGES not supported\n");
0074 goto err;
0075 }
0076
0077
0078
0079
0080
0081 drop_privileges(fd, -1U);
0082
0083 printf("Available options:\n"
0084 "[0] Exit now\n"
0085 "[1] Reset device. Should fail if device is in use\n"
0086 "[2] Claim 4 interfaces. Should succeed where not in use\n"
0087 "[3] Narrow interface permission mask\n"
0088 "Which option shall I run?: ");
0089
0090 while (scanf("%d", &c) == 1) {
0091 switch (c) {
0092 case 0:
0093 goto exit;
0094 case 1:
0095 reset_device(fd);
0096 break;
0097 case 2:
0098 claim_some_intf(fd);
0099 break;
0100 case 3:
0101 printf("Insert new mask: ");
0102 scanf("%x", &mask);
0103 drop_privileges(fd, mask);
0104 break;
0105 default:
0106 printf("I don't recognize that\n");
0107 }
0108
0109 printf("Which test shall I run next?: ");
0110 }
0111
0112 exit:
0113 close(fd);
0114 return 0;
0115
0116 err:
0117 close(fd);
0118 err_fd:
0119 return 1;
0120 }