1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /*
3 * Copyright (C) 2024 SUSE LLC Andrea Cervesato <andrea.cervesato@suse.com>
4 */
5
6 /*\
7 * [Description]
8 *
9 * This test verifies that statmount() is raising the correct errors according
10 * with invalid input values.
11 */
12
13 #define _GNU_SOURCE
14
15 #include "statmount.h"
16 #include "lapi/stat.h"
17
18 #define MNTPOINT "mntpoint"
19
20 static struct statmount *st_mount;
21 static struct statmount *st_mount_null;
22 static struct statmount *st_mount_small;
23 static struct statmount *st_mount_bad;
24 static uint64_t mnt_id;
25 static uint64_t mnt_id_dont_exist = -1;
26 static size_t buff_size;
27
28 struct tcase {
29 int exp_errno;
30 char *msg;
31 uint64_t *mnt_id;
32 uint64_t mask;
33 unsigned int flags;
34 struct statmount **buff;
35 } tcases[] = {
36 {
37 .exp_errno = ENOENT,
38 .msg = "mount id doesn't exist'",
39 .mnt_id = &mnt_id_dont_exist,
40 .buff = &st_mount
41 },
42 {
43 .exp_errno = EOVERFLOW,
44 .msg = "invalid mask",
45 .mnt_id = &mnt_id,
46 .mask = -1,
47 .buff = &st_mount
48 },
49 {
50 .exp_errno = EOVERFLOW,
51 .msg = "small buffer for fs type",
52 .mnt_id = &mnt_id,
53 .mask = STATMOUNT_FS_TYPE,
54 .buff = &st_mount_small,
55 },
56 {
57 .exp_errno = EOVERFLOW,
58 .msg = "small buffer for mnt root",
59 .mnt_id = &mnt_id,
60 .mask = STATMOUNT_MNT_ROOT,
61 .buff = &st_mount_small,
62 },
63 {
64 .exp_errno = EOVERFLOW,
65 .msg = "small buffer for mnt point",
66 .mnt_id = &mnt_id,
67 .mask = STATMOUNT_MNT_POINT,
68 .buff = &st_mount_small,
69 },
70 {
71 .exp_errno = EINVAL,
72 .msg = "flags must be zero",
73 .mnt_id = &mnt_id,
74 .flags = 1,
75 .buff = &st_mount,
76 },
77 {
78 .exp_errno = EFAULT,
79 .msg = "buffer crosses to PROT_NONE",
80 .mnt_id = &mnt_id,
81 .buff = &st_mount_bad,
82 },
83 {
84 .exp_errno = EFAULT,
85 .msg = "invalid buffer pointer",
86 .mnt_id = &mnt_id,
87 .buff = &st_mount_null,
88 },
89 };
90
run(unsigned int n)91 static void run(unsigned int n)
92 {
93 struct tcase *tc = &tcases[n];
94
95 memset(st_mount, 0, sizeof(struct statmount));
96
97 TST_EXP_FAIL(statmount(*tc->mnt_id, tc->mask,
98 *tc->buff, buff_size, tc->flags),
99 tc->exp_errno, "%s", tc->msg);
100 }
101
setup(void)102 static void setup(void)
103 {
104 struct ltp_statx sx;
105
106 SAFE_STATX(AT_FDCWD, MNTPOINT, 0, STATX_MNT_ID_UNIQUE, &sx);
107
108 mnt_id = sx.data.stx_mnt_id;
109 buff_size = sizeof(struct statmount);
110 }
111 static struct tst_test test = {
112 .test = run,
113 .tcnt = ARRAY_SIZE(tcases),
114 .setup = setup,
115 .min_kver = "6.8",
116 .mount_device = 1,
117 .mntpoint = MNTPOINT,
118 .bufs = (struct tst_buffers []) {
119 {&st_mount, .size = sizeof(struct statmount)},
120 {&st_mount_small, .size = sizeof(struct statmount)},
121 {&st_mount_bad, .size = 1},
122 {}
123 }
124 };
125