Blame view

Documentation/usb/usbdevfs-drop-permissions.c 2.33 KB
d883f52e1   Reilly Grant   usb: devio: Add i...
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
  #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
  ", res);
  	else
  		printf("OK: privileges dropped!
  ");
  }
  
  void reset_device(int fd)
  {
  	int res;
  
  	res = ioctl(fd, USBDEVFS_RESET);
  	if (!res)
  		printf("OK: USBDEVFS_RESET succeeded
  ");
  	else
  		printf("ERROR: reset failed! (%d - %s)
  ",
  		       -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
  ", i);
  		else
  			printf("ERROR claiming if %d (%d - %s)
  ",
  			       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
  ");
  		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
  ");
  		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:
  "
  		"[0] Exit now
  "
  		"[1] Reset device. Should fail if device is in use
  "
  		"[2] Claim 4 interfaces. Should succeed where not in use
  "
  		"[3] Narrow interface permission mask
  "
  		"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
  ");
  		}
  
  		printf("Which test shall I run next?: ");
  	}
  
  exit:
  	close(fd);
  	return 0;
  
  err:
  	close(fd);
  err_fd:
  	return 1;
  }