Project

General

Profile

Actions

Bug #975

open

execve compat syscall exit syscall value issue

Added by Mathieu Desnoyers over 8 years ago. Updated over 1 year ago.

Status:
Confirmed
Priority:
Normal
Target version:
-
Start date:
11/08/2015
Due date:
% Done:

0%

Estimated time:

Description

syscall_exit for execve changing the 32/64-bit compat mode for a process has wrong system call number on exit:

[19:36:57.188066018] (+0.000000616) sinkpad syscall_entry_execve: { cpu_id = 0 }, { filename = "/usr/bin/burnP6", argv = 0x7FFD275BBF40, envp = 0x7FFD275BBF50 }
[19:36:57.188162705] (+0.000000851) sinkpad module_get: { cpu_id = 0 }, { ip = 18446744071581118857, refcnt = 3, name = "binfmt_misc" }
[19:36:57.188170506] (+0.000000517) sinkpad module_put: { cpu_id = 0 }, { ip = 18446744071581118912, refcnt = 2, name = "binfmt_misc" }
[19:36:57.188630250] (+0.000000911) sinkpad random_get_random_bytes: { cpu_id = 0 }, { nbytes = 16, IP = 18446744071581461559 }
[19:36:57.188630781] (+0.000000531) sinkpad random_extract_entropy: { cpu_id = 0 }, { pool_name = "nonblocking", nbytes = 16, entropy_count = 0, IP = 18446744071583984742 }
[19:36:57.188634640] (+0.000001773) sinkpad sched_waking: { cpu_id = 0 }, { comm = "rngd", tid = 2177, prio = 120, target_cpu = 2 }
[19:36:57.188637855] (+0.000003215) sinkpad sched_stat_sleep: { cpu_id = 0 }, { comm = "rngd", tid = 2177, delay = 2656341 }
[19:36:57.188639681] (+0.000001826) sinkpad sched_wakeup: { cpu_id = 0 }, { comm = "rngd", tid = 2177, prio = 120, target_cpu = 2 }
[19:36:57.188641483] (+0.000000180) sinkpad power_cpu_idle: { cpu_id = 2 }, { state = 4294967295, cpu_id = 2 }
[19:36:57.188646080] (+0.000000644) sinkpad random_mix_pool_bytes_nolock: { cpu_id = 0 }, { pool_name = "nonblocking", bytes = 20, IP = 18446744071583981062 }
[19:36:57.188649456] (+0.000000788) sinkpad random_mix_pool_bytes_nolock: { cpu_id = 0 }, { pool_name = "nonblocking", bytes = 20, IP = 18446744071583981062 }
[19:36:57.188649704] (+0.000000248) sinkpad rcu_utilization: { cpu_id = 2 }, { s = "Start context switch" }
[19:36:57.188650149] (+0.000000182) sinkpad rcu_utilization: { cpu_id = 2 }, { s = "End context switch" }
[19:36:57.188652253] (+0.000001864) sinkpad sched_stat_wait: { cpu_id = 2 }, { comm = "rngd", tid = 2177, delay = 0 }
[19:36:57.188654080] (+0.000001827) sinkpad sched_switch: { cpu_id = 2 }, { prev_comm = "swapper/2", prev_tid = 0, prev_prio = 20, prev_state = 0, next_comm = "rngd", next_tid = 2177, next_prio = 20 }
[19:36:57.188658382] (+0.000000567) sinkpad sched_process_exec: { cpu_id = 0 }, { filename = "/usr/bin/burnP6", tid = 29058, old_tid = 29058 }
[19:36:57.188661040] (+0.000000020) sinkpad rcu_utilization: { cpu_id = 2 }, { s = "Start context switch" }
[19:36:57.188661415] (+0.000000375) sinkpad rcu_utilization: { cpu_id = 2 }, { s = "End context switch" }
[19:36:57.188662327] (+0.000000409) sinkpad sched_stat_runtime: { cpu_id = 2 }, { comm = "rngd", tid = 2177, runtime = 25827, vruntime = 1365908673 }
[19:36:57.188664216] (+0.000001266) sinkpad compat_syscall_exit_olduname: { cpu_id = 0 }, { ret = 0, name = 0 }

Actions #1

Updated by Mathieu Desnoyers over 8 years ago

One possible approach would be to reserve a status flag (per-thread) to store the compatibility mode at syscall entry.

Actions #2

Updated by Mathieu Desnoyers over 8 years ago

Another approach would be to keep this per-thread state in a hash table within lttng-modules.

Actions #3

Updated by Mathieu Desnoyers over 8 years ago

Yet another approach would be to change the syscall nr in the struct pt_regs whenever we change the compat mode of a process. A 64-bit execve would be mapped to a 32-bit compat execve, or the opposite.

Actions #4

Updated by Mathieu Desnoyers over 1 year ago

This last approach (changing the orig_ax syscall number when changing personality) is what appears to have been implemented in the Linux kernel on x86 in 2017:

commit ada26481dfe698ac64b4aaf19a726e66eb8508c6
Author: Dmitry Safonov <0x7f454c46@gmail.com>
Date:   Fri Mar 31 14:11:37 2017 +0300
     x86/mm: Make in_compat_syscall() work during exec

I just validated that execve is traced correctly when executing a ia32 executable running on a 6.1.0-rc7 x86-64 kernel.

Note that x32 syscall tracing is not supported by LTTng (syscalls are not present in the trace).

Leaving this issue open because other architectures may have inaccurate execve exit events and need a similar upstream kernel fix.

Actions

Also available in: Atom PDF