From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-alma10-1.taild15c8.ts.net [100.103.45.18]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id DAA0F35F8D1 for ; Thu, 21 May 2026 08:33:35 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=100.103.45.18 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1779352417; cv=none; b=mIez7tdA96G3lZwtU65eiO0wflbCJqAeC3hKFu9QkQFIkA0OTSeDty2r3/Ot6y9naUfTb86wBTMVGc3dU1rSz5u01VSS1jAPIsyUX98lBPs80V8tn670DjV0iz8PNRg9r3C5g+HXNZvakgVxjwIe7Uus0qpSH0lYugSYrEjZ+Bc= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1779352417; c=relaxed/simple; bh=iCQxr4xbMb/MRk02hRL2dNy4loo5BCigANgIlmBAbdU=; h=Message-ID:Date:MIME-Version:Cc:Subject:To:References:From: In-Reply-To:Content-Type; b=jv6FEA8PpRtkN09sJQduwqjy9IOwxui89nAn/zuM7MR73MrDOPboWMN3JVQFzDjzXaQmlBlVnJssIDs7tAfZ/RQTIXBYQh6iM3UntWX0McE4T8tAgxxlDAjTDbiIygiWBeb6RcctPzM3uRtuVB16IIUGHazD3qNq45FE8m7JoQs= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=JqMYXInT; arc=none smtp.client-ip=100.103.45.18 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="JqMYXInT" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 4C95E1F000E9; Thu, 21 May 2026 08:33:33 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=kernel.org; s=k20260515; t=1779352415; bh=5uJVI5XPO57gLyBlcGvJvIzQZOz39KDgj0mLzTJ0SEE=; h=Date:Cc:Subject:To:References:From:In-Reply-To; b=JqMYXInTXLOTnQ/+LI3w7ERAT6rmRKIC4PTUF6zZgYIbESP31XsNYpWufdQoupT15 hPssy4mk8qFf+9UNfitS0XFr/O2lxDSPCeoGRVgRAaCRryoSxx/UCmAlmXFrpVXIBR fjystY/werxZ7pYrV7x0R6zkPMOYDykm6QiunHndoPyAXzn9Mmf5EbFkUQK/nS8/3J +Zj28Ak5TF5HmdUnRwTc9YUqi6MaJOEW3yuiavTQsn7MJCx9EHxEUOplLphordCv7m xQrqdlb5kTcaLfClAZ936iDvYdWGhyqlf18PU2QRGLAme1zRg5uJTjYuv8Wme2J/g4 Xm0akkqv9gCvg== Message-ID: <72ad802a-040d-43f4-9679-225f0b8c716e@kernel.org> Date: Thu, 21 May 2026 16:33:30 +0800 Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 User-Agent: Mozilla Thunderbird Cc: chao@kernel.org, linux-f2fs-devel@lists.sourceforge.net, linux-kernel@vger.kernel.org, qiwenjie@xiaomi.com Subject: Re: [PATCH] f2fs: fix user.fadvise xattr input validation To: Wenjie Qi , jaegeuk@kernel.org References: <20260520141935.1363513-1-qiwenjie@xiaomi.com> Content-Language: en-US From: Chao Yu In-Reply-To: <20260520141935.1363513-1-qiwenjie@xiaomi.com> Content-Type: text/plain; charset=UTF-8; format=flowed Content-Transfer-Encoding: 7bit On 5/20/26 22:19, Wenjie Qi wrote: > The user.fadvise xattr handler reads an unsigned int directly from value, > but it is also reached by xattr removal and does not validate the supplied > value length. > > removexattr("user.fadvise") calls the xattr set callback with value == NULL > and size == 0, which can dereference NULL. A normal setxattr() call with a > short value, including size == 0, can also make the handler read past the > provided value buffer. > > Treat a NULL value as clearing the large-folio inode registration. Reject > non-NULL user.fadvise values whose length is not exactly > sizeof(unsigned int) before reading the value. > Cc: stable@kernel.org > Fixes: 39774f27deaf ("f2fs: another way to set large folio by remembering inode number") > Signed-off-by: Wenjie Qi > --- > fs/f2fs/xattr.c | 13 +++++++++++-- > 1 file changed, 11 insertions(+), 2 deletions(-) > > diff --git a/fs/f2fs/xattr.c b/fs/f2fs/xattr.c > index 84273936f2a..4e11d774a2c 100644 > --- a/fs/f2fs/xattr.c > +++ b/fs/f2fs/xattr.c > @@ -80,10 +80,19 @@ static int f2fs_xattr_generic_get(const struct xattr_handler *handler, > buffer, size, NULL); > } > > -static int f2fs_xattr_fadvise_set(struct inode *inode, const void *value) > +static int f2fs_xattr_fadvise_set(struct inode *inode, const void *value, > + size_t size) > { > unsigned int new_fadvise; > Better to add a comment here to describe it's from removexattr("user.fadvise") path? Thanks, > + if (!value) { > + f2fs_remove_ino_entry(F2FS_I_SB(inode), > + inode->i_ino, LARGE_FOLIO_INO); > + return 0; > + } > + if (size != sizeof(new_fadvise)) > + return -EINVAL; > + > new_fadvise = *(unsigned int *)value; > > if (new_fadvise & BIT(F2FS_XATTR_FADV_LARGEFOLIO)) > @@ -116,7 +125,7 @@ static int f2fs_xattr_generic_set(const struct xattr_handler *handler, > } > if (handler->flags == F2FS_XATTR_INDEX_USER && > !strcmp(name, "fadvise")) > - return f2fs_xattr_fadvise_set(inode, value); > + return f2fs_xattr_fadvise_set(inode, value, size); > > return f2fs_setxattr(inode, handler->flags, name, > value, size, NULL, flags);