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