123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121 |
- #include <sys/ioctl.h>
- #include <sys/types.h>
- #include <sys/stat.h>
- #include <fcntl.h>
- #include <stdio.h>
- #include <errno.h>
- #include <string.h>
- #include <inttypes.h>
- #include <unistd.h>
- #include <linux/usbdevice_fs.h>
- /* For building without an updated set of headers */
- #ifndef USBDEVFS_DROP_PRIVILEGES
- #define USBDEVFS_DROP_PRIVILEGES _IOW('U', 30, __u32)
- #define USBDEVFS_CAP_DROP_PRIVILEGES 0x40
- #endif
- void drop_privileges(int fd, uint32_t mask)
- {
- int res;
- res = ioctl(fd, USBDEVFS_DROP_PRIVILEGES, &mask);
- if (res)
- printf("ERROR: USBDEVFS_DROP_PRIVILEGES returned %d\n", res);
- else
- printf("OK: privileges dropped!\n");
- }
- void reset_device(int fd)
- {
- int res;
- res = ioctl(fd, USBDEVFS_RESET);
- if (!res)
- printf("OK: USBDEVFS_RESET succeeded\n");
- else
- printf("ERROR: reset failed! (%d - %s)\n",
- -res, strerror(-res));
- }
- void claim_some_intf(int fd)
- {
- int i, res;
- for (i = 0; i < 4; i++) {
- res = ioctl(fd, USBDEVFS_CLAIMINTERFACE, &i);
- if (!res)
- printf("OK: claimed if %d\n", i);
- else
- printf("ERROR claiming if %d (%d - %s)\n",
- i, -res, strerror(-res));
- }
- }
- int main(int argc, char *argv[])
- {
- uint32_t mask, caps;
- int c, fd;
- fd = open(argv[1], O_RDWR);
- if (fd < 0) {
- printf("Failed to open file\n");
- goto err_fd;
- }
- /*
- * check if dropping privileges is supported,
- * bail on systems where the capability is not present
- */
- ioctl(fd, USBDEVFS_GET_CAPABILITIES, &caps);
- if (!(caps & USBDEVFS_CAP_DROP_PRIVILEGES)) {
- printf("DROP_PRIVILEGES not supported\n");
- goto err;
- }
- /*
- * Drop privileges but keep the ability to claim all
- * free interfaces (i.e., those not used by kernel drivers)
- */
- drop_privileges(fd, -1U);
- printf("Available options:\n"
- "[0] Exit now\n"
- "[1] Reset device. Should fail if device is in use\n"
- "[2] Claim 4 interfaces. Should succeed where not in use\n"
- "[3] Narrow interface permission mask\n"
- "Which option shall I run?: ");
- while (scanf("%d", &c) == 1) {
- switch (c) {
- case 0:
- goto exit;
- case 1:
- reset_device(fd);
- break;
- case 2:
- claim_some_intf(fd);
- break;
- case 3:
- printf("Insert new mask: ");
- scanf("%x", &mask);
- drop_privileges(fd, mask);
- break;
- default:
- printf("I don't recognize that\n");
- }
- printf("Which test shall I run next?: ");
- }
- exit:
- close(fd);
- return 0;
- err:
- close(fd);
- err_fd:
- return 1;
- }
|