{"record":{"id":"273dc56d2bf69138","repo":"can1357/oh-my-pi","slug":"invalid-rpm-package-non-zero-signature-alignment","errorCode":null,"errorMessage":"Invalid RPM package: non-zero signature alignment padding","messagePattern":"Invalid RPM package: non-zero signature alignment padding","errorType":"validation","errorClass":"ArchiveError","httpStatus":null,"severity":"error","filePath":"packages/utils/src/ar/rpm.ts","lineNumber":278,"sourceCode":"\t\tif (decoded) leadName = decoded;\n\t} catch {}\n\n\tconst signatureIntro = parseHeaderIntro(initial.subarray(RPM_LEAD_SIZE), options, \"signature\");\n\tconst signatureEnd = RPM_LEAD_SIZE + signatureIntro.totalSize;\n\tconst mainHeaderOffset = align(signatureEnd, 8);\n\tconst signatureBodyAndPadding = await readExact(\n\t\tsource,\n\t\tRPM_LEAD_SIZE + RPM_HEADER_INTRO_SIZE,\n\t\tmainHeaderOffset,\n\t\t\"signature header\",\n\t);\n\tif (signatureBodyAndPadding.byteLength < signatureIntro.bodySize) {\n\t\tthrow new ArchiveError(\"Invalid RPM package: truncated signature header\");\n\t}\n\tvalidateHeaderBody(signatureBodyAndPadding.subarray(0, signatureIntro.bodySize), signatureIntro, \"signature\");\n\tfor (let offset = signatureIntro.bodySize; offset < signatureBodyAndPadding.byteLength; offset++) {\n\t\tif (signatureBodyAndPadding[offset] !== 0) {\n\t\t\tthrow new ArchiveError(\"Invalid RPM package: non-zero signature alignment padding\");\n\t\t}\n\t}\n\n\tconst mainIntroBytes = await readExact(\n\t\tsource,\n\t\tmainHeaderOffset,\n\t\tmainHeaderOffset + RPM_HEADER_INTRO_SIZE,\n\t\t\"main header intro\",\n\t);\n\tconst mainIntro = parseHeaderIntro(mainIntroBytes, options, \"main\");\n\tassertIndexSize(signatureIntro.totalSize + mainIntro.totalSize, options.limits, \"RPM headers\");\n\tconst mainBodyOffset = mainHeaderOffset + RPM_HEADER_INTRO_SIZE;\n\tconst mainBody = await readExact(source, mainBodyOffset, mainBodyOffset + mainIntro.bodySize, \"main header\");\n\tconst metadata = parseMainHeader(mainBody, mainIntro);\n\tconst identity = rpmIdentity(metadata, leadName);\n\tif (metadata.payloadFormat && metadata.payloadFormat.toLowerCase() !== \"cpio\") {\n\t\tthrow new ArchiveError(`RPM package '${identity}' uses unsupported payload format '${metadata.payloadFormat}'`);\n\t}","sourceCodeStart":260,"sourceCodeEnd":296,"githubUrl":"https://github.com/can1357/oh-my-pi/blob/969062200754ea02cfac922e5ebb8c608c079e15/packages/utils/src/ar/rpm.ts#L260-L296","documentation":"readRpmArchive validates that the 8-byte alignment padding between the RPM signature header body and the main header is all zero bytes, as required by the RPM file format. A non-zero byte in this padding means the package is malformed, corrupted, or hand-crafted, so the library refuses to parse it rather than guessing at the layout.","triggerScenarios":"Calling readRpm/readRpmArchive on an RPM file whose signature header body size is not 8-byte aligned and whose padding bytes are non-zero (corrupt download, truncated-and-reassembled file, maliciously crafted package).","commonSituations":"Partially downloaded or re-uploaded .rpm files; packages produced by non-rpm tooling that writes junk padding; deliberate fuzzing/malware-crafted archives.","solutions":["Re-download or re-export the .rpm from a trusted source and verify its checksum.","Rebuild the package with standard rpmbuild so headers are correctly 8-byte aligned.","If you must accept such files, copy them and zero the padding region before parsing (only for trusted data)."],"exampleFix":"// before (trusting a possibly corrupt file)\nawait readRpm(source);\n// after (verify integrity first)\nconst ok = (await Bun.file(\"pkg.rpm\").slice()).size && await verifyChecksum(\"pkg.rpm\", expectedSha256);\nif (!ok) throw new Error(\"RPM download corrupt\");\nawait readRpm(source);","handlingStrategy":"validation","validationCode":"// check 8-byte alignment padding zero-ness before parsing\nfunction signaturePaddingIsClean(bytes: Uint8Array, bodyStart: number, bodySize: number): boolean {\n  const padEnd = Math.min(bodyStart + bodySize + 8, bytes.byteLength);\n  for (let i = bodyStart + bodySize; i < padEnd; i++) if (bytes[i] !== 0) return false;\n  return true;\n}","typeGuard":null,"tryCatchPattern":"try {\n  const entries = await readRpm(source);\n} catch (err) {\n  if (err instanceof ArchiveError && err.message.includes(\"alignment padding\")) {\n    // treat as corrupt/untrusted package; refuse or re-fetch\n  } else throw err;\n}","preventionTips":["Verify package checksums (sha256) against the repository before parsing","Only parse RPMs built by standard rpmbuild tooling","Treat padding violations as untrusted input, never attempt in-place repair"],"tags":["rpm","archive","corruption","validation"],"backgroundTag":"archive-header-corruption","analyzedSha":"969062200754ea02cfac922e5ebb8c608c079e15","analyzedAt":"2026-08-31T10:29:35.737Z","schemaVersion":2},"datasetVersion":"2026-08-31T14:17:45.589Z"}