Skip to content

Commit

Permalink
Interrupt blocking threads when changing altsetting/interface
Browse files Browse the repository at this point in the history
Disable endpoint before attempting to join threads that might be
blocked on read/write Raw Gadget ioctls.

Hopefully fixes AristoChen#9.
  • Loading branch information
xairy committed Oct 22, 2023
1 parent b0ccd74 commit 763c7bd
Show file tree
Hide file tree
Showing 4 changed files with 31 additions and 8 deletions.
10 changes: 7 additions & 3 deletions host-raw-gadget.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -107,8 +107,10 @@ int usb_raw_ep_read(int fd, struct usb_raw_ep_io *io) {
// Ignore failures caused by the test that halts endpoints.
return rv;
}
else if (errno == EBUSY)
else if (errno == EBUSY || errno == ESHUTDOWN) {
// Ignore failures caused by thread cancellation.
return rv;
}
perror("ioctl(USB_RAW_IOCTL_EP_READ)");
exit(EXIT_FAILURE);
}
Expand All @@ -122,8 +124,10 @@ int usb_raw_ep_write(int fd, struct usb_raw_ep_io *io) {
// Ignore failures caused by the test that halts endpoints.
return rv;
}
else if (errno == EBUSY)
else if (errno == EBUSY || errno == ESHUTDOWN) {
// Ignore failures caused by thread cancellation.
return rv;
}
perror("ioctl(USB_RAW_IOCTL_EP_WRITE)");
exit(EXIT_FAILURE);
}
Expand Down Expand Up @@ -315,7 +319,7 @@ void log_event(struct usb_raw_event *event) {
log_control_request((struct usb_ctrlrequest *)&event->data[0]);
break;
default:
printf("event: unknown, length: %u\n", event->length);
printf("event: unknown (%d), length: %u\n", (int)event->type, event->length);
}
}

Expand Down
2 changes: 1 addition & 1 deletion misc.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@

extern int verbose_level;
extern bool please_stop_ep0;
extern bool please_stop_eps;
extern volatile bool please_stop_eps;

extern bool injection_enabled;
extern std::string injection_file;
Expand Down
25 changes: 22 additions & 3 deletions proxy.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,16 @@ void *ep_loop_write(void *arg) {

if (ep.bEndpointAddress & USB_DIR_IN) {
int rv = usb_raw_ep_write(fd, (struct usb_raw_ep_io *)&io);
if (rv >= 0) {
if (rv < 0 && please_stop_eps) {
printf("EP%x(%s_%s): thread interrupted\n", ep.bEndpointAddress,
transfer_type.c_str(), dir.c_str());
break;
}
else if (rv < 0) {
perror("usb_raw_ep_write()");
exit(EXIT_FAILURE);
}
else {
printf("EP%x(%s_%s): wrote %d bytes to host\n", ep.bEndpointAddress,
transfer_type.c_str(), dir.c_str(), rv);
}
Expand Down Expand Up @@ -204,7 +213,16 @@ void *ep_loop_read(void *arg) {
io.inner.length = sizeof(io.data);

int rv = usb_raw_ep_read(fd, (struct usb_raw_ep_io *)&io);
if (rv >= 0) {
if (rv < 0 && please_stop_eps) {
printf("EP%x(%s_%s): thread interrupted\n", ep.bEndpointAddress,
transfer_type.c_str(), dir.c_str());
break;
}
else if (rv < 0) {
perror("usb_raw_ep_read()");
exit(EXIT_FAILURE);
}
else {
printf("EP%x(%s_%s): read %d bytes from host\n", ep.bEndpointAddress,
transfer_type.c_str(), dir.c_str(), rv);
io.inner.length = rv;
Expand Down Expand Up @@ -291,6 +309,8 @@ void terminate_eps(int fd, int config, int interface, int altsetting) {
for (int i = 0; i < alt->interface.bNumEndpoints; i++) {
struct raw_gadget_endpoint *ep = &alt->endpoints[i];

usb_raw_ep_disable(fd, ep->thread_info.ep_num);

if (ep->thread_read && pthread_join(ep->thread_read, NULL)) {
fprintf(stderr, "Error join thread_read\n");
}
Expand All @@ -300,7 +320,6 @@ void terminate_eps(int fd, int config, int interface, int altsetting) {
ep->thread_read = 0;
ep->thread_write = 0;

usb_raw_ep_disable(fd, ep->thread_info.ep_num);
ep->thread_info.ep_num = -1;

delete ep->thread_info.data_queue;
Expand Down
2 changes: 1 addition & 1 deletion usb-proxy.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

int verbose_level = 0;
bool please_stop_ep0 = false;
bool please_stop_eps = false;
volatile bool please_stop_eps = false; // Use volatile to mark as atomic.

bool injection_enabled = false;
std::string injection_file = "injection.json";
Expand Down

0 comments on commit 763c7bd

Please sign in to comment.