[<prev] [next>] [day] [month] [year] [list]
Message-ID: <AE8DCEC7-6056-4D70-9EA6-F312350BA767@purdue.edu>
Date: Wed, 29 Dec 2021 02:23:31 +0000
From: "Gong, Sishuai" <sishuai@...due.edu>
To: "linux-kernel@...r.kernel.org" <linux-kernel@...r.kernel.org>
CC: Christoph Hellwig <hch@....de>,
"jlbec@...lplan.org" <jlbec@...lplan.org>
Subject: Re: [PATCH] configfs: fix a race in configfs_lookup()
Sorry, this email was delayed by several months due to some network
issues on my machine.
Please simply ignore it, since the bug mentioned is fixed already by
the commit c42dd069be8dfc9b2239a5c89e73bbd08ab35de0.
> On Dec 28, 2021, at 8:35 PM, Sishuai Gong <sishuai@...due.edu> wrote:
>
> From: sishuaigong <sishuai@...due.edu>
>
> When configfs_lookup() is executing list_for_each_entry(),
> it is possible that configfs_dir_lseek() is calling list_del().
> Some unfortunate interleavings of them can cause a kernel NULL
> pointer dereference error
>
> Thread 1 Thread 2
> //configfs_dir_lseek() //configfs_lookup()
> list_del(&cursor->s_sibling);
> list_for_each_entry(sd, ...)
>
> Fix this bug by using list_for_each_entry_safe() instead.
>
> Reported-by: Sishuai Gong <sishuai@...due.edu>
> Signed-off-by: sishuaigong <sishuai@...due.edu>
> ---
> fs/configfs/dir.c | 4 ++--
> 1 file changed, 2 insertions(+), 2 deletions(-)
>
> diff --git a/fs/configfs/dir.c b/fs/configfs/dir.c
> index ac5e0c0e9181..8f5d0309fb4a 100644
> --- a/fs/configfs/dir.c
> +++ b/fs/configfs/dir.c
> @@ -452,7 +452,7 @@ static struct dentry * configfs_lookup(struct inode *dir,
> unsigned int flags)
> {
> struct configfs_dirent * parent_sd = dentry->d_parent->d_fsdata;
> - struct configfs_dirent * sd;
> + struct configfs_dirent *sd, *tmp;
> int found = 0;
> int err;
>
> @@ -468,7 +468,7 @@ static struct dentry * configfs_lookup(struct inode *dir,
> if (!configfs_dirent_is_ready(parent_sd))
> goto out;
>
> - list_for_each_entry(sd, &parent_sd->s_children, s_sibling) {
> + list_for_each_entry_safe(sd, tmp, &parent_sd->s_children, s_sibling) {
> if (sd->s_type & CONFIGFS_NOT_PINNED) {
> const unsigned char * name = configfs_get_name(sd);
>
> --
> 2.17.1
>
Powered by blists - more mailing lists