{"record":{"id":"9591829ac519bf6e","repo":"awslabs/llrt","slug":"failed-to-set-file-size","errorCode":null,"errorMessage":"Failed to set file size","messagePattern":"Failed to set file size","errorType":"error_code","errorClass":null,"httpStatus":null,"severity":"critical","filePath":"llrt/src/main.c","lineNumber":205,"sourceCode":"  char *uncompressed;\n  uint8_t *compressedData;\n\n  pthread_t threads[parts];\n\n  if (parts > 1)\n  {\n    logInfo(\"Decompressing using %d threads\\n\", parts);\n  }\n  else\n  {\n    logInfo(\"Decompressing\\n\");\n  }\n\n  readData(data, parts, &inputSizes, &outputSizes, &compressedData, uncompressedSize);\n\n  if (ftruncate(outputFd, *uncompressedSize) == -1)\n  {\n    err(1, \"Failed to set file size\");\n  }\n\n  uncompressed = mmap(NULL, *uncompressedSize, PROT_READ | PROT_WRITE, MAP_SHARED, outputFd, 0);\n  if (uncompressed == MAP_FAILED || !uncompressed)\n  {\n    err(1, \"Memory mapping failed: Unable to map %u bytes. Make sure you have enough memory available\", *uncompressedSize);\n  }\n\n  DecompressThreadArgs args[parts];\n  for (uint32_t i = 0; i < parts; i++)\n  {\n    args[i].inputBuffer = compressedData + inputOffset;\n    args[i].outputBuffer = uncompressed + outputOffset;\n    args[i].srcSize = inputSizes[i];\n    args[i].dstSize = outputSizes[i];\n    args[i].id = i;\n    inputOffset += inputSizes[i];\n    outputOffset += outputSizes[i];","sourceCodeStart":187,"sourceCodeEnd":223,"githubUrl":"https://github.com/awslabs/llrt/blob/742fc00b82cbeaab1c1b76f0d706c302a5cbc306/llrt/src/main.c#L187-L223","documentation":"During decompression of the embedded (self-extracted) payload, llrt calls ftruncate(outputFd, *uncompressedSize) to pre-size the output memfd to the expected uncompressed size before mmap'ing it. This err(1) means the ftruncate syscall returned -1, so the output file could not be sized. Without a correctly sized file the subsequent shared mmap of the decompressed data is impossible, so the runtime aborts immediately.","triggerScenarios":"ftruncate on the memfd created in main fails — practically only when the file descriptor outputFd is invalid (memfd creation silently broken), the fd was closed, or the process hits RLIMIT_FSIZE / runs on a filesystem or kernel lacking ftruncate support for the fd. Triggered by running the binary at all, since decompress() is called from main before any user code.","commonSituations":"Running the llrt binary in a hardened sandbox (seccomp filter blocking ftruncate), inside containers with restricted syscall allowlists, or on exotic kernels/fork servers where fd 0-state is manipulated before entry. Extremely rare on normal Linux.","solutions":["Check sandbox/seccomp/container settings and allow the ftruncate syscall (e.g. adjust seccomp profile or AppArmor/SELinux policy).","Verify the kernel is Linux with memfd/ftruncate support; run on a standard glibc/musl Linux environment.","Rebuild llrt with debugging (logInfo) to confirm the memfd_create_syscall succeeded and outputFd is valid.","Check RLIMIT_FSIZE (ulimit -f) is not set to 0 for the process."],"exampleFix":null,"handlingStrategy":"validation","validationCode":"// Before deploying, smoke-test the binary in the target environment:\n// it must run in a sandbox allowing ftruncate on memfd.\nimport { execFileSync } from 'node:child_process';\ntry {\n  execFileSync('./llrt', ['-v'], { stdio: 'ignore' });\n} catch (e) {\n  throw new Error('llrt cannot start here (ftruncate/memfd blocked): ' + e.message);\n}","typeGuard":null,"tryCatchPattern":"// err(1) exits the process — it cannot be caught inside llrt.\n// Catch at the supervisor level:\ntry {\n  child_process.execFileSync('./llrt', ['app.js']);\n} catch (e) {\n  if (e.status === 1 && /Failed to set file size/.test(String(e.stderr))) {\n    // fall back to a non-self-extracting runtime or fix the sandbox\n  }\n}","preventionTips":["Smoke-test the binary inside the actual container/sandbox image before shipping.","Keep seccomp/AppArmor profiles permissive enough for memfd + ftruncate.","Avoid ulimit -f 0 and other restrictive rlimits for the process.","Prefer standard Linux kernels with full memfd support."],"tags":["ftruncate","syscall","self-extraction","sandbox"],"backgroundTag":"file-write-failed","analyzedSha":"742fc00b82cbeaab1c1b76f0d706c302a5cbc306","analyzedAt":"2026-09-12T11:14:07.838Z","contentChangedAt":"2026-09-12T11:14:07.838Z","schemaVersion":2},"datasetVersion":"2026-09-16T04:17:20.429Z"}