mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
From: syzbot <syzbot+a2748ba908c108e7e525@syzkaller.appspotmail.com>
To: linux-kernel@vger.kernel.org, syzkaller-bugs@googlegroups.com
Subject: Forwarded: KASAN: slab-out-of-bounds Write in utf32_to_utf8
Date: Wed, 07 Oct 2026 08:42:57 -0700	[thread overview]
Message-ID: <6ac66881.a36481ec.1ba24c.0001.GAE@google.com> (raw)
In-Reply-To: <6ac3be67.34119e79.2f92f3.0035.GAE@google.com>

For archival purposes, forwarding an incoming command email to
linux-kernel@vger.kernel.org, syzkaller-bugs@googlegroups.com.

***

Subject: KASAN: slab-out-of-bounds Write in utf32_to_utf8
Author: j.bhargav.u@gmail.com

#syz test: git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
master

From 17072f0e3fe2eb3e6e6323c60b52f3dee8c02e82 Mon Sep 17 00:00:00 2001
From: Bhargav Joshi <j.bhargav.u@gmail.com>
Date: Wed, 7 Oct 2026 02:49:53 +0530
Subject: [PATCH] jfs: fix out-of-bounds write in jfs_readdir()

jfs_readdir() converts on-disk UTF-16 directory names into a
PAGE_SIZE buffer. The existing space check assumes that each UTF-16
unit produces one output byte:

if (((long) jfs_dirent + d->namlen + 1) >
   ((long)dirent_buf + PAGE_SIZE))

This is insufficient for multibyte NLS encodings, where a UTF-16 unit
can expand to multiple output bytes. jfs_strfromUCS_le() also passes
NLS_MAX_CHARSET_SIZE to uni2char() without accounting for the space
actually remaining in the destination buffer, allowing the conversion
to write past dirent_buf.

Pass remaining buffer size to jfs_strfromUCS_le, Ensure that at least
NLS_MAX_CHARSET_SIZE bytes remain before calling uni2char(). If the
remaining space is insufficient, return -ENAMETOOLONG so jfs_readdir()
can retry the entry in a fresh buffer.

Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
Reported-by: syzbot+a2748ba908c108e7e525@syzkaller.appspotmail.com
Closes: https://syzkaller.appspot.com/bug?extid=a2748ba908c108e7e525
Assisted-by: ChatGPT:LLM
Signed-off-by: Bhargav Joshi <j.bhargav.u@gmail.com>
---
 fs/jfs/jfs_dtree.c   | 24 ++++++++++++++++++++----
 fs/jfs/jfs_unicode.c | 14 ++++++++++++--
 fs/jfs/jfs_unicode.h |  2 +-
 3 files changed, 33 insertions(+), 7 deletions(-)

diff --git a/fs/jfs/jfs_dtree.c b/fs/jfs/jfs_dtree.c
index 8ce6e4458cc25..7b80c34e841db 100644
--- a/fs/jfs/jfs_dtree.c
+++ b/fs/jfs/jfs_dtree.c
@@ -2961,8 +2961,15 @@ int jfs_readdir(struct file *file, struct
dir_context *ctx)
  }

  /* copy the name of head/only segment */
- outlen = jfs_strfromUCS_le(name_ptr, d->name, len,
-   codepage);
+ outlen = jfs_strfromUCS_le(name_ptr,
+   (char *)dirent_buf +
+   PAGE_SIZE - name_ptr,
+   d->name, len, codepage);
+ if (outlen < 0) {
+ index = i;
+ overflow = 1;
+ break;
+ }
  jfs_dirent->name_len = outlen;

  /* copy name in the additional segment(s) */
@@ -2981,12 +2988,21 @@ int jfs_readdir(struct file *file, struct
dir_context *ctx)
  goto skip_one;
  }
  len = min(d_namleft, DTSLOTDATALEN);
- outlen = jfs_strfromUCS_le(name_ptr, t->name,
-   len, codepage);
+ outlen = jfs_strfromUCS_le(name_ptr,
+   (char *)dirent_buf +
+   PAGE_SIZE - name_ptr,
+   t->name, len, codepage);
+ if (outlen < 0) {
+ index = i;
+ overflow = 1;
+ break;
+ }
  jfs_dirent->name_len += outlen;

  next = t->next;
  }
+ if (overflow == 1)
+ break;

  jfs_dirents++;
  jfs_dirent = next_jfs_dirent(jfs_dirent);
diff --git a/fs/jfs/jfs_unicode.c b/fs/jfs/jfs_unicode.c
index 0c1e9027245a6..f73c718c5dd03 100644
--- a/fs/jfs/jfs_unicode.c
+++ b/fs/jfs/jfs_unicode.c
@@ -16,17 +16,25 @@
  * FUNCTION: Convert little-endian unicode string to character string
  *
  */
-int jfs_strfromUCS_le(char *to, const __le16 * from,
+int jfs_strfromUCS_le(char *to, int to_size, const __le16 *from,
       int len, struct nls_table *codepage)
 {
- int i;
+ int i, remaining_size;
  int outlen = 0;
  static int warn_again = 5; /* Only warn up to 5 times total */
  int warn = !!warn_again; /* once per string */

+ if (to_size <= 0)
+ return -ENAMETOOLONG;
+
  if (codepage) {
  for (i = 0; (i < len) && from[i]; i++) {
  int charlen;
+
+ remaining_size = to_size - outlen - 1;
+ if (remaining_size < NLS_MAX_CHARSET_SIZE)
+ return -ENAMETOOLONG;
+
  charlen =
     codepage->uni2char(le16_to_cpu(from[i]),
        &to[outlen],
@@ -38,6 +46,8 @@ int jfs_strfromUCS_le(char *to, const __le16 * from,
  }
  } else {
  for (i = 0; (i < len) && from[i]; i++) {
+ if (i >= to_size - 1)
+ return -ENAMETOOLONG;
  if (unlikely(le16_to_cpu(from[i]) & 0xff00)) {
  to[i] = '?';
  if (unlikely(warn)) {
diff --git a/fs/jfs/jfs_unicode.h b/fs/jfs/jfs_unicode.h
index b6a78d4aef1b0..ea03dd5a0e0cb 100644
--- a/fs/jfs/jfs_unicode.h
+++ b/fs/jfs/jfs_unicode.h
@@ -12,7 +12,7 @@
 #include "jfs_types.h"

 extern int get_UCSname(struct component_name *, struct dentry *);
-extern int jfs_strfromUCS_le(char *, const __le16 *, int, struct nls_table *);
+extern int jfs_strfromUCS_le(char *, int, const __le16 *, int, struct
nls_table *);

 #define free_UCSname(COMP) kfree((COMP)->name)

-- 
2.56.0

  parent reply	other threads:[~2026-10-07 15:42 UTC|newest]

Thread overview: 4+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-10-05 15:12 [syzbot] " syzbot
2026-10-06  5:53 ` Forwarded: [PATCH] jfs: fix slab-out-of-bounds write in jfs_readdir() with multibyte names syzbot
2026-10-07 15:42 ` syzbot [this message]
2026-10-07 18:06 ` Forwarded: KASAN: slab-out-of-bounds Write in utf32_to_utf8 syzbot

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=6ac66881.a36481ec.1ba24c.0001.GAE@google.com \
    --to=syzbot+a2748ba908c108e7e525@syzkaller.appspotmail.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=syzkaller-bugs@googlegroups.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

all inboxes | Powered by JetHome®