Saturday, February 25, 2023

Reverse Engineering Notes - CVE-2022-26721

     xpc_object_t content = xpc_dictionary_get_value(req, "source");
    size_t count = xpc_array_get_count(content); //XENO: count SACI, based on number of array elements sent
    size_t descriptors = malloc(sizeof(size_t) * 4 * count);
    size_t *accessBeginPointer = &descriptors[count * 0],
      *accessDataLength = &descriptors[count * 1],
      *mappedBaseAddress = &descriptors[count * 2],
      *mappedLength = &descriptors[count * 3];

    for(size_t i = 0; i < count; i++) {
      accessBeginPointer[i] = accessDataLength[i] =
      mappedBaseAddress[i] = mappedLength[i] = 0;

      xpc_object_t chunk = xpc_array_get_value(content, i);

      if(xpc_get_type(chunk) == XPC_TYPE_DATA) { /*...*/ }
      else if(xpc_get_type(chunk) == XPC_TYPE_SHMEM) {
        xpc_object_t map = xpc_array_get_value(chunk, 0);
        size_t offset = min(xpc_array_get_uint64(chunk, 1), 0xFFF), //XENO: offset ACID
        size = xpc_array_get_uint64(chunk, 2);                      //XENO: size ACID

        size_t mapped_address;
        size_t mapped_size = xpc_shmem_map(map, &mapped_address);   //XENO: mapped_size ACID

        size = min(size, mapped_size - offset);
        // ...
    // ...
    // cleanup
    for(size_t index = 0; index < count; i++) {
      if(mappedLength[index]) {

There are a few potential vulnerabilities or issues with the code:

  1. Memory allocation issue: the descriptors array is allocated with malloc using the size of a size_t multiplied by 4 times the number of count elements, which should be the number of elements in the content XPC array. However, sizeof(size_t) is the size of the size_t type, not the size of a pointer, so the allocated size may not be correct. It should use sizeof(size_t *) instead.

  2. Unchecked array access: the code uses the count variable to access the descriptors array and set the accessBeginPointer, accessDataLength, mappedBaseAddress, and mappedLength values. However, if count is greater than the size of the descriptors array, this could result in undefined behavior or memory corruption.

  3. Uninitialized memory: the code initializes the accessBeginPointer, accessDataLength, mappedBaseAddress, and mappedLength values to zero for each array element. However, it is unclear if these values are actually used or set correctly later in the code. If they are not set correctly, this could result in unexpected behavior or vulnerabilities.

  4. Missing error checking: the code calls xpc_shmem_map to map shared memory, but does not check the return value to ensure that the mapping was successful. If the mapping fails, this could result in undefined behavior or vulnerabilities.

  5. Memory leak: the code calls munmap to unmap shared memory, but does not free the xpc_object_t objects or the chunk array, which could result in a memory leak.

No comments:

Post a Comment

A Guide to Multi-Level Pointer Analysis

  A Comprehensive Guide to Multi-Level Pointer Analysis   A regular pointer points to only one address, but when it's accompanied by a l...