1f08c3bdfSopenharmony_ci// SPDX-License-Identifier: GPL-2.0-or-later 2f08c3bdfSopenharmony_ci/* 3f08c3bdfSopenharmony_ci * Copyright (c) 2022 FUJITSU LIMITED. All rights reserved. 4f08c3bdfSopenharmony_ci * Author: Dai Shili <daisl.fnst@fujitsu.com> 5f08c3bdfSopenharmony_ci * Author: Chen Hanxiao <chenhx.fnst@fujitsu.com> 6f08c3bdfSopenharmony_ci */ 7f08c3bdfSopenharmony_ci 8f08c3bdfSopenharmony_ci/*\ 9f08c3bdfSopenharmony_ci * [Description] 10f08c3bdfSopenharmony_ci * 11f08c3bdfSopenharmony_ci * Basic mount_setattr() test. 12f08c3bdfSopenharmony_ci * Test whether the basic mount attributes are set correctly. 13f08c3bdfSopenharmony_ci * 14f08c3bdfSopenharmony_ci * Verify some MOUNT_SETATTR(2) attributes: 15f08c3bdfSopenharmony_ci * 16f08c3bdfSopenharmony_ci * - MOUNT_ATTR_RDONLY - makes the mount read-only 17f08c3bdfSopenharmony_ci * - MOUNT_ATTR_NOSUID - causes the mount not to honor the 18f08c3bdfSopenharmony_ci * set-user-ID and set-group-ID mode bits and file capabilities 19f08c3bdfSopenharmony_ci * when executing programs. 20f08c3bdfSopenharmony_ci * - MOUNT_ATTR_NODEV - prevents access to devices on this mount 21f08c3bdfSopenharmony_ci * - MOUNT_ATTR_NOEXEC - prevents executing programs on this mount 22f08c3bdfSopenharmony_ci * - MOUNT_ATTR_NOSYMFOLLOW - prevents following symbolic links 23f08c3bdfSopenharmony_ci * on this mount 24f08c3bdfSopenharmony_ci * - MOUNT_ATTR_NODIRATIME - prevents updating access time for 25f08c3bdfSopenharmony_ci * directories on this mount 26f08c3bdfSopenharmony_ci * 27f08c3bdfSopenharmony_ci * The functionality was added in v5.12. 28f08c3bdfSopenharmony_ci */ 29f08c3bdfSopenharmony_ci 30f08c3bdfSopenharmony_ci#define _GNU_SOURCE 31f08c3bdfSopenharmony_ci 32f08c3bdfSopenharmony_ci#include <sys/statvfs.h> 33f08c3bdfSopenharmony_ci#include "tst_test.h" 34f08c3bdfSopenharmony_ci#include "lapi/fsmount.h" 35f08c3bdfSopenharmony_ci 36f08c3bdfSopenharmony_ci#define MNTPOINT "mntpoint" 37f08c3bdfSopenharmony_ci#define OT_MNTPOINT "ot_mntpoint" 38f08c3bdfSopenharmony_ci#define TCASE_ENTRY(attrs, exp_attrs) \ 39f08c3bdfSopenharmony_ci { \ 40f08c3bdfSopenharmony_ci .name = #attrs, \ 41f08c3bdfSopenharmony_ci .mount_attrs = attrs, \ 42f08c3bdfSopenharmony_ci .expect_attrs = exp_attrs \ 43f08c3bdfSopenharmony_ci } 44f08c3bdfSopenharmony_ci 45f08c3bdfSopenharmony_cistatic int mount_flag, otfd = -1; 46f08c3bdfSopenharmony_ci 47f08c3bdfSopenharmony_cistatic struct tcase { 48f08c3bdfSopenharmony_ci char *name; 49f08c3bdfSopenharmony_ci unsigned int mount_attrs; 50f08c3bdfSopenharmony_ci unsigned int expect_attrs; 51f08c3bdfSopenharmony_ci} tcases[] = { 52f08c3bdfSopenharmony_ci TCASE_ENTRY(MOUNT_ATTR_RDONLY, ST_RDONLY), 53f08c3bdfSopenharmony_ci TCASE_ENTRY(MOUNT_ATTR_NOSUID, ST_NOSUID), 54f08c3bdfSopenharmony_ci TCASE_ENTRY(MOUNT_ATTR_NODEV, ST_NODEV), 55f08c3bdfSopenharmony_ci TCASE_ENTRY(MOUNT_ATTR_NOEXEC, ST_NOEXEC), 56f08c3bdfSopenharmony_ci TCASE_ENTRY(MOUNT_ATTR_NOSYMFOLLOW, ST_NOSYMFOLLOW), 57f08c3bdfSopenharmony_ci TCASE_ENTRY(MOUNT_ATTR_NODIRATIME, ST_NODIRATIME), 58f08c3bdfSopenharmony_ci}; 59f08c3bdfSopenharmony_ci 60f08c3bdfSopenharmony_cistatic void cleanup(void) 61f08c3bdfSopenharmony_ci{ 62f08c3bdfSopenharmony_ci if (otfd > -1) 63f08c3bdfSopenharmony_ci SAFE_CLOSE(otfd); 64f08c3bdfSopenharmony_ci if (mount_flag) 65f08c3bdfSopenharmony_ci SAFE_UMOUNT(OT_MNTPOINT); 66f08c3bdfSopenharmony_ci} 67f08c3bdfSopenharmony_ci 68f08c3bdfSopenharmony_cistatic void setup(void) 69f08c3bdfSopenharmony_ci{ 70f08c3bdfSopenharmony_ci fsopen_supported_by_kernel(); 71f08c3bdfSopenharmony_ci struct stat st = {0}; 72f08c3bdfSopenharmony_ci 73f08c3bdfSopenharmony_ci if (stat(OT_MNTPOINT, &st) == -1) 74f08c3bdfSopenharmony_ci SAFE_MKDIR(OT_MNTPOINT, 0777); 75f08c3bdfSopenharmony_ci} 76f08c3bdfSopenharmony_ci 77f08c3bdfSopenharmony_cistatic void run(unsigned int n) 78f08c3bdfSopenharmony_ci{ 79f08c3bdfSopenharmony_ci struct tcase *tc = &tcases[n]; 80f08c3bdfSopenharmony_ci struct mount_attr attr = { 81f08c3bdfSopenharmony_ci .attr_set = tc->mount_attrs, 82f08c3bdfSopenharmony_ci }; 83f08c3bdfSopenharmony_ci struct statvfs buf; 84f08c3bdfSopenharmony_ci 85f08c3bdfSopenharmony_ci TST_EXP_FD_SILENT(open_tree(AT_FDCWD, MNTPOINT, AT_EMPTY_PATH | 86f08c3bdfSopenharmony_ci AT_SYMLINK_NOFOLLOW | OPEN_TREE_CLOEXEC | OPEN_TREE_CLONE)); 87f08c3bdfSopenharmony_ci if (!TST_PASS) 88f08c3bdfSopenharmony_ci return; 89f08c3bdfSopenharmony_ci 90f08c3bdfSopenharmony_ci otfd = (int)TST_RET; 91f08c3bdfSopenharmony_ci 92f08c3bdfSopenharmony_ci TST_EXP_PASS_SILENT(mount_setattr(otfd, "", AT_EMPTY_PATH, &attr, sizeof(attr)), 93f08c3bdfSopenharmony_ci "%s set", tc->name); 94f08c3bdfSopenharmony_ci if (!TST_PASS) 95f08c3bdfSopenharmony_ci goto out1; 96f08c3bdfSopenharmony_ci 97f08c3bdfSopenharmony_ci TST_EXP_PASS_SILENT(move_mount(otfd, "", AT_FDCWD, OT_MNTPOINT, MOVE_MOUNT_F_EMPTY_PATH)); 98f08c3bdfSopenharmony_ci if (!TST_PASS) 99f08c3bdfSopenharmony_ci goto out1; 100f08c3bdfSopenharmony_ci mount_flag = 1; 101f08c3bdfSopenharmony_ci SAFE_CLOSE(otfd); 102f08c3bdfSopenharmony_ci 103f08c3bdfSopenharmony_ci TST_EXP_PASS_SILENT(statvfs(OT_MNTPOINT, &buf), "statvfs sucess"); 104f08c3bdfSopenharmony_ci if (!TST_PASS) 105f08c3bdfSopenharmony_ci goto out2; 106f08c3bdfSopenharmony_ci 107f08c3bdfSopenharmony_ci if (buf.f_flag & tc->expect_attrs) 108f08c3bdfSopenharmony_ci tst_res(TPASS, "%s is actually set as expected", tc->name); 109f08c3bdfSopenharmony_ci else 110f08c3bdfSopenharmony_ci tst_res(TFAIL, "%s is not actually set as expected", tc->name); 111f08c3bdfSopenharmony_ci 112f08c3bdfSopenharmony_ci goto out2; 113f08c3bdfSopenharmony_ci 114f08c3bdfSopenharmony_ciout1: 115f08c3bdfSopenharmony_ci SAFE_CLOSE(otfd); 116f08c3bdfSopenharmony_ciout2: 117f08c3bdfSopenharmony_ci if (mount_flag) 118f08c3bdfSopenharmony_ci SAFE_UMOUNT(OT_MNTPOINT); 119f08c3bdfSopenharmony_ci 120f08c3bdfSopenharmony_ci mount_flag = 0; 121f08c3bdfSopenharmony_ci} 122f08c3bdfSopenharmony_ci 123f08c3bdfSopenharmony_cistatic struct tst_test test = { 124f08c3bdfSopenharmony_ci .tcnt = ARRAY_SIZE(tcases), 125f08c3bdfSopenharmony_ci .test = run, 126f08c3bdfSopenharmony_ci .setup = setup, 127f08c3bdfSopenharmony_ci .cleanup = cleanup, 128f08c3bdfSopenharmony_ci .needs_root = 1, 129f08c3bdfSopenharmony_ci .mount_device = 1, 130f08c3bdfSopenharmony_ci .mntpoint = MNTPOINT, 131f08c3bdfSopenharmony_ci .all_filesystems = 1, 132f08c3bdfSopenharmony_ci .skip_filesystems = (const char *const []){"fuse", NULL}, 133f08c3bdfSopenharmony_ci}; 134