Skip to content

Heap buffer overflow in cupsJSONExportString for extreme floating-point numbers #1546

@Tomer-PL

Description

@Tomer-PL

Summary

cupsJSONExportString() budgets 32 bytes per CUPS_JTYPE_NUMBER in its size estimation (line 276), but _cupsStrFormatd() with %.12f can produce up to 322 characters for extreme doubles like 1e308. The allocated buffer overflows when formatting such numbers.

Details

Size estimation (cups/json.c:276):

case CUPS_JTYPE_NUMBER :
    length += 32;  // Only 32 bytes
    break;

Serialization (cups/json.c:375-376):

_cupsStrFormatd(ptr, s + length, current->value.number, loc);
ptr += strlen(ptr);

For 1e308, _cupsStrFormatd uses snprintf(temp, 1024, "%.12f", number) which produces a 310-character string. The 32-byte budget is exceeded by ~278 bytes per extreme number.

Additionally, _cupsStrFormatd() at cups/string.c:728 writes *bufptr = '\0' when bufptr == bufend, placing a NUL 1 byte past the allocation.

Reproducer

#include "cups/json.h"

int main(void) {
    cups_json_t *root = cupsJSONNew(NULL, NULL, CUPS_JTYPE_OBJECT);
    cupsJSONNewKey(root, NULL, "value");
    cupsJSONNewNumber(root, NULL, 1e308);
    char *exported = cupsJSONExportString(root);  // heap overflow
    if (exported) free(exported);
    cupsJSONDelete(root);
    return 0;
}

Also triggered by import-then-export:

cups_json_t *json = cupsJSONImportString("{\"e\":1e308}");
char *s = cupsJSONExportString(json);  // overflow

ASan output:

ERROR: AddressSanitizer: heap-buffer-overflow on address 0x504000000080
WRITE of size 1 at 0x504000000080 thread T0
    #0 _cupsStrFormatd cups/string.c:728
    #1 cupsJSONExportString cups/json.c:375

Suggested Fix

  case CUPS_JTYPE_NUMBER :
-     length += 32;
+     length += 330;  // DBL_MAX with %.12f = ~322 chars + margin
      break;

And fix the off-by-one in cups/string.c:728:

- *bufptr = '\0';
+ if (bufptr < bufend) *bufptr = '\0';
+ else if (bufptr > buffer) *(bufptr - 1) = '\0';

Metadata

Metadata

Assignees

Labels

bugSomething isn't working

Type

No type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions