Skip to content

Commit

Permalink
Check bounds in array functions
Browse files Browse the repository at this point in the history
  • Loading branch information
petabyt committed Jun 14, 2024
1 parent fb3ad31 commit 34c1e45
Show file tree
Hide file tree
Showing 4 changed files with 42 additions and 18 deletions.
3 changes: 2 additions & 1 deletion src/camlib.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@
void ptp_verbose_log(char *fmt, ...);
__attribute__ ((noreturn)) void ptp_panic(char *fmt, ...);

// 4mb recommended default buffer size
// 1mb default buffer size
#define CAMLIB_DEFAULT_SIZE 1000000

/// @brief Camlib library errors, not PTP return codes
Expand Down Expand Up @@ -267,6 +267,7 @@ int ptp_read_string(uint8_t *dat, char *string, int max);
int ptp_write_string(uint8_t *dat, char *string);
int ptp_write_utf8_string(void *dat, char *string);
int ptp_read_uint16_array(uint8_t *dat, uint16_t *buf, int max, int *length);
int ptp_read_uint16_array_s(uint8_t *bs, uint8_t *be, uint16_t *buf, int max, int *length);
inline static int ptp_write_u8 (void *buf, uint8_t out) { ((uint8_t *)buf)[0] = out; return 1; }
inline static int ptp_write_u16(void *buf, uint16_t out) { ((uint16_t *)buf)[0] = out; return 2; }
inline static int ptp_write_u32(void *buf, uint32_t out) { ((uint32_t *)buf)[0] = out; return 4; }
Expand Down
32 changes: 16 additions & 16 deletions src/data.c
Original file line number Diff line number Diff line change
Expand Up @@ -263,27 +263,27 @@ void *ptp_pack_chdk_upload_file(struct PtpRuntime *r, char *in, char *out, int *
}

int ptp_parse_device_info(struct PtpRuntime *r, struct PtpDeviceInfo *di) {
uint8_t *e = ptp_get_payload(r);
uint8_t *b = ptp_get_payload(r);
uint8_t *e = b + r->data_length;

e += ptp_read_u16(e, &di->standard_version);
e += ptp_read_u32(e, &di->vendor_ext_id);
e += ptp_read_u16(e, &di->version);
b += ptp_read_u16(b, &di->standard_version);
b += ptp_read_u32(b, &di->vendor_ext_id);
b += ptp_read_u16(b, &di->version);

e += ptp_read_string(e, di->extensions, sizeof(di->extensions));

e += ptp_read_u16(e, &di->functional_mode);
b += ptp_read_string(b, di->extensions, sizeof(di->extensions));
b += ptp_read_u16(b, &di->functional_mode);

e += ptp_read_uint16_array(e, di->ops_supported, sizeof(di->ops_supported) / 2, &di->ops_supported_length);
e += ptp_read_uint16_array(e, di->events_supported, sizeof(di->events_supported) / 2, &di->events_supported_length);
e += ptp_read_uint16_array(e, di->props_supported, sizeof(di->props_supported) / 2, &di->props_supported_length);
e += ptp_read_uint16_array(e, di->capture_formats, sizeof(di->capture_formats) / 2, &di->capture_formats_length);
e += ptp_read_uint16_array(e, di->playback_formats, sizeof(di->playback_formats) / 2, &di->playback_formats_length);
b += ptp_read_uint16_array_s(b, e, di->ops_supported, sizeof(di->ops_supported) / 2, &di->ops_supported_length);
b += ptp_read_uint16_array_s(b, e, di->events_supported, sizeof(di->events_supported) / 2, &di->events_supported_length);
b += ptp_read_uint16_array_s(b, e, di->props_supported, sizeof(di->props_supported) / 2, &di->props_supported_length);
b += ptp_read_uint16_array_s(b, e, di->capture_formats, sizeof(di->capture_formats) / 2, &di->capture_formats_length);
b += ptp_read_uint16_array_s(b, e, di->playback_formats, sizeof(di->playback_formats) / 2, &di->playback_formats_length);

e += ptp_read_string(e, di->manufacturer, sizeof(di->manufacturer));
e += ptp_read_string(e, di->model, sizeof(di->model));
b += ptp_read_string(b, di->manufacturer, sizeof(di->manufacturer));
b += ptp_read_string(b, di->model, sizeof(di->model));

e += ptp_read_string(e, di->device_version, sizeof(di->device_version));
e += ptp_read_string(e, di->serial_number, sizeof(di->serial_number));
b += ptp_read_string(b, di->device_version, sizeof(di->device_version));
b += ptp_read_string(b, di->serial_number, sizeof(di->serial_number));

r->di = di; // set last parsed di

Expand Down
2 changes: 1 addition & 1 deletion src/log.c
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,6 @@ void ptp_panic(char *fmt, ...) {
va_start(args, fmt);
vprintf(fmt, args);
va_end(args);

fflush(stdout);
abort();
}
23 changes: 23 additions & 0 deletions src/packet.c
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,14 @@
#include <ptp.h>
#include <camlib.h>

static void boundcheck(uint8_t *bs, uint8_t *be, int size) {
if (be == NULL) return;
if ((uintptr_t)bs > (uintptr_t)be) ptp_panic("PTP: bs after be\n");
if (((uintptr_t)be - (uintptr_t)bs) < (uintptr_t)size) {
ptp_panic("PTP: buffer overflow %p-%p (%u)\n", bs, be, size);
}
}

// Read standard UTF16 string
int ptp_read_string(uint8_t *d, char *string, int max) {
int of = 0;
Expand Down Expand Up @@ -48,6 +56,21 @@ int ptp_read_uint16_array(uint8_t *dat, uint16_t *buf, int max, int *length) {
return of;
}

int ptp_read_uint16_array_s(uint8_t *bs, uint8_t *be, uint16_t *buf, int max, int *length) {
int of = 0;
uint32_t n;
of += ptp_read_u32(bs + of, &n);
boundcheck(bs, be, 4 * n + 4);
for (uint32_t i = 0; i < n; i++) {
if (i >= max) {
ptp_panic("ptp_read_uint16_array overflow\n");
} else {
of += ptp_read_u16(bs + of, &buf[i]);
}
}
return of;
}

// Write standard PTP wchar string
int ptp_write_string(uint8_t *dat, char *string) {
int of = 0;
Expand Down

0 comments on commit 34c1e45

Please sign in to comment.