1 #include <sys/ioctl.h> 2 #include <sys/types.h> 3 #include <sys/stat.h> 4 #include <fcntl.h> 5 #include <stdio.h> 6 #include <errno.h> 7 #include <string.h> 8 #include <inttypes.h> 9 #include <unistd.h> 10 11 #include <linux/usbdevice_fs.h> 12 13 /* For building without an updated set of headers */ 14 #ifndef USBDEVFS_DROP_PRIVILEGES 15 #define USBDEVFS_DROP_PRIVILEGES _IOW('U', 30, __u32) 16 #define USBDEVFS_CAP_DROP_PRIVILEGES 0x40 17 #endif 18 19 void drop_privileges(int fd, uint32_t mask) 20 { 21 int res; 22 23 res = ioctl(fd, USBDEVFS_DROP_PRIVILEGES, &mask); 24 if (res) 25 printf("ERROR: USBDEVFS_DROP_PRIVILEGES returned %d\n", res); 26 else 27 printf("OK: privileges dropped!\n"); 28 } 29 30 void reset_device(int fd) 31 { 32 int res; 33 34 res = ioctl(fd, USBDEVFS_RESET); 35 if (!res) 36 printf("OK: USBDEVFS_RESET succeeded\n"); 37 else 38 printf("ERROR: reset failed! (%d - %s)\n", 39 -res, strerror(-res)); 40 } 41 42 void claim_some_intf(int fd) 43 { 44 int i, res; 45 46 for (i = 0; i < 4; i++) { 47 res = ioctl(fd, USBDEVFS_CLAIMINTERFACE, &i); 48 if (!res) 49 printf("OK: claimed if %d\n", i); 50 else 51 printf("ERROR claiming if %d (%d - %s)\n", 52 i, -res, strerror(-res)); 53 } 54 } 55 56 int main(int argc, char *argv[]) 57 { 58 uint32_t mask, caps; 59 int c, fd; 60 61 fd = open(argv[1], O_RDWR); 62 if (fd < 0) { 63 printf("Failed to open file\n"); 64 goto err_fd; 65 } 66 67 /* 68 * check if dropping privileges is supported, 69 * bail on systems where the capability is not present 70 */ 71 ioctl(fd, USBDEVFS_GET_CAPABILITIES, &caps); 72 if (!(caps & USBDEVFS_CAP_DROP_PRIVILEGES)) { 73 printf("DROP_PRIVILEGES not supported\n"); 74 goto err; 75 } 76 77 /* 78 * Drop privileges but keep the ability to claim all 79 * free interfaces (i.e., those not used by kernel drivers) 80 */ 81 drop_privileges(fd, -1U); 82 83 printf("Available options:\n" 84 "[0] Exit now\n" 85 "[1] Reset device. Should fail if device is in use\n" 86 "[2] Claim 4 interfaces. Should succeed where not in use\n" 87 "[3] Narrow interface permission mask\n" 88 "Which option shall I run?: "); 89 90 while (scanf("%d", &c) == 1) { 91 switch (c) { 92 case 0: 93 goto exit; 94 case 1: 95 reset_device(fd); 96 break; 97 case 2: 98 claim_some_intf(fd); 99 break; 100 case 3: 101 printf("Insert new mask: "); 102 scanf("%x", &mask); 103 drop_privileges(fd, mask); 104 break; 105 default: 106 printf("I don't recognize that\n"); 107 } 108 109 printf("Which test shall I run next?: "); 110 } 111 112 exit: 113 close(fd); 114 return 0; 115 116 err: 117 close(fd); 118 err_fd: 119 return 1; 120 } 121