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