]> granicus.if.org Git - strace/commitdiff
syscall.c: parse return code second time after injecting
authorEugene Syromyatnikov <evgsyr@gmail.com>
Thu, 8 Feb 2018 10:42:19 +0000 (11:42 +0100)
committerDmitry V. Levin <ldv@altlinux.org>
Mon, 12 Feb 2018 11:42:04 +0000 (11:42 +0000)
In order to have the same view as tracee has, with regards to
"never fail" syscalls.

* syscall.c (tamper_with_syscall_exiting): Call get_error after the
return value tampering to re-initialise u_rval and u_error fields
of struct tcb.

syscall.c

index e5963f9416bb2ef210c8b9b8e534e0ca3e109b1c..4a97c09a21dcd59516a7d79cf84ad283dd10f3a6 100644 (file)
--- a/syscall.c
+++ b/syscall.c
@@ -560,6 +560,7 @@ tamper_with_syscall_exiting(struct tcb *tcp)
        }
 
        struct inject_opts *opts = tcb_inject_opts(tcp);
+       bool update_tcb = false;
 
        if (!opts)
                return 0;
@@ -571,6 +572,7 @@ tamper_with_syscall_exiting(struct tcb *tcp)
                if (arch_set_success(tcp)) {
                        tcp->u_rval = u_rval;
                } else {
+                       update_tcb = true;
                        tcp->u_error = 0;
                }
        } else {
@@ -582,10 +584,17 @@ tamper_with_syscall_exiting(struct tcb *tcp)
                        tcp->u_error = new_error;
                        if (arch_set_error(tcp)) {
                                tcp->u_error = u_error;
+                       } else {
+                               update_tcb = true;
                        }
                }
        }
 
+       if (update_tcb) {
+               tcp->u_error = 0;
+               get_error(tcp, !(tcp->s_ent->sys_flags & SYSCALL_NEVER_FAILS));
+       }
+
        return 0;
 }