From: Dmitry V. Levin Date: Mon, 28 Aug 2017 22:37:27 +0000 (+0000) Subject: Add "flags" field to struct inject_data X-Git-Tag: v4.19~38 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=fe1ab2a53aff62bcbed84b5e14b17740a67f651b;p=strace 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. --- diff --git a/defs.h b/defs.h index 0f276ba2..e37c555b 100644 --- a/defs.h +++ b/defs.h @@ -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 { diff --git a/filter_qualify.c b/filter_qualify.c index d3c036cf..f77ceed8 100644 --- a/filter_qualify.c +++ b/filter_qualify.c @@ -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); diff --git a/syscall.c b/syscall.c index a622f0bf..b1047feb 100644 --- a/syscall.c +++ b/syscall.c @@ -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;