Hi, Konstantin, In log_replay, enum_rstbl didn't check the real size of the entry. It traverses based on RESTART_TABLE.size. There is a lack of boundary check if the real size is not equal to RESTART_TABLE.size. Here is a PoC to reproduce. PoC: 1) Found NTFS_RESTART by CLIENT_REC[0].restart_lsn NTFS_RESTART.open_attr_table_lsn: LSN where PoC is located NTFS_RESTART.open_attr_len: 0x1 2) Layout PoC as follow in a LSN area as follow: LFS_RECORD_HDR.this_lsn: 0x28455b LFS_RECORD_HDR.client_prev_lsn: 0x0 LFS_REOCRD_HDR.client_undo_next_lsn: 0x0 LFS_RECORD_HDR.client_data_len: 0x98 LFS_RECORD_HDR.CLIENT_ID.seq_num: 0x0 LFS_RECORD_HDR.CLIENT_ID.client_idx: 0x0 LFS_RECORD_HDR.record_type: 0x1 LFS_RECORD_HDR.transact_id: 0x18 LFS_RECORD_HDR.flags: 0x4 LOG_REC_HDR.redo_op: 0x0 LOG_REC_HDR.undo_op: 0x0 LOG_REC_HDR.redo_off: 0x98-sizeof(RESTART_TABLE)-RESTART_TABLE.size (redo_off&7 != 0) LOG_REC_HDR.redo_len: 0x0 LOG_REC_HDR.undo_off: 0x0 LOG_REC_HDR.undo_len: 0x0 LOG_REC_HDR.target_attr: 0x0 LOG_REC_HDR.lcns_follow: 0x0 LOG_REC_HDR.record_off: 0x0 LOG_REC_HDR.attr_off: 0x0 LOG_REC_HDR.cluster_off: 0x0 LOG_REC_HDR.reserved: 0x0 LOG_REC_HDR.target_vcn: 0x0 LOG_REC_HDR.page_lcns[0]: 0x0 RESTART_TABLE.size: 8 RESTART_TABLE.used: 0x1 RESTART_TABLE.total: 0x1 RESTART_TABLE.res[0]: 0x0 RESTART_TABLE.res[1]: 0x0 RESTART_TABLE.res[2]: 0x0 RESTART_TABLE.free_goal: 0x0 RESTART_TABLE.first_free: 0x0 RESTART_TABLE.last_free: 0x0 entry[0][0:4]: 0xFFFFFFFF (OPEN_ATTR_ENRTY[0].next) OPEN_ATTR_ENRTY[0].bytes_per_index: 0x0 In the patch, taking DIR_PAGE_ENTRY_32/DIR_PAGE_ENTRY as an example, there are two situations: [1] https://elixir.bootlin.com/linux/v6.10-rc4/source/fs/ntfs3/fslog.c#L4186 If entry is DIR_PAGE_ENTRY_32, it seems to explain it as DIR_PAGE_ENTRY, but the entry size is still DIR_PAGE_ENTRY_32, so we use sizeof(struct DIR_PAGE_ENTRY_32) [2] https://elixir.bootlin.com/linux/v6.10-rc4/source/fs/ntfs3/fslog.c#L4206 - If entry is DIR_PAGE_ENTRY directly, we use sizeof(*dp) - If entry is DIR_PAGE_ENTRY_32, but it is explained as DIR_PAGE_ENTRY. Because We check it in [1], and sizeof(struct DIR_PAGE_ENTRY) is smaller, so we also use sizeof(*dp) Thanks, LL