[LTP] [PATCH v2 1/2] fanotify: fix crash when running multiple iterations

Amir Goldstein amir73il@gmail.com
Thu May 28 15:03:15 CEST 2026


[reducing CC to LTP context]

On Wed, May 27, 2026 at 9:51 PM AnonymeMeow <anonymemeow@gmail.com> wrote:
>
> This commit fixes ./fanotify13 -i10 crash by restoring the deleted objects
> every time a test finishes.
>
> This commit also fixes ./fanotify21 -i10 crash by remounting the read-only
> mount (if the mount is remounted read-only during the test) back to
> read-write every time a test finishes.
>
> Signed-off-by: AnonymeMeow <anonymemeow@gmail.com>
> ---
>
> On 2026-05-27 09:23:12+02:00, Petr Vorel wrote:
> > @AnonymeMeow nit: if you put whole conversation after --- (below), it will not
> > be part of the commit message when one applies the patch. And here should be a
> > proper commit message.
>
> Thank you for pointing this out, I will be more mindful the next time
> (this time).
>
> > Also I found that fanotify21.c on the current master fails when running more
> > than 1 iteration:
>
> Thanks for testing my patch, I didn't know that the standalone test binary
> supports the -i option to specify the number of iterations. Running
> multiple iterations through kirk's -i option seems to work fine.
>
> I then tested all fanotify tests with the -i option and found that
> fanotify13 also crashed when running multiple iterations. I fixed both
> fanotify13 and fanotify21 in this patch. So now all fanotify tests pass
> with the -i option.


Thanks for testing! and for the fixes.

For fanotify21, I prefer a simpler fix (attached) which also removes the
FUSE limitation.

For fanotify13, see comments below.

Thanks,
Amir.

>
> With Best Regards,
> AnonymeMeow
>
> ---
>  .../kernel/syscalls/fanotify/fanotify13.c     | 20 +++++++++++++++++++
>  .../kernel/syscalls/fanotify/fanotify21.c     | 13 +++++++++++-
>  2 files changed, 32 insertions(+), 1 deletion(-)
>
> diff --git a/testcases/kernel/syscalls/fanotify/fanotify13.c b/testcases/kernel/syscalls/fanotify/fanotify13.c
> index 76d40eaf7..540e0b483 100644
> --- a/testcases/kernel/syscalls/fanotify/fanotify13.c
> +++ b/testcases/kernel/syscalls/fanotify/fanotify13.c
> @@ -137,6 +137,16 @@ static void delete_objects(void)
>         }
>  }
>
> +static void clean_upper_dir(void)
> +{
> +       unsigned int i;
> +
> +       SAFE_MOUNT(OVL_UPPER, MOUNT_PATH, "none", MS_BIND, NULL);
> +       for (i = 0; i < ARRAY_SIZE(objects); i++)
> +               SAFE_UNLINK(objects[i].path);
> +       SAFE_UMOUNT(MOUNT_PATH);
> +}

Nah, this is "illegal" and results are undefined when cleaning stuff underneath
a mounted overlayfs.

> +
>  static void get_object_stats(void)
>  {
>         unsigned int i;
> @@ -340,6 +350,15 @@ static void do_test(unsigned int number)
>                         "Did not get an expected event (expected: %llx)",
>                         event_set[i].expected_mask);
>         }
> +
> +       if (tc->mask & FAN_DELETE_SELF) {
> +               if (tst_variant & 1) {
> +                       clean_upper_dir();
> +               } else {
> +                       create_objects();
> +                       get_object_stats();
> +               }

I am wondering why create_objects() does not work for overlayfs
I tested and I saw that it fails but did not yet understand why
looks like an unrelated issue. I will take a closer look.

The textbook solution is to do all the setup at the start of do_test()
but that's really ugly IMO.

Let me think about this some more...

> +       }
>  out:
>         SAFE_CLOSE(fanotify_fd);
>  }
> @@ -417,6 +436,7 @@ static void do_cleanup(void)
>         if (ovl_bind_mounted)
>                 SAFE_UMOUNT(MOUNT_PATH);
>         if (bind_mounted) {
> +               delete_objects();
>                 SAFE_UMOUNT(MOUNT_PATH);
>                 SAFE_RMDIR(MOUNT_PATH);
>         }
> diff --git a/testcases/kernel/syscalls/fanotify/fanotify21.c b/testcases/kernel/syscalls/fanotify/fanotify21.c
> index 340fb0018..2e3dbd4bd 100644
> --- a/testcases/kernel/syscalls/fanotify/fanotify21.c
> +++ b/testcases/kernel/syscalls/fanotify/fanotify21.c
> @@ -199,7 +199,7 @@ static void do_test(unsigned int num)
>         if (len < 0) {
>                 if (tc->remount_ro && !fd_err && errno == EROFS) {
>                         tst_res(TPASS, "cannot read event with rw fd from a ro fs");
> -                       return;
> +                       goto restore_rw_mount;
>                 }
>                 tst_brk(TBROK | TERRNO, "reading fanotify events failed");
>         } else if (tc->remount_ro && !fd_err) {
> @@ -346,6 +346,17 @@ next_event:
>                 if (event_pidfd_fdinfo)
>                         free(event_pidfd_fdinfo);
>         }
> +
> +restore_rw_mount:
> +       if (tc->remount_ro) {
> +               /* SAFE_MOUNT fails to remount FUSE */
> +               if (mount(tst_device->dev, MOUNT_PATH, tst_device->fs_type,
> +                         MS_REMOUNT, NULL) != 0) {
> +                       tst_brk(TFAIL,
> +                               "filesystem %s failed to remount read-write",
> +                               tst_device->fs_type);
> +               }
> +       }
>  }

I think my attached version is simpler/cleaner.

Thanks,
Amir.


More information about the ltp mailing list