From mboxrd@z Thu Jan 1 00:00:00 1970 Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.remote-ip=100.103.45.18 ARC-Seal: i=1; d=subspace.kernel.org; s=arc20261015; a=rsa-sha256; cv=none; t=1794063203; b=gmGjHPJXJ6EPKylSxIaUNxWCjoGFzJ2gNZYY59Zet/wMIu2JF8EAQ7f4v8MRX43vEH5/ uFtwqorHlS2bBRNryumtz5Id8VZYbFM5Vf9J+L+TiNt2agvGB31qA63LJF2AREjAS7Mom OwzRdbHoyjqgIHATYv4UeAH20oLGjn/xQS513wfS9NjAEo8juFtGSau8Kgj3XIyHdAa0l UeBf3BBiPUxdwgl5dfMhwmGl7eOOQIbtIT/LmQL71JZZl4H8N+JVJw6mQ8MhFia9brzTF o1TteTyxlqag5+AIbFHdmcgB3phBrSs+NXM5hjSvxZZYQV74S/j1GmTaAqU3dQeMhMA== ARC-Message-Signature: i=1; d=subspace.kernel.org; s=arc20261015; a=rsa-sha256; c=relaxed/relaxed; t=1794063203; h=Received:DKIM-Signature:From:To:Cc:Subject:Date:Message-ID:X-Mailer: In-Reply-To:References:User-Agent:X-stable:X-Patchwork-Hint: MIME-Version:Content-Transfer-Encoding; bh=y5Z5OVGsn7xFFoPC/JeVslYUY0KMBUTKuDjdXyEsLDs=; b=tiPl4I/l8PMVq5nXMRY72DGLY4R4099OjmzJUMUO5niOSRgbBUy0Suce8+o8UHL6V9Hk 0fPGaMUkOc+X09kKR5CDcHlM55yCDC3JHx7cSMPaP77B82lxZxgzc4Pcs6o3r62QzmLKS 9j3AFbrY0TRHKY7nWFBIkqSLDze2nKJZLTyeBmXgaPrJMUQuoJkOInQRGtD1Ms26K9iKD hsGqhH2BSf+8NKcyHVqULiyP8Pi23Gpu+2rpHg1RXUUkD5PjrNks8FncQN9+7PmQY/MHw a7F8BZzAq43VESmn4DjTEW3CpCO1M3gnW7+g1GsShMNUWIhR4k/wi6QyMH3TB0vedow== ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass header.d=linuxfoundation.org header.i=@linuxfoundation.org header.a=rsa-sha256 header.s=korg header.b=ifONIc8T; arc=none smtp.remote-ip=100.103.45.18 Received: from smtp.kernel.org (quasi.space.kernel.org [100.103.45.18]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (prime256v1)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id BCE6F606D802; Sat, 7 Nov 2026 14:53:22 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=linuxfoundation.org header.i=@linuxfoundation.org header.a=rsa-sha256 header.s=korg header.b=ifONIc8T Received: by smtp.kernel.org (Postfix) with ESMTPSA id 282801F0089F; Sat, 7 Nov 2026 14:53:22 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linuxfoundation.org; s=korg; t=1794063202; bh=y5Z5OVGsn7xFFoPC/JeVslYUY0KMBUTKuDjdXyEsLDs=; h=From:To:Cc:Subject:Date:In-Reply-To:References; b=ifONIc8TDuS35cXX24K5skCCdjSYn4tvfrJX/Ykfz3e6+TWnZnRNVyJYZNnEU+K1c 7A3FEXFUjEYEgbjJgfrnpgjWM2PhUrOkZQF2NoXCeuVbdxghKyQVqYSW3XgIzJvyyU V4Nm/ULvgl5OSfHsdr/Dp3T2ITZUnAJRrMe9HwCs= From: Greg Kroah-Hartman To: stable@vger.kernel.org Cc: Greg Kroah-Hartman , patches@lists.linux.dev, Matthias Goergens , Jan Kara , Sasha Levin Subject: [PATCH 6.18 415/869] fanotify: report names longer than NAME_MAX Date: Sat, 7 Nov 2026 08:51:37 -0500 Message-ID: <20261107134907.475743090@linuxfoundation.org> X-Mailer: git-send-email 2.56.0 In-Reply-To: <20261107134852.069646174@linuxfoundation.org> References: <20261107134852.069646174@linuxfoundation.org> User-Agent: quilt/0.69 X-stable: review X-Patchwork-Hint: ignore X-Mailing-List: stable@vger.kernel.org List-Id: List-Post: List-Help: List-Subscribe: List-Unsubscribe: List-Owner: Precedence: list MIME-Version: 1.0 Content-Transfer-Encoding: 8bit 6.18-stable review patch. If anyone has any objections, please let me know. ------------------ From: Matthias Goergens [ Upstream commit ff05910cb1b77c2b229c5e6e260c6173a17b579b ] fanotify keeps the length of a reported name in a u8, so it drops any name longer than NAME_MAX and warns: WARNING: fs/notify/fanotify/fanotify.h:217 at fanotify_handle_event+0x2e82/0x39f0 Such names are legitimate on some filesystems. vfat mounted with utf8 takes up to 255 UTF-16 characters, which are up to 765 bytes of UTF-8, and FUSE accepts names up to PATH_MAX - 1. readdir() and inotify report them in full. fanotify sends the event without the name, and for FAN_RENAME it trips a second warning in copy_fid_info_to_user(), after which read() fails with EFAULT and the event is lost. When syzbot hit this, Jan suggested accommodating names up to PATH_MAX [1], the limit readdir() already applies to a name (verify_dirent_name()). Store the name lengths as u16, which keeps struct fanotify_info at 8 bytes, and drop without a warning only names of PATH_MAX bytes or more, which no path can refer to. An event with such a name can exceed a page, so allocate name events with kvmalloc(), as Jan also suggested. Names up to NAME_MAX are reported exactly as before, and the record format is unchanged: an event with a long name is just longer. Link: https://lore.kernel.org/all/20241112115059.ecvomkalee5m4i4i@quack3/ [1] Fixes: 2d9374f09513 ("fanotify: use macros to get the offset to fanotify_info buffer") Cc: stable@vger.kernel.org Signed-off-by: Matthias Goergens Link: https://patch.msgid.link/20260926020851.2938961-1-matthias.goergens@gmail.com Signed-off-by: Jan Kara Signed-off-by: Sasha Levin --- fs/notify/fanotify/fanotify.c | 7 +++++-- fs/notify/fanotify/fanotify.h | 21 ++++++++++++--------- 2 files changed, 17 insertions(+), 11 deletions(-) diff --git a/fs/notify/fanotify/fanotify.c b/fs/notify/fanotify/fanotify.c index cdb69c23e2e6c..bb12baebd0c94 100644 --- a/fs/notify/fanotify/fanotify.c +++ b/fs/notify/fanotify/fanotify.c @@ -650,6 +650,9 @@ static struct fanotify_event *fanotify_alloc_name_event(struct inode *dir, unsigned long name2_len = name2 ? name2->len : 0; unsigned int len, size; + if (WARN_ON_ONCE(name_len >= PATH_MAX || name2_len >= PATH_MAX)) + return NULL; + /* Reserve terminating null byte even for empty name */ size = sizeof(*fne) + name_len + name2_len + 2; if (dir_fh_len) @@ -658,7 +661,7 @@ static struct fanotify_event *fanotify_alloc_name_event(struct inode *dir, size += FANOTIFY_FH_HDR_LEN + dir2_fh_len; if (child_fh_len) size += FANOTIFY_FH_HDR_LEN + child_fh_len; - fne = kmalloc(size, gfp); + fne = kvmalloc(size, gfp); if (!fne) return NULL; @@ -1048,7 +1051,7 @@ static void fanotify_free_fid_event(struct fanotify_event *event) static void fanotify_free_name_event(struct fanotify_event *event) { - kfree(FANOTIFY_NE(event)); + kvfree(FANOTIFY_NE(event)); } static void fanotify_free_error_event(struct fsnotify_group *group, diff --git a/fs/notify/fanotify/fanotify.h b/fs/notify/fanotify/fanotify.h index eb2ba71d5c81a..775f55080dd4d 100644 --- a/fs/notify/fanotify/fanotify.h +++ b/fs/notify/fanotify/fanotify.h @@ -42,9 +42,16 @@ struct fanotify_info { u8 dir_fh_totlen; u8 dir2_fh_totlen; u8 file_fh_totlen; - u8 name_len; - u8 name2_len; - u8 pad[3]; + u8 pad; + /* + * Deliberately not limited to NAME_MAX: some filesystems return longer + * names (vfat up to 255 UTF-16 characters, as Windows allows, which is + * up to 765 bytes of UTF-8; FUSE up to PATH_MAX - 1), and readdir() and + * inotify report them in full. Only names of PATH_MAX bytes or more, + * which no path can refer to, are dropped. + */ + u16 name_len; + u16 name2_len; unsigned char buf[]; /* * (struct fanotify_fh) dir_fh starts at buf[0] @@ -167,7 +174,7 @@ static inline char *fanotify_info_name2(struct fanotify_info *info) static inline void fanotify_info_init(struct fanotify_info *info) { BUILD_BUG_ON(FANOTIFY_FH_HDR_LEN + MAX_HANDLE_SZ > U8_MAX); - BUILD_BUG_ON(NAME_MAX > U8_MAX); + BUILD_BUG_ON(PATH_MAX > U16_MAX); info->dir_fh_totlen = 0; info->dir2_fh_totlen = 0; @@ -213,8 +220,7 @@ static inline void fanotify_info_set_file_fh(struct fanotify_info *info, static inline void fanotify_info_copy_name(struct fanotify_info *info, const struct qstr *name) { - if (WARN_ON_ONCE(name->len > NAME_MAX) || - WARN_ON_ONCE(info->name2_len > 0)) + if (WARN_ON_ONCE(info->name2_len > 0)) return; info->name_len = name->len; @@ -224,9 +230,6 @@ static inline void fanotify_info_copy_name(struct fanotify_info *info, static inline void fanotify_info_copy_name2(struct fanotify_info *info, const struct qstr *name) { - if (WARN_ON_ONCE(name->len > NAME_MAX)) - return; - info->name2_len = name->len; strcpy(fanotify_info_name2(info), name->name); } -- 2.53.0