If di_fname is not terminated by '\0', it can cause buffer overrun and
trigger a user-after-free bug. This can happen in some corrupted or
 malicious qnx4 image. Use strnlen to prevent buffer overrun.

[  513.248784] qnx4_readdir: bread failed (3718095557)
[  513.251109] BUG: KASAN: use-after-free in strlen+0x1f/0x40
[  513.251268] Read of size 1 at addr ffff888002700000 by task find/230
[  513.252069] Call Trace:
[  513.252869]  ? strlen+0x1f/0x40
[  513.253237]  strlen+0x1f/0x40
[  513.253329]  qnx4_lookup+0xab/0x220
[  513.253431]  __lookup_slow+0x103/0x220

Co-Developed-by: Anders Larsen <[email protected]>
Signed-off-by: Tong Zhang <[email protected]>
Signed-off-by: Anders Larsen <[email protected]>
---
v2: The name can grow longer than QNX4_SHORT_NAME_MAX if de is a
QNX4_FILE_LINK type and de should points to a qnx4_link_info struct, so
this is safe.  We also remove redundant checks in this version.
v3: make commit log short and resend

 fs/qnx4/namei.c | 4 +---
 1 file changed, 1 insertion(+), 3 deletions(-)

diff --git a/fs/qnx4/namei.c b/fs/qnx4/namei.c
index 8d72221735d7..2bcbbd7c772e 100644
--- a/fs/qnx4/namei.c
+++ b/fs/qnx4/namei.c
@@ -40,9 +40,7 @@ static int qnx4_match(int len, const char *name,
        } else {
                namelen = QNX4_SHORT_NAME_MAX;
        }
-       thislen = strlen( de->di_fname );
-       if ( thislen > namelen )
-               thislen = namelen;
+       thislen = strnlen( de->di_fname, namelen );
        if (len != thislen) {
                return 0;
        }
-- 
2.25.1

Reply via email to