usbdevfs-drop-permissions.c 2.3 KB

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