Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
44 changes: 37 additions & 7 deletions src/platforms/rp2/src/lib/usb_cdc_driver.c
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@
#include "rp2_sys.h"

static NativeHandlerResult usb_cdc_driver_consume_mailbox(Context *ctx);
static void usb_cdc_send_error_reply(Context *ctx, term pid, term ref, AtomString reason_atom_str);

#define USB_CDC_BUF_SIZE 256
#define NO_REF 0
Expand Down Expand Up @@ -187,13 +188,32 @@ static Context *usb_cdc_driver_create_port(GlobalContext *global, term opts)
return NULL;
}

Context *ctx = context_new(global);

struct USBCDCData *cdc_data = malloc(sizeof(struct USBCDCData));
if (IS_NULL_PTR(cdc_data)) {
SMP_MUTEX_UNLOCK(s_open_lock);
fprintf(stderr, "Failed to allocate memory: %s:%i.\n", __FILE__, __LINE__);
AVM_ABORT();
return NULL;
}

#ifndef AVM_NO_SMP
cdc_data->reader_lock = smp_mutex_create();
if (IS_NULL_PTR(cdc_data->reader_lock)) {
free(cdc_data);
SMP_MUTEX_UNLOCK(s_open_lock);
fprintf(stderr, "Failed to allocate memory: %s:%i.\n", __FILE__, __LINE__);
return NULL;
}
#endif

Context *ctx = context_new(global);
if (IS_NULL_PTR(ctx)) {
#ifndef AVM_NO_SMP
smp_mutex_destroy(cdc_data->reader_lock);
#endif
free(cdc_data);
SMP_MUTEX_UNLOCK(s_open_lock);
fprintf(stderr, "Failed to allocate memory: %s:%i.\n", __FILE__, __LINE__);
return NULL;
}

queue_init(&cdc_data->rxqueue, sizeof(uint32_t), EVENT_QUEUE_LEN);
Expand All @@ -204,10 +224,6 @@ static Context *usb_cdc_driver_create_port(GlobalContext *global, term opts)
cdc_data->reader_ref_ticks = 0;
cdc_data->itf = 0;

#ifndef AVM_NO_SMP
cdc_data->reader_lock = smp_mutex_create();
#endif

// TinyUSB should already be initialized by Pico SDK when
// pico_enable_stdio_usb is set. For distribution use, stdio_usb
// should be disabled and this driver takes over the CDC interface.
Expand Down Expand Up @@ -295,6 +311,10 @@ static void usb_cdc_driver_do_cancel_read(Context *ctx, GenMessage gen_message)
bool clear_unconditionally = term_is_atom(req);
uint64_t target_ref_ticks = 0;
if (!clear_unconditionally) {
if (UNLIKELY(term_get_tuple_arity(req) < 2)) {
usb_cdc_send_error_reply(ctx, pid, ref, ATOM_STR("\x6", "badarg"));
return;
}
target_ref_ticks = term_to_ref_ticks(term_get_tuple_element(req, 1));
}

Expand Down Expand Up @@ -333,6 +353,10 @@ static void usb_cdc_driver_do_write(Context *ctx, GenMessage gen_message)
term pid = gen_message.pid;
term ref = gen_message.ref;

if (UNLIKELY(!term_is_tuple(msg) || term_get_tuple_arity(msg) < 2)) {
usb_cdc_send_error_reply(ctx, pid, ref, ATOM_STR("\x6", "badarg"));
return;
}
term data = term_get_tuple_element(msg, 1);
int local_pid = term_to_local_process_id(pid);

Expand Down Expand Up @@ -530,6 +554,12 @@ static NativeHandlerResult usb_cdc_driver_consume_mailbox(Context *ctx)
}

term req = gen_message.req;
// req is unvalidated: an immediate would be misread as a boxed tuple pointer below.
if (UNLIKELY(!term_is_atom(req) && !(term_is_tuple(req) && term_get_tuple_arity(req) >= 1))) {
usb_cdc_send_error_reply(ctx, gen_message.pid, gen_message.ref, ATOM_STR("\xF", "unknown_command"));
mailbox_remove_message(&ctx->mailbox, &ctx->heap);
continue;
}
term cmd_term = term_is_atom(req) ? req : term_get_tuple_element(req, 0);

enum usb_cdc_cmd cmd = interop_atom_term_select_int(cmd_table, cmd_term, ctx->global);
Expand Down
14 changes: 14 additions & 0 deletions src/platforms/stm32/src/lib/usb_cdc_driver.c
Original file line number Diff line number Diff line change
Expand Up @@ -252,6 +252,10 @@ static void usb_cdc_driver_do_cancel_read(Context *ctx, GenMessage gen_message)
bool clear_unconditionally = term_is_atom(req);
uint64_t target_ref_ticks = 0;
if (!clear_unconditionally) {
if (UNLIKELY(term_get_tuple_arity(req) < 2)) {
usb_cdc_send_error_reply(ctx, pid, ref, ATOM_STR("\x6", "badarg"));
return;
}
target_ref_ticks = term_to_ref_ticks(term_get_tuple_element(req, 1));
}

Expand All @@ -276,6 +280,10 @@ static void usb_cdc_driver_do_write(Context *ctx, GenMessage gen_message)
term pid = gen_message.pid;
term ref = gen_message.ref;

if (UNLIKELY(!term_is_tuple(msg) || term_get_tuple_arity(msg) < 2)) {
usb_cdc_send_error_reply(ctx, pid, ref, ATOM_STR("\x6", "badarg"));
return;
}
term data = term_get_tuple_element(msg, 1);
int local_pid = term_to_local_process_id(pid);

Expand Down Expand Up @@ -458,6 +466,12 @@ static NativeHandlerResult usb_cdc_driver_consume_mailbox(Context *ctx)
}

term req = gen_message.req;
// req is unvalidated: an immediate would be misread as a boxed tuple pointer below.
if (UNLIKELY(!term_is_atom(req) && !(term_is_tuple(req) && term_get_tuple_arity(req) >= 1))) {
usb_cdc_send_error_reply(ctx, gen_message.pid, gen_message.ref, ATOM_STR("\xF", "unknown_command"));
mailbox_remove_message(&ctx->mailbox, &ctx->heap);
continue;
}
term cmd_term = term_is_atom(req) ? req : term_get_tuple_element(req, 0);

enum usb_cdc_cmd cmd = interop_atom_term_select_int(cmd_table, cmd_term, ctx->global);
Expand Down
Loading