Revert "lockless next_positive()"
hulk inclusion category: bugfix bugzilla: 20810 CVE: NA --------------------------- [ This reverts commit ebaaa80e ("lockless next_positive()"), To avoid the following oops. Of course, we can still find a better way, I suggest revert this first. ] Use a script to test kernel(arm64) in the following steps: (filesystem is tmpfs, dirA already have 10 files, dirB have 12 files) 1. keep open filenotexist(O_RDWR) in dirA 2. keep open filenotexist(O_RDWR) in dirB 3. keep ls dirB After 10 minutes, there will be an oops: Unable to handle kernel paging request at virtual address 00000000003564ad Process ls (pid: 142652, stack limit = 0x0000000055c452f6) Call trace: dcache_readdir+0xf8/0x1b0 iterate_dir+0x8c/0x1a8 ksys_getdents64+0xa4/0x190 __arm64_sys_getdents64+0x28/0x38 el0_svc_common+0x78/0x130 el0_svc_handler+0x38/0x78 el0_svc+0x8/0xc The reason is as follows: 1. dirA create new dentryA(dentryA->next = fileA1), and will delete it lookup_open d_alloc_parallel d_alloc dput -->prev allocated dentry has been added to dentry_hashtable dput remove dentryA from dirA, dentryA->next is still fileA1. 2. dirB create new dentry(use dentryA), and add it to dirB d_alloc -->This will need dirB shared lock __d_alloc INIT_LIST_HEAD(&dentry->d_child) spin_lock(&parent->d_lock) list_add(&dentry->d_child, &parent->d_subdirs) 3. At the same time, ls dirB -->This will need dirB shared lock dcache_readdir p = &dentry->d_subdirs next_positive p = from->next Although d_alloc has spin_lock, next_positive does not have it since commit ebaaa80e ("lockless next_positive()"). In arm64, CPU may run out of order. Maybe set parent->d_subdirs->next first, while dentry->d_child.next is still uninitialized. dentryA->next is still fileA1, So ls dirB will goto fileA1 which belongs to dirA, thus oops happens. Signed-off-by: Nzhengbin <zhengbin13@huawei.com> Reviewed-by: Nzhangyi (F) <yi.zhang@huawei.com> Signed-off-by: NYang Yingliang <yangyingliang@huawei.com>
Showing
想要评论请 注册 或 登录