On 25/08/05 10:43AM, Seyediman Seyedarab wrote: > On 25/08/05 09:38AM, Seyediman Seyedarab wrote: > > On 25/08/05 07:22PM, Sergey Senozhatsky wrote: > > > On (25/08/03 02:25), Seyediman Seyedarab wrote: > > > > Temporarily add a NULL check in zcomp_available_show() to prevent the > > > > crash. The use-after-free issue requires a more comprehensive fix using > > > > proper reference counting to ensure the zram structure isn't freed while > > > > still in use. > > > > > > Not without a reproducer, sorry. Per my limited experience, attempts > > > to fix syzkaller reports w/o reproducers often lead to regressions or > > > just more problems. > > > > It can be reproduced with the following code: > > #include <stdlib.h> > > #include <stdio.h> > > #include <fcntl.h> > > #include <unistd.h> > > > > int main() > > { > > int hot_remove_fd, comp_alg_fd, disksize_fd; > > char buf[256]; > > > > system("modprobe -r zram"); > > system("modprobe zram"); > > > > disksize_fd = open("/sys/block/zram0/disksize", O_WRONLY); > > if (disksize_fd >= 0) { > > write(disksize_fd, "1073741824", 10); > > close(disksize_fd); > > } > > > > hot_remove_fd = open("/sys/class/zram-control/hot_remove", O_WRONLY); > > comp_alg_fd = open("/sys/block/zram0/comp_algorithm", O_RDONLY); > > > > write(hot_remove_fd, "0", 1); > > > > for (int i = 0; i < 1000000; i++) { > > lseek(comp_alg_fd, 0, SEEK_SET); > > read(comp_alg_fd, buf, sizeof(buf)); > > printf("comp_algorithm: %s", buf); > > } > > } > > > > Which produces corrupted output sometimes. (it's a race condition, so it > > doesn't happen all the time...) > > To clarify: the reproducer I provided shows only the use-after-free > issue where zram structure is freed while sysfs reads are ongoing. > > The NULL dereference (which syzbot reported) has a much tighter race > window: it requires catching the brief moment during zram_reset_device() > where comp_algs[prio] is NULL between zram_destroy_comps() and > comp_algorithm_set(). This 'can' be triggered by racing concurrent: > - writes to /sys/block/zram0/reset > - reads from /sys/block/zram0/comp_algorithm > The window is only a few instructions wide under write lock, so it is > significantly harder to reproduce than the use-after-free. > > Your patch [1] should fixes the NULL deref, but the use-after-free remains. > > [1] https://lore.kernel.org/r/20250805101946.1774112-1-senozhatsky@xxxxxxxxxxxx I need to correct my previous statement about the use-after-free issue. My reproducer was wrong. The garbage output I reported was actually from an uninitialized buffer in my test code, not from reading freed memory! When the device is removed, the kernel correctly returns -ENODEV rather than accessing freed memory: #include <stdlib.h> #include <stdio.h> #include <fcntl.h> #include <unistd.h> int main() { int hot_remove_fd, comp_alg_fd, disksize_fd; ssize_t nBytes = 0; char buf[256] = {0}; system("modprobe -r zram"); system("modprobe zram"); disksize_fd = open("/sys/block/zram0/disksize", O_WRONLY); if (disksize_fd >= 0) { write(disksize_fd, "1G", 2); close(disksize_fd); } hot_remove_fd = open("/sys/class/zram-control/hot_remove", O_WRONLY); comp_alg_fd = open("/sys/block/zram0/comp_algorithm", O_RDONLY); write(hot_remove_fd, "0", 1); for (int i = 0; i < 1000000; i++) { lseek(comp_alg_fd, 0, SEEK_SET); nBytes = read(comp_alg_fd, buf, sizeof(buf)); if (nBytes <= 0) { perror("read"); break; } printf("comp_alg: %s", buf); } } Output: read: No such device The kernel properly protects against use-after-free in this path. I apologize for the confusion. Kindest Regards, Seyediman