1 Star 0 Fork 2

gaoxuelong / stress-ng

forked from HoperunHarmony / stress-ng 
加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
克隆/下载
stress-verity.c 6.94 KB
一键复制 编辑 原始数据 按行查看 历史
/*
* Copyright (C) 2013-2021 Canonical, Ltd.
* Copyright (C) 2022 Colin Ian King.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
*/
#include "stress-ng.h"
#if defined(HAVE_LINUX_FS_H)
#include <linux/fs.h>
#else
UNEXPECTED
#endif
#if defined(HAVE_LINUX_FSVERITY_H)
#include <linux/fsverity.h>
#endif
static const stress_help_t help[] = {
{ NULL, "verity N", "start N workers exercising file verity ioctls" },
{ NULL, "verity-ops N", "stop after N file verity bogo operations" },
{ NULL, NULL, NULL }
};
#if defined(HAVE_LINUX_FSVERITY_H) && \
defined(HAVE_FSVERITY_ENABLE_ARG) && \
defined(HAVE_FSVERITY_DIGEST) && \
defined(FS_IOC_ENABLE_VERITY) && \
defined(FS_IOC_MEASURE_VERITY) && \
(defined(FS_VERITY_HASH_ALG_SHA256) || \
defined(FS_VERITY_HASH_ALG_SHA512))
static const uint32_t hash_algorithms[] = {
#if defined(FS_VERITY_HASH_ALG_SHA256)
FS_VERITY_HASH_ALG_SHA256,
#endif
#if defined(FS_VERITY_HASH_ALG_SHA512)
FS_VERITY_HASH_ALG_SHA512,
#endif
};
/*
* For FS_IOC_READ_VERITY_METADATA, introduced in Linux 5.12
*/
struct shim_fsverity_read_metadata_arg {
uint64_t metadata_type;
uint64_t offset;
uint64_t length;
uint64_t buf_ptr;
uint64_t __reserved;
};
/*
* stress_verity
* stress file verity
*/
static int stress_verity(const stress_args_t *args)
{
char filename[PATH_MAX];
int ret, fd;
uint32_t rnd = stress_mwc32();
size_t hash = 0;
if (SIZEOF_ARRAY(hash_algorithms) == (0)) {
if (args->instance == 0)
pr_inf_skip("%s: no hash algorithms defined, skipping stressor\n",
args->name);
return EXIT_NO_RESOURCE;
}
ret = stress_temp_dir_mk_args(args);
if (ret < 0)
return exit_status(-ret);
(void)stress_temp_filename_args(args, filename, sizeof(filename), rnd);
stress_set_proc_state(args->name, STRESS_STATE_RUN);
do {
struct fsverity_enable_arg enable;
char digest_buf[256];
struct fsverity_digest *digest = (struct fsverity_digest *)digest_buf;
char block[512];
int i;
#if defined(FS_IOC_READ_VERITY_METADATA)
struct shim_fsverity_read_metadata_arg md_arg;
char md_buf[4096];
#else
UNEXPECTED
#endif
fd = open(filename, O_CREAT | O_RDWR, S_IRUSR | S_IWUSR);
if (fd < 0) {
ret = exit_status(errno);
pr_err("%s: cannot create %s, errno=%d (%s)\n",
args->name, filename, errno, strerror(errno));
return ret;
}
for (i = 0; i < 16; i++) {
const off_t off = (off_t)i * 64 * 1024;
(void)memset(block, i, sizeof(block));
ret = (int)lseek(fd, off, SEEK_SET);
(void)ret;
ret = (int)write(fd, block, sizeof(block));
if (ret < 0) {
ret = exit_status(errno);
pr_err("%s: cannot write %s\n", args->name, filename);
(void)close(fd);
goto clean;
}
}
(void)shim_fsync(fd);
(void)close(fd);
(void)sync();
fd = open(filename, O_RDONLY);
if (fd < 0) {
ret = exit_status(errno);
pr_err("%s: cannot re-open %s, errno=%d (%s)\n",
args->name, filename, errno, strerror(errno));
goto clean;
}
(void)memset(&enable, 0, sizeof(enable));
enable.version = 1;
enable.hash_algorithm = hash_algorithms[hash];
enable.block_size = (uint32_t)args->page_size;
enable.salt_size = 0;
enable.salt_ptr = (intptr_t)NULL;
enable.sig_size = 0;
enable.sig_ptr = (intptr_t)NULL;
hash++;
if (hash >= SIZEOF_ARRAY(hash_algorithms))
hash = 0;
ret = ioctl(fd, FS_IOC_ENABLE_VERITY, &enable);
if (ret < 0) {
switch (errno) {
case EINVAL:
case ENOTTY:
case EOPNOTSUPP:
case ENOSYS:
if (args->instance == 0)
pr_inf_skip("%s: verity is not supported on the "
"file system or by the kernel, skipping stress test\n",
args->name);
ret = EXIT_NOT_IMPLEMENTED;
break;
case ENOPKG:
pr_inf("%s: kernel does not have sha256 "
"crypto enabled\n",
args->name);
ret = EXIT_NOT_IMPLEMENTED;
break;
case EROFS:
case EACCES:
case EBUSY:
case EINTR:
case ENOSPC:
ret = EXIT_NO_RESOURCE;
break;
default:
pr_inf("%s: verity ioctl FS_IOC_ENABLE_VERITY "
"failed on file %s, errno=%d (%s)\n",
args->name, filename, errno, strerror(errno));
ret = EXIT_FAILURE;
}
(void)close(fd);
goto clean;
}
/*
* Exercise measuring verity, ignore return for now
*/
digest->digest_algorithm = FS_VERITY_HASH_ALG_SHA256;
digest->digest_size = 32;
ret = ioctl(fd, FS_IOC_MEASURE_VERITY, digest);
(void)ret;
#if defined(FS_IOC_GETFLAGS) && \
defined(FS_VERITY_FL)
{
int flags = 0;
ret = ioctl(fd, FS_IOC_GETFLAGS, &flags);
if ((ret == 0) && !(flags & FS_VERITY_FL)) {
pr_fail("%s: verity enabled but FS_VERITY_FL bit not "
"set on file flags from ioctl FS_IOC_GETFLAGS\n",
args->name);
}
}
#else
UNEXPECTED
#endif
(void)close(fd);
/*
* Read data back, should exercise verity verification
*/
fd = open(filename, O_RDONLY);
if (fd < 0) {
ret = exit_status(errno);
pr_err("%s: cannot re-open %s, errno=%d (%s)\n",
args->name, filename, errno, strerror(errno));
goto clean;
}
for (i = 0; i < 16; i++) {
const off_t off = (off_t)i * 64 * 1024;
(void)memset(block, i, sizeof(block));
ret = (int)lseek(fd, off, SEEK_SET);
(void)ret;
ret = (int)read(fd, block, sizeof(block));
if (ret < 0) {
ret = exit_status(errno);
pr_err("%s: cannot read %s\n", args->name, filename);
(void)close(fd);
goto clean;
}
if (block[0] != i) {
pr_err("%s: data in file block %d is incorrect\n",
args->name, i);
(void)close(fd);
goto clean;
}
}
(void)shim_fsync(fd);
#if defined(FS_IOC_READ_VERITY_METADATA)
(void)memset(&md_arg, 0, sizeof(md_arg));
md_arg.metadata_type = 0ULL;
md_arg.offset = 0ULL;
md_arg.buf_ptr = (uint64_t)(intptr_t)md_buf;
md_arg.length = (uint64_t)sizeof(md_buf);
(void)ioctl(fd, FS_IOC_READ_VERITY_METADATA, &md_arg);
#else
UNEXPECTED
#endif
(void)close(fd);
(void)shim_unlink(filename);
inc_counter(args);
} while (keep_stressing(args));
ret = EXIT_SUCCESS;
clean:
stress_set_proc_state(args->name, STRESS_STATE_DEINIT);
(void)shim_unlink(filename);
(void)stress_temp_dir_rm_args(args);
return ret;
}
stressor_info_t stress_verity_info = {
.stressor = stress_verity,
.class = CLASS_FILESYSTEM | CLASS_OS,
.help = help
};
#else
stressor_info_t stress_verity_info = {
.stressor = stress_not_implemented,
.class = CLASS_FILESYSTEM | CLASS_OS,
.help = help
};
#endif
1
https://gitee.com/gaoxuelong/stress-ng.git
git@gitee.com:gaoxuelong/stress-ng.git
gaoxuelong
stress-ng
stress-ng
master

搜索帮助