All of lore.kernel.org
 help / color / mirror / Atom feed
From: Cyril Hrubis <chrubis@suse.cz>
To: Dai Shili <daisl.fnst@fujitsu.com>
Cc: ltp@lists.linux.it
Subject: Re: [LTP] [RESEND] syscalls/statx09: Add new test
Date: Mon, 24 Jan 2022 14:40:41 +0100	[thread overview]
Message-ID: <Ye6sWQ/kRf1V1FWy@yuki> (raw)
In-Reply-To: <1643001572-1567-1-git-send-email-daisl.fnst@fujitsu.com>

Hi!
> Signed-off-by: Dai Shili <daisl.fnst@fujitsu.com>
> ---
>  configure.ac                               |   1 +
>  include/lapi/fs.h                          |   4 +
>  include/lapi/fsverity.h                    |  38 ++++++
>  include/lapi/stat.h                        |   4 +
>  m4/ltp-fsverity.m4                         |  22 ++++
>  runtest/syscalls                           |   1 +
>  testcases/kernel/syscalls/statx/.gitignore |   1 +
>  testcases/kernel/syscalls/statx/statx09.c  | 200 +++++++++++++++++++++++++++++
>  8 files changed, 271 insertions(+)
>  create mode 100644 include/lapi/fsverity.h
>  create mode 100644 m4/ltp-fsverity.m4
>  create mode 100644 testcases/kernel/syscalls/statx/statx09.c
> 
> diff --git a/configure.ac b/configure.ac
> index 3c56d19..aeb486f 100644
> --- a/configure.ac
> +++ b/configure.ac
> @@ -367,6 +367,7 @@ LTP_CHECK_SELINUX
>  LTP_CHECK_SYNC_ADD_AND_FETCH
>  LTP_CHECK_SYSCALL_EVENTFD
>  LTP_CHECK_SYSCALL_FCNTL
> +LTP_CHECK_FSVERITY
>  
>  if test "x$with_numa" = xyes; then
>  	LTP_CHECK_SYSCALL_NUMA
> diff --git a/include/lapi/fs.h b/include/lapi/fs.h
> index aafeab4..27b3a18 100644
> --- a/include/lapi/fs.h
> +++ b/include/lapi/fs.h
> @@ -41,6 +41,10 @@
>  #define FS_NODUMP_FL	   0x00000040 /* do not dump file */
>  #endif
>  
> +#ifndef FS_VERITY_FL
> +#define FS_VERITY_FL	   0x00100000 /* Verity protected inode */
> +#endif
> +
>  /*
>   * Helper function to get MAX_LFS_FILESIZE.
>   * Missing PAGE_SHIFT on some libc prevents defining MAX_LFS_FILESIZE.
> diff --git a/include/lapi/fsverity.h b/include/lapi/fsverity.h
> new file mode 100644
> index 0000000..30a3c2a
> --- /dev/null
> +++ b/include/lapi/fsverity.h
> @@ -0,0 +1,38 @@
> +// SPDX-License-Identifier: GPL-2.0-or-later
> +/*
> + * Copyright (c) 2022 FUJITSU LIMITED. All rights reserved.
> + * Author: Dai Shili <daisl.fnst@cn.fujitsu.com>
> + */
> +#ifndef LAPI_FSVERITY_H__
> +#define LAPI_FSVERITY_H__
> +
> +#include "config.h"
> +#include <linux/types.h>
> +
> +#ifdef HAVE_LINUX_FSVERITY_H
> +#include <linux/fsverity.h>
> +#endif
> +
> +#ifndef FS_VERITY_HASH_ALG_SHA256
> +# define FS_VERITY_HASH_ALG_SHA256       1
> +#endif
> +
> +#ifndef FS_IOC_ENABLE_VERITY
> +# define FS_IOC_ENABLE_VERITY    _IOW('f', 133, struct fsverity_enable_arg)
> +#endif
> +
> +#ifndef HAVE_STRUCT_FSVERITY_ENABLE_ARG
> +struct fsverity_enable_arg {
> +	__u32 version;
> +	__u32 hash_algorithm;
> +	__u32 block_size;
> +	__u32 salt_size;
> +	__u64 salt_ptr;
> +	__u32 sig_size;
> +	__u32 __reserved1;
> +	__u64 sig_ptr;
> +	__u64 __reserved2[11];
> +};
> +#endif

Shouldn't this structure fallback be defined before the
FS_IOC_ENABLE_VERITY?

> +#endif
> diff --git a/include/lapi/stat.h b/include/lapi/stat.h
> index d596058..ce1f2b6 100644
> --- a/include/lapi/stat.h
> +++ b/include/lapi/stat.h
> @@ -223,6 +223,10 @@ static inline int statx(int dirfd, const char *pathname, unsigned int flags,
>  # define STATX_ATTR_AUTOMOUNT	0x00001000
>  #endif
>  
> +#ifndef STATX_ATTR_VERITY
> +# define STATX_ATTR_VERITY	0x00100000
> +#endif
> +
>  #ifndef AT_SYMLINK_NOFOLLOW
>  # define AT_SYMLINK_NOFOLLOW	0x100
>  #endif
> diff --git a/m4/ltp-fsverity.m4 b/m4/ltp-fsverity.m4
> new file mode 100644
> index 0000000..3d466f5
> --- /dev/null
> +++ b/m4/ltp-fsverity.m4
> @@ -0,0 +1,22 @@
> +dnl SPDX-License-Identifier: GPL-2.0-or-later
> +dnl Copyright (c) 2022 Fujitsu Ltd.
> +dnl Author: Dai Shili <daisl.fnst@cfujitsu.com>
> +
> +AC_DEFUN([LTP_CHECK_FSVERITY],[
> +	AC_CHECK_HEADERS([linux/fsverity.h], [have_fsverity=yes] ,[AC_MSG_WARN(missing linux/fsverity.h header)])
> +	if test "x$have_fsverity" = "xyes"; then
> +		AC_COMPILE_IFELSE([AC_LANG_SOURCE([
> +#include <linux/fsverity.h>
> +int main(void) {
> +	struct fsverity_enable_arg tst_fsverity_enable_arg;
> +	return 0;
> +}])], [has_fsverity_enable_arg="yes"])
> +	fi
> +
> +if test "x$has_fsverity_enable_arg" = "xyes"; then
> +	AC_DEFINE(HAVE_STRUCT_FSVERITY_ENABLE_ARG, 1, [Define to 1 if you have struct fsverity_enable_arg])
> +	AC_MSG_RESULT(yes)
> +else
> +	AC_MSG_RESULT(no)
> +fi

This whole AC_COMPILE_IFELSE() should probably be just:

AC_CHECK_TYPES(struct fsverity_enable_arg,,,[#include <linux/fsverity.h>])

> +])
> diff --git a/runtest/syscalls b/runtest/syscalls
> index 3b2deb6..7ba0331 100644
> --- a/runtest/syscalls
> +++ b/runtest/syscalls
> @@ -1744,6 +1744,7 @@ statx05 statx05
>  statx06 statx06
>  statx07 statx07
>  statx08 statx08
> +statx09 statx09
>  
>  membarrier01 membarrier01
>  
> diff --git a/testcases/kernel/syscalls/statx/.gitignore b/testcases/kernel/syscalls/statx/.gitignore
> index 4db060d..1cea43c 100644
> --- a/testcases/kernel/syscalls/statx/.gitignore
> +++ b/testcases/kernel/syscalls/statx/.gitignore
> @@ -6,3 +6,4 @@
>  /statx06
>  /statx07
>  /statx08
> +/statx09
> diff --git a/testcases/kernel/syscalls/statx/statx09.c b/testcases/kernel/syscalls/statx/statx09.c
> new file mode 100644
> index 0000000..38f7ca7
> --- /dev/null
> +++ b/testcases/kernel/syscalls/statx/statx09.c
> @@ -0,0 +1,200 @@
> +// SPDX-License-Identifier: GPL-2.0-or-later
> +/*
> + * Copyright (c) 2022 FUJITSU LIMITED. All rights reserved.
> + * Author: Dai Shili <daisl.fnst@fujitsu.com>
> + */
> +
> +/*\
> + * [Description]
> + *
> + * This code tests if the attributes field of statx received expected value.
> + * File set with following flags by using SAFE_IOCTL:
> + *
> + * - STATX_ATTR_VERITY: statx() system call sets STATX_ATTR_VERITY if the file
> + * has fs-verity enabled. This can perform better than FS_IOC_GETFLAGS and
> + * FS_IOC_MEASURE_VERITY because it doesn't require opening the file,
> + * and opening verity files can be expensive.
> + *
> + * Minimum Linux version required is v5.5.
> + * fs-verity is currently supported by the ext4 and f2fs filesystems.
> + * The CONFIG_FS_VERITY kconfig option must be enabled to use fs-verity
> + * on either filesystem.
> + * ext4 supports fs-verity since Linux v5.4 and e2fsprogs v1.45.2.
> + */
> +
> +#define _GNU_SOURCE
> +#include <sys/mount.h>
> +#include <stdlib.h>
> +#include <linux/ioctl.h>
> +#include "tst_test.h"
> +#include "lapi/fs.h"
> +#include "lapi/fsverity.h"
> +#include "lapi/stat.h"
> +#include <inttypes.h>
> +
> +#define MNTPOINT "mnt_point"
> +#define TESTFILE_FLAGGED MNTPOINT"/test_file1"
> +#define TESTFILE_UNFLAGGED MNTPOINT"/test_file2"
> +
> +static int fd_flagged, fd_unflagged, clear_flags;
> +static int mount_flag;
> +static char wrbuf[5];
> +
> +static const uint32_t hash_algorithms[] = {
> +	FS_VERITY_HASH_ALG_SHA256,
> +};
> +
> +static void test_flagged(void)
> +{
> +	struct statx buf;
> +
> +	TEST(statx(AT_FDCWD, TESTFILE_FLAGGED, 0, 0, &buf));
> +	if (TST_RET == 0)
> +		tst_res(TPASS,
> +			"sys_statx(AT_FDCWD, %s, 0, 0, &buf)", TESTFILE_FLAGGED);
> +	else
> +		tst_brk(TFAIL | TTERRNO,
> +			"sys_statx(AT_FDCWD, %s, 0, 0, &buf)", TESTFILE_FLAGGED);

Just use TST_EXP_PASS().

> +	if (buf.stx_attributes & STATX_ATTR_VERITY)
> +		tst_res(TPASS, "STATX_ATTR_VERITY flag is set: (%"PRIu64") ", buf.stx_attributes);
> +	else
> +		tst_res(TFAIL, "STATX_ATTR_VERITY flag is not set");
> +}
> +
> +static void test_unflagged(void)
> +{
> +	struct statx buf;
> +
> +	TEST(statx(AT_FDCWD, TESTFILE_UNFLAGGED, 0, 0, &buf));
> +	if (TST_RET == 0)
> +		tst_res(TPASS,
> +			"sys_statx(AT_FDCWD, %s, 0, 0, &buf)",
> +			TESTFILE_UNFLAGGED);
> +	else
> +		tst_brk(TFAIL | TTERRNO,
> +			"sys_statx(AT_FDCWD, %s, 0, 0, &buf)",
> +			TESTFILE_UNFLAGGED);

Here as well.

> +	if ((buf.stx_attributes & STATX_ATTR_VERITY) == 0)
> +		tst_res(TPASS, "STATX_ATTR_VERITY flag is not set");
> +	else
> +		tst_res(TFAIL, "STATX_ATTR_VERITY flag is set");
> +}
> +
> +static struct test_cases {
> +	void (*tfunc)(void);
> +} tcases[] = {
> +	{&test_flagged},
> +	{&test_unflagged},
> +};
> +
> +static void run(unsigned int i)
> +{
> +	tcases[i].tfunc();
> +}
> +
> +static void flag_setup(void)
> +{
> +	int attr, ret;
> +	struct fsverity_enable_arg enable;
> +
> +	fd_flagged = SAFE_OPEN(TESTFILE_FLAGGED, O_RDONLY, 0664);
> +	fd_unflagged = SAFE_OPEN(TESTFILE_UNFLAGGED, O_RDWR | O_CREAT, 0664);

What is this file descriptor even used for?

I guess that we can create this file in the test setup as well and there
is no point in doing anything with the unflagged file here.

> +	ret = ioctl(fd_flagged, FS_IOC_GETFLAGS, &attr);
> +	if (ret < 0) {
> +		if (errno == ENOTTY)
> +			tst_brk(TCONF | TERRNO, "FS_IOC_GETFLAGS not supported");
> +
> +		tst_brk(TBROK | TERRNO, "ioctl(%i, FS_IOC_GETFLAGS, ...)", fd_flagged);
> +	}
> +
> +	memset(&enable, 0, sizeof(enable));
> +	enable.version = 1;
> +	enable.hash_algorithm = hash_algorithms[0];
> +	enable.block_size = 4096;
> +	enable.salt_size = 0;
> +	enable.salt_ptr = (intptr_t)NULL;
> +	enable.sig_size = 0;
> +	enable.sig_ptr = (intptr_t)NULL;
> +
> +	ret = ioctl(fd_flagged, FS_IOC_ENABLE_VERITY, &enable);
> +	if (ret < 0) {
> +		if (errno == EOPNOTSUPP) {
> +			tst_brk(TCONF,
> +				"fs-verity is not supported on the file system or by the kernel");
> +		}
> +		tst_brk(TBROK | TERRNO, "ioctl(%i, FS_IOC_ENABLE_VERITY) failed", fd_flagged);
> +	}
> +
> +	ret = ioctl(fd_flagged, FS_IOC_GETFLAGS, &attr);
> +	if ((ret == 0) && !(attr & FS_VERITY_FL))
> +		tst_res(TFAIL, "%i: fs-verity enabled but FS_VERITY_FL bit not set", fd_flagged);
> +
> +	clear_flags = 1;
> +}
> +
> +static void setup(void)
> +{
> +	const char *fs_opts[] = {"-O verity", NULL};
> +
> +	SAFE_MKFS(tst_device->dev, tst_device->fs_type, fs_opts, NULL);

Why can't we use the .format_device in tst_test structure along with
dev_fs_opts?

> +	TEST(mount(tst_device->dev, MNTPOINT, tst_device->fs_type, 0, NULL));
> +	if (TST_RET) {
> +		if (TST_RET == -1) {
> +			tst_res(TFAIL | TERRNO, "mount(%s, %s, %s) failed. "
> +				"Loop device does not support fs-verity, pls export LTP_DEV.",
> +					tst_device->dev, MNTPOINT, tst_device->fs_type);

You should really check the TST_ERR here as well. I guess that you get
EINVAL in case that kernel does not support fs-verity?

	if (TST_RET) {
		if (TST_ERR == EINVAL)
			tst_brk(TCONF, "fs-verity not supported on loopdev");

		tst_brk(TBROK | TERRNO "mount() failed with %ld", TST_RET);
	}

Also this code actually uses tst_brk() which exits the test if the mount
failed.


> +		} else {
> +			tst_res(TFAIL | TERRNO, "Invalid mount(%s, %s, %s) return value %ld",
> +				tst_device->dev, MNTPOINT, tst_device->fs_type, TST_RET);
> +		}
> +	}
> +	mount_flag = 1;
> +
> +	fd_flagged = SAFE_OPEN(TESTFILE_FLAGGED, O_RDWR | O_CREAT, 0664);
> +	memset(wrbuf, 'a', 5);
> +	SAFE_WRITE(1, fd_flagged, wrbuf, 5);
> +	SAFE_CLOSE(fd_flagged);

Just use SAFE_FILE_PRINTF() instead.

> +	flag_setup();
> +}
> +
> +static void cleanup(void)
> +{
> +	int attr;
> +
> +	if (clear_flags) {
> +		SAFE_IOCTL(fd_flagged, FS_IOC_GETFLAGS, &attr);
> +		attr &= ~FS_VERITY_FL;
> +		SAFE_IOCTL(fd_flagged, FS_IOC_SETFLAGS, &attr);
> +	}

Is there a reason to clear the flags here? Does that prevent the
MNTPOINT from being unmounted? If not we can remove this piece of code
and also close fd_flagged at the end of the flag_setup() function.

> +	if (fd_flagged > 0)
> +		SAFE_CLOSE(fd_flagged);
> +	if (fd_unflagged > 0)
> +		SAFE_CLOSE(fd_unflagged);
> +
> +	if (mount_flag)
> +		tst_umount(MNTPOINT);
> +}
> +
> +static struct tst_test test = {
> +	.test = run,
> +	.tcnt = ARRAY_SIZE(tcases),
> +	.setup = setup,
> +	.cleanup = cleanup,
> +	.needs_root = 1,
> +	.mntpoint = MNTPOINT,
> +	.needs_device = 1,
> +	.dev_fs_type = "ext4",
> +	.needs_kconfigs = (const char *[]) {
> +		"CONFIG_FS_VERITY",
> +		NULL
> +	},
> +	.needs_cmds = (const char *[]) {
> +		"mkfs.ext4 >= 1.45.2",
> +		NULL
> +	}
> +};
> -- 
> 1.8.3.1
> 
> 
> -- 
> Mailing list info: https://lists.linux.it/listinfo/ltp

-- 
Cyril Hrubis
chrubis@suse.cz

-- 
Mailing list info: https://lists.linux.it/listinfo/ltp

  reply	other threads:[~2022-01-24 13:39 UTC|newest]

Thread overview: 14+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-01-24  5:19 [LTP] [RESEND] syscalls/statx09: Add new test Dai Shili
2022-01-24 13:40 ` Cyril Hrubis [this message]
2022-01-26  2:37   ` daisl.fnst
2022-01-26  3:00   ` [LTP] [PATCH v2] " Dai Shili
2022-01-27 13:57     ` Cyril Hrubis
2022-01-28  3:02       ` [LTP] [PATCH v3] " Dai Shili
2022-01-28  4:07         ` xuyang2018.jy
2022-01-28 10:29           ` [LTP] [PATCH v4] " Dai Shili
2022-01-30  2:33             ` xuyang2018.jy
2022-02-04 13:42             ` Cyril Hrubis
2022-02-07 11:26             ` Petr Vorel
2022-02-07 11:31               ` Cyril Hrubis
2022-02-07 11:55                 ` Petr Vorel
2022-02-07 13:45                   ` Andrea Cervesato via ltp

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=Ye6sWQ/kRf1V1FWy@yuki \
    --to=chrubis@suse.cz \
    --cc=daisl.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.