Actions
Bug #14109
openbuffer overflow loading brand module
Start date:
2021-09-23
Due date:
% Done:
0%
Estimated time:
Difficulty:
Bite-size
Tags:
Gerrit CR:
Description
brand_register_zone() will allocate a buffer named modname of size MAXPATHLEN when it needs to load a brand's module with ddi_modopen(). This buffer is set with user provided content using strcat() that may not include a null character. Writing past this buffer can cause a system crash.
usr/src/uts/common/os/brand.c
253 modname = kmem_alloc(MAXPATHLEN, KM_SLEEP); 254 (void) strcpy(modname, "brand/"); 255 (void) strcat(modname, attr->ba_modname); 256 hdl = ddi_modopen(modname, KRTLD_MODE_FIRST, &err); 257 kmem_free(modname, MAXPATHLEN);
This was tested with OmniOS r151038 (with illumos-omnios and illumos-gate). To reproduce:
- create a zone: sudo zadm create -b illumos -i 44feb128 test
- put the zone into the ready state: sudo zoneadm -z test ready
- compile the test: gcc test.c -o test
- run the test: while true; do sudo ./test; done
The following dtrace program shows the string can be greater than MAXPATHLEN (1024):
dtrace -x strsize=2048 -n fbt:genunix:ddi_modopen:entry'{ printf("%d", strlen(stringof(arg0))); }'
1 30368 ddi_modopen:entry 1030 1 30368 ddi_modopen:entry 1030 1 30368 ddi_modopen:entry 1030 1 30368 ddi_modopen:entry 1030 0 30368 ddi_modopen:entry 1104 0 30368 ddi_modopen:entry 1104 0 30368 ddi_modopen:entry 1030 0 30368 ddi_modopen:entry 1303
The machine can crash and provide the following error:
kernel memory allocator: redzone violation: write past end of buffer buffer=fffffe066cffe4c0 bufctl=fffffe066ef112f0 cache: kmem_alloc_1152 previous transaction on buffer fffffe066cffe4c0: thread=fffffe0666179020 time=T-0.000534589 slab=fffffe066df24e58 cache: kmem_alloc_1152 kmem_cache_alloc_debug+2fc kmem_cache_alloc+135 kmem_alloc+4b brand_register_zone+b5 zone_set_brand+53 zone_setattr+28c zone+1f5 panic[cpu1]/thread=fffffe0666179020: kernel heap corruption detected fffffe0009e21c60 genunix:kmem_error+5fd () fffffe0009e21cb0 genunix:kmem_free+f2 () fffffe0009e21d00 unix:brand_register_zone+f8 () fffffe0009e21d40 genunix:zone_set_brand+53 () fffffe0009e21db0 genunix:zone_setattr+28c () fffffe0009e21ef0 genunix:zone+1f5 () fffffe0009e21f00 unix:brand_sys_syscall+304 ()
Files
Actions