static long tamper_with_syscall_exiting(struct tcb *tcp) { struct inject_opts *opts = tcb_inject_opts(tcp); if (!opts) return 0; if (opts->data.rval >= 0) { kernel_long_t u_rval = tcp->u_rval; tcp->u_rval = opts->data.rval; if (arch_set_success(tcp)) { tcp->u_rval = u_rval; } else { tcp->u_error = 0; } } else { unsigned long new_error = -opts->data.rval; if (new_error != tcp->u_error && new_error <= MAX_ERRNO_VALUE) { unsigned long u_error = tcp->u_error; tcp->u_error = new_error; if (arch_set_error(tcp)) { tcp->u_error = u_error; } } } return 0; }
static long update_syscall_fault_exiting(struct tcb *tcp) { struct fault_opts *opts = tcb_fault_opts(tcp); if (opts && opts->err > 0 && tcp->u_error != (uint16_t) opts->err) { unsigned long u_error = tcp->u_error; tcp->u_error = opts->err; if (arch_set_error(tcp)) tcp->u_error = u_error; } return 0; }