File size: 1,533 Bytes
7f61860
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
#include <cstdio>
#include <cstdint>

// Standalone test: demonstrates int64_t → size_t truncation on 32-bit
// This simulates what happens at unpickler.cpp:344-345 on ARM32

void demonstrate_truncation() {
    struct TestCase {
        int64_t length;
        const char* desc;
    };

    TestCase tests[] = {
        {6, "correct length for 'weight'"},
        {0x0000000100000006LL, "4GB + 6 (truncates to 6 on 32-bit)"},
        {0x0000000100000010LL, "4GB + 16 (truncates to 16 on 32-bit)"},
        {0x0000000200000000LL, "8GB (truncates to 0 on 32-bit)"},
        {(int64_t)0x8000000000000006LL, "MSB set + 6"},
    };

    printf("%-28s %-22s %-20s %-10s\n",
           "int64_t length", "64-bit size_t", "32-bit size_t", "Truncated?");
    printf("%-28s %-22s %-20s %-10s\n", "---", "---", "---", "---");

    for (const auto& t : tests) {
        uint64_t as_u64 = static_cast<uint64_t>(t.length);
        uint32_t as_u32 = static_cast<uint32_t>(as_u64);

        printf("0x%016llX  %20llu  %10u          %s\n",
               (unsigned long long)as_u64,
               (unsigned long long)as_u64,
               (unsigned)as_u32,
               (as_u64 != as_u32) ? "YES!" : "no");
    }

    printf("\nOn 32-bit ARM (PyTorch Mobile):\n");
    printf("  readBytes(size_t) receives truncated value\n");
    printf("  Reads WRONG number of bytes from pickle stream\n");
    printf("  Unpickler desyncs → crash or arbitrary opcode execution\n");
    return;
}

int main() {
    demonstrate_truncation();
    return 0;
}