linux/Documentation/usb/usbdevfs-drop-permissions.c
<<
>>
Prefs
   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
  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        else
  27                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        else
  38                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                else
  51                        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 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
 112exit:
 113        close(fd);
 114        return 0;
 115
 116err:
 117        close(fd);
 118err_fd:
 119        return 1;
 120}
 121