1 /*
2 * Check decoding of FS_IOC{,32}_{G,S}ETFLAGS ioctl commands.
3 *
4 * Copyright (c) 2020-2021 The strace developers.
5 * All rights reserved.
6 *
7 * SPDX-License-Identifier: GPL-2.0-or-later
8 */
9
10 #include "tests.h"
11 #include <linux/fs.h>
12
13 #include <errno.h>
14 #include <stdio.h>
15 #include <sys/ioctl.h>
16
17 static const char *errstr;
18
19 static int
20 do_ioctl(kernel_ulong_t cmd, kernel_ulong_t arg)
21 {
22 int rc = ioctl(-1, cmd, arg);
23 errstr = sprintrc(rc);
24
25 return rc;
26 }
27
28 static int
29 do_ioctl_ptr(kernel_ulong_t cmd, const void *arg)
30 {
31 return do_ioctl(cmd, (uintptr_t) arg);
32 }
33
34 int
35 main(int argc, const char *argv[])
36 {
37 static const struct {
38 uint32_t cmd;
39 const char *str;
40 bool on_enter;
41 bool on_exit;
42 bool skip;
43 } cmds[] = {
44 { ARG_STR(FS_IOC32_GETFLAGS), false, true, false },
45 { ARG_STR(FS_IOC32_SETFLAGS), true, false, false },
46 { ARG_STR(FS_IOC_GETFLAGS), false, true,
47 FS_IOC_GETFLAGS == FS_IOC32_GETFLAGS },
48 { ARG_STR(FS_IOC_SETFLAGS), true, false,
49 FS_IOC_SETFLAGS == FS_IOC32_SETFLAGS },
50 { _IO('f', 0xff), "_IOC(_IOC_NONE, 0x66, 0xff, 0)",
51 false, false, false },
52 };
53
54 TAIL_ALLOC_OBJECT_CONST_PTR(unsigned int, p_flags);
55
56 for (size_t i = 0; i < ARRAY_SIZE(cmds); ++i) {
57 if (cmds[i].skip)
58 continue;
59
60 do_ioctl(cmds[i].cmd, 0);
61 printf("ioctl(-1, " XLAT_FMT ", %s) = %s\n",
62 XLAT_SEL(cmds[i].cmd, cmds[i].str),
63 (cmds[i].on_enter || cmds[i].on_exit) ? "NULL" : "0",
64 errstr);
65
66 do_ioctl_ptr(cmds[i].cmd, p_flags + 1);
67 printf("ioctl(-1, " XLAT_FMT ", %p) = %s\n",
68 XLAT_SEL(cmds[i].cmd, cmds[i].str),
69 p_flags + 1, errstr);
70
71 #define VALID_FLAGS 0xf2ffffff
72 #define INVALID_FLAGS 0xd000000
73 *p_flags = INVALID_FLAGS;
74
75 if (cmds[i].on_enter) {
76 do_ioctl_ptr(cmds[i].cmd, p_flags);
77 printf("ioctl(-1, " XLAT_FMT ", [%s]) = %s\n",
78 XLAT_SEL(cmds[i].cmd, cmds[i].str),
79 XLAT_UNKNOWN(INVALID_FLAGS, "FS_???_FL"),
80 errstr);
81
82 *p_flags = ~*p_flags;
83 do_ioctl_ptr(cmds[i].cmd, p_flags);
84 printf("ioctl(-1, " XLAT_FMT ", [%s]) = %s\n",
85 XLAT_SEL(cmds[i].cmd, cmds[i].str),
86 XLAT_KNOWN(VALID_FLAGS,
87 "FS_SECRM_FL|"
88 "FS_UNRM_FL|"
89 "FS_COMPR_FL|"
90 "FS_SYNC_FL|"
91 "FS_IMMUTABLE_FL|"
92 "FS_APPEND_FL|"
93 "FS_NODUMP_FL|"
94 "FS_NOATIME_FL|"
95 "FS_DIRTY_FL|"
96 "FS_COMPRBLK_FL|"
97 "FS_NOCOMP_FL|"
98 "FS_ENCRYPT_FL|"
99 "FS_INDEX_FL|"
100 "FS_IMAGIC_FL|"
101 "FS_JOURNAL_DATA_FL|"
102 "FS_NOTAIL_FL|"
103 "FS_DIRSYNC_FL|"
104 "FS_TOPDIR_FL|"
105 "FS_HUGE_FILE_FL|"
106 "FS_EXTENT_FL|"
107 "FS_VERITY_FL|"
108 "FS_EA_INODE_FL|"
109 "FS_EOFBLOCKS_FL|"
110 "FS_NOCOW_FL|"
111 "FS_DAX_FL|"
112 "FS_INLINE_DATA_FL|"
113 "FS_PROJINHERIT_FL|"
114 "FS_CASEFOLD_FL|"
115 "FS_RESERVED_FL"),
116 errstr);
117 } else if (cmds[i].on_exit) {
118 do_ioctl_ptr(cmds[i].cmd, p_flags);
119 printf("ioctl(-1, " XLAT_FMT ", %p) = %s\n",
120 XLAT_SEL(cmds[i].cmd, cmds[i].str),
121 p_flags, errstr);
122 }
123
124 }
125
126 puts("+++ exited with 0 +++");
127 return 0;
128 }