121 lines · c
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_PRIVILEGES15#define USBDEVFS_DROP_PRIVILEGES _IOW('U', 30, __u32)16#define USBDEVFS_CAP_DROP_PRIVILEGES 0x4017#endif18 19void 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 else27 printf("OK: privileges dropped!\n");28}29 30void 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 else38 printf("ERROR: reset failed! (%d - %s)\n",39 -res, strerror(-res));40}41 42void 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 else51 printf("ERROR claiming if %d (%d - %s)\n",52 i, -res, strerror(-res));53 }54}55 56int 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 present70 */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 all79 * 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 112exit:113 close(fd);114 return 0;115 116err:117 close(fd);118err_fd:119 return 1;120}121