Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

A potential off-by-one overflow in cmsIT8SaveToMem #355

Closed
hopper-vul opened this issue Jan 10, 2023 · 1 comment
Closed

A potential off-by-one overflow in cmsIT8SaveToMem #355

hopper-vul opened this issue Jan 10, 2023 · 1 comment

Comments

@hopper-vul
Copy link

Hi,
we found cmsIT8SaveToMem could suffer off-by-one problem by using fuzzing.

In document, it restricts the 3-th argument of cmsIT8SaveToMem shoud follow that

bytesNeeded: Points to a user-allocated cmsUInt32Number which will receive the needed memory size in bytes.

Which means the number of bytesNeeded stored should be less than or equal to the buffer size of MemPtr.

However, if the number stored in bytesNeeded equal to the sizeof MemPtr, the off-by-one will happen.

    for (i=0; i < it8 ->TablesCount; i++) {

        cmsIT8SetTable(hIT8, i);
        WriteHeader(it8, &sd);
        WriteDataFormat(&sd, it8);
        WriteData(&sd, it8);
    }

    sd.Used++;  // The \0 at the very end

    if (sd.Base)
->        *sd.Ptr = 0; // off-by-one

Let just assume the size of MemPtr is 0x20 and the number stored in bytesNeeded is 0x20 too. After the for loop, the sd.Ptr will point to the MemPtr + 0x20 location, then a 0 byte will be write out of the bound of MemPtr.


A trigger case is listed bellow:

// gcc -fsanitizer=address -g -llcms2 test.c -o test.out
#include "lcms2.h"
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
typedef uint8_t   u8;   
typedef uint32_t  u32;  
typedef int8_t  i8;
typedef int32_t i32;
int main() {
    struct _cmsContext_struct *v0 = NULL; // ContextID
    void *v1 = cmsIT8Alloc(v0); // hIT8
    if (v1 == NULL) return 0;
    void *v3 = v1; // hIT8
    i8 v4_tmp[] = {70, 37, 118, -99, -66, -27, -75, 107, 0, }; // MemPtr
    i8 *v4 = malloc(sizeof v4_tmp);
    memcpy(v4, v4_tmp, sizeof v4_tmp);
    i8 *v5 = v4; // MemPtr
    u32 v6_tmp[] = {9, 0, }; // BytesNeeded
    u32 *v6 = malloc(sizeof v6_tmp);
    memcpy(v6, v6_tmp, sizeof v6_tmp);
    u32 *v7 = v6; // BytesNeeded
    i32 v8 = cmsIT8SaveToMem(v3, v5, v7); // $target
}
@mm2
Copy link
Owner

mm2 commented Jan 10, 2023

Thanks for reporting. Should be solved by e71aeb6

@mm2 mm2 closed this as completed Jan 10, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants