Verify the FID provided in the event. If the FH has size 0, this is assumed to be a superblock error (i.e. null FH). Reviewed-by: Petr Vorel <pvorel@xxxxxxx> Reviewed-by: Amir Goldstein <amir73il@xxxxxxxxx> Signed-off-by: Gabriel Krisman Bertazi <krisman@xxxxxxxxxxxxx> --- Changes since v2: - Move FILEID_INVALID define to header file (Amir) - Don't use FSID_VAL_MEMBER (Petr) Changes since v1: - Move defines to header file. - Use 0-len FH for sb error --- testcases/kernel/syscalls/fanotify/fanotify.h | 8 +++ .../kernel/syscalls/fanotify/fanotify22.c | 60 +++++++++++++++++++ 2 files changed, 68 insertions(+) diff --git a/testcases/kernel/syscalls/fanotify/fanotify.h b/testcases/kernel/syscalls/fanotify/fanotify.h index 6b0e68a23a6b..f7778bb36b4d 100644 --- a/testcases/kernel/syscalls/fanotify/fanotify.h +++ b/testcases/kernel/syscalls/fanotify/fanotify.h @@ -255,6 +255,10 @@ static inline void fanotify_get_fid(const char *path, __kernel_fsid_t *fsid, } } +#ifndef FILEID_INVALID +#define FILEID_INVALID 0xff +#endif + struct fanotify_fid_t { __kernel_fsid_t fsid; struct file_handle handle; @@ -450,4 +454,8 @@ struct fanotify_event_info_header *get_event_info( ((struct fanotify_event_info_error *) \ get_event_info((event), FAN_EVENT_INFO_TYPE_ERROR)) +#define get_event_info_fid(event) \ + ((struct fanotify_event_info_fid *) \ + get_event_info((event), FAN_EVENT_INFO_TYPE_FID)) + #endif /* __FANOTIFY_H__ */ diff --git a/testcases/kernel/syscalls/fanotify/fanotify22.c b/testcases/kernel/syscalls/fanotify/fanotify22.c index d324191c28c8..eeee582f1268 100644 --- a/testcases/kernel/syscalls/fanotify/fanotify22.c +++ b/testcases/kernel/syscalls/fanotify/fanotify22.c @@ -40,6 +40,9 @@ int fd_notify; #define MOUNT_PATH "test_mnt" +/* These expected FIDs are common to multiple tests */ +static struct fanotify_fid_t null_fid; + static void trigger_fs_abort(void) { SAFE_MOUNT(tst_device->dev, MOUNT_PATH, tst_device->fs_type, @@ -50,6 +53,7 @@ static struct test_case { char *name; int error; unsigned int error_count; + struct fanotify_fid_t *fid; void (*trigger_error)(void); } testcases[] = { { @@ -57,9 +61,43 @@ static struct test_case { .trigger_error = &trigger_fs_abort, .error_count = 1, .error = ESHUTDOWN, + .fid = &null_fid, }, }; +int check_error_event_info_fid(struct fanotify_event_info_fid *fid, + const struct test_case *ex) +{ + struct file_handle *fh = (struct file_handle *) &fid->handle; + + if (memcmp(&fid->fsid, &ex->fid->fsid, sizeof(fid->fsid))) { + tst_res(TFAIL, "%s: Received bad FSID type (%x...!=%x...)", + ex->name, FSID_VAL_MEMBER(fid->fsid, 0), + ex->fid->fsid.val[0]); + + return 1; + } + if (fh->handle_type != ex->fid->handle.handle_type) { + tst_res(TFAIL, "%s: Received bad file_handle type (%d!=%d)", + ex->name, fh->handle_type, ex->fid->handle.handle_type); + return 1; + } + + if (fh->handle_bytes != ex->fid->handle.handle_bytes) { + tst_res(TFAIL, "%s: Received bad file_handle len (%d!=%d)", + ex->name, fh->handle_bytes, ex->fid->handle.handle_bytes); + return 1; + } + + if (memcmp(fh->f_handle, ex->fid->handle.f_handle, fh->handle_bytes)) { + tst_res(TFAIL, "%s: Received wrong handle. " + "Expected (%x...) got (%x...) ", ex->name, + *(int *)ex->fid->handle.f_handle, *(int *)fh->f_handle); + return 1; + } + return 0; +} + int check_error_event_info_error(struct fanotify_event_info_error *info_error, const struct test_case *ex) { @@ -103,6 +141,7 @@ void check_event(char *buf, size_t len, const struct test_case *ex) struct fanotify_event_metadata *event = (struct fanotify_event_metadata *) buf; struct fanotify_event_info_error *info_error; + struct fanotify_event_info_fid *info_fid; int fail = 0; if (len < FAN_EVENT_METADATA_LEN) { @@ -121,6 +160,14 @@ void check_event(char *buf, size_t len, const struct test_case *ex) fail++; } + info_fid = get_event_info_fid(event); + if (info_fid) + fail += check_error_event_info_fid(info_fid, ex); + else { + tst_res(TFAIL, "FID record not found"); + fail++; + } + if (!fail) tst_res(TPASS, "Successfully received: %s", ex->name); } @@ -143,6 +190,17 @@ static void do_test(unsigned int i) check_event(event_buf, read_len, tcase); } +static void init_null_fid(void) +{ + /* Use fanotify_save_fid to fill the fsid and overwrite the + * file_handler to create a null_fid + */ + fanotify_save_fid(MOUNT_PATH, &null_fid); + + null_fid.handle.handle_type = FILEID_INVALID; + null_fid.handle.handle_bytes = 0; +} + static void setup(void) { REQUIRE_FANOTIFY_EVENTS_SUPPORTED_ON_FS(FAN_CLASS_NOTIF|FAN_REPORT_FID, @@ -151,6 +209,8 @@ static void setup(void) fd_notify = SAFE_FANOTIFY_INIT(FAN_CLASS_NOTIF|FAN_REPORT_FID, O_RDONLY); + + init_null_fid(); } static void cleanup(void) -- 2.33.0