Skip to content

UBSan: applying zero offset to a NULL dataptr in jpc_ppmstabtostreams() (jpc_dec.c) #437

Description

@MMu-Aqua

Affected: JasPer 4.2.9 (5ce57f67e0011e0d2483992a5d77a092b1b64eb7)
Sanitizer: UndefinedBehaviorSanitizer (applying zero offset to null pointer), not ASan
Entry point: imginfo -f poc.jpc

Summary

jpc_ppmstabtostreams() unpacks PPM (packed packet header) marker data. After switching to the next table entry it does:

			const size_t n = JAS_MIN(tpcnt, datacnt);
			if (jas_stream_write(stream, dataptr, n) != n) {
				goto error;
			}
			tpcnt -= n;
			dataptr += n;  /* jpc_dec.c:2558 */

If the new entry has ent->data == NULL and ent->len == 0, then n == 0 and dataptr is NULL, so dataptr += 0 is undefined behavior. UBSan:

jpc_dec.c:2558:12: runtime error: applying zero offset to null pointer

Code

jpc_dec.c, jpc_ppmstabtostreams():

		while (tpcnt) {
			if (!datacnt) {
				if (++entno >= tab->numents) {
					goto error;
				}
				ent = tab->ents[entno];
				dataptr = ent->data;
				datacnt = ent->len;
			}
			const size_t n = JAS_MIN(tpcnt, datacnt);
			if (jas_stream_write(stream, dataptr, n) != n) {
				goto error;
			}
			tpcnt -= n;
			dataptr += n;
			datacnt -= n;
		}

Reached from jpc_dec_process_sot when the main header has PPM marker segments (dec->ppmstab).

PoC

poc_ppmstab_null.zip

# poc_ppmstab_null.py
open("poc_ppmstab_null.jpc", "wb").write(bytes.fromhex(
    "ff4fff5100290101000101170001011700010101000101010101011701010117"
    "00010101000101010001180101ff60000c0101010001011c1c0100ff60000340"
    "ff90000a0101010f02283342565d00"
))

Reproduce

cmake -S . -B build \
  -DCMAKE_C_FLAGS="-fsanitize=undefined,address -fno-omit-frame-pointer" \
  -DCMAKE_EXE_LINKER_FLAGS="-fsanitize=undefined,address"
cmake --build build -j
export UBSAN_OPTIONS='halt_on_error=1:abort_on_error=1:print_stacktrace=1'
./build/src/app/imginfo -f poc_ppmstab_null.jpc

Stack

jpc_dec.c:2558:12: runtime error: applying zero offset to null pointer
#0 jpc_ppmstabtostreams jpc_dec.c:2558:12
#1 jpc_dec_process_sot  jpc_dec.c:525:31
#2 jpc_dec_decode       jpc_dec.c:434:10
#3 jpc_decode           jpc_dec.c:270:6
#4 jas_image_decode     jas_image.c:477:16
#5 main                 imginfo.c:334:16
SUMMARY: UndefinedBehaviorSanitizer: undefined-behavior .../jpc_dec.c:2558:12

Suggested fix

After taking the next table entry, reject a NULL data pointer or a zero len (goto error) instead of doing dataptr += n on NULL. Do not perform pointer arithmetic when n == 0.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions