]> granicus.if.org Git - strace/commitdiff
Add "flags" field to struct inject_data
authorDmitry V. Levin <ldv@altlinux.org>
Mon, 28 Aug 2017 22:37:27 +0000 (22:37 +0000)
committerDmitry V. Levin <ldv@altlinux.org>
Mon, 28 Aug 2017 22:37:27 +0000 (22:37 +0000)
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.

defs.h
filter_qualify.c
syscall.c

diff --git a/defs.h b/defs.h
index 0f276ba294848dcd12dc05b32b87b1e44a8ad416..e37c555bd9002062fbe477d675f5b13c73cc698b 100644 (file)
--- 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 {
index d3c036cf4aafeb32d0418c117c1db6e9f7638801..f77ceed81dab7bcc38827225eb3d44fabf51f1fa 100644 (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);
index a622f0bf8b2f2d5889e51be1aab9099aab70c753..b1047feb67f0ec2cb43180f1e59b00f963b03ddf 100644 (file)
--- 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;