From: Chuck Lever <chuck.lever@oracle.com>
To: yangerkun <yangerkun@huaweicloud.com>
Cc: Yu Kuai <yukuai1@huaweicloud.com>, Chuck Lever <cel@kernel.org>,
linux-stable <stable@vger.kernel.org>,
"harry.wentland@amd.com" <harry.wentland@amd.com>,
"sunpeng.li@amd.com" <sunpeng.li@amd.com>,
"Rodrigo.Siqueira@amd.com" <Rodrigo.Siqueira@amd.com>,
"alexander.deucher@amd.com" <alexander.deucher@amd.com>,
"christian.koenig@amd.com" <christian.koenig@amd.com>,
"Xinhui.Pan@amd.com" <Xinhui.Pan@amd.com>,
"airlied@gmail.com" <airlied@gmail.com>,
Daniel Vetter <daniel@ffwll.ch>,
Al Viro <viro@zeniv.linux.org.uk>,
Christian Brauner <brauner@kernel.org>,
Liam Howlett <liam.howlett@oracle.com>,
Andrew Morton <akpm@linux-foundation.org>,
Hugh Dickins <hughd@google.com>,
"Matthew Wilcox (Oracle)" <willy@infradead.org>,
Greg KH <gregkh@linuxfoundation.org>,
Sasha Levin <sashal@kernel.org>,
"srinivasan.shanmugam@amd.com" <srinivasan.shanmugam@amd.com>,
"chiahsuan.chung@amd.com" <chiahsuan.chung@amd.com>,
"mingo@kernel.org" <mingo@kernel.org>,
"mgorman@techsingularity.net" <mgorman@techsingularity.net>,
"chengming.zhou@linux.dev" <chengming.zhou@linux.dev>,
"zhangpeng.00@bytedance.com" <zhangpeng.00@bytedance.com>,
"amd-gfx@lists.freedesktop.org" <amd-gfx@lists.freedesktop.org>,
"dri-devel@lists.freedesktop.org"
<dri-devel@lists.freedesktop.org>,
Linux Kernel Mailing List <linux-kernel@vger.kernel.org>,
Linux FS Devel <linux-fsdevel@vger.kernel.org>,
"maple-tree@lists.infradead.org" <maple-tree@lists.infradead.org>,
linux-mm <linux-mm@kvack.org>,
"yi.zhang@huawei.com" <yi.zhang@huawei.com>,
"yukuai (C)" <yukuai3@huawei.com>
Subject: Re: [RFC PATCH 6/6 6.6] libfs: fix infinite directory reads for offset dir
Date: Wed, 13 Nov 2024 10:17:39 -0500 [thread overview]
Message-ID: <ZzTDE+RN5d/mwUXl@tissot.1015granger.net> (raw)
In-Reply-To: <73a05cb9-569c-9b3c-3359-824e76b14461@huaweicloud.com>
On Mon, Nov 11, 2024 at 11:20:17PM +0800, yangerkun wrote:
>
>
> 在 2024/11/11 22:39, Chuck Lever III 写道:
> >
> >
> > > On Nov 10, 2024, at 9:36 PM, Yu Kuai <yukuai1@huaweicloud.com> wrote:
> > > I'm in the cc list ,so I assume you saw my set, then I don't know why
> > > you're ignoring my concerns.
> > > 1) next_offset is 32-bit and can overflow in a long-time running
> > > machine.
> > > 2) Once next_offset overflows, readdir will skip the files that offset
> > > is bigger.
>
> I'm sorry, I'm a little busy these days, so I haven't responded to this
> series of emails.
>
> > In that case, that entry won't be visible via getdents(3)
> > until the directory is re-opened or the process does an
> > lseek(fd, 0, SEEK_SET).
>
> Yes.
>
> >
> > That is the proper and expected behavior. I suspect you
> > will see exactly that behavior with ext4 and 32-bit
> > directory offsets, for example.
>
> Emm...
>
> For this case like this:
>
> 1. mkdir /tmp/dir and touch /tmp/dir/file1 /tmp/dir/file2
> 2. open /tmp/dir with fd1
> 3. readdir and get /tmp/dir/file1
> 4. rm /tmp/dir/file2
> 5. touch /tmp/dir/file2
> 4. loop 4~5 for 2^32 times
> 5. readdir /tmp/dir with fd1
>
> For tmpfs now, we may see no /tmp/dir/file2, since the offset has been
> overflow, for ext4 it is ok... So we think this will be a problem.
I constructed a simple test program using the above steps:
/*
* 1. mkdir /tmp/dir and touch /tmp/dir/file1 /tmp/dir/file2
* 2. open /tmp/dir with fd1
* 3. readdir and get /tmp/dir/file1
* 4. rm /tmp/dir/file2
* 5. touch /tmp/dir/file2
* 6. loop 4~5 for 2^32 times
* 7. readdir /tmp/dir with fd1
*/
#include <sys/types.h>
#include <sys/stat.h>
#include <dirent.h>
#include <errno.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdbool.h>
#include <stdio.h>
#include <string.h>
static void list_directory(DIR *dirp)
{
struct dirent *de;
errno = 0;
do {
de = readdir(dirp);
if (!de)
break;
printf("d_off: %lld\n", de->d_off);
printf("d_name: %s\n", de->d_name);
} while (true);
if (errno)
perror("readdir");
else
printf("EOD\n");
}
int main(int argc, char **argv)
{
unsigned long i;
DIR *dirp;
int ret;
/* 1. */
ret = mkdir("/tmp/dir", 0755);
if (ret < 0) {
perror("mkdir");
return 1;
}
ret = creat("/tmp/dir/file1", 0644);
if (ret < 0) {
perror("creat");
return 1;
}
close(ret);
ret = creat("/tmp/dir/file2", 0644);
if (ret < 0) {
perror("creat");
return 1;
}
close(ret);
/* 2. */
errno = 0;
dirp = opendir("/tmp/dir");
if (!dirp) {
if (errno)
perror("opendir");
else
fprintf(stderr, "EOD\n");
closedir(dirp);
return 1;
}
/* 3. */
errno = 0;
do {
struct dirent *de;
de = readdir(dirp);
if (!de) {
if (errno) {
perror("readdir");
closedir(dirp);
return 1;
}
break;
}
if (strcmp(de->d_name, "file1") == 0) {
printf("Found 'file1'\n");
break;
}
} while (true);
/* run the test. */
for (i = 0; i < 10000; i++) {
/* 4. */
ret = unlink("/tmp/dir/file2");
if (ret < 0) {
perror("unlink");
closedir(dirp);
return 1;
}
/* 5. */
ret = creat("/tmp/dir/file2", 0644);
if (ret < 0) {
perror("creat");
fprintf(stderr, "i = %lu\n", i);
closedir(dirp);
return 1;
}
close(ret);
}
/* 7. */
printf("\ndirectory after test:\n");
list_directory(dirp);
/* cel. */
rewinddir(dirp);
printf("\ndirectory after rewind:\n");
list_directory(dirp);
closedir(dirp);
return 0;
}
> > Does that not directly address your concern? Or do you
> > mean that Erkun's patch introduces a new issue?
>
> Yes, to be honest, my personal feeling is a problem. But for 64bit, it may
> never been trigger.
I ran the test program above on this kernel:
https://git.kernel.org/pub/scm/linux/kernel/git/cel/linux.git/log/?h=nfsd-testing
Note that it has a patch to restrict the range of directory offset
values for tmpfs to 2..4096.
I did not observe any unexpected behavior after the offset values
wrapped. At step 7, I can always see file2, and its offset is always
4. At step "cel" I can see all expected directory entries.
I tested on v6.12-rc7 with the same range restriction but using
Maple tree and 64-bit offsets. No unexpected behavior there either.
So either we're still missing something, or there is no problem. My
only theory is maybe it's an issue with an implicit integer sign
conversion, and we should restrict the offset range to 2..S32_MAX.
I can try testing with a range of (U32_MAX - 4096)..(U32_MAX).
> > If there is a problem here, please construct a reproducer
> > against this patch set and post it.
Invitation still stands: if you have a solid reproducer, please post
it.
--
Chuck Lever
next prev parent reply other threads:[~2024-11-13 15:19 UTC|newest]
Thread overview: 15+ messages / expand[flat|nested] mbox.gz Atom feed top
2024-11-11 0:52 [RFC PATCH 0/6 6.6] Address rename/readdir bugs in fs/libfs.c cel
2024-11-11 0:52 ` [RFC PATCH 1/6 6.6] libfs: Define a minimum directory offset cel
2024-11-11 0:52 ` [RFC PATCH 2/6 6.6] libfs: Add simple_offset_empty() cel
2024-11-11 0:52 ` [RFC PATCH 3/6 6.6] libfs: Fix simple_offset_rename_exchange() cel
2024-11-11 0:52 ` [RFC PATCH 4/6 6.6] libfs: Add simple_offset_rename() API cel
2024-11-11 0:52 ` [RFC PATCH 5/6 6.6] shmem: Fix shmem_rename2() cel
2024-11-11 0:52 ` [RFC PATCH 6/6 6.6] libfs: fix infinite directory reads for offset dir cel
2024-11-11 2:36 ` Yu Kuai
2024-11-11 14:39 ` Chuck Lever III
2024-11-11 15:20 ` yangerkun
2024-11-11 15:34 ` Chuck Lever III
2024-11-12 3:43 ` yangerkun
2024-11-12 15:37 ` Chuck Lever III
2024-11-13 15:17 ` Chuck Lever [this message]
2024-11-16 7:22 ` Yu Kuai
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=ZzTDE+RN5d/mwUXl@tissot.1015granger.net \
--to=chuck.lever@oracle.com \
--cc=Rodrigo.Siqueira@amd.com \
--cc=Xinhui.Pan@amd.com \
--cc=airlied@gmail.com \
--cc=akpm@linux-foundation.org \
--cc=alexander.deucher@amd.com \
--cc=amd-gfx@lists.freedesktop.org \
--cc=brauner@kernel.org \
--cc=cel@kernel.org \
--cc=chengming.zhou@linux.dev \
--cc=chiahsuan.chung@amd.com \
--cc=christian.koenig@amd.com \
--cc=daniel@ffwll.ch \
--cc=dri-devel@lists.freedesktop.org \
--cc=gregkh@linuxfoundation.org \
--cc=harry.wentland@amd.com \
--cc=hughd@google.com \
--cc=liam.howlett@oracle.com \
--cc=linux-fsdevel@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-mm@kvack.org \
--cc=maple-tree@lists.infradead.org \
--cc=mgorman@techsingularity.net \
--cc=mingo@kernel.org \
--cc=sashal@kernel.org \
--cc=srinivasan.shanmugam@amd.com \
--cc=stable@vger.kernel.org \
--cc=sunpeng.li@amd.com \
--cc=viro@zeniv.linux.org.uk \
--cc=willy@infradead.org \
--cc=yangerkun@huaweicloud.com \
--cc=yi.zhang@huawei.com \
--cc=yukuai1@huaweicloud.com \
--cc=yukuai3@huawei.com \
--cc=zhangpeng.00@bytedance.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