The root issue is sqfs_cache_add always reserved an allocated space
before a read failure occurred. When the failure then happened, the
entry was still "alive" and later would be discarded, causing
segfaults.
Now when these failures occur, we mark the entry as invalid. Since
"in-place construction" didn't complete, we don't call discard.
This crash was reproducible by simply adding a return SQFS_ERR; in
sqfs_data_block_read. Before this fix, the process would crash (and
ASAN would verify this); with this fix, the process stays up and the
caller receives an Input/output error instead.
The root issue is sqfs_cache_add always reserved an allocated space before a read failure occurred. When the failure then happened, the entry was still "alive" and later would be discarded, causing segfaults.
Now when these failures occur, we mark the entry as invalid. Since "in-place construction" didn't complete, we don't call discard.
This crash was reproducible by simply adding a
return SQFS_ERR;
insqfs_data_block_read
. Before this fix, the process would crash (and ASAN would verify this); with this fix, the process stays up and the caller receives anInput/output error
instead.