Add "flags" field to struct inject_data

Introduce "flags" field to struct inject_data and use it instead
of magic rval and signo constants.
Due to layout of struct inject_data, this new field does not change
sizeof(struct inject_data).

* defs.h (INJECT_F_RETVAL, INJECT_F_SIGNAL): New macros.
(INJECT_OPTS_RVAL_DEFAULT): Remove macro.
(struct inject_data): Add "flags" field.
* filter_qualify.c (parse_inject_token, qualify_inject_common): Check
struct inject_data.flags instead of inject_data.rval
and inject_data.signo, do not initialize inject_opts.data.
* syscall.c (tamper_with_syscall_entering): Check struct
inject_data.flags instead of inject_data.rval and inject_data.signo.
This commit is contained in:
Дмитрий Левин 2017-08-28 22:37:27 +00:00
parent 4fa9ea3707
commit fe1ab2a53a
3 changed files with 14 additions and 11 deletions

5
defs.h
View File

@ -180,7 +180,11 @@ typedef struct ioctlent {
unsigned int code;
} struct_ioctlent;
#define INJECT_F_SIGNAL 1
#define INJECT_F_RETVAL 2
struct inject_data {
uint16_t flags;
uint16_t signo;
int rval;
};
@ -192,7 +196,6 @@ struct inject_opts {
};
#define MAX_ERRNO_VALUE 4095
#define INJECT_OPTS_RVAL_DEFAULT (-(MAX_ERRNO_VALUE + 1))
/* Trace Control Block */
struct tcb {

View File

@ -120,7 +120,7 @@ parse_inject_token(const char *const token, struct inject_opts *const fopts,
fopts->step = 0;
}
} else if ((val = STR_STRIP_PREFIX(token, "error=")) != token) {
if (fopts->data.rval != INJECT_OPTS_RVAL_DEFAULT)
if (fopts->data.flags & INJECT_F_RETVAL)
return false;
intval = string_to_uint_upto(val, MAX_ERRNO_VALUE);
if (intval < 0)
@ -128,20 +128,23 @@ parse_inject_token(const char *const token, struct inject_opts *const fopts,
if (intval < 1)
return false;
fopts->data.rval = -intval;
fopts->data.flags |= INJECT_F_RETVAL;
} else if (!fault_tokens_only
&& (val = STR_STRIP_PREFIX(token, "retval=")) != token) {
if (fopts->data.rval != INJECT_OPTS_RVAL_DEFAULT)
if (fopts->data.flags & INJECT_F_RETVAL)
return false;
intval = string_to_uint(val);
if (intval < 0)
return false;
fopts->data.rval = intval;
fopts->data.flags |= INJECT_F_RETVAL;
} else if (!fault_tokens_only
&& (val = STR_STRIP_PREFIX(token, "signal=")) != token) {
intval = sigstr_to_uint(val);
if (intval < 1 || intval > NSIG_BYTES * 8)
return false;
fopts->data.signo = intval;
fopts->data.flags |= INJECT_F_SIGNAL;
} else {
return false;
}
@ -238,11 +241,7 @@ qualify_inject_common(const char *const str,
{
struct inject_opts opts = {
.first = 1,
.step = 1,
.data = {
.rval = INJECT_OPTS_RVAL_DEFAULT,
.signo = 0
}
.step = 1
};
char *buf = NULL;
char *name = parse_inject_expression(str, &buf, &opts, fault_tokens_only);
@ -251,10 +250,11 @@ qualify_inject_common(const char *const str,
}
/* If neither of retval, error, or signal is specified, then ... */
if (opts.data.rval == INJECT_OPTS_RVAL_DEFAULT && !opts.data.signo) {
if (!opts.data.flags) {
if (fault_tokens_only) {
/* in fault= syntax the default error code is ENOSYS. */
opts.data.rval = -ENOSYS;
opts.data.flags |= INJECT_F_RETVAL;
} else {
/* in inject= syntax this is not allowed. */
error_msg_and_die("invalid %s '%s'", description, str);

View File

@ -570,9 +570,9 @@ tamper_with_syscall_entering(struct tcb *tcp, unsigned int *signo)
opts->first = opts->step;
if (opts->data.signo > 0)
if (opts->data.flags & INJECT_F_SIGNAL)
*signo = opts->data.signo;
if (opts->data.rval != INJECT_OPTS_RVAL_DEFAULT && !arch_set_scno(tcp, -1))
if (opts->data.flags & INJECT_F_RETVAL && !arch_set_scno(tcp, -1))
tcp->flags |= TCB_TAMPERED;
return 0;