Fix meaning of negated sets in fault expressions
Change the parser of fault expression to follow the POLA: -e fault=!SET means that all syscalls except those from SET are subject to fault injection; -e fault=!SET1:error=ERRNO1, -e fault=!SET2:error=ERRNO2 means that all syscalls except those from SET2 are subject to fault injection with error code ERRNO2, and all syscalls from SET2 that are not in SET1 are subject to fault injection with error code ERRNO1. * syscall.c (qualify_scno, qualify_syscall_class, qualify_syscall_name): Handle negated QUAL_FAULT case differently. * tests/fault_syntax.test: Add checks of negated sets.
This commit is contained in:
parent
c84536f975
commit
4399fa976a
40
syscall.c
40
syscall.c
@ -457,11 +457,27 @@ static bool
|
||||
qualify_scno(const char *const s, const unsigned int bitflag,
|
||||
const int not, const struct fault_opts *const fopts)
|
||||
{
|
||||
int i = string_to_uint_upto(s, MAX_NSYSCALLS - 1);
|
||||
if (i < 0)
|
||||
int n = string_to_uint_upto(s, MAX_NSYSCALLS - 1);
|
||||
if (n < 0)
|
||||
return false;
|
||||
|
||||
qualify_one(i, bitflag, not, -1, fopts);
|
||||
if (not && fopts) {
|
||||
/* set bitflag for all syscall numbers except n */
|
||||
unsigned int p;
|
||||
for (p = 0; p < SUPPORTED_PERSONALITIES; ++p) {
|
||||
unsigned int i;
|
||||
|
||||
for (i = 0; i < nsyscall_vec[p]; ++i) {
|
||||
if (i != (unsigned int) n
|
||||
&& sysent_vec[p][i].sys_name) {
|
||||
qualify_one(i, bitflag, 0, p, fopts);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
qualify_one(n, bitflag, not, -1, fopts);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -501,9 +517,11 @@ qualify_syscall_class(const char *const s, const unsigned int bitflag,
|
||||
unsigned int i;
|
||||
|
||||
for (i = 0; i < nsyscall_vec[p]; ++i) {
|
||||
if (sysent_vec[p][i].sys_name
|
||||
&& (sysent_vec[p][i].sys_flags & n) == n) {
|
||||
qualify_one(i, bitflag, not, p, fopts);
|
||||
if (!sysent_vec[p][i].sys_name)
|
||||
continue;
|
||||
const bool match = (sysent_vec[p][i].sys_flags & n) == n;
|
||||
if (match ^ (not && fopts)) {
|
||||
qualify_one(i, bitflag, not && !fopts, p, fopts);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -522,10 +540,12 @@ qualify_syscall_name(const char *const s, const unsigned int bitflag,
|
||||
unsigned int i;
|
||||
|
||||
for (i = 0; i < nsyscall_vec[p]; ++i) {
|
||||
if (sysent_vec[p][i].sys_name
|
||||
&& strcmp(s, sysent_vec[p][i].sys_name) == 0) {
|
||||
qualify_one(i, bitflag, not, p, fopts);
|
||||
found = true;
|
||||
if (!sysent_vec[p][i].sys_name)
|
||||
continue;
|
||||
const bool match = !strcmp(s, sysent_vec[p][i].sys_name);
|
||||
found = found || match;
|
||||
if (match ^ (not && fopts)) {
|
||||
qualify_one(i, bitflag, not && !fopts, p, fopts);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -40,16 +40,16 @@ fail_with()
|
||||
"strace -e fault=$* failed to handle an argument error properly"
|
||||
}
|
||||
|
||||
for arg in '' , ,, ,,, : :: ::: \
|
||||
for arg in '' , ,, ,,, : :: ::: \! \!, \!: \
|
||||
invalid_syscall_name \
|
||||
invalid_syscall_name:when=3 \
|
||||
-1 \
|
||||
-1 \!-1 \
|
||||
-1:when=4 \
|
||||
-2 \
|
||||
-2:when=5 \
|
||||
32767 \
|
||||
32767 \!32767 \
|
||||
32767:when=6 \
|
||||
chdir:42 \
|
||||
chdir:42 \!chdir:42 \
|
||||
chdir:42:when=7 \
|
||||
chdir:invalid \
|
||||
chdir:invalid:when=8 \
|
||||
@ -92,6 +92,12 @@ for arg in '' , ,, ,,, : :: ::: \
|
||||
chdir:when=65536:error=30 \
|
||||
chdir:when=1+65536 \
|
||||
chdir:when=1+65536:error=31 \
|
||||
file,nonsense \
|
||||
\!desc,nonsense \
|
||||
chdir,nonsense \
|
||||
\!chdir,nonsense \
|
||||
1,nonsense \
|
||||
\!1,nonsense \
|
||||
; do
|
||||
$STRACE -e fault="$arg" true 2> "$LOG" &&
|
||||
fail_with "$arg"
|
||||
|
Loading…
x
Reference in New Issue
Block a user