Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F166337004
D51865.id.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
20 KB
Referenced Files
None
Subscribers
None
D51865.id.diff
View Options
diff --git a/lib/libusb/libusb.3 b/lib/libusb/libusb.3
--- a/lib/libusb/libusb.3
+++ b/lib/libusb/libusb.3
@@ -945,8 +945,25 @@
.Fn usb_get_driver_np
.Fn usb_detach_kernel_driver_np
.Fn usb_attach_kernel_driver_np
+.Sh CAPABILITY MODE
+Every
+.Nm
+context opens the file descriptors needed to reach the USB devices at
+.Fn libusb_init
+time and opens device nodes relative to a per-context directory
+descriptor using
+.Xr openat 2 .
+All operations on the context, including enumeration of hotplugged
+devices, therefore keep working after entering capability mode, see
+.Xr capsicum 4 .
+The file descriptors are limited with
+.Xr cap_rights_limit 2 .
+Initialise the context before calling
+.Xr cap_enter 2 .
.Sh SEE ALSO
+.Xr cap_enter 2 ,
.Xr libusb20 3 ,
+.Xr capsicum 4 ,
.Xr usb 4 ,
.Xr usbconfig 8 ,
.Xr usbdump 8
diff --git a/lib/libusb/libusb01.c b/lib/libusb/libusb01.c
--- a/lib/libusb/libusb01.c
+++ b/lib/libusb/libusb01.c
@@ -85,6 +85,13 @@
static struct libusb20_backend *usb_backend = NULL;
+/*
+ * The backend context lives for the lifetime of the process, because
+ * opened devices are dequeued from the backend and survive backend
+ * rescans. The libusb v0.1 API has no exit function anyway.
+ */
+static struct libusb20_be_ctx *usb_be_ctx = NULL;
+
struct usb_parse_state {
struct {
@@ -901,8 +908,14 @@
libusb20_be_free(usb_backend);
+ if (usb_be_ctx == NULL) {
+ usb_be_ctx = libusb20_be_ctx_alloc();
+ if (usb_be_ctx == NULL) {
+ return (-1);
+ }
+ }
/* do a new backend device search */
- usb_backend = libusb20_be_alloc_default();
+ usb_backend = libusb20_be_alloc_default(usb_be_ctx);
if (usb_backend == NULL) {
return (-1);
}
diff --git a/lib/libusb/libusb10.h b/lib/libusb/libusb10.h
--- a/lib/libusb/libusb10.h
+++ b/lib/libusb/libusb10.h
@@ -120,6 +120,9 @@
void *fd_cb_user_data;
libusb_log_cb log_cb;
int no_discovery;
+
+ /* backend context holding the USB file descriptors */
+ struct libusb20_be_ctx *be_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
@@ -302,6 +302,21 @@
return (LIBUSB_ERROR_OTHER);
}
+ /*
+ * The backend context acquires the file descriptors needed to
+ * reach the USB devices, so that the context keeps working
+ * after cap_enter(2) has been called.
+ */
+ ctx->be_ctx = libusb20_be_ctx_alloc();
+ if (ctx->be_ctx == NULL) {
+ close(ctx->event);
+ pthread_mutex_destroy(&ctx->ctx_lock);
+ pthread_mutex_destroy(&ctx->hotplug_lock);
+ pthread_cond_destroy(&ctx->ctx_cond);
+ free(ctx);
+ return (LIBUSB_ERROR_NO_MEM);
+ }
+
libusb10_add_pollfd(ctx, &ctx->ctx_poll, NULL, ctx->event, POLLIN);
pthread_mutex_lock(&default_context_lock);
@@ -353,6 +368,7 @@
libusb10_remove_pollfd(ctx, &ctx->ctx_poll);
close(ctx->event);
+ libusb20_be_ctx_free(ctx->be_ctx);
pthread_mutex_destroy(&ctx->ctx_lock);
pthread_mutex_destroy(&ctx->hotplug_lock);
pthread_cond_destroy(&ctx->ctx_cond);
@@ -384,7 +400,7 @@
if (list == NULL)
return (LIBUSB_ERROR_INVALID_PARAM);
- usb_backend = libusb20_be_alloc_default();
+ usb_backend = libusb20_be_alloc_default(ctx->be_ctx);
if (usb_backend == NULL)
return (LIBUSB_ERROR_NO_MEM);
diff --git a/lib/libusb/libusb20.h b/lib/libusb/libusb20.h
--- a/lib/libusb/libusb20.h
+++ b/lib/libusb/libusb20.h
@@ -177,6 +177,7 @@
struct libusb20_transfer;
struct libusb20_backend;
struct libusb20_backend_methods;
+struct libusb20_be_ctx;
struct libusb20_device;
struct libusb20_device_methods;
struct libusb20_config;
@@ -294,11 +295,13 @@
/* 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_freebsd(void);
-struct libusb20_backend *libusb20_be_alloc_linux(void);
-struct libusb20_backend *libusb20_be_alloc_ugen20(void);
+struct libusb20_backend *libusb20_be_alloc(const struct libusb20_backend_methods *methods, struct libusb20_be_ctx *pctx);
+struct libusb20_backend *libusb20_be_alloc_default(struct libusb20_be_ctx *pctx);
+struct libusb20_backend *libusb20_be_alloc_freebsd(struct libusb20_be_ctx *pctx);
+struct libusb20_backend *libusb20_be_alloc_linux(struct libusb20_be_ctx *pctx);
+struct libusb20_backend *libusb20_be_alloc_ugen20(struct libusb20_be_ctx *pctx);
+struct libusb20_be_ctx *libusb20_be_ctx_alloc(void);
+void libusb20_be_ctx_free(struct libusb20_be_ctx *pctx);
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
@@ -198,11 +198,15 @@
.Ft int
.Fn libusb20_be_remove_dev_quirk "struct libusb20_backend *pbe" "struct libusb20_quirk *pq"
.Ft struct libusb20_backend *
-.Fn libusb20_be_alloc_default "void"
+.Fn libusb20_be_alloc_default "struct libusb20_be_ctx *pctx"
.Ft struct libusb20_backend *
-.Fn libusb20_be_alloc_freebsd "void"
+.Fn libusb20_be_alloc_freebsd "struct libusb20_be_ctx *pctx"
.Ft struct libusb20_backend *
-.Fn libusb20_be_alloc_linux "void"
+.Fn libusb20_be_alloc_linux "struct libusb20_be_ctx *pctx"
+.Ft struct libusb20_be_ctx *
+.Fn libusb20_be_ctx_alloc "void"
+.Ft void
+.Fn libusb20_be_ctx_free "struct libusb20_be_ctx *pctx"
.Ft struct libusb20_device *
.Fn libusb20_be_device_foreach "struct libusb20_backend *pbe" "struct libusb20_device *pdev"
.Ft void
@@ -994,6 +998,31 @@
These functions are used to allocate a specific USB backend or the operating system
default USB backend.
Allocating a backend is a way to scan for currently present USB devices.
+The backend and the USB devices it enumerates borrow the given
+backend context, which holds the file descriptors used to reach the
+USB devices and must stay alive for as long as they are in use.
+If the
+.Fa pctx
+argument is NULL, the backend allocates its own context and releases
+it when the backend is freed.
+USB devices which have been dequeued from such a backend must not be
+used after the backend has been freed.
+.Pp
+.
+.Fn libusb20_be_ctx_alloc
+allocates a backend context, which opens and holds the file
+descriptors used to reach the USB devices.
+The context is immutable after allocation and may therefore be shared
+between threads, backends and devices without any locking.
+Sharing one context across multiple backend allocations allows
+devices to be enumerated and opened after the process has entered
+capability mode.
+.
+.Fn libusb20_be_ctx_free
+frees the given backend context.
+No backend or device allocated from the context may be used
+afterwards.
+This function is NULL safe.
.Pp
.
.Fn libusb20_be_device_foreach
@@ -1086,8 +1115,36 @@
.Bl -tag -width Pa
.It Pa /dev/usb
.El
+.Sh CAPABILITY MODE
+The backend context holds file descriptors for
+.Pa /dev/usbctl
+and the
+.Pa /dev/usb
+directory, and device nodes are opened relative to the directory
+descriptor using
+.Xr openat 2 .
+All backend operations, including enumeration of hotplugged devices,
+therefore keep working after entering capability mode, see
+.Xr capsicum 4 ,
+as long as the backend context was allocated before
+.Xr cap_enter 2
+was called.
+Applications which allocate more than one USB backend from capability
+mode must allocate a backend context with
+.Fn libusb20_be_ctx_alloc
+up front and pass it to every backend allocation.
+The file descriptors are limited with
+.Xr cap_rights_limit 2 ,
+and USB device file descriptors derived from the directory descriptor
+inherit the
+.Dv CAP_PREAD , CAP_PWRITE , CAP_EVENT
+and
+.Dv CAP_IOCTL
+rights.
.Sh SEE ALSO
+.Xr cap_enter 2 ,
.Xr libusb 3 ,
+.Xr capsicum 4 ,
.Xr usb 4 ,
.Xr usbconfig 8 ,
.Xr usbdump 8
diff --git a/lib/libusb/libusb20.c b/lib/libusb/libusb20.c
--- a/lib/libusb/libusb20.c
+++ b/lib/libusb/libusb20.c
@@ -1273,7 +1273,8 @@
}
struct libusb20_backend *
-libusb20_be_alloc(const struct libusb20_backend_methods *methods)
+libusb20_be_alloc(const struct libusb20_backend_methods *methods,
+ struct libusb20_be_ctx *pctx)
{
struct libusb20_backend *pbe;
@@ -1283,6 +1284,17 @@
}
memset(pbe, 0, sizeof(*pbe));
+ if (pctx == NULL) {
+ /* the backend owns its own context */
+ pctx = libusb20_be_ctx_alloc();
+ if (pctx == NULL) {
+ free(pbe);
+ return (NULL);
+ }
+ pbe->be_ctx_owner = 1;
+ }
+ pbe->be_ctx = pctx;
+
TAILQ_INIT(&(pbe->usb_devs));
pbe->methods = methods; /* set backend methods */
@@ -1295,29 +1307,29 @@
}
struct libusb20_backend *
-libusb20_be_alloc_linux(void)
+libusb20_be_alloc_linux(struct libusb20_be_ctx *pctx)
{
return (NULL);
}
struct libusb20_backend *
-libusb20_be_alloc_ugen20(void)
+libusb20_be_alloc_ugen20(struct libusb20_be_ctx *pctx)
{
- return (libusb20_be_alloc(&libusb20_ugen20_backend));
+ return (libusb20_be_alloc(&libusb20_ugen20_backend, pctx));
}
struct libusb20_backend *
-libusb20_be_alloc_default(void)
+libusb20_be_alloc_default(struct libusb20_be_ctx *pctx)
{
struct libusb20_backend *pbe;
#ifdef __linux__
- pbe = libusb20_be_alloc_linux();
+ pbe = libusb20_be_alloc_linux(pctx);
if (pbe) {
return (pbe);
}
#endif
- pbe = libusb20_be_alloc_ugen20();
+ pbe = libusb20_be_alloc_ugen20(pctx);
if (pbe) {
return (pbe);
}
@@ -1340,6 +1352,8 @@
if (pbe->methods->exit_backend) {
pbe->methods->exit_backend(pbe);
}
+ if (pbe->be_ctx_owner)
+ libusb20_be_ctx_free(pbe->be_ctx);
/* free backend */
free(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
@@ -43,6 +43,21 @@
uint32_t plugtime;
};
+/*
+ * The backend context holds the file descriptors needed to reach the
+ * USB devices. It is immutable after allocation, so it can be shared
+ * between threads, backends and devices without any locking. Sharing
+ * it between backend allocations keeps enumeration working after the
+ * process has entered capability mode, see capsicum(4).
+ *
+ * The context must stay alive for as long as any backend or device
+ * allocated from it is in use.
+ */
+struct libusb20_be_ctx {
+ int ctrl_fd; /* /dev/usbctl */
+ int usb_dfd; /* /dev/usb directory */
+};
+
/* 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);
@@ -144,6 +159,10 @@
struct libusb20_backend {
TAILQ_HEAD(, libusb20_device) usb_devs;
const struct libusb20_backend_methods *methods;
+
+ /* borrowed backend context, owned when "be_ctx_owner" is set */
+ struct libusb20_be_ctx *be_ctx;
+ uint8_t be_ctx_owner;
};
struct libusb20_transfer {
@@ -195,6 +214,9 @@
/* backend methods */
const struct libusb20_backend_methods *beMethods;
+ /* borrowed backend context */
+ struct libusb20_be_ctx *be_ctx;
+
/* list of USB transfers */
struct libusb20_transfer *pTransfer;
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
@@ -35,6 +35,7 @@
#include <string.h>
#include <unistd.h>
#include <time.h>
+#include <sys/capsicum.h>
#include <sys/queue.h>
#include <sys/types.h>
#endif
@@ -69,6 +70,67 @@
LIBUSB20_BACKEND(LIBUSB20_DECLARE, ugen20)
};
+struct libusb20_be_ctx *
+libusb20_be_ctx_alloc(void)
+{
+ cap_rights_t rights;
+ struct libusb20_be_ctx *pctx;
+ int fd;
+
+ pctx = malloc(sizeof(*pctx));
+ if (pctx == NULL)
+ return (NULL);
+
+ /*
+ * The context is immutable once this function returns, which
+ * makes it safe to share between threads without any locking.
+ * Open failures are tolerated, so that allocation also
+ * succeeds on systems without USB support.
+ */
+ fd = open("/dev/" USB_DEVICE_NAME, O_RDONLY | O_CLOEXEC);
+ if (fd > -1) {
+ cap_rights_init(&rights, CAP_READ, CAP_EVENT, CAP_IOCTL);
+ if (cap_rights_limit(fd, &rights) == -1 && errno != ENOSYS) {
+ close(fd);
+ fd = -1;
+ }
+ }
+ pctx->ctrl_fd = fd;
+
+ fd = open("/dev/" USB_DEVICE_DIR, O_DIRECTORY | O_PATH | O_CLOEXEC);
+ if (fd > -1) {
+ /*
+ * Device descriptors derived through openat(2)
+ * inherit these rights, so they must cover all
+ * operations performed on open devices, including by
+ * applications using libusb20_dev_get_fd().
+ */
+ cap_rights_init(&rights, CAP_LOOKUP, CAP_PREAD, CAP_PWRITE,
+ CAP_EVENT, CAP_IOCTL);
+ if (cap_rights_limit(fd, &rights) == -1 && errno != ENOSYS) {
+ close(fd);
+ fd = -1;
+ }
+ }
+ pctx->usb_dfd = fd;
+
+ return (pctx);
+}
+
+void
+libusb20_be_ctx_free(struct libusb20_be_ctx *pctx)
+{
+ if (pctx == NULL) {
+ /* be NULL safe */
+ return;
+ }
+ if (pctx->ctrl_fd > -1)
+ close(pctx->ctrl_fd);
+ if (pctx->usb_dfd > -1)
+ close(pctx->usb_dfd);
+ free(pctx);
+}
+
/* USB device specific */
static libusb20_get_config_desc_full_t ugen20_get_config_desc_full;
static libusb20_get_config_index_t ugen20_get_config_index;
@@ -130,6 +192,25 @@
return (temp);
}
+static int
+ugen20_open_dev(struct libusb20_be_ctx *pctx, int bus_num, int dev_addr,
+ int flag)
+{
+ char path[48];
+ int usb_dfd;
+
+ usb_dfd = pctx->usb_dfd;
+ if (usb_dfd > -1) {
+ snprintf(path, sizeof(path), "%u.%u.0", bus_num, dev_addr);
+ return (openat(usb_dfd, path, flag));
+ }
+
+ /* fall back when the /dev/usb directory is not available */
+ snprintf(path, sizeof(path), "/dev/" USB_GENERIC_NAME "%u.%u",
+ bus_num, dev_addr);
+ return (open(path, flag));
+}
+
static int
ugen20_enumerate(struct libusb20_device *pdev, const char *id)
{
@@ -138,17 +219,14 @@
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->be_ctx, pdev->bus_number,
+ pdev->device_address, O_RDWR);
if (f < 0) {
return (LIBUSB20_ERROR_OTHER);
}
@@ -289,7 +367,7 @@
memset(&state, 0, sizeof(state));
- state.f = open("/dev/" USB_DEVICE_NAME, O_RDONLY);
+ state.f = pbe->be_ctx->ctrl_fd;
if (state.f < 0)
return (LIBUSB20_ERROR_OTHER);
@@ -305,6 +383,12 @@
if (pdev == NULL) {
continue;
}
+ /*
+ * The device borrows the backend context, which must
+ * stay alive for as long as the device is in use.
+ */
+ pdev->be_ctx = pbe->be_ctx;
+
if (ugen20_enumerate(pdev, state.src + 4)) {
libusb20_dev_free(pdev);
continue;
@@ -312,7 +396,6 @@
/* put the device on the backend list */
libusb20_be_enqueue_device(pbe, pdev);
}
- close(state.f);
return (0); /* success */
}
@@ -379,24 +462,22 @@
ugen20_open_device(struct libusb20_device *pdev, uint16_t nMaxTransfer)
{
uint32_t plugtime;
- char buf[64];
int f;
int g;
int error;
- snprintf(buf, sizeof(buf), "/dev/" USB_GENERIC_NAME "%u.%u",
- pdev->bus_number, pdev->device_address);
-
/*
* We need two file handles, one for the control endpoint and one
* for BULK, INTERRUPT and ISOCHRONOUS transactions due to optimised
* kernel locking.
*/
- g = open(buf, O_RDWR);
+ g = ugen20_open_dev(pdev->be_ctx, pdev->bus_number,
+ pdev->device_address, O_RDWR);
if (g < 0) {
return (LIBUSB20_ERROR_NO_DEVICE);
}
- f = open(buf, O_RDWR);
+ f = ugen20_open_dev(pdev->be_ctx, pdev->bus_number,
+ pdev->device_address, O_RDWR);
if (f < 0) {
close(g);
return (LIBUSB20_ERROR_NO_DEVICE);
@@ -948,12 +1029,12 @@
}
static int
-ugen20_be_ioctl(uint32_t cmd, void *data)
+ugen20_be_ioctl(struct libusb20_be_ctx *pctx, uint32_t cmd, void *data)
{
int f;
int error;
- f = open("/dev/" USB_DEVICE_NAME, O_RDONLY);
+ f = pctx->ctrl_fd;
if (f < 0)
return (LIBUSB20_ERROR_OTHER);
error = ioctl(f, cmd, data);
@@ -964,7 +1045,6 @@
error = LIBUSB20_ERROR_OTHER;
}
}
- close(f);
return (error);
}
@@ -1007,7 +1087,7 @@
q.index = quirk_index;
- error = ugen20_be_ioctl(IOUSB(USB_DEV_QUIRK_GET), &q);
+ error = ugen20_be_ioctl(pbe->be_ctx, IOUSB(USB_DEV_QUIRK_GET), &q);
if (error) {
if (errno == EINVAL) {
@@ -1034,7 +1114,7 @@
q.index = quirk_index;
- error = ugen20_be_ioctl(IOUSB(USB_QUIRK_NAME_GET), &q);
+ error = ugen20_be_ioctl(pbe->be_ctx, IOUSB(USB_QUIRK_NAME_GET), &q);
if (error) {
if (errno == EINVAL) {
@@ -1061,7 +1141,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(pbe->be_ctx, IOUSB(USB_DEV_QUIRK_ADD), &q);
if (error) {
if (errno == ENOMEM) {
return (LIBUSB20_ERROR_NO_MEM);
@@ -1085,7 +1165,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(pbe->be_ctx, IOUSB(USB_DEV_QUIRK_REMOVE), &q);
if (error) {
if (errno == EINVAL) {
return (LIBUSB20_ERROR_NOT_FOUND);
@@ -1097,11 +1177,11 @@
static int
ugen20_root_set_template(struct libusb20_backend *pbe, int temp)
{
- return (ugen20_be_ioctl(IOUSB(USB_SET_TEMPLATE), &temp));
+ return (ugen20_be_ioctl(pbe->be_ctx, IOUSB(USB_SET_TEMPLATE), &temp));
}
static int
ugen20_root_get_template(struct libusb20_backend *pbe, int *ptemp)
{
- return (ugen20_be_ioctl(IOUSB(USB_GET_TEMPLATE), ptemp));
+ return (ugen20_be_ioctl(pbe->be_ctx, IOUSB(USB_GET_TEMPLATE), ptemp));
}
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_be_ctx);
pdev = NULL;
index = 0;
@@ -916,7 +916,7 @@
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_be_ctx);
struct libusb20_device *pdev = NULL;
struct LIBUSB20_DEVICE_DESC_DECODED *ddesc;
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);
+struct libusb20_be_ctx;
+extern struct libusb20_be_ctx *usb_be_ctx;
+
#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
@@ -32,8 +32,13 @@
#include <stdlib.h>
#include <sys/types.h>
+#include <sys/capsicum.h>
#include <sys/sysctl.h>
+#include <capsicum_helpers.h>
+
+#include <libusb20.h>
+
#include <dev/usb/usb_ioctl.h>
#include "usbtest.h"
@@ -45,6 +50,8 @@
static uint8_t usb_ts_select[USB_TS_MAX_LEVELS];
+struct libusb20_be_ctx *usb_be_ctx;
+
const char *indent[USB_TS_MAX_LEVELS] = {
" ",
" ",
@@ -805,7 +812,20 @@
int
main(int argc, char **argv)
{
+ /*
+ * The backend context acquires the descriptors needed to
+ * reach the USB devices before entering capability mode.
+ */
+ usb_be_ctx = libusb20_be_ctx_alloc();
+ if (usb_be_ctx == NULL)
+ err(1, "could not allocate USB backend context");
+
+ if (caph_enter() == -1)
+ err(1, "caph_enter() failed");
+
show_mode_select(1);
+ libusb20_be_ctx_free(usb_be_ctx);
+
return (0);
}
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
@@ -38,6 +38,9 @@
#include <errno.h>
#include <ctype.h>
#include <sys/param.h>
+#include <sys/capsicum.h>
+
+#include <capsicum_helpers.h>
#include <libusb20_desc.h>
#include <libusb20.h>
@@ -568,10 +571,17 @@
if (argc < 1) {
usage(EX_USAGE);
}
- pbe = libusb20_be_alloc_default();
+ pbe = libusb20_be_alloc_default(NULL);
if (pbe == NULL)
err(1, "could not access USB backend\n");
+ /*
+ * The backend has cached the descriptors needed to reach the
+ * USB devices, so the rest can run in capability mode.
+ */
+ if (caph_enter() == -1)
+ err(1, "caph_enter() failed");
+
while ((ch = getopt(argc, argv, "a:d:hi:lu:v")) != -1) {
switch (ch) {
case 'a':
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Fri, Aug 14, 12:02 AM (11 h, 43 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
36688732
Default Alt Text
D51865.id.diff (20 KB)
Attached To
Mode
D51865: libusb: capsicumize libusb
Attached
Detach File
Event Timeline
Log In to Comment