RPM Community Forums

Mailing List Message of <rpm-devel>

Re: damaged headers are due to FILESTATES RPM_CHAR_TYPE

From: Jeff Johnson <n3npq@mac.com>
Date: Fri 29 Aug 2008 - 16:25:16 CEST
Message-id: <24948425-5C6B-442E-BF24-97A7D3A34658@mac.com>

On Aug 29, 2008, at 6:11 AM, Alexey Tourbin wrote:

>>
>>
>> RPMTAG_FILESTATES is the only tag that was ever type'd as  
>> RPM_CHAR_TYPE
>> iirc. And here are the uses, none of the code is directly on a query
>> code path (this is HEAD):
>
> There's a code that handles this case.
>
> rpmdb/header_internal.c:
>     36  int headerVerifyInfo(rpmuint32_t il, rpmuint32_t dl, const  
> void * pev, void * iv, int negate)
>     37  {
>     38  /*@-castexpose@*/
>     39      entryInfo pe = (entryInfo) pev;
>     40  /*@=castexpose@*/
>     41      entryInfo info = iv;
>     42      rpmuint32_t i;
>     43
> (The following line was added by me.)
>     44      fprintf(stderr, "headerVerifyInfo\n");
>     45
>     46      for (i = 0; i < il; i++) {
>     47          info->tag = (rpmuint32_t) ntohl(pe[i].tag);
>     48          info->type = (rpmuint32_t) ntohl(pe[i].type);
>     49          /* XXX Convert RPMTAG_FILESTATE to RPM_UINT8_TYPE. */
>     50          if (info->tag == 1029 && info->type == 1) {
>     51              info->type = RPM_UINT8_TYPE;
>     52              pe[i].type = (rpmuint32_t) htonl(info->type);
>     53          }
>

After 1st cup of coffee, I can actually see my cryptic note-to-self  
and now
start to understand the issue.

Line #52 is changing a value directly in the plaintext of a header.

Normally the header plaintext cannot be altered because of the header  
SHA1 digest
checks, performed the 1st time a header is read, and ever time that a  
header is
unloaded and written to an rpmdb.

However RPMTAG_FILESTATES is appended to the original package header
during install and so is outside the plaintext that is digest  
verified before a header is
added to an rpmdb. Which is why I attempted the retrofit.

However, the address that is modified has a scope associated, see the  
code
paths under _USE_COPY_LOAD in rpmdb/rpmdb.c that are forced in order
to attempt weird legacy retrofit on-the-fly hackery like line #52. In  
almost
all rpmdb access cases the Berkeley DB scoping "valid until next db  
call"
could (and likely should for performance reasons) be used instead.

Doing the legacy retrofit in headerVerifyInfo() was expedient because  
it was
the deepest common code path for rpmdb access. Other approaches could
be attempted, but the intent was (and is) to eliminate RPM_CHAR_TYPE
everywhere, and use RPM_UINT8_TYPE instead.

That's the start of the explanation for why --whatprovides sees bad  
headers
while other rpmdb accesses do not.

It will be fascinating (to me ;-) to find the root cause for bad  
headers with
--whatprovides but not other accesses.
Received on Fri Aug 29 16:26:35 2008
Driven by Jeff Johnson and the RPM project team.
Hosted by OpenPKG and Ralf S. Engelschall.
Powered by FreeBSD and OpenPKG.