From: Cyril Hrubis <chrubis@suse.cz>
To: Chen Hanxiao <chenhx.fnst@fujitsu.com>
Cc: ltp@lists.linux.it
Subject: Re: [LTP] [PATCH v3] syscalls/mount_setattr01: Add basic functional test
Date: Tue, 26 Apr 2022 14:43:15 +0200 [thread overview]
Message-ID: <Ymfo4yKddW7OWfRO@yuki> (raw)
In-Reply-To: <20220425060806.1038-1-chenhx.fnst@fujitsu.com>
Hi!
> The mount_setattr() system call changes the mount properties of
> a mount or an entire mount tree. Here we check whether the mount
> attributes are set correctly.
>
> Signed-off-by: Dai Shili <daisl.fnst@fujitsu.com>
> Signed-off-by: Chen Hanxiao <chenhx.fnst@fujitsu.com>
> ---
> v3:
> 1) fix doc issue
> 2) fix bugs according to Petr's comments
> v2:
> 1) fix bugs according to Cyril's comments
> 2) just set and test mount attributes, remove attr_clr section.
>
> include/lapi/fsmount.h | 45 ++++++
> runtest/syscalls | 2 +
> .../kernel/syscalls/mount_setattr/.gitignore | 1 +
> .../kernel/syscalls/mount_setattr/Makefile | 6 +
> .../syscalls/mount_setattr/mount_setattr01.c | 135 ++++++++++++++++++
> 5 files changed, 189 insertions(+)
> create mode 100644 testcases/kernel/syscalls/mount_setattr/.gitignore
> create mode 100644 testcases/kernel/syscalls/mount_setattr/Makefile
> create mode 100644 testcases/kernel/syscalls/mount_setattr/mount_setattr01.c
>
> diff --git a/include/lapi/fsmount.h b/include/lapi/fsmount.h
> index 377af85ec..2aa92dc0c 100644
> --- a/include/lapi/fsmount.h
> +++ b/include/lapi/fsmount.h
> @@ -16,6 +16,42 @@
> #include "lapi/fcntl.h"
> #include "lapi/syscalls.h"
>
> +/*
> + * Mount attributes.
> + */
> +#ifndef MOUNT_ATTR_RDONLY
> +# define MOUNT_ATTR_RDONLY 0x00000001 /* Mount read-only */
> +#endif
> +#ifndef MOUNT_ATTR_NOSUID
> +# define MOUNT_ATTR_NOSUID 0x00000002 /* Ignore suid and sgid bits */
> +#endif
> +#ifndef MOUNT_ATTR_NODEV
> +# define MOUNT_ATTR_NODEV 0x00000004 /* Disallow access to device special files */
> +#endif
> +#ifndef MOUNT_ATTR_NOEXEC
> +# define MOUNT_ATTR_NOEXEC 0x00000008 /* Disallow program execution */
> +#endif
> +#ifndef MOUNT_ATTR_NODIRATIME
> +# define MOUNT_ATTR_NODIRATIME 0x00000080 /* Do not update directory access times */
> +#endif
> +#ifndef MOUNT_ATTR_NOSYMFOLLOW
> +# define MOUNT_ATTR_NOSYMFOLLOW 0x00200000 /* Do not follow symlinks */
> +#endif
> +
> +#ifndef ST_NOSYMFOLLOW
> +# define ST_NOSYMFOLLOW 0x2000 /* do not follow symlinks */
> +#endif
> +
> +/*
> + * mount_setattr()
> + */
> +struct mount_attr {
> + uint64_t attr_set;
> + uint64_t attr_clr;
> + uint64_t propagation;
> + uint64_t userns_fd;
> +};
> +
> #ifndef HAVE_FSOPEN
> static inline int fsopen(const char *fsname, unsigned int flags)
> {
> @@ -62,6 +98,15 @@ static inline int open_tree(int dirfd, const char *pathname, unsigned int flags)
> }
> #endif /* HAVE_OPEN_TREE */
>
> +#ifndef HAVE_MOUNT_SETATTR
> +static inline int mount_setattr(int dirfd, const char *from_pathname, unsigned int flags,
> + struct mount_attr *attr, size_t size)
> +{
> + return tst_syscall(__NR_mount_setattr, dirfd, from_pathname, flags,
> + attr, size);
> +}
> +#endif /* HAVE_MOUNT_SETATTR */
> +
> /*
> * New headers added in kernel after 5.2 release, create them for old userspace.
> */
> diff --git a/runtest/syscalls b/runtest/syscalls
> index d43d6983b..307f9bed1 100644
> --- a/runtest/syscalls
> +++ b/runtest/syscalls
> @@ -803,6 +803,8 @@ mount04 mount04
> mount05 mount05
> mount06 mount06
>
> +mount_setattr01 mount_setattr01
> +
> move_mount01 move_mount01
> move_mount02 move_mount02
>
> diff --git a/testcases/kernel/syscalls/mount_setattr/.gitignore b/testcases/kernel/syscalls/mount_setattr/.gitignore
> new file mode 100644
> index 000000000..52a77b9ca
> --- /dev/null
> +++ b/testcases/kernel/syscalls/mount_setattr/.gitignore
> @@ -0,0 +1 @@
> +/mount_setattr01
> diff --git a/testcases/kernel/syscalls/mount_setattr/Makefile b/testcases/kernel/syscalls/mount_setattr/Makefile
> new file mode 100644
> index 000000000..5ea7d67db
> --- /dev/null
> +++ b/testcases/kernel/syscalls/mount_setattr/Makefile
> @@ -0,0 +1,6 @@
> +# SPDX-License-Identifier: GPL-2.0-or-later
> +
> +top_srcdir ?= ../../../..
> +
> +include $(top_srcdir)/include/mk/testcases.mk
> +include $(top_srcdir)/include/mk/generic_leaf_target.mk
> diff --git a/testcases/kernel/syscalls/mount_setattr/mount_setattr01.c b/testcases/kernel/syscalls/mount_setattr/mount_setattr01.c
> new file mode 100644
> index 000000000..f56409a40
> --- /dev/null
> +++ b/testcases/kernel/syscalls/mount_setattr/mount_setattr01.c
> @@ -0,0 +1,135 @@
> +// SPDX-License-Identifier: GPL-2.0-or-later
> +/*
> + * Copyright (c) 2022 FUJITSU LIMITED. All rights reserved.
> + * Author: Dai Shili <daisl.fnst@fujitsu.com>
> + * Author: Chen Hanxiao <chenhx.fnst@fujitsu.com>
> + */
> +
> +/*\
> + * [Description]
> + *
> + * Basic mount_setattr() test.
> + * Test whether the basic mount attributes are set correctly.
> + *
> + * Verify some MOUNT_SETATTR(2) attributes:
> + *
> + * - 1) MOUNT_ATTR_RDONLY - makes the mount read-only
> + * - 2) MOUNT_ATTR_NOSUID - causes the mount not to honor the
> + * set-user-ID and set-group-ID mode bits and file capabilities
> + * when executing programs.
> + * - 3) MOUNT_ATTR_NODEV - prevents access to devices on this mount
> + * - 4) MOUNT_ATTR_NOEXEC - prevents executing programs on this mount
> + * - 5) MOUNT_ATTR_NOSYMFOLLOW - prevents following symbolic links
> + * on this mount
> + * - 6) MOUNT_ATTR_NODIRATIME - prevents updating access time for
> + * directories on this mount
> + *
> + * The functionality was added in v5.12.
> + */
> +
> +#define _GNU_SOURCE
> +
> +#include <sys/statvfs.h>
> +#include "tst_test.h"
> +#include "lapi/fsmount.h"
> +#include "lapi/stat.h"
> +
> +#define MNTPOINT "mntpoint"
> +#define OT_MNTPOINT "ot_mntpoint"
> +#define TCASE_ENTRY(attrs, exp_attrs) \
> + { \
> + .name = #attrs, \
> + .mount_attrs = attrs, \
> + .expect_attrs = exp_attrs \
> + }
> +
> +static int dir_created;
> +static int mount_flag, otfd;
^
This has to be set to -1 here
Otherwise we will close fd 0 in a case that the test did exit before we
opened the fd.
> +static struct tcase {
> + char *name;
> + unsigned int mount_attrs;
> + unsigned int expect_attrs;
> +} tcases[] = {
> + TCASE_ENTRY(MOUNT_ATTR_RDONLY, ST_RDONLY),
> + TCASE_ENTRY(MOUNT_ATTR_NOSUID, ST_NOSUID),
> + TCASE_ENTRY(MOUNT_ATTR_NODEV, ST_NODEV),
> + TCASE_ENTRY(MOUNT_ATTR_NOEXEC, ST_NOEXEC),
> + TCASE_ENTRY(MOUNT_ATTR_NOSYMFOLLOW, ST_NOSYMFOLLOW),
> + TCASE_ENTRY(MOUNT_ATTR_NODIRATIME, ST_NODIRATIME),
> +};
> +
> +static void cleanup(void)
> +{
> + if (otfd > -1)
> + SAFE_CLOSE(otfd);
> + if (mount_flag && tst_is_mounted_at_tmpdir(OT_MNTPOINT)) {
I would simply trust the mount_flag here, no need for the additional
tests.
> + mount_flag = 0;
Also no need to zero the flag here.
> + SAFE_UMOUNT(OT_MNTPOINT);
> + }
This shouldn't be any more complicated than:
if (mount_flag)
SAFE_UMOUNT(OT_MNTPOINT);
> + if (dir_created)
> + SAFE_RMDIR(OT_MNTPOINT);
There is no need remove the directory here, the test library will remove
the temporary directory created for the test recursively.
> +}
> +
> +static void setup(void)
> +{
> + fsopen_supported_by_kernel();
> + SAFE_MKDIR(OT_MNTPOINT, 0777);
> + dir_created = 1;
> +}
> +
> +static void run(unsigned int n)
> +{
> + struct tcase *tc = &tcases[n];
> + struct mount_attr attr = {
> + .attr_set = tc->mount_attrs,
> + };
> + struct statvfs buf;
> +
> + TST_EXP_FD_SILENT(open_tree(AT_FDCWD, MNTPOINT, AT_EMPTY_PATH |
> + AT_SYMLINK_NOFOLLOW | OPEN_TREE_CLOEXEC | OPEN_TREE_CLONE));
> + if (!TST_PASS)
> + goto out;
We can do just return here, no need to do any cleanup here.
> + otfd = (int)TST_RET;
> +
> + TST_EXP_PASS_SILENT(mount_setattr(otfd, "", AT_EMPTY_PATH, &attr, sizeof(attr)),
> + "%s set", tc->name);
> + if (!TST_PASS)
> + return;
And here we should close the file descriptor.
> + TST_EXP_PASS_SILENT(move_mount(otfd, "", AT_FDCWD, OT_MNTPOINT, MOVE_MOUNT_F_EMPTY_PATH));
> + if (!TST_PASS)
> + goto out;
> + mount_flag = 1;
> +
> + TST_EXP_PASS_SILENT(statvfs(OT_MNTPOINT, &buf), "statvfs sucess");
> + if (!TST_PASS)
> + goto out;
> +
> + if (buf.f_flag & tc->expect_attrs)
> + tst_res(TPASS, "%s is actually set as expected", tc->name);
> + else
> + tst_res(TFAIL, "%s is not actually set as expected", tc->name);
> +
> +out:
> + if (otfd > -1)
> + SAFE_CLOSE(otfd);
> +
> + if (tst_is_mounted_at_tmpdir(OT_MNTPOINT)) {
> + mount_flag = 0;
> + SAFE_UMOUNT(OT_MNTPOINT);
> + }
Generally the cleanup here is really messed up. What we do is to put the
cleanup in a reverse order and put goto labels between cleanup steps so
that we don't have to do any checks such as:
...
if (fd < 0)
goto ret0;
...
if (ret < 0)
goto ret1;
...
ret1:
SAFE_UMOUNT(MNTPOINT);
ret0:
SAFE_CLOSE(fd);
> +}
> +
> +static struct tst_test test = {
> + .tcnt = ARRAY_SIZE(tcases),
> + .test = run,
> + .setup = setup,
> + .cleanup = cleanup,
> + .needs_root = 1,
> + .mount_device = 1,
> + .mntpoint = MNTPOINT,
> + .all_filesystems = 1,
> + .skip_filesystems = (const char *const []){"fuse", NULL},
> +};
--
Cyril Hrubis
chrubis@suse.cz
--
Mailing list info: https://lists.linux.it/listinfo/ltp
next prev parent reply other threads:[~2022-04-26 12:41 UTC|newest]
Thread overview: 6+ messages / expand[flat|nested] mbox.gz Atom feed top
2022-04-25 6:08 [LTP] [PATCH v3] syscalls/mount_setattr01: Add basic functional test Chen Hanxiao
2022-04-25 10:48 ` Petr Vorel
2022-04-26 10:18 ` [LTP] 回复: " chenhx.fnst
2022-04-26 12:43 ` Cyril Hrubis [this message]
2022-04-27 8:23 ` chenhx.fnst
2022-04-27 15:30 ` [LTP] ????: " Cyril Hrubis
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=Ymfo4yKddW7OWfRO@yuki \
--to=chrubis@suse.cz \
--cc=chenhx.fnst@fujitsu.com \
--cc=ltp@lists.linux.it \
/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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.