]> git.hungrycats.org Git - linux/commitdiff
fs/ntfs3: Add a check for attr_names and oatbl
authorKonstantin Komarov <almaz.alexandrovich@paragon-software.com>
Mon, 3 Jun 2024 10:13:17 +0000 (13:13 +0300)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Sat, 27 Jul 2024 09:36:15 +0000 (11:36 +0200)
commit 702d4930eb06dcfda85a2fa67e8a1a27bfa2a845 upstream.

Added out-of-bound checking for *ane (ATTR_NAME_ENTRY).

Reported-by: lei lu <llfamsec@gmail.com>
Fixes: 865e7a7700d93 ("fs/ntfs3: Reduce stack usage")
Signed-off-by: Konstantin Komarov <almaz.alexandrovich@paragon-software.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
fs/ntfs3/fslog.c

index 4085fe30bf481e039a7846cadd1cc5d385a1b631..2e2348f8e285fbe7f778091443d87bc68ff5bcd1 100644 (file)
@@ -3722,6 +3722,8 @@ int log_replay(struct ntfs_inode *ni, bool *initialized)
 
        u64 rec_lsn, checkpt_lsn = 0, rlsn = 0;
        struct ATTR_NAME_ENTRY *attr_names = NULL;
+       u32 attr_names_bytes = 0;
+       u32 oatbl_bytes = 0;
        struct RESTART_TABLE *dptbl = NULL;
        struct RESTART_TABLE *trtbl = NULL;
        const struct RESTART_TABLE *rt;
@@ -3736,6 +3738,7 @@ int log_replay(struct ntfs_inode *ni, bool *initialized)
        struct NTFS_RESTART *rst = NULL;
        struct lcb *lcb = NULL;
        struct OPEN_ATTR_ENRTY *oe;
+       struct ATTR_NAME_ENTRY *ane;
        struct TRANSACTION_ENTRY *tr;
        struct DIR_PAGE_ENTRY *dp;
        u32 i, bytes_per_attr_entry;
@@ -4314,17 +4317,40 @@ check_attr_table:
        lcb = NULL;
 
 check_attribute_names2:
-       if (rst->attr_names_len && oatbl) {
-               struct ATTR_NAME_ENTRY *ane = attr_names;
-               while (ane->off) {
+       if (attr_names && oatbl) {
+               off = 0;
+               for (;;) {
+                       /* Check we can use attribute name entry 'ane'. */
+                       static_assert(sizeof(*ane) == 4);
+                       if (off + sizeof(*ane) > attr_names_bytes) {
+                               /* just ignore the rest. */
+                               break;
+                       }
+
+                       ane = Add2Ptr(attr_names, off);
+                       t16 = le16_to_cpu(ane->off);
+                       if (!t16) {
+                               /* this is the only valid exit. */
+                               break;
+                       }
+
+                       /* Check we can use open attribute entry 'oe'. */
+                       if (t16 + sizeof(*oe) > oatbl_bytes) {
+                               /* just ignore the rest. */
+                               break;
+                       }
+
                        /* TODO: Clear table on exit! */
-                       oe = Add2Ptr(oatbl, le16_to_cpu(ane->off));
+                       oe = Add2Ptr(oatbl, t16);
                        t16 = le16_to_cpu(ane->name_bytes);
+                       off += t16 + sizeof(*ane);
+                       if (off > attr_names_bytes) {
+                               /* just ignore the rest. */
+                               break;
+                       }
                        oe->name_len = t16 / sizeof(short);
                        oe->ptr = ane->name;
                        oe->is_attr_name = 2;
-                       ane = Add2Ptr(ane,
-                                     sizeof(struct ATTR_NAME_ENTRY) + t16);
                }
        }