From e587e1918cca570111fa697d4c6116829171bf56 Mon Sep 17 00:00:00 2001 From: Panu Matilainen Date: Fri, 19 Jan 2024 16:25:06 +0200 Subject: [PATCH] First attempt at technical documentation for header regions There are all sorts of details missing still, but it's a start. --- docs/CMakeLists.txt | 1 - docs/manual/format_header.md | 43 +++++++++++++++++ docs/manual/hregions.md | 91 ------------------------------------ docs/manual/index.md | 1 - 4 files changed, 43 insertions(+), 93 deletions(-) delete mode 100644 docs/manual/hregions.md diff --git a/docs/CMakeLists.txt b/docs/CMakeLists.txt index 14646215d3..3f15a34451 100644 --- a/docs/CMakeLists.txt +++ b/docs/CMakeLists.txt @@ -37,7 +37,6 @@ install(FILES manual/file_triggers.md manual/format_v3.md manual/format_v4.md - manual/hregions.md manual/index.md manual/large_files.md manual/lua.md diff --git a/docs/manual/format_header.md b/docs/manual/format_header.md index b15a92fbde..abc4cb16b6 100644 --- a/docs/manual/format_header.md +++ b/docs/manual/format_header.md @@ -158,3 +158,46 @@ could start at byte 589, byte that is an improper boundary for an INT32. As a result, 3 null bytes are inserted and the date for the SIZE actually starts at byte 592: "00 09 9b 31", which is 629553). +## Immutable regions + +RPM v4 introduced the concept of contiguous immutable header regions +which allow the original header data to be digitally verified even after +modifying the data. This is done with special tags which keep track +of a contiguous region (i.e. the original header). + +These region tags are technically like any other tag with associated +binary data and thus fully backwards compatible. The special part is the +interpretation of the region tag data, called the trailer, which looks +like a Index Entry despite residing in the Data section, + +A region Index Entry looks like this: + +Field | Value +--------|------ +tag | 62 or 63 (HEADERIMMUTABLE or HEADERSIGNATURES) +type | BIN +offset | Offset to the region trailer in the Data section +count | 16 + +And the region trailer in the Data section: + +Field | Value +--------|------ +tag | Must equal the Index Entry (ie 62 or 63) +type | BIN +offset | Size of the region entries in the Index +count | 16 + +The number of entries in the region (aka region index length) can thus be +calculated as `ril = -offset / sizeof(struct index_entry)`. + +When reading a package from disk, the number of region entries is expected +to be the same as the index length in the Intro. However when a package +is installed, extra data such as the install time is added to the header, +that data falls outside the otherwise invisible region line in the index. +These tags outside the immutable region are called "dribbles" in the RPM +lore. + +With the aid of regions and dribbles, it's possible to add, modify and +delete header data but still pull out the original contents at will. +It gets complicated. diff --git a/docs/manual/hregions.md b/docs/manual/hregions.md deleted file mode 100644 index 681f4aa135..0000000000 --- a/docs/manual/hregions.md +++ /dev/null @@ -1,91 +0,0 @@ ---- -layout: default -title: rpm.org - Immutable header regions ---- -# Immutable header regions in rpm-4.0.1 and later - -The header data structure has changed in rpm-4.0.[12] to preserve the -original header from a package. The goal is to keep the original -header intact so that metadata can be verified separately from the -payload by the RHN up2date client and by the rpm command line verify -mode using signatures saved in the rpm database. I believe the change -is entirely forward and backward compatible, and will not require -any artifacts like changing the version number of packaging or -adding an "rpmlib(...)" tracking dependency. We'll see ... - -Here's a short description of the change. An rpm header has three sections: -``` - 1) intro (# entries in index, # bytes of data) - 2) index 16 byte entries, one per tag, big endian - 3) data tag values, properly aligned, big endian -``` - -Representing sections in the header (ignoring the intro) with -``` - A,B,C index entries sorted by tag number - a,b,c variable length entry data - | boundary between index/data -``` -a header with 3 tag/value pairs (A,a) can be represented something like -``` - ABC|abc -``` - -The change is to introduce a new tag that keeps track of a contiguous -region (i.e. the original header). Representing the boundaries with -square/angle brackets, an "immutable region" in the header thus becomes -``` - [ABC|abc] -``` -or more generally (spaces added for clarity) -``` - [ABC> QRS | [DEF> QRS | > QRS | < QRS XYZ | QRS D |