forked from Qortal/Brooklyn
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
120 lines
2.3 KiB
120 lines
2.3 KiB
#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; |
|
}
|
|
|