#include #include #include #include #include #include #include struct inner { //# decoder encoder int sz; uint8_t data[255]; //#1 num_at=^ }; struct st { //# decoder encoder char s[8]; //#1 int8_t i8; //#2 signed uint8_t u8; //#3 int16_t i16; //#4 signed uint16_t u16; //#5 int32_t i32; //#6 signed uint32_t u32; //#7 uint64_t u64; //#8 uint8_t b[4]; //#9 size=2 uint32_t i[4]; //#10 int spa_num; char *spa[3]; //#11 num_at=^ struct inner in; //#12 char buffer[2+13]; //# buffer=here }; struct reqfield { //# encoder const char *s; //#1 required }; struct reqmsg { //# encoder struct reqfield *f; //#1 required }; struct rest { //# decoder encoder int x; //#1 uint8_t rest[33]; //# rest=here }; #include "test_security.pb.h" void test_security_buffer_overflow(void **state) { // spa:"1234567890", spa:"01" const uint8_t raw[] = { 0x5a, 0x0a, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x5a, 0x02, 0x30, 0x31, }; struct st s; (void)state; assert_null(pb_decode_st(&s, raw, raw+sizeof(raw))); } void test_security_string_overflow(void **state) { // s:"12345678" const uint8_t raw[] = { 0x0a, 0x08, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, }; struct st s; (void)state; assert_null(pb_decode_st(&s, raw, raw+sizeof(raw))); } void test_security_bytes_wrong_size(void **state) { // b:"\x00" const uint8_t raw[] = { 0x4a, 0x01, 0x00, }; struct st s; (void)state; assert_null(pb_decode_st(&s, raw, raw+sizeof(raw))); } void test_security_bytes_wrong_size_2(void **state) { // b:"\x00\x00\x00" const uint8_t raw[] = { 0x4a, 0x03, 0x00, 0x00, 0x00, }; struct st s; (void)state; assert_null(pb_decode_st(&s, raw, raw+sizeof(raw))); } void test_security_bytes_wrong_size_3(void **state) { // b:"" const uint8_t raw[] = { 0x4a, 0x00 }; struct st s; (void)state; assert_null(pb_decode_st(&s, raw, raw+sizeof(raw))); } void test_security_varint_overflow(void **state) { const struct { int sz; const char *raw; }data[] = { {3, "\x10\x80\x02"}, // i8:128 {3, "\x10\x81\x02"}, // i8:-129 {3, "\x18\x80\x02"}, // u8:256 {4, "\x20\x80\x80\x04"}, // i16:32678 {4, "\x20\x81\x80\x04"}, // i16:-32769 {4, "\x28\x80\x80\x04"}, // u16:65536 {6, "\x30\x80\x80\x80\x80\x10"}, // i32:0x80000000 {6, "\x30\x81\x80\x80\x80\x10"}, // i32:-0x80000001 {6, "\x38\x80\x80\x80\x80\x10"}, // u32:0x1000000000 {7, "\x52\x05\x80\x80\x80\x80\x10"}, // i:0x1000000000 {11, "\x40\xff\xff\xff\xff\xff\xff\xff\xff\xff\x02"}, // too many bits }; struct st s; int i; (void)state; for(i = 0; i < (int)(sizeof(data)/sizeof(data[0])); i++) assert_null(pb_decode_st(&s, (const uint8_t*)data[i].raw, (const uint8_t*)data[i].raw+data[i].sz)); } void test_security_wrong_type(void **state) { const struct { int sz; const char *raw; }data[] = { {2, "\x08\x00"}, // i:0 (st2) {2, "\x48\x00"}, // i2:0 (st2) }; struct st s; int i; (void)state; for(i = 0; i < (int)(sizeof(data)/sizeof(data[0])); i++) assert_null(pb_decode_st(&s, (const uint8_t*)data[i].raw, (const uint8_t*)data[i].raw+data[i].sz)); } void test_security_unsupported_type(void **state) { const struct { int sz; const char *raw; }data[] = { {2, "\x09\x00"}, {2, "\x0b\x00"}, {2, "\x0c\x00"}, {2, "\x0d\x00"}, {2, "\x0e\x00"}, {2, "\x0f\x00"}, }; struct st s; int i; (void)state; for(i = 0; i < (int)(sizeof(data)/sizeof(data[0])); i++) assert_null(pb_decode_st(&s, (const uint8_t*)data[i].raw, (const uint8_t*)data[i].raw+data[i].sz)); } void test_security_invalid_data_size(void **state) { const struct { int sz; const char *raw; }data[] = { {7, "\x0a\xff\xff\xff\xff\xff\x00"}, }; struct st s; int i; (void)state; for(i = 0; i < (int)(sizeof(data)/sizeof(data[0])); i++) assert_null(pb_decode_st(&s, (const uint8_t*)data[i].raw, (const uint8_t*)data[i].raw+data[i].sz)); } void test_security_invalid_tag(void **state) { const struct { int sz; const char *raw; }data[] = { {3, "\xff\xff\xff"}, }; struct st s; int i; (void)state; for(i = 0; i < (int)(sizeof(data)/sizeof(data[0])); i++) assert_null(pb_decode_st(&s, (const uint8_t*)data[i].raw, (const uint8_t*)data[i].raw+data[i].sz)); } void test_security_short_read(void **state) { const struct { int sz; const char *raw; }data[] = { {1, "\x0a"}, {2, "\x0a\x01"}, {2, "\x10\xff"}, {3, "\x10\xff\xff"}, {4, "\x10\xff\xff\xff"}, {5, "\x10\xff\xff\xff\xff"}, {6, "\x10\xff\xff\xff\xff\xff"}, {7, "\x10\xff\xff\xff\xff\xff\xff"}, {8, "\x10\xff\xff\xff\xff\xff\xff\xff"}, {9, "\x10\xff\xff\xff\xff\xff\xff\xff\xff"}, {10, "\x10\xff\xff\xff\xff\xff\xff\xff\xff\xff"}, }; struct st s; int i; (void)state; for(i = 0; i < (int)(sizeof(data)/sizeof(data[0])); i++) assert_null(pb_decode_st(&s, (const uint8_t*)data[i].raw, (const uint8_t*)data[i].raw+data[i].sz)); } void test_security_empty(void **state) { const uint8_t raw[] = {}; struct st s; (void)state; assert_non_null(pb_decode_st(&s, raw, raw+sizeof(raw))); } void test_security_required_field(void **state) { struct reqfield r; uint8_t buf[32]; (void)state; r.s = NULL; assert_null(pb_encode_reqfield(&r, buf, buf+sizeof(buf))); } void test_security_required_field_msg(void **state) { struct reqmsg r; uint8_t buf[32]; (void)state; r.f = NULL; assert_null(pb_encode_reqmsg(&r, buf, buf+sizeof(buf))); } void test_security_encode_no_space(void **state) { struct st s; uint8_t buf[256]; (void)state; memset(&s, 0, sizeof(s)); s.s[0] = 'a'; assert_null(pb_encode_st(&s, buf, buf+0)); // index doesn't fit assert_null(pb_encode_st(&s, buf, buf+1)); // len+string doesn't fit assert_null(pb_encode_st(&s, buf, buf+2)); // len+string doesn't fit assert_non_null(pb_encode_st(&s, buf, buf+3)); memset(&s, 0, sizeof(s)); s.b[0] = 0xff; assert_null(pb_encode_st(&s, buf, buf+1)); // sz+bytes doesn't fit assert_null(pb_encode_st(&s, buf, buf+2)); // sz+bytes doesn't fit assert_null(pb_encode_st(&s, buf, buf+3)); // sz+bytes doesn't fit assert_non_null(pb_encode_st(&s, buf, buf+4)); memset(&s, 0, sizeof(s)); s.u64 = ~0LL; assert_null(pb_encode_st(&s, buf, buf+10)); // integer doesn't fit assert_non_null(pb_encode_st(&s, buf, buf+11)); memset(&s, 0, sizeof(s)); s.in.sz = 128; assert_null(pb_encode_st(&s, buf, buf+133)); // sz+field doesn't fit assert_non_null(pb_encode_st(&s, buf, buf+134)); } void test_security_decode_no_space_rest(void **state) { // x:1, x2:2, z:3, z:4, z2:5, z2:6, z2:7, b:"\x08\x09\x0a", b2:"\x0b\x0c\x0d", s:"abc", s2:"def" const uint8_t raw[] = { 0x08, 0x01, 0x10, 0x02, 0x18, 0x03, 0x18, 0x04, 0x20, 0x05, 0x20, 0x06, 0x20, 0x07, 0x2a, 0x03, 0x08, 0x09, 0x0a, 0x32, 0x03, 0x0b, 0x0c, 0x0d, 0x3a, 0x03, 0x61, 0x62, 0x63, 0x42, 0x03, 0x64, 0x65, 0x66, }; struct rest r; (void)state; assert_null(pb_decode_rest(&r, raw, raw+sizeof(raw))); } void test_security_invalid_packed_integers(void **state) { const uint8_t raw[] = {0x52, 0x02, 0x80, 0x80}; struct st s; (void)state; assert_null(pb_decode_st(&s, raw, raw+sizeof(raw))); } void test_security_encode_invalid_bytes_size(void **state) { struct st s; uint8_t buf[512]; (void)state; memset(&s, 0, sizeof(s)); s.in.sz = 256; // obviously greater than 255 assert_null(pb_encode_st(&s, buf, buf+sizeof(buf))); s.in.sz = -1; assert_null(pb_encode_st(&s, buf, buf+sizeof(buf))); }