Files
scoutfs/utils
Auke Kok f55895d6b5 Guard print_log_merge_item against NULL parent-item value
Scoutfs print segfaults walking a log_merge btree that has more than one
level. print_btree_block() prints parent (level > 0) items via
print_block_ref(), which invokes the item callback with a NULL value to
print the key portion before printing the child ref:

	func(key, 0, 0, NULL, 0, arg);

Leaf-item printers handle this (e.g. print_srch_root_item guards with
"if (val)"), but print_log_merge_item immediately casts val and reads a
field, dereferencing NULL. Filesystems whose log_merge is a single leaf
block (height 1) never hit the parent path; one with height > 1 crashes
on the first parent item.

Observed on a system whose log_merge is height 2. The faulting address
is a small fixed offset (NULL + 8), not a wild pointer, and the crash
is in print_log_merge_item called from print_btree_block:

  [Mon Jun 15 10:46:17 2026] scoutfs[22043]: segfault at 8 ip 0000000000408ef0 sp 00007fffc5edd8b0 error 4 in scoutfs[402000+e000] likely on CPU 29 (core 9, socket 1)

  #0  0x0000000000408ef0 in print_log_merge_item ()
  #1  0x000000000040958d in print_btree_block.constprop.0.isra ()
  #2  0x000000000040a471 in print_cmd ()
  #3  0x0000000000404264 in cmd_execute ()
  #4  0x00000000004025c9 in main ()

The print stops at the first level-1 item (a 16-byte block_ref, matching
sizeof(struct scoutfs_block_ref)); the "[0]" line is emitted before the
callback at print_btree_block, and neither a decoded item line nor the
"ref blkno" line that print_block_ref prints after the callback appears,
so the crash is inside the callback with val == NULL:

  log_merge btree blkno 11477029
    crc 858a064c fsid 0000000000000000 seq 13289998818052716408 blkno 11477029
    total_item_bytes 7848 mid_free_len 57640
    level 1 nr_items 109 item_root.node 3600
    [0] off 104 par 128 l 0 r 0 h 1 vo 65504 vl 16
  Segmentation fault

Return early when val is NULL, and bounds-check val_len before each cast
so a short or malformed item is reported instead of read past its end.

Signed-off-by: Auke Kok <auke.kok@versity.com>
2026-06-15 10:53:48 -07:00
..
2018-06-29 14:42:08 -07:00