1 #include <stdio.h> 2 #include <stdlib.h> 3 #include <string.h> 4 #include <stdint.h> 5 6 #include "blobmsg.h" 7 #include "blobmsg_json.h" 8 9 /* 10 * Regression test for the type-confusion / out-of-bounds read reported in 11 * GHSA-r59q-rcp6-w5j2. 12 * 13 * A non-extended attribute carries no blobmsg name header, yet when such an 14 * attribute appears in a table context blobmsg_format_element() used to call 15 * blobmsg_name() on it unconditionally. blobmsg_name() blind-casts the raw 16 * payload to struct blobmsg_hdr and returns hdr->name, which is then strlen()d 17 * with no guarantee that a NUL terminator exists within the attribute's own 18 * bounds. 19 * 20 * This builds a tightly sized buffer so the crafted attribute's payload ends 21 * exactly at the end of the allocation. On an unfixed build the name strlen() 22 * reads past that boundary, which an ASAN build detects. The payload bytes are 23 * all non-NUL and non-'A'-free so that, even without ASAN, a leaked name would 24 * surface as 'A' characters in the JSON output. 25 */ 26 27 static void put_be32(uint8_t *p, uint32_t v) 28 { 29 p[0] = v >> 24; 30 p[1] = v >> 16; 31 p[2] = v >> 8; 32 p[3] = v; 33 } 34 35 int main(void) 36 { 37 /* 38 * Layout, all 4-byte aligned: 39 * [0] outer table container: non-extended, id TABLE, raw_len = size 40 * [4] crafted child: non-extended, id TABLE, raw_len = size - 4 41 * [8] child payload: non-NUL bytes up to the allocation end 42 */ 43 const size_t size = 64; 44 uint8_t *buf = malloc(size); 45 char *json; 46 47 if (!buf) 48 return EXIT_FAILURE; 49 50 put_be32(buf, (BLOBMSG_TYPE_TABLE << BLOB_ATTR_ID_SHIFT) | size); 51 put_be32(buf + 4, (BLOBMSG_TYPE_TABLE << BLOB_ATTR_ID_SHIFT) | (size - 4)); 52 memset(buf + 8, 'A', size - 8); 53 54 json = blobmsg_format_json((struct blob_attr *)buf, true); 55 56 if (json) { 57 fprintf(stderr, "result: %s\n", json); 58 if (strchr(json, 'A')) { 59 fprintf(stderr, "FAIL: leaked payload bytes in output\n"); 60 free(json); 61 free(buf); 62 return EXIT_FAILURE; 63 } 64 free(json); 65 } 66 67 free(buf); 68 return EXIT_SUCCESS; 69 } 70
This page was automatically generated by LXR 0.3.1. • OpenWrt