rpmdb/rpmdb.c (rpmdbNextIterator):
2381 top:
2382 uh = NULL;
2383 uhlen = 0;
2384
2385 do {
2386 union _dbswap mi_offset;
2387
2388 if (mi->mi_set) {
2389 if (!(mi->mi_setx < mi->mi_set->count))
2390 return NULL;
2391 mi->mi_offset = dbiIndexRecordOffset(mi->mi_set, mi->mi_setx);
2392 mi->mi_filenum = dbiIndexRecordFileNumber(mi->mi_set, mi->mi_setx);
2393 mi_offset.ui = mi->mi_offset;
2394 if (dbiByteSwapped(dbi) == 1)
2395 _DBSWAP(mi_offset);
2396 keyp = &mi_offset;
2397 keylen = sizeof(mi_offset.ui);
2398 } else {
* 2399 key->data = (void *)mi->mi_keyp;
2400 key->size = (UINT32_T) mi->mi_keylen;
2401 data->data = uh;
2402 data->size = (UINT32_T) uhlen;
2403 #if !defined(_USE_COPY_LOAD)
2404 data->flags |= DB_DBT_MALLOC;
2405 #endif
2406 rc = dbiGet(dbi, mi->mi_dbc, key, data,
2407 (key->data == NULL ? DB_NEXT : DB_SET));
2408 data->flags = 0;
2409 keyp = key->data;
2410 keylen = key->size;
2411 uh = data->data;
2412 uhlen = data->size;
2413
2414 /*
2415 * If we got the next key, save the header instance number.
2416 *
2417 * For db3 Packages, instance 0 (i.e. mi->mi_setx == 0) is the
2418 * largest header instance in the database, and should be
2419 * skipped.
2420 */
2421 if (keyp && mi->mi_setx && rc == 0) {
2422 memcpy(&mi_offset, keyp, sizeof(mi_offset.ui));
2423 if (dbiByteSwapped(dbi) == 1)
2424 _DBSWAP(mi_offset);
2425 mi->mi_offset = (unsigned) mi_offset.ui;
2426 }
2427
2428 /* Terminate on error or end of keys */
2429 /*@-compmempass@*/
2430 if (rc || (mi->mi_setx && mi->mi_offset == 0))
2431 return NULL;
2432 /*@=compmempass@*/
2433 #ifdef REFERENCE
2434 if (mi->mi_offset & 0xffff0000) {
2435 fprintf(stderr, "*** damaged key 0x%x reset to 0\n", mi->mi_offset);
2436 mi->mi_offset = 0;
2437 }
2438 #endif
2439 }
2440 mi->mi_setx++;
2441 } while (mi->mi_offset == 0);
...
2532 if (mi->mi_h == NULL || !headerIsEntry(mi->mi_h, RPMTAG_NAME)) {
2533 rpmlog(RPMLOG_ERR,
2534 _("rpmdb: damaged header #%u retrieved -- skipping.\n"),
2535 mi->mi_offset);
* 2536 goto top;
2537 }
This code is subject to infinite loop.
Consider how it is called:
mi = rpmdbInitIterator(db, RPMDBI_PACKAGES, hdrNum, sizeof(hdrNum));
h = rpmdbNextIterator(mi);
and consider that the header indentified with hdrNum is damaged.
What happens then? In line 2536, you "goto top". And on top,
mi->mi_set is epmty (because it is not index-to-join-key lookup),
and key->data is hdrNum. This means that dbiGet gets called with
DB_SET, you get the same header which is damaged etc.
(I'll try to fix this but I'm not sure what's the best way to fix
this yet.)
- application/pgp-signature attachment: stored
Received on Sun Aug 24 16:27:23 2008