Re: [PATCH v2] ntfs3: Add bounds checking to enum_rstbl()

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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




[Index of Archives]     [Linux Driver Backports]     [DMA Engine]     [Linux GPIO]     [Linux SPI]     [Video for Linux]     [Linux USB Devel]     [Linux Coverity]     [Linux Audio Users]     [Linux Kernel]     [Linux SCSI]     [Yosemite Backpacking]
  Powered by Linux