Advertisement
Guest User

Bug Patched on 12.50 PS4

a guest
Apr 1st, 2025
2,938
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 8.78 KB | None | 0 0
  1. /*
  2.  * aio_multi_delete - Delete multiple asynchronous I/O requests.
  3.  *
  4.  * Parameters:
  5.  *   aioCtx          - Pointer to the AIO context structure.
  6.  *   userReqArray    - Pointer to a user-space array with deletion request IDs.
  7.  *   reqCount        - Number of deletion requests (should be less than 129).
  8.  *   userResultsBuf  - Pointer to a user-space buffer for per-request status codes.
  9.  *
  10.  * Returns:
  11.  *   An overall status code (unsigned long).
  12.  */
  13. unsigned long aio_multi_delete(void *aioCtx,
  14.                                  uint64_t userReqArray,
  15.                                  unsigned int reqCount,
  16.                                  uint64_t userResultsBuf)
  17. {
  18.     /* --- Variable Declarations --- */
  19.     AioInternal *internalAio;   // Internal AIO structure pointer.
  20.     uint64_t aioState;          // Internal state value.
  21.     int contextFlag;
  22.     uint32_t localSingleReq = 0, localSingleErr = 0;
  23.     uint32_t *reqBuffer = NULL; // Local copy of the user request array.
  24.     uint32_t *errBuffer = NULL; // Local buffer for per-request error codes.
  25.     size_t bufferSize;
  26.     unsigned int effectiveReqCount;
  27.     unsigned int i, reqValue, reqId;
  28.     int reqIndex;
  29.     short *lookupResult = NULL; // Pointer returned from the lookup function.
  30.     unsigned int currentLookupId = 0;
  31.     uint64_t lookupCookie = 0;  // (Patched) variable to mark lookup state.
  32.     uint64_t stackCookieInitial;
  33.    
  34.     /* --- Stack Integrity Setup --- */
  35.     // (Patched) Record initial stack cookie to check for stack corruption later.
  36.     stackCookieInitial = GLOBAL_STACK_COOKIE;
  37.    
  38.     /* --- Get Internal AIO Context --- */
  39.     internalAio = *(AioInternal **)((char *)aioCtx + 8);
  40.     aioState = internalAio->stateField;  // e.g., offset 0xAB8.
  41.    
  42.     /* --- Determine Context Flag --- */
  43.     contextFlag = (internalAio == globalAioInternal) ? 0 : -1;
  44.     if (internalAio->flagField != -1) {
  45.         contextFlag = internalAio->flagField;
  46.     }
  47.    
  48.     /* --- Check if Multi-Delete Is Enabled --- */
  49.     if (configMultiDeleteEnabled(contextFlag)) {
  50. multi_delete:
  51.         /* --- Validate Request Count --- */
  52.         // PATCHED: The patched code uses "if (reqCount - 1 < 0x80)" instead of "if (reqCount < 129)".
  53.         if (reqCount - 1 < 0x80) {
  54.             // Save the userResultsBuf for later use.
  55.             // (In the decompiled code, this was stored in a stack slot.)
  56.             uint64_t localResultsBuf = userResultsBuf;
  57.            
  58.             /* --- Prepare Local Buffers --- */
  59.             if (reqCount < 2) {
  60.                 reqBuffer = &localSingleReq;
  61.                 errBuffer = &localSingleErr;
  62.                 bufferSize = 4;
  63.                 effectiveReqCount = 1;
  64.             } else {
  65.                 effectiveReqCount = reqCount;
  66.                 bufferSize = effectiveReqCount * 4;
  67.                 // PATCHED: Align the buffers to a 16-byte boundary.
  68.                 size_t alignedSize = (bufferSize + 0xF) & ~0xF;
  69.                 // (Original code simply computed an offset; here we simulate that.)
  70.                 reqBuffer = (uint32_t *)alloca(alignedSize);
  71.                 errBuffer = (uint32_t *)alloca(alignedSize);
  72.                 // PATCHED: Write a magic header value for debugging.
  73.                 // Original code did not include this extra write.
  74.                 ((uint64_t *)errBuffer)[-2] = 0xffffffff8231f7c1;
  75.                 // PATCHED: Explicitly clear the error buffer.
  76.                 memset(errBuffer, 0, bufferSize);
  77.             }
  78.            
  79.             /* --- Copy in User-Space Data --- */
  80.             debug_log("copyin", aioState);
  81.             if (copyin_data(userReqArray, reqBuffer, bufferSize) == 0) {
  82.                 // Initialize lookup tracking.
  83.                 lookupCookie = 0;  // Initially, no active lookup.
  84.                 for (i = 0; i < effectiveReqCount; i++) {
  85.                     reqValue = reqBuffer[i];
  86.                     errBuffer[i] = 0;  // Assume success.
  87.                    
  88.                     // Validate request value.
  89.                     if ((reqValue < 0x800000) && ((reqId = reqValue & 0xFFFF) != 0)) {
  90.                         // If we have a new request ID, perform a lookup.
  91.                         if (reqId != currentLookupId) {
  92.                             // PATCHED: If a previous lookup was active, release it.
  93.                             if (lookupCookie != 0) {
  94.                                 release_lookup_resource(lookupResult);
  95.                             }
  96.                             // (Original code did not explicitly reset lookupCookie.)
  97.                             lookupResult = lookup_aio_request(aioState, reqId, 0x160, &lookupCookie);
  98.                             if (lookupResult == NULL) {
  99.                                 errBuffer[i] = ERROR_NOT_FOUND;  // e.g., 0x80020003.
  100.                                 lookupCookie = 0; // PATCHED: Reset lookupCookie.
  101.                                 goto next_request;
  102.                             }
  103.                             currentLookupId = reqId;
  104.                             // PATCHED: Mark that lookup is active.
  105.                             lookupCookie = 1;
  106.                         }
  107.                         // If lookupResult is still NULL, error out.
  108.                         if (lookupResult == NULL) {
  109.                             errBuffer[i] = ERROR_NOT_FOUND;
  110.                             log_error("_aio_multi_delete", __LINE__, i, ERROR_NOT_FOUND);
  111.                         } else {
  112.                             // Extract the request index from the high 16 bits.
  113.                             reqIndex = reqValue >> 16;
  114.                             if (reqIndex < lookupResult->numEntries) {
  115.                                 // Validate that the AIO request is still valid.
  116.                                 if (validate_aio_request(aioState) == 0) {
  117.                                     RequestEntry *entry = lookupResult->entries[reqIndex];
  118.                                     if (entry == NULL) {
  119.                                         errBuffer[i] = ERROR_NOT_FOUND;
  120.                                         log_error("_aio_multi_delete", __LINE__, i, ERROR_NOT_FOUND);
  121.                                     } else {
  122.                                         // Process the deletion for this entry.
  123.                                         if (process_request_entry(entry, lookupResult) != 0) {
  124.                                             errBuffer[i] = ERROR_PROCESSING;
  125.                                             log_error("_aio_multi_delete", __LINE__, i, ERROR_PROCESSING);
  126.                                         }
  127.                                     }
  128.                                 } else {
  129.                                     errBuffer[i] = ERROR_INVALID;
  130.                                     log_error("_aio_multi_delete", __LINE__, i, ERROR_INVALID);
  131.                                 }
  132.                             } else {
  133.                                 errBuffer[i] = ERROR_INVALID_INDEX;
  134.                             }
  135.                         }
  136.                     } else {
  137.                         errBuffer[i] = ERROR_NOT_FOUND;
  138.                     }
  139. next_request:
  140.                     ; // Continue to next request.
  141.                 } // End for-loop.
  142.                
  143.                 // PATCHED: Clean up any active lookup resource.
  144.                 if (lookupCookie != 0) {
  145.                     release_lookup_resource(lookupResult);
  146.                 }
  147.                
  148.                 /* --- Copy out Error Codes to User Space --- */
  149.                 debug_log("copyout", aioState);
  150.                 int copyoutStatus = copyout_data(errBuffer, localResultsBuf, bufferSize);
  151.                 return (unsigned long)copyoutStatus;
  152.             } else {
  153.                 // If copyin failed, log the error.
  154.                 int copyinErr = copyin_data(userReqArray, reqBuffer, bufferSize);
  155.                 log_error("_aio_multi_delete", __LINE__, copyinErr, copyinErr);
  156.                 return (unsigned long)copyinErr;
  157.             }
  158.         } else {
  159.             // PATCHED: Return an error if too many requests are provided.
  160.             log_error("_aio_multi_delete", __LINE__, REQUEST_COUNT_ERROR, REQUEST_COUNT_ERROR);
  161.             return REQUEST_COUNT_ERROR;
  162.         }
  163.     } else {
  164.         // Fallback configuration check.
  165.         unsigned int configStatus = get_config_flag(1, baseConfig + ((contextFlag != 0) ? OFFSET_VALUE : 0));
  166.         if (configStatus == 0)
  167.             goto multi_delete;
  168.         log_error("_aio_multi_delete", __LINE__, configStatus, configStatus);
  169.         return configStatus;
  170.     }
  171.    
  172.     /* --- Check Stack Integrity --- */
  173.     // PATCHED: Verify that the stack cookie has not been altered.
  174.     if (GLOBAL_STACK_COOKIE != stackCookieInitial) {
  175.         panic("Stack integrity violation in aio_multi_delete");
  176.     }
  177.    
  178.     return 0;
  179. }
  180.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement