When choosing a different dentry for an inode being extracted, the code didn't
check if it was actually in the tree being extracted.
This bug could cause an infinite loop in extraction backends that required DOS
name reordering and also allowed extracting only a subset of an image---
currently, just the Windows backend.
* characters). Otherwise this will always be 0. */
u8 extraction_skipped : 1;
* characters). Otherwise this will always be 0. */
u8 extraction_skipped : 1;
+ /* For extraction operations, this flag will be set on dentries in the
+ * tree being extracted. */
+ u8 in_extraction_tree : 1;
+
+ /* During extraction extractions, this flag will be set after the
+ * "skeleton" of the dentry has been extracted. */
u8 skeleton_extracted : 1;
/* When capturing from a NTFS volume using NTFS-3g, this flag is set on
u8 skeleton_extracted : 1;
/* When capturing from a NTFS volume using NTFS-3g, this flag is set on
{
inode_for_each_dentry(other_dentry, dentry->d_inode) {
if (dentry_has_short_name(other_dentry)
{
inode_for_each_dentry(other_dentry, dentry->d_inode) {
if (dentry_has_short_name(other_dentry)
- && !other_dentry->skeleton_extracted)
+ && !other_dentry->skeleton_extracted
+ && other_dentry->in_extraction_tree)
{
DEBUG("Creating %"TS" before %"TS" "
"to guarantee correct DOS name extraction",
{
DEBUG("Creating %"TS" before %"TS" "
"to guarantee correct DOS name extraction",
struct apply_ctx *ctx = _args;
int ret;
struct apply_ctx *ctx = _args;
int ret;
+ dentry->in_extraction_tree = 1;
+
if (dentry == ctx->extract_root || dentry->extraction_skipped)
return 0;
if (dentry == ctx->extract_root || dentry->extraction_skipped)
return 0;
{
struct wim_inode *inode = dentry->d_inode;
{
struct wim_inode *inode = dentry->d_inode;
+ dentry->in_extraction_tree = 0;
dentry->extraction_skipped = 0;
dentry->was_hardlinked = 0;
dentry->skeleton_extracted = 0;
dentry->extraction_skipped = 0;
dentry->was_hardlinked = 0;
dentry->skeleton_extracted = 0;