• source navigation  • diff markup  • identifier search  • freetext search  • 

Sources/libubox/tests/test-blobmsg-format-json.c

  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