diff --git a/lib/libusb/libusb.h b/lib/libusb/libusb.h --- a/lib/libusb/libusb.h +++ b/lib/libusb/libusb.h @@ -278,7 +278,8 @@ LIBUSB_OPTION_NO_DEVICE_DISCOVERY = 2, LIBUSB_OPTION_WEAK_AUTHORITY = 2, LIBUSB_OPTION_LOG_CB = 3, - LIBUSB_OPTION_MAX = 4, + LIBUSB_OPTION_CAPSICUMIZE = 4, + LIBUSB_OPTION_MAX = 5, }; /* libusb structures */ diff --git a/lib/libusb/libusb.3 b/lib/libusb/libusb.3 --- a/lib/libusb/libusb.3 +++ b/lib/libusb/libusb.3 @@ -121,6 +121,10 @@ .It Va LIBUSB_OPTION_LOG_CB customize default callback function with .Fa value . +.It Va LIBUSB_OPTION_CAPSICUMIZE +capsicumize libusb. +Note that it is users' responsibility to call +.Fn cap_enter . .El .Pp .Ft const char * diff --git a/lib/libusb/libusb01.c b/lib/libusb/libusb01.c --- a/lib/libusb/libusb01.c +++ b/lib/libusb/libusb01.c @@ -157,7 +157,7 @@ { int err; - err = libusb20_dev_open(dev->dev, 16 * 2); + err = libusb20_dev_open(dev->dev, 16 * 2, -1); if (err == LIBUSB20_ERROR_BUSY) { /* * Workaround buggy USB applications which open the USB @@ -902,7 +902,7 @@ libusb20_be_free(usb_backend); /* do a new backend device search */ - usb_backend = libusb20_be_alloc_default(); + usb_backend = libusb20_be_alloc_default(-1, -1); if (usb_backend == NULL) { return (-1); } @@ -950,7 +950,7 @@ udev->dev = pdev; pdev->privLuData = udev; - err = libusb20_dev_open(pdev, 0); + err = libusb20_dev_open(pdev, 0, -1); if (err == 0) { /* XXX get all config descriptors by default */ usb_fetch_and_parse_descriptors((void *)pdev); diff --git a/lib/libusb/libusb10.h b/lib/libusb/libusb10.h --- a/lib/libusb/libusb10.h +++ b/lib/libusb/libusb10.h @@ -91,6 +91,11 @@ usb_event_netlink } usb_event_mode_t; +struct libusb_backend_context { + int usbd_fd; + int ctrl_fd; +}; + struct libusb_context { int debug; int debug_fixed; @@ -120,6 +125,7 @@ void *fd_cb_user_data; libusb_log_cb log_cb; int no_discovery; + struct libusb_backend_context backend_ctx; }; struct libusb_device { diff --git a/lib/libusb/libusb10.c b/lib/libusb/libusb10.c --- a/lib/libusb/libusb10.c +++ b/lib/libusb/libusb10.c @@ -43,6 +43,7 @@ #include #include #include +#include #include #include #include @@ -382,7 +383,8 @@ if (list == NULL) return (LIBUSB_ERROR_INVALID_PARAM); - usb_backend = libusb20_be_alloc_default(); + usb_backend = libusb20_be_alloc_default(ctx->backend_ctx.ctrl_fd, + ctx->backend_ctx.usbd_fd); if (usb_backend == NULL) return (LIBUSB_ERROR_NO_MEM); @@ -644,7 +646,8 @@ if (dev == NULL) return (LIBUSB_ERROR_INVALID_PARAM); - err = libusb20_dev_open(pdev, LIBUSB_NUM_SW_ENDPOINTS); + err = libusb20_dev_open(pdev, LIBUSB_NUM_SW_ENDPOINTS, + ctx->backend_ctx.usbd_fd); if (err) { libusb_unref_device(dev); return (LIBUSB_ERROR_NO_MEM); @@ -746,11 +749,18 @@ libusb_get_configuration(struct libusb20_device *pdev, int *config) { struct libusb20_config *pconf; + struct libusb_device *dev; + struct libusb_context *ctx; if (pdev == NULL || config == NULL) return (LIBUSB_ERROR_INVALID_PARAM); - pconf = libusb20_dev_alloc_config(pdev, libusb20_dev_get_config_index(pdev)); + dev = libusb_get_device(pdev); + ctx = dev->ctx; + + pconf = libusb20_dev_alloc_config(pdev, + libusb20_dev_get_config_index(pdev, ctx->backend_ctx.usbd_fd), + ctx->backend_ctx.usbd_fd); if (pconf == NULL) return (LIBUSB_ERROR_NO_MEM); @@ -766,12 +776,14 @@ { struct libusb20_config *pconf; struct libusb_device *dev; + struct libusb_context *ctx; int err; uint8_t i; dev = libusb_get_device(pdev); if (dev == NULL) return (LIBUSB_ERROR_INVALID_PARAM); + ctx = dev->ctx; if (configuration < 1) { /* unconfigure */ @@ -780,7 +792,8 @@ for (i = 0; i != 255; i++) { uint8_t found; - pconf = libusb20_dev_alloc_config(pdev, i); + pconf = libusb20_dev_alloc_config(pdev, i, + ctx->backend_ctx.usbd_fd); if (pconf == NULL) return (LIBUSB_ERROR_INVALID_PARAM); found = (pconf->desc.bConfigurationValue @@ -1945,6 +1958,8 @@ enum libusb_log_level level; va_list args; libusb_log_cb callback; + const char *path; + cap_rights_t rights; ctx = GET_CONTEXT(ctx); va_start(args, option); @@ -1995,6 +2010,46 @@ */ case LIBUSB_OPTION_USE_USBDK: break; + case LIBUSB_OPTION_CAPSICUMIZE: + path = libusb20_be_get_path(LIBUSB20_PATH_CTRL); + if (path == NULL) { + err = LIBUSB_ERROR_INVALID_PARAM; + break; + } + ctx->backend_ctx.ctrl_fd = open(path, O_RDWR); + if (ctx->backend_ctx.ctrl_fd == -1) { + err = LIBUSB_ERROR_IO; + break; + } + path = libusb20_be_get_path(LIBUSB20_PATH_USBD_PATH); + if (path == NULL) { + close(ctx->backend_ctx.ctrl_fd); + err = LIBUSB_ERROR_INVALID_PARAM; + break; + } + ctx->backend_ctx.usbd_fd = open(path, O_RDONLY); + if (ctx->backend_ctx.usbd_fd == -1) { + close(ctx->backend_ctx.ctrl_fd); + err = LIBUSB_ERROR_IO; + break; + } + cap_rights_init(&rights, CAP_READ, CAP_WRITE, CAP_EVENT, + CAP_IOCTL, CAP_LOOKUP, CAP_PREAD, CAP_FSTATAT); + if (cap_rights_limit(ctx->backend_ctx.usbd_fd, &rights) == -1) { + close(ctx->backend_ctx.usbd_fd); + close(ctx->backend_ctx.ctrl_fd); + err = LIBUSB_ERROR_IO; + break; + } + cap_rights_init(&rights, CAP_READ, CAP_WRITE, CAP_EVENT, + CAP_IOCTL); + if (cap_rights_limit(ctx->backend_ctx.ctrl_fd, &rights) == -1) { + close(ctx->backend_ctx.usbd_fd); + close(ctx->backend_ctx.ctrl_fd); + err = LIBUSB_ERROR_IO; + break; + } + break; case LIBUSB_OPTION_MAX: default: err = LIBUSB_ERROR_INVALID_PARAM; diff --git a/lib/libusb/libusb10_desc.c b/lib/libusb/libusb10_desc.c --- a/lib/libusb/libusb10_desc.c +++ b/lib/libusb/libusb10_desc.c @@ -83,10 +83,13 @@ struct libusb_config_descriptor **config) { struct libusb20_device *pdev; + struct libusb_context *ctx; uint8_t config_index; pdev = dev->os_priv; - config_index = libusb20_dev_get_config_index(pdev); + ctx = dev->ctx; + config_index = libusb20_dev_get_config_index(pdev, + ctx->backend_ctx.usbd_fd); return (libusb_get_config_descriptor(dev, config_index, config)); } @@ -102,6 +105,7 @@ struct libusb_config_descriptor *pconfd; struct libusb_interface_descriptor *ifd; struct libusb_endpoint_descriptor *endd; + struct libusb_context *ctx; uint8_t *pextra; uint16_t nextra; uint8_t nif; @@ -117,7 +121,9 @@ *config = NULL; pdev = dev->os_priv; - pconf = libusb20_dev_alloc_config(pdev, config_index); + ctx = dev->ctx; + pconf = libusb20_dev_alloc_config(pdev, config_index, + ctx->backend_ctx.usbd_fd); if (pconf == NULL) return (LIBUSB_ERROR_NOT_FOUND); diff --git a/lib/libusb/libusb20.h b/lib/libusb/libusb20.h --- a/lib/libusb/libusb20.h +++ b/lib/libusb/libusb20.h @@ -173,6 +173,14 @@ LIBUSB20_POWER_RESUME, }; +/** \ingroup misc + * libusb20_be_get_path() values + */ +enum libusb20_path_type { + LIBUSB20_PATH_CTRL, + LIBUSB20_PATH_USBD_PATH, +}; + struct usb_device_info; struct libusb20_transfer; struct libusb20_backend; @@ -249,9 +257,9 @@ int libusb20_dev_set_config_index(struct libusb20_device *pdev, uint8_t configIndex); int libusb20_dev_get_debug(struct libusb20_device *pdev); int libusb20_dev_get_fd(struct libusb20_device *pdev); -int libusb20_dev_get_stats(struct libusb20_device *pdev, struct libusb20_device_stats *pstat); +int libusb20_dev_get_stats(struct libusb20_device *pdev, struct libusb20_device_stats *pstat, int usb_dfd); int libusb20_dev_kernel_driver_active(struct libusb20_device *pdev, uint8_t iface_index); -int libusb20_dev_open(struct libusb20_device *pdev, uint16_t transfer_max); +int libusb20_dev_open(struct libusb20_device *pdev, uint16_t transfer_max, int usb_dfd); int libusb20_dev_process(struct libusb20_device *pdev); int libusb20_dev_request_sync(struct libusb20_device *pdev, struct LIBUSB20_CONTROL_SETUP_DECODED *setup, void *data, uint16_t *pactlen, uint32_t timeout, uint8_t flags); int libusb20_dev_req_string_sync(struct libusb20_device *pdev, uint8_t index, uint16_t langid, void *ptr, uint16_t len); @@ -267,7 +275,7 @@ int libusb20_dev_get_iface_desc(struct libusb20_device *pdev, uint8_t iface_index, char *buf, uint8_t len); struct LIBUSB20_DEVICE_DESC_DECODED *libusb20_dev_get_device_desc(struct libusb20_device *pdev); -struct libusb20_config *libusb20_dev_alloc_config(struct libusb20_device *pdev, uint8_t config_index); +struct libusb20_config *libusb20_dev_alloc_config(struct libusb20_device *pdev, uint8_t config_index, int usb_dfd); struct libusb20_device *libusb20_dev_alloc(void); uint8_t libusb20_dev_get_address(struct libusb20_device *pdev); uint8_t libusb20_dev_get_parent_address(struct libusb20_device *pdev); @@ -275,27 +283,28 @@ uint8_t libusb20_dev_get_bus_number(struct libusb20_device *pdev); uint8_t libusb20_dev_get_mode(struct libusb20_device *pdev); uint8_t libusb20_dev_get_speed(struct libusb20_device *pdev); -uint8_t libusb20_dev_get_config_index(struct libusb20_device *pdev); +uint8_t libusb20_dev_get_config_index(struct libusb20_device *pdev, int usb_dfd); void libusb20_dev_free(struct libusb20_device *pdev); void libusb20_dev_set_debug(struct libusb20_device *pdev, int debug); void libusb20_dev_wait_process(struct libusb20_device *pdev, int timeout); /* USB global operations */ -int libusb20_be_get_dev_quirk(struct libusb20_backend *pbe, uint16_t index, struct libusb20_quirk *pq); -int libusb20_be_get_quirk_name(struct libusb20_backend *pbe, uint16_t index, struct libusb20_quirk *pq); -int libusb20_be_add_dev_quirk(struct libusb20_backend *pbe, struct libusb20_quirk *pq); -int libusb20_be_remove_dev_quirk(struct libusb20_backend *pbe, struct libusb20_quirk *pq); -int libusb20_be_get_template(struct libusb20_backend *pbe, int *ptemp); -int libusb20_be_set_template(struct libusb20_backend *pbe, int temp); +int libusb20_be_get_dev_quirk(struct libusb20_backend *pbe, uint16_t index, struct libusb20_quirk *pq, int cfd); +int libusb20_be_get_quirk_name(struct libusb20_backend *pbe, uint16_t index, struct libusb20_quirk *pq, int cfd); +int libusb20_be_add_dev_quirk(struct libusb20_backend *pbe, struct libusb20_quirk *pq, int cfd); +int libusb20_be_remove_dev_quirk(struct libusb20_backend *pbe, struct libusb20_quirk *pq, int cfd); +int libusb20_be_get_template(struct libusb20_backend *pbe, int *ptemp, int cfd); +int libusb20_be_set_template(struct libusb20_backend *pbe, int temp, int cfd); /* USB backend operations */ -struct libusb20_backend *libusb20_be_alloc(const struct libusb20_backend_methods *methods); -struct libusb20_backend *libusb20_be_alloc_default(void); +struct libusb20_backend *libusb20_be_alloc(const struct libusb20_backend_methods *methods, int cfd, int usb_dfd); +struct libusb20_backend *libusb20_be_alloc_default(int cfd, int usb_dfd); struct libusb20_backend *libusb20_be_alloc_freebsd(void); struct libusb20_backend *libusb20_be_alloc_linux(void); -struct libusb20_backend *libusb20_be_alloc_ugen20(void); +struct libusb20_backend *libusb20_be_alloc_ugen20(int cfd, int usb_dfd); +const char *libusb20_be_get_path(enum libusb20_path_type ptype); struct libusb20_device *libusb20_be_device_foreach(struct libusb20_backend *pbe, struct libusb20_device *pdev); void libusb20_be_dequeue_device(struct libusb20_backend *pbe, struct libusb20_device *pdev); void libusb20_be_enqueue_device(struct libusb20_backend *pbe, struct libusb20_device *pdev); diff --git a/lib/libusb/libusb20.3 b/lib/libusb/libusb20.3 --- a/lib/libusb/libusb20.3 +++ b/lib/libusb/libusb20.3 @@ -134,7 +134,7 @@ .Ft int .Fn libusb20_dev_kernel_driver_active "struct libusb20_device *pdev" "uint8_t iface_index" .Ft int -.Fn libusb20_dev_open "struct libusb20_device *pdev" "uint16_t transfer_max" +.Fn libusb20_dev_open "struct libusb20_device *pdev" "uint16_t transfer_max" "int usb_dfd" .Ft int .Fn libusb20_dev_process "struct libusb20_device *pdev" .Ft int @@ -158,7 +158,7 @@ .Ft struct LIBUSB20_DEVICE_DESC_DECODED * .Fn libusb20_dev_get_device_desc "struct libusb20_device *pdev" .Ft struct libusb20_config * -.Fn libusb20_dev_alloc_config "struct libusb20_device *pdev" "uint8_t config_index" +.Fn libusb20_dev_alloc_config "struct libusb20_device *pdev" "uint8_t config_index" "int usb_dfd" .Ft struct libusb20_device * .Fn libusb20_dev_alloc "void" .Ft uint8_t @@ -174,7 +174,7 @@ .Ft uint8_t .Fn libusb20_dev_get_speed "struct libusb20_device *pdev" .Ft uint8_t -.Fn libusb20_dev_get_config_index "struct libusb20_device *pdev" +.Fn libusb20_dev_get_config_index "struct libusb20_device *pdev" "int usb_dfd" .Ft void .Fn libusb20_dev_free "struct libusb20_device *pdev" .Ft void @@ -182,23 +182,25 @@ .Ft void .Fn libusb20_dev_wait_process "struct libusb20_device *pdev" "int timeout" .Ft int -.Fn libusb20_be_get_template "struct libusb20_backend *pbe" "int *ptemp" +.Fn libusb20_be_get_template "struct libusb20_backend *pbe" "int *ptemp" "int cfd" .Ft int -.Fn libusb20_be_set_template "struct libusb20_backend *pbe" "int temp" +.Fn libusb20_be_set_template "struct libusb20_backend *pbe" "int temp" "int cfd" .Ft int -.Fn libusb20_be_get_dev_quirk "struct libusb20_backend *pber" "uint16_t index" "struct libusb20_quirk *pq" +.Fn libusb20_be_get_dev_quirk "struct libusb20_backend *pber" "uint16_t index" "struct libusb20_quirk *pq" "int cfd" .Ft int -.Fn libusb20_be_get_quirk_name "struct libusb20_backend *pbe" "uint16_t index" "struct libusb20_quirk *pq" +.Fn libusb20_be_get_quirk_name "struct libusb20_backend *pbe" "uint16_t index" "struct libusb20_quirk *pq" "int cfd" .Ft int -.Fn libusb20_be_add_dev_quirk "struct libusb20_backend *pbe" "struct libusb20_quirk *pq" +.Fn libusb20_be_add_dev_quirk "struct libusb20_backend *pbe" "struct libusb20_quirk *pq" "int cfd" .Ft int -.Fn libusb20_be_remove_dev_quirk "struct libusb20_backend *pbe" "struct libusb20_quirk *pq" +.Fn libusb20_be_remove_dev_quirk "struct libusb20_backend *pbe" "struct libusb20_quirk *pq" "int cfd" .Ft struct libusb20_backend * -.Fn libusb20_be_alloc_default "void" +.Fn libusb20_be_alloc_default "int cfd" "int dfd" .Ft struct libusb20_backend * .Fn libusb20_be_alloc_freebsd "void" .Ft struct libusb20_backend * .Fn libusb20_be_alloc_linux "void" +.ft const char * +.Fn libusb20_be_get_path "enum libusb20_path_type ptype" .Ft struct libusb20_device * .Fn libusb20_be_device_foreach "struct libusb20_backend *pbe" "struct libusb20_device *pdev" .Ft void @@ -974,6 +976,10 @@ Allocating a backend is a way to scan for currently present USB devices. .Pp . +.Fn libusb20_be_get_path +is used to get the default path in a USB backend of the given type +.Pp +. .Fn libusb20_be_device_foreach is used to iterate USB devices present in a USB backend. . diff --git a/lib/libusb/libusb20.c b/lib/libusb/libusb20.c --- a/lib/libusb/libusb20.c +++ b/lib/libusb/libusb20.c @@ -658,7 +658,8 @@ } int -libusb20_dev_open(struct libusb20_device *pdev, uint16_t nTransferMax) +libusb20_dev_open(struct libusb20_device *pdev, uint16_t nTransferMax, + int usb_dfd) { struct libusb20_transfer *xfer; uint32_t size; @@ -691,7 +692,7 @@ /* set "nTransfer" early */ pdev->nTransfer = nTransferMax; - error = pdev->beMethods->open_device(pdev, nTransferMax); + error = pdev->beMethods->open_device(pdev, nTransferMax, usb_dfd); if (error) { if (pdev->pTransfer != NULL) { @@ -952,7 +953,8 @@ } struct libusb20_config * -libusb20_dev_alloc_config(struct libusb20_device *pdev, uint8_t configIndex) +libusb20_dev_alloc_config(struct libusb20_device *pdev, uint8_t configIndex, + int usb_dfd) { struct libusb20_config *retval = NULL; uint8_t *ptr; @@ -969,7 +971,7 @@ return (NULL); if (!pdev->is_opened) { - error = libusb20_dev_open(pdev, 0); + error = libusb20_dev_open(pdev, 0, usb_dfd); if (error) { return (NULL); } @@ -1014,14 +1016,14 @@ } uint8_t -libusb20_dev_get_config_index(struct libusb20_device *pdev) +libusb20_dev_get_config_index(struct libusb20_device *pdev, int usb_dfd) { int error; uint8_t cfg_index; uint8_t do_close; if (!pdev->is_opened) { - error = libusb20_dev_open(pdev, 0); + error = libusb20_dev_open(pdev, 0, usb_dfd); if (error == 0) { do_close = 1; } else { @@ -1055,13 +1057,14 @@ } int -libusb20_dev_get_stats(struct libusb20_device *pdev, struct libusb20_device_stats *pstats) +libusb20_dev_get_stats(struct libusb20_device *pdev, + struct libusb20_device_stats *pstats, int usb_dfd) { uint8_t do_close; int error; if (!pdev->is_opened) { - error = libusb20_dev_open(pdev, 0); + error = libusb20_dev_open(pdev, 0, usb_dfd); if (error == 0) { do_close = 1; } else { @@ -1198,48 +1201,48 @@ /* USB backend operations */ int -libusb20_be_get_dev_quirk(struct libusb20_backend *pbe, - uint16_t quirk_index, struct libusb20_quirk *pq) +libusb20_be_get_dev_quirk(struct libusb20_backend *pbe, uint16_t quirk_index, + struct libusb20_quirk *pq, int cfd) { - return (pbe->methods->root_get_dev_quirk(pbe, quirk_index, pq)); + return (pbe->methods->root_get_dev_quirk(pbe, quirk_index, pq, cfd)); } int -libusb20_be_get_quirk_name(struct libusb20_backend *pbe, - uint16_t quirk_index, struct libusb20_quirk *pq) +libusb20_be_get_quirk_name(struct libusb20_backend *pbe, uint16_t quirk_index, + struct libusb20_quirk *pq, int cfd) { - return (pbe->methods->root_get_quirk_name(pbe, quirk_index, pq)); + return (pbe->methods->root_get_quirk_name(pbe, quirk_index, pq, cfd)); } int libusb20_be_add_dev_quirk(struct libusb20_backend *pbe, - struct libusb20_quirk *pq) + struct libusb20_quirk *pq, int cfd) { - return (pbe->methods->root_add_dev_quirk(pbe, pq)); + return (pbe->methods->root_add_dev_quirk(pbe, pq, cfd)); } int libusb20_be_remove_dev_quirk(struct libusb20_backend *pbe, - struct libusb20_quirk *pq) + struct libusb20_quirk *pq, int cfd) { - return (pbe->methods->root_remove_dev_quirk(pbe, pq)); + return (pbe->methods->root_remove_dev_quirk(pbe, pq, cfd)); } int -libusb20_be_set_template(struct libusb20_backend *pbe, int temp) +libusb20_be_set_template(struct libusb20_backend *pbe, int temp, int cfd) { - return (pbe->methods->root_set_template(pbe, temp)); + return (pbe->methods->root_set_template(pbe, temp, cfd)); } int -libusb20_be_get_template(struct libusb20_backend *pbe, int *ptemp) +libusb20_be_get_template(struct libusb20_backend *pbe, int *ptemp, int cfd) { int temp; if (ptemp == NULL) ptemp = &temp; - return (pbe->methods->root_get_template(pbe, ptemp)); + return (pbe->methods->root_get_template(pbe, ptemp, cfd)); } struct libusb20_device * @@ -1256,7 +1259,8 @@ } struct libusb20_backend * -libusb20_be_alloc(const struct libusb20_backend_methods *methods) +libusb20_be_alloc(const struct libusb20_backend_methods *methods, int cfd, + int usb_dfd) { struct libusb20_backend *pbe; @@ -1272,7 +1276,7 @@ /* do the initial device scan */ if (pbe->methods->init_backend) { - pbe->methods->init_backend(pbe); + pbe->methods->init_backend(pbe, cfd, usb_dfd); } return (pbe); } @@ -1284,13 +1288,13 @@ } struct libusb20_backend * -libusb20_be_alloc_ugen20(void) +libusb20_be_alloc_ugen20(int cfd, int usb_dfd) { - return (libusb20_be_alloc(&libusb20_ugen20_backend)); + return (libusb20_be_alloc(&libusb20_ugen20_backend, cfd, usb_dfd)); } struct libusb20_backend * -libusb20_be_alloc_default(void) +libusb20_be_alloc_default(int cfd, int usb_dfd) { struct libusb20_backend *pbe; @@ -1300,13 +1304,19 @@ return (pbe); } #endif - pbe = libusb20_be_alloc_ugen20(); + pbe = libusb20_be_alloc_ugen20(cfd, usb_dfd); if (pbe) { return (pbe); } return (NULL); /* no backend found */ } +const char * +libusb20_be_get_path(enum libusb20_path_type ptype) +{ + return (libusb20_ugen20_backend).backend_get_path(ptype); +} + void libusb20_be_free(struct libusb20_backend *pbe) { diff --git a/lib/libusb/libusb20_int.h b/lib/libusb/libusb20_int.h --- a/lib/libusb/libusb20_int.h +++ b/lib/libusb/libusb20_int.h @@ -45,18 +45,19 @@ /* USB backend specific */ typedef const char *(libusb20_get_backend_name_t)(void); -typedef int (libusb20_root_get_dev_quirk_t)(struct libusb20_backend *pbe, uint16_t index, struct libusb20_quirk *pq); -typedef int (libusb20_root_get_quirk_name_t)(struct libusb20_backend *pbe, uint16_t index, struct libusb20_quirk *pq); -typedef int (libusb20_root_add_dev_quirk_t)(struct libusb20_backend *pbe, struct libusb20_quirk *pq); -typedef int (libusb20_root_remove_dev_quirk_t)(struct libusb20_backend *pbe, struct libusb20_quirk *pq); +typedef int (libusb20_root_get_dev_quirk_t)(struct libusb20_backend *pbe, uint16_t index, struct libusb20_quirk *pq, int cfd); +typedef int (libusb20_root_get_quirk_name_t)(struct libusb20_backend *pbe, uint16_t index, struct libusb20_quirk *pq, int cfd); +typedef int (libusb20_root_add_dev_quirk_t)(struct libusb20_backend *pbe, struct libusb20_quirk *pq, int cfd); +typedef int (libusb20_root_remove_dev_quirk_t)(struct libusb20_backend *pbe, struct libusb20_quirk *pq, int cfd); typedef int (libusb20_close_device_t)(struct libusb20_device *pdev); typedef int (libusb20_dev_get_info_t)(struct libusb20_device *pdev, struct usb_device_info *pinfo); typedef int (libusb20_dev_get_iface_desc_t)(struct libusb20_device *pdev, uint8_t iface_index, char *buf, uint8_t len); -typedef int (libusb20_init_backend_t)(struct libusb20_backend *pbe); -typedef int (libusb20_open_device_t)(struct libusb20_device *pdev, uint16_t transfer_count_max); +typedef int (libusb20_init_backend_t)(struct libusb20_backend *pbe, int cfd, int usb_dfd); +typedef int (libusb20_open_device_t)(struct libusb20_device *pdev, uint16_t transfer_count_max, int usb_dfd); typedef void (libusb20_exit_backend_t)(struct libusb20_backend *pbe); -typedef int (libusb20_root_set_template_t)(struct libusb20_backend *pbe, int temp); -typedef int (libusb20_root_get_template_t)(struct libusb20_backend *pbe, int *ptemp); +typedef int (libusb20_root_set_template_t)(struct libusb20_backend *pbe, int temp, int cfd); +typedef int (libusb20_root_get_template_t)(struct libusb20_backend *pbe, int *ptemp, int cfd); +typedef const char* (libusb20_backend_get_path_t)(enum libusb20_path_type ptype); #define LIBUSB20_DEFINE(n,field) \ libusb20_##field##_t *field; @@ -81,6 +82,7 @@ /* mandatory device methods */ \ m(n, open_device) \ m(n, close_device) \ + m(n, backend_get_path) \ struct libusb20_backend_methods { LIBUSB20_BACKEND(LIBUSB20_DEFINE,) diff --git a/lib/libusb/libusb20_ugen20.c b/lib/libusb/libusb20_ugen20.c --- a/lib/libusb/libusb20_ugen20.c +++ b/lib/libusb/libusb20_ugen20.c @@ -64,6 +64,7 @@ static libusb20_root_remove_dev_quirk_t ugen20_root_remove_dev_quirk; static libusb20_root_set_template_t ugen20_root_set_template; static libusb20_root_get_template_t ugen20_root_get_template; +static libusb20_backend_get_path_t ugen20_backend_get_path; const struct libusb20_backend_methods libusb20_ugen20_backend = { LIBUSB20_BACKEND(LIBUSB20_DECLARE, ugen20) @@ -130,24 +131,38 @@ } static int -ugen20_enumerate(struct libusb20_device *pdev, const char *id) +ugen20_open_dev(int bus_num, int dev_addr, int usb_dfd, int flag) +{ + char dev_path[16]; + char full_path[48]; + + snprintf(dev_path, sizeof(dev_path), "%u.%u.0", bus_num, dev_addr); + + if (usb_dfd == -1) { + snprintf(full_path, sizeof(full_path), + "/dev/" USB_GENERIC_NAME "%u.%u", bus_num, dev_addr); + return (open(full_path, flag)); + } + + return (openat(usb_dfd, dev_path, flag)); +} + +static int +ugen20_enumerate(struct libusb20_device *pdev, const char *id, int usb_dfd) { const char *tmp = id; struct usb_device_descriptor ddesc; struct usb_device_info devinfo; struct usb_device_port_path udpp; uint32_t plugtime; - char buf[64]; int f; int error; pdev->bus_number = ugen20_path_convert_one(&tmp); pdev->device_address = ugen20_path_convert_one(&tmp); - snprintf(buf, sizeof(buf), "/dev/" USB_GENERIC_NAME "%u.%u", - pdev->bus_number, pdev->device_address); - - f = open(buf, O_RDWR); + f = ugen20_open_dev(pdev->bus_number, pdev->device_address, usb_dfd, + O_RDWR); if (f < 0) { return (LIBUSB20_ERROR_OTHER); } @@ -281,14 +296,14 @@ } static int -ugen20_init_backend(struct libusb20_backend *pbe) +ugen20_init_backend(struct libusb20_backend *pbe, int cfd, int usb_dfd) { struct ugen20_urd_state state; struct libusb20_device *pdev; memset(&state, 0, sizeof(state)); - state.f = open("/dev/" USB_DEVICE_NAME, O_RDONLY); + state.f = cfd == -1 ? open("/dev/" USB_DEVICE_NAME, O_RDONLY) : cfd; if (state.f < 0) return (LIBUSB20_ERROR_OTHER); @@ -304,7 +319,7 @@ if (pdev == NULL) { continue; } - if (ugen20_enumerate(pdev, state.src + 4)) { + if (ugen20_enumerate(pdev, state.src + 4, usb_dfd)) { libusb20_dev_free(pdev); continue; } @@ -375,7 +390,8 @@ } static int -ugen20_open_device(struct libusb20_device *pdev, uint16_t nMaxTransfer) +ugen20_open_device(struct libusb20_device *pdev, uint16_t nMaxTransfer, + int usb_dfd) { uint32_t plugtime; char buf[64]; @@ -391,11 +407,13 @@ * for BULK, INTERRUPT and ISOCHRONOUS transactions due to optimised * kernel locking. */ - g = open(buf, O_RDWR); + g = ugen20_open_dev(pdev->bus_number, pdev->device_address, usb_dfd, + O_RDWR); if (g < 0) { return (LIBUSB20_ERROR_NO_DEVICE); } - f = open(buf, O_RDWR); + f = ugen20_open_dev(pdev->bus_number, pdev->device_address, usb_dfd, + O_RDWR); if (f < 0) { close(g); return (LIBUSB20_ERROR_NO_DEVICE); @@ -927,12 +945,12 @@ } static int -ugen20_be_ioctl(uint32_t cmd, void *data) +ugen20_be_ioctl(uint32_t cmd, void *data, int cfd) { int f; int error; - f = open("/dev/" USB_DEVICE_NAME, O_RDONLY); + f = cfd == -1 ? cfd : open("/dev/" USB_DEVICE_NAME, O_RDONLY); if (f < 0) return (LIBUSB20_ERROR_OTHER); error = ioctl(f, cmd, data); @@ -976,8 +994,8 @@ } static int -ugen20_root_get_dev_quirk(struct libusb20_backend *pbe, - uint16_t quirk_index, struct libusb20_quirk *pq) +ugen20_root_get_dev_quirk(struct libusb20_backend *pbe, uint16_t quirk_index, + struct libusb20_quirk *pq, int cfd) { struct usb_gen_quirk q; int error; @@ -986,7 +1004,7 @@ q.index = quirk_index; - error = ugen20_be_ioctl(IOUSB(USB_DEV_QUIRK_GET), &q); + error = ugen20_be_ioctl(IOUSB(USB_DEV_QUIRK_GET), &q, cfd); if (error) { if (errno == EINVAL) { @@ -1004,7 +1022,7 @@ static int ugen20_root_get_quirk_name(struct libusb20_backend *pbe, uint16_t quirk_index, - struct libusb20_quirk *pq) + struct libusb20_quirk *pq, int cfd) { struct usb_gen_quirk q; int error; @@ -1013,7 +1031,7 @@ q.index = quirk_index; - error = ugen20_be_ioctl(IOUSB(USB_QUIRK_NAME_GET), &q); + error = ugen20_be_ioctl(IOUSB(USB_QUIRK_NAME_GET), &q, cfd); if (error) { if (errno == EINVAL) { @@ -1027,7 +1045,7 @@ static int ugen20_root_add_dev_quirk(struct libusb20_backend *pbe, - struct libusb20_quirk *pq) + struct libusb20_quirk *pq, int cfd) { struct usb_gen_quirk q; int error; @@ -1040,7 +1058,7 @@ q.bcdDeviceHigh = pq->bcdDeviceHigh; strlcpy(q.quirkname, pq->quirkname, sizeof(q.quirkname)); - error = ugen20_be_ioctl(IOUSB(USB_DEV_QUIRK_ADD), &q); + error = ugen20_be_ioctl(IOUSB(USB_DEV_QUIRK_ADD), &q, cfd); if (error) { if (errno == ENOMEM) { return (LIBUSB20_ERROR_NO_MEM); @@ -1051,7 +1069,7 @@ static int ugen20_root_remove_dev_quirk(struct libusb20_backend *pbe, - struct libusb20_quirk *pq) + struct libusb20_quirk *pq, int cfd) { struct usb_gen_quirk q; int error; @@ -1064,7 +1082,7 @@ q.bcdDeviceHigh = pq->bcdDeviceHigh; strlcpy(q.quirkname, pq->quirkname, sizeof(q.quirkname)); - error = ugen20_be_ioctl(IOUSB(USB_DEV_QUIRK_REMOVE), &q); + error = ugen20_be_ioctl(IOUSB(USB_DEV_QUIRK_REMOVE), &q, cfd); if (error) { if (errno == EINVAL) { return (LIBUSB20_ERROR_NOT_FOUND); @@ -1074,13 +1092,24 @@ } static int -ugen20_root_set_template(struct libusb20_backend *pbe, int temp) +ugen20_root_set_template(struct libusb20_backend *pbe, int temp, int cfd) { - return (ugen20_be_ioctl(IOUSB(USB_SET_TEMPLATE), &temp)); + return (ugen20_be_ioctl(IOUSB(USB_SET_TEMPLATE), &temp, cfd)); } static int -ugen20_root_get_template(struct libusb20_backend *pbe, int *ptemp) +ugen20_root_get_template(struct libusb20_backend *pbe, int *ptemp, int cfd) +{ + return (ugen20_be_ioctl(IOUSB(USB_GET_TEMPLATE), ptemp, cfd)); +} + +static const char * +ugen20_backend_get_path(enum libusb20_path_type path_type) { - return (ugen20_be_ioctl(IOUSB(USB_GET_TEMPLATE), ptemp)); + switch (path_type) { + case LIBUSB20_PATH_CTRL: + return ("/dev/" USB_DEVICE_NAME); + case LIBUSB20_PATH_USBD_PATH: + return ("/dev/usb/"); + } } diff --git a/tools/tools/usbtest/usb_control_ep_test.c b/tools/tools/usbtest/usb_control_ep_test.c --- a/tools/tools/usbtest/usb_control_ep_test.c +++ b/tools/tools/usbtest/usb_control_ep_test.c @@ -90,7 +90,7 @@ printf("USB device not found\n"); return; } - error = libusb20_dev_open(pdev, 0); + error = libusb20_dev_open(pdev, 0, usbd_fd); if (error) { printf("Could not open USB device\n"); libusb20_dev_free(pdev); @@ -174,7 +174,7 @@ printf("USB device not found\n"); return; } - error = libusb20_dev_open(pdev, 0); + error = libusb20_dev_open(pdev, 0, usbd_fd); if (error) { printf("Could not open USB device\n"); libusb20_dev_free(pdev); @@ -256,7 +256,7 @@ printf("USB device not found\n"); return; } - error = libusb20_dev_open(pdev, 0); + error = libusb20_dev_open(pdev, 0, usbd_fd); if (error) { libusb20_dev_free(pdev); printf("Could not open USB device\n"); @@ -319,7 +319,7 @@ printf("USB device not found\n"); return; } - error = libusb20_dev_open(pdev, 0); + error = libusb20_dev_open(pdev, 0, usbd_fd); if (error) { printf("Could not open USB device\n"); libusb20_dev_free(pdev); @@ -407,7 +407,7 @@ printf("USB device not found\n"); return; } - error = libusb20_dev_open(pdev, 0); + error = libusb20_dev_open(pdev, 0, usbd_fd); if (error) { printf("Could not open USB device\n"); libusb20_dev_free(pdev); @@ -482,7 +482,7 @@ printf("USB device not found\n"); return; } - error = libusb20_dev_open(pdev, 1); + error = libusb20_dev_open(pdev, 1, usbd_fd); if (error) { printf("Could not open USB device\n"); libusb20_dev_free(pdev); @@ -623,7 +623,7 @@ "for VID=0x%04x PID=0x%04x\n", uaddr.vid, uaddr.pid); config = libusb20_dev_alloc_config(pdev, - libusb20_dev_get_config_index(pdev)); + libusb20_dev_get_config_index(pdev, usbd_fd), usbd_fd); if (config == NULL) { printf("Could not get configuration descriptor\n"); libusb20_dev_free(pdev); @@ -636,7 +636,7 @@ /* detach kernel driver */ libusb20_dev_detach_kernel_driver(pdev, n); - error = libusb20_dev_open(pdev, 0); + error = libusb20_dev_open(pdev, 0, usbd_fd); if (error) printf("ERROR could not open device\n"); diff --git a/tools/tools/usbtest/usb_modem_test.c b/tools/tools/usbtest/usb_modem_test.c --- a/tools/tools/usbtest/usb_modem_test.c +++ b/tools/tools/usbtest/usb_modem_test.c @@ -458,7 +458,7 @@ printf("Attaching to: %s @ iface %d\n", libusb20_dev_get_desc(pdev), iface); - if (libusb20_dev_open(pdev, 2)) { + if (libusb20_dev_open(pdev, 2, usbd_fd)) { printf("Could not open USB device\n"); libusb20_dev_free(pdev); return; diff --git a/tools/tools/usbtest/usb_msc_test.c b/tools/tools/usbtest/usb_msc_test.c --- a/tools/tools/usbtest/usb_msc_test.c +++ b/tools/tools/usbtest/usb_msc_test.c @@ -870,7 +870,7 @@ const char *ptr; top: - pbe = libusb20_be_alloc_default(); + pbe = libusb20_be_alloc_default(usb_ctrl_fd, usbd_fd); pdev = NULL; index = 0; @@ -916,7 +916,8 @@ struct libusb20_device * find_usb_device(struct uaddr uaddr) { - struct libusb20_backend *pbe = libusb20_be_alloc_default(); + struct libusb20_backend *pbe = libusb20_be_alloc_default(usb_ctrl_fd, + usbd_fd); struct libusb20_device *pdev = NULL; struct LIBUSB20_DEVICE_DESC_DECODED *ddesc; @@ -952,7 +953,6 @@ struct libusb20_interface *iface; struct libusb20_endpoint *ep; uint8_t x; - uint8_t y; uint8_t z; *in_ep = 0; @@ -960,15 +960,12 @@ *pif = 0; pcfg = libusb20_dev_alloc_config(pdev, - libusb20_dev_get_config_index(pdev)); + libusb20_dev_get_config_index(pdev, usbd_fd), usbd_fd); if (pcfg == NULL) return; for (x = 0; x != pcfg->num_interface; x++) { - - y = alt_setting; - iface = (pcfg->interface + x); if ((iface->desc.bInterfaceClass == class) && @@ -1035,7 +1032,7 @@ printf("Attaching to: %s @ iface %d\n", libusb20_dev_get_desc(pdev), iface); - if (libusb20_dev_open(pdev, 2)) { + if (libusb20_dev_open(pdev, 2, usbd_fd)) { printf("Could not open USB device\n"); libusb20_dev_free(pdev); return; diff --git a/tools/tools/usbtest/usbtest.h b/tools/tools/usbtest/usbtest.h --- a/tools/tools/usbtest/usbtest.h +++ b/tools/tools/usbtest/usbtest.h @@ -65,4 +65,7 @@ extern uint8_t usb_ts_show_menu(uint8_t, const char *, const char *,...); extern int32_t usb_ts_rand_noise(void); +extern int usb_ctrl_fd; +extern int usbd_fd; + #endif /* _USBTEST_H_ */ diff --git a/tools/tools/usbtest/usbtest.c b/tools/tools/usbtest/usbtest.c --- a/tools/tools/usbtest/usbtest.c +++ b/tools/tools/usbtest/usbtest.c @@ -23,27 +23,32 @@ * SUCH DAMAGE. */ -#include -#include -#include -#include -#include -#include -#include - #include +#include #include #include -#include "usbtest.h" - +#include +#include +#include +#include #include -#include #include -#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "usbtest.h" static uint8_t usb_ts_select[USB_TS_MAX_LEVELS]; +int usb_ctrl_fd = -1; +int usbd_fd = -1; const char *indent[USB_TS_MAX_LEVELS] = { " ", @@ -805,7 +810,46 @@ int main(int argc, char **argv) { + const char *path; + cap_rights_t rights; + + path = libusb20_be_get_path(LIBUSB20_PATH_CTRL); + if (path == NULL) + return (1); + usb_ctrl_fd = open(path, O_RDWR); + if (usb_ctrl_fd == -1) + return (1); + + path = libusb20_be_get_path(LIBUSB20_PATH_USBD_PATH); + if (path == NULL) { + close(usb_ctrl_fd); + return (1); + } + usbd_fd = open(path, O_RDONLY); + if (usbd_fd == -1) { + close(usb_ctrl_fd); + return (1); + } + cap_rights_init(&rights, CAP_READ, CAP_WRITE, CAP_EVENT, CAP_IOCTL, + CAP_LOOKUP, CAP_PREAD); + if (cap_rights_limit(usbd_fd, &rights) == -1) { + close(usbd_fd); + close(usb_ctrl_fd); + return (1); + } + cap_rights_init(&rights, CAP_READ, CAP_WRITE, CAP_EVENT, CAP_IOCTL); + if (cap_rights_limit(usb_ctrl_fd, &rights) == -1) { + close(usbd_fd); + close(usb_ctrl_fd); + return (1); + } + + cap_enter(); + show_mode_select(1); + close(usb_ctrl_fd); + close(usbd_fd); + return (0); } diff --git a/usr.sbin/usbconfig/dump.c b/usr.sbin/usbconfig/dump.c --- a/usr.sbin/usbconfig/dump.c +++ b/usr.sbin/usbconfig/dump.c @@ -62,6 +62,9 @@ #define DUMP2(n,type,field,...) dump_field(pdev, " ", #field, n->field); #define DUMP3(n,type,field,...) dump_field(pdev, " ", #field, n->field); +extern int usb_ctrl_fd; +extern int usbd_fd; + struct usb_product_info { STAILQ_ENTRY(usb_product_info) link; int id; @@ -551,11 +554,10 @@ else printf("%s, cfg=%u md=%s spd=%s pwr=%s (%umA)\n", desc ? desc : libusb20_dev_get_desc(pdev), - libusb20_dev_get_config_index(pdev), + libusb20_dev_get_config_index(pdev, usbd_fd), dump_mode(libusb20_dev_get_mode(pdev)), dump_speed(libusb20_dev_get_speed(pdev)), - dump_power_mode(libusb20_dev_get_power_mode(pdev)), - usage); + dump_power_mode(libusb20_dev_get_power_mode(pdev)), usage); free(desc); if (list_mode || !show_ifdrv) @@ -584,8 +586,7 @@ printf("\nDumping list of supported quirks:\n\n"); for (x = 0; x != 0xFFFF; x++) { - - error = libusb20_be_get_quirk_name(pbe, x, &q); + error = libusb20_be_get_quirk_name(pbe, x, &q, usb_ctrl_fd); if (error) { if (x == 0) { printf("No quirk names - maybe the USB quirk " @@ -611,8 +612,7 @@ printf("\nDumping current device quirks:\n\n"); for (x = 0; x != 0xFFFF; x++) { - - error = libusb20_be_get_dev_quirk(pbe, x, &q); + error = libusb20_be_get_dev_quirk(pbe, x, &q, usb_ctrl_fd); if (error) { if (x == 0) { printf("No device quirks - maybe the USB quirk " @@ -665,13 +665,12 @@ cfg_index = 0; cfg_index_end = ddesc->bNumConfigurations; } else { - cfg_index = libusb20_dev_get_config_index(pdev); + cfg_index = libusb20_dev_get_config_index(pdev, usbd_fd); cfg_index_end = cfg_index + 1; } for (; cfg_index != cfg_index_end; cfg_index++) { - - pcfg = libusb20_dev_alloc_config(pdev, cfg_index); + pcfg = libusb20_dev_alloc_config(pdev, cfg_index, usbd_fd); if (!pcfg) { continue; } @@ -738,7 +737,7 @@ { struct libusb20_device_stats st; - if (libusb20_dev_get_stats(pdev, &st)) { + if (libusb20_dev_get_stats(pdev, &st, usbd_fd)) { printf("{}\n"); } else { printf("{\n" diff --git a/usr.sbin/usbconfig/usbconfig.c b/usr.sbin/usbconfig/usbconfig.c --- a/usr.sbin/usbconfig/usbconfig.c +++ b/usr.sbin/usbconfig/usbconfig.c @@ -25,25 +25,33 @@ * SUCH DAMAGE. */ +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include #include +#include #include #include -#include -#include -#include #include +#include #include -#include -#include -#include -#include -#include - -#include -#include #include "dump.h" +extern int usb_ctrl_fd; +extern int usbd_fd; + +int usb_ctrl_fd = -1; +int usbd_fd = -1; + struct options { const char *quirkname; void *buffer; @@ -179,7 +187,7 @@ q.bcdDeviceHigh = hirev; strlcpy(q.quirkname, str, sizeof(q.quirkname)); - error = libusb20_be_remove_dev_quirk(pbe, &q); + error = libusb20_be_remove_dev_quirk(pbe, &q, usb_ctrl_fd); if (error) { fprintf(stderr, "Removing quirk '%s' failed, continuing.\n", str); } @@ -201,7 +209,7 @@ q.bcdDeviceHigh = hirev; strlcpy(q.quirkname, str, sizeof(q.quirkname)); - error = libusb20_be_add_dev_quirk(pbe, &q); + error = libusb20_be_add_dev_quirk(pbe, &q, usb_ctrl_fd); if (error) { fprintf(stderr, "Adding quirk '%s' failed, continuing.\n", str); } @@ -354,14 +362,14 @@ } if (opt->got_set_template) { opt->got_any--; - if (libusb20_be_set_template(pbe, opt->template)) { + if (libusb20_be_set_template(pbe, opt->template, usb_ctrl_fd)) { fprintf(stderr, "Setting USB template %u failed, " "continuing.\n", opt->template); } } if (opt->got_get_template) { opt->got_any--; - if (libusb20_be_get_template(pbe, &opt->template)) + if (libusb20_be_get_template(pbe, &opt->template, usb_ctrl_fd)) printf("USB template: \n"); else printf("USB template: %u\n", opt->template); @@ -407,7 +415,7 @@ opt->quirkname); } - if (libusb20_dev_open(pdev, 0)) { + if (libusb20_dev_open(pdev, 0, usbd_fd)) { err(1, "could not open device"); } if (opt->got_dump_string) { @@ -550,6 +558,8 @@ struct libusb20_backend *pbe; struct options *opt = &options; const char *ptr; + const char *path; + cap_rights_t rights; int unit; int addr; int n; @@ -559,7 +569,7 @@ if (argc < 1) { usage(EX_USAGE); } - pbe = libusb20_be_alloc_default(); + pbe = libusb20_be_alloc_default(usb_ctrl_fd, usbd_fd); if (pbe == NULL) err(1, "could not access USB backend\n"); @@ -623,6 +633,36 @@ argc -= optind; argv += optind; + path = libusb20_be_get_path(LIBUSB20_PATH_CTRL); + if (path == NULL) + return (1); + usb_ctrl_fd = open(path, O_RDWR); + if (usb_ctrl_fd == -1) + return (1); + path = libusb20_be_get_path(LIBUSB20_PATH_USBD_PATH); + if (path == NULL) + return (1); + usbd_fd = open(path, O_PATH | O_DIRECTORY); + if (usbd_fd == -1) { + close(usb_ctrl_fd); + return (1); + } + cap_rights_init(&rights, CAP_READ, CAP_WRITE, CAP_EVENT, CAP_IOCTL, + CAP_LOOKUP, CAP_PREAD); + if (cap_rights_limit(usbd_fd, &rights) == -1) { + close(usbd_fd); + close(usb_ctrl_fd); + return (1); + } + cap_rights_init(&rights, CAP_READ, CAP_WRITE, CAP_EVENT, CAP_IOCTL); + if (cap_rights_limit(usb_ctrl_fd, &rights) == -1) { + close(usbd_fd); + close(usb_ctrl_fd); + return (1); + } + + cap_enter(); + for (n = 0; n != argc; n++) { /* get number of additional options */ @@ -895,6 +935,10 @@ } /* release data */ libusb20_be_free(pbe); + if (usb_ctrl_fd != -1) + close(usb_ctrl_fd); + if (usbd_fd) + close(usbd_fd); return (0); }