arch_check_bp_in_kernelspace: fix the range check
Subsystems (6)
PATCH 1/1 arch_check_bp_in_kernelspace: fix the range check
arch_check_bp_in_kernelspace() tries to avoid the overflow and does 2 TASK_SIZE checks but it needs OR, not AND. Consider va = TASK_SIZE -1 and len = 2 case.
Note: TASK_SIZE doesn't look right at least on x86, I think it should be replaced by TASK_SIZE_MAX.
arch/arm64/kernel/hw_breakpoint.c +1 -1
@@ -293,7 +293,7 @@ int arch_check_bp_in_kernelspace(struct va = info->address; len =get_hbp_len (info->ctrl.len); -return (va >=TASK_SIZE ) && ((va + len -1 ) >=TASK_SIZE ); +return (va >=TASK_SIZE ) || ((va + len -1 ) >=TASK_SIZE ); }/*
arch/arm/kernel/hw_breakpoint.c +1 -1
@@ -464,7 +464,7 @@ int arch_check_bp_in_kernelspace(struct va = info->address; len =get_hbp_len (info->ctrl.len); -return (va >=TASK_SIZE ) && ((va + len -1 ) >=TASK_SIZE ); +return (va >=TASK_SIZE ) || ((va + len -1 ) >=TASK_SIZE ); }/*
arch/sh/kernel/hw_breakpoint.c +1 -1
@@ -132,7 +132,7 @@ int arch_check_bp_in_kernelspace(struct va = info->address; len =get_hbp_len (info->len); -return (va >=TASK_SIZE ) && ((va + len -1 ) >=TASK_SIZE ); +return (va >=TASK_SIZE ) || ((va + len -1 ) >=TASK_SIZE ); } int arch_bp_generic_fields(int sh_len, int sh_type,
arch/x86/kernel/hw_breakpoint.c +1 -1
@@ -200,7 +200,7 @@ int arch_check_bp_in_kernelspace(struct va = info->address; len =get_hbp_len (info->len); -return (va >=TASK_SIZE ) && ((va + len -1 ) >=TASK_SIZE ); +return (va >=TASK_SIZE ) || ((va + len -1 ) >=TASK_SIZE ); } int arch_bp_generic_fields(int x86_len, int x86_type,
arch/x86/kernel/hw_breakpoint.c int arch_check_bp_in_kernelspace(struct · line 203
Quoted 12 lines · Oleg Nesterov
Note:
TASK_SIZEdoesn't look right at least on x86, I think it should be replaced byTASK_SIZE_MAX.
...arch/x86/kernel/hw_breakpoint.c +1
-1@@ -200,7 +200,7 @@ int arch_check_bp_in_kernelspace(struct va = info->address; len =get_hbp_len (info->len); -return (va >=TASK_SIZE ) && ((va + len -1 ) >=TASK_SIZE ); +return (va >=TASK_SIZE ) || ((va + len -1 ) >=TASK_SIZE );
But actully I'd like to ask another question.
Can't we add the additional !in_gate_area_no_mm() check to allow the hw breakpoints in vsyscall?
Quoting Amnon:
My service needs to catch the system-calls of its traced son. Almost all system-calls are caught with PTRACE_SYSCALL, but not those using the vsyscall page - especially "gettimeofday()" and "time()".
...
However, the code in "arch/x86/kernel/ptrace.c" forbids catching kernel addresses.
I tend to agree with Amnon...
What do you think?
Oleg.
Quoted 26 lines · Oleg Nesterov
arch/x86/kernel/hw_breakpoint.c int arch_check_bp_in_kernelspace(struct · line 203
Quoted 12 lines · Oleg Nesterov
Note:
TASK_SIZEdoesn't look right at least on x86, I think it should be replaced byTASK_SIZE_MAX.
...arch/x86/kernel/hw_breakpoint.c +1
-1@@ -200,7 +200,7 @@ int arch_check_bp_in_kernelspace(struct va = info->address; len =get_hbp_len (info->len); -return (va >=TASK_SIZE ) && ((va + len -1 ) >=TASK_SIZE ); +return (va >=TASK_SIZE ) || ((va + len -1 ) >=TASK_SIZE );But actully I'd like to ask another question.
Can't we add the additional !in_gate_area_no_mm() check to allow the hw breakpoints in vsyscall?
Quoting Amnon:
My service needs to catch the system-calls of its traced son. Almost all system-calls are caught with
PTRACE_SYSCALL, but not those using the vsyscall page - especially "gettimeofday()" and "time()".
Quoted 8 lines
...
However, the code in "
arch/x86/kernel/ptrace.c" forbids catching kernel addresses.I tend to agree with Amnon...
What do you think?
ping ;)
I agree the patch I sent is very minor (although it looks like the trivial bugfix to me).
Just I think Amnon has a point, shouldn't we change this change like below? (on top of this fixlet).
Oleg.
arch/x86/kernel/hw_breakpoint.c +7 -1
@@ -188,6 +188,11 @@ static int get_hbp_len(u8 hbp_len)return len_in_bytes; } +static inline bool bp_in_gate (unsigned long start,unsigned long end) +{ +return in_gate_area_no_mm (start) &&in_gate_area_no_mm (end); +} +/* * Check for virtual address in kernel space. */
@@ -200,7 +205,8 @@ int arch_check_bp_in_kernelspace(struct va = info->address; len =get_hbp_len (info->len); -return (va >=TASK_SIZE ) || ((va + len -1 ) >=TASK_SIZE ); +return ((va >=TASK_SIZE ) || ((va + len -1 ) >=TASK_SIZE )) && + !bp_in_gate (va, va + len -1 ); } int arch_bp_generic_fields(int x86_len, int x86_type,
Quoted 61 lines · Oleg Nesterov
Quoted 26 lines · Oleg Nesterov
arch/x86/kernel/hw_breakpoint.c int arch_check_bp_in_kernelspace(struct · line 203
Quoted 12 lines · Oleg Nesterov
Note:
TASK_SIZEdoesn't look right at least on x86, I think it should be replaced byTASK_SIZE_MAX.
...arch/x86/kernel/hw_breakpoint.c +1
-1@@ -200,7 +200,7 @@ int arch_check_bp_in_kernelspace(struct va = info->address; len =get_hbp_len (info->len); -return (va >=TASK_SIZE ) && ((va + len -1 ) >=TASK_SIZE ); +return (va >=TASK_SIZE ) || ((va + len -1 ) >=TASK_SIZE );But actully I'd like to ask another question.
Can't we add the additional !in_gate_area_no_mm() check to allow the hw breakpoints in vsyscall?
Quoting Amnon:
My service needs to catch the system-calls of its traced son. Almost all system-calls are caught with
PTRACE_SYSCALL, but not those using the vsyscall page - especially "gettimeofday()" and "time()".Quoted 8 lines
...
However, the code in "
arch/x86/kernel/ptrace.c" forbids catching kernel addresses.I tend to agree with Amnon...
What do you think?
ping ;)
I agree the patch I sent is very minor (although it looks like the trivial bugfix to me).
Just I think Amnon has a point, shouldn't we change this change like below? (on top of this fixlet).
Oleg.
arch/x86/kernel/hw_breakpoint.c +5
-0@@ -188,6 +188,11 @@ static int get_hbp_len(u8 hbp_len)return len_in_bytes; } +static inline bool bp_in_gate (unsigned long start,unsigned long end) +{ +return in_gate_area_no_mm (start) &&in_gate_area_no_mm (end); +} +/* * Check for virtual address in kernel space. */
arch/x86/kernel/hw_breakpoint.c int arch_check_bp_in_kernelspace(struct · line 209
Quoted 6 lines
arch/x86/kernel/hw_breakpoint.c +2
-1@@ -200,7 +205,8 @@ int arch_check_bp_in_kernelspace(struct va = info->address; len =get_hbp_len (info->len); -return (va >=TASK_SIZE ) || ((va + len -1 ) >=TASK_SIZE ); +return ((va >=TASK_SIZE ) || ((va + len -1 ) >=TASK_SIZE )) && + !bp_in_gate (va, va + len -1 );
So we want to allow non privileged to add a breakpoint in a vsyscall area even if it happens to lay in kernel space?
Is this really what we want? I mean, isn't syscall tracing in the kernel done by a flag set to the task's structure. If the task has a flag set, then it does the slow (ptrace) path which handles the breakpoint for the user.
But here, there's no prejudice between tasks. All tasks will now hit the breakpoint regardless of if it is being traced or not.
-- Steve
Quoted 3 lines
arch/x86/kernel/hw_breakpoint.c +0
-0} int arch_bp_generic_fields(int x86_len, int x86_type,
Dear Steve,
Quoted 2 lines
But here, there's no prejudice between tasks. All tasks will now hit the breakpoint regardless of if it is being traced or not.
Just to clarify, there is no intention to allow conventional breakpoints in the vsyscall page - that would indeed be a disaster affecting all other processes.
The aim of this patch is to allow ptracers to set the x86 debug-registers of their traced process, so that it stops when it reaches the entry points of those (few) system-calls that are in the vsyscall page. Note that those debug registers are anyway swapped at context-switch, so no other processes are affected.
Quoted 4 lines
Is this really what we want? I mean, isn't syscall tracing in the kernel done by a flag set to the task's structure. If the task has a flag set, then it does the slow (ptrace) path which handles the breakpoint for the user.
Most system-calls can be trapped by the PTRACE_SYSCALL option (and the later PTRACE_SYSEMU), but those few system-calls on the vsyscall page defy the intention to trap ALL system-calls. They also cannot be checkpointed by inserting a trap-instruction (as that, if allowed, would break all other processes), hence the only alternative left is to have this patch that fixes the oversight in the design of PTRACE_SYSCALL/PTRACE_SYSEMU in the presence of a vsyscall page.
Best Regards,
Amnon.
Quoted 23 lines · Oleg Nesterov
Quoted 22 lines · Oleg Nesterov
Quoted 4 lines · Oleg Nesterov
Quoted 2 lines
Note:
TASK_SIZEdoesn't look right at least on x86, I think itshould
Quoted 16 lines
arch/x86/kernel/hw_breakpoint.c int arch_check_bp_in_kernelspace(struct · line 203
Quoted 10 lines
be replaced by
TASK_SIZE_MAX.
...arch/x86/kernel/hw_breakpoint.c +1
-1@@ -200,7 +200,7 @@ int arch_check_bp_in_kernelspace(struct va = info->address; len =get_hbp_len (info->len); -return (va >=TASK_SIZE ) && ((va + len -1 ) >=TASK_SIZE ); +return (va >=TASK_SIZE ) || ((va + len -1 ) >=TASK_SIZE );But actully I'd like to ask another question.
Can't we add the additional !in_gate_area_no_mm() check to allow the hw breakpoints in vsyscall?
Quoted 7 lines
Quoted 7 lines
Quoted 7 lines
Quoting Amnon:
My service needs to catch the system-calls of its traced son. Almost all system-calls are caught with
PTRACE_SYSCALL, but not those using the vsyscall page - especially "gettimeofday()" and "time()"....> Is this really what we want? I mean, isn't syscall tracing in
the kernel
Quoted 66 lines
done by a flag set to the task's structure. If the task has a flag set, then it does the slow (ptrace) path which handles the breakpoint for the user.
Quoted 36 lines
Quoted 2 lines
However, the code in "
arch/x86/kernel/ptrace.c" forbids catchingkernel
Quoted 5 lines
addresses.
I tend to agree with Amnon...
What do you think?
ping ;)
I agree the patch I sent is very minor (although it looks like the trivial
bugfix to me).Just I think Amnon has a point, shouldn't we change this change like below?
(on top of this fixlet).Oleg.
arch/x86/kernel/hw_breakpoint.c +5
-0@@ -188,6 +188,11 @@ static int get_hbp_len(u8 hbp_len)return len_in_bytes; } +static inline bool bp_in_gate (unsigned long start,unsigned long end) +{ +return in_gate_area_no_mm (start) &&in_gate_area_no_mm (end); +} +/* * Check for virtual address in kernel space. */ arch/x86/kernel/hw_breakpoint.c int arch_check_bp_in_kernelspace(struct · line 209
Quoted 6 lines
arch/x86/kernel/hw_breakpoint.c +2
-1@@ -200,7 +205,8 @@ int arch_check_bp_in_kernelspace(struct va = info->address; len =get_hbp_len (info->len); -return (va >=TASK_SIZE ) || ((va + len -1 ) >=TASK_SIZE ); +return ((va >=TASK_SIZE ) || ((va + len -1 ) >=TASK_SIZE )) && + !bp_in_gate (va, va + len -1 );So we want to allow non privileged to add a breakpoint in a vsyscall area even if it happens to lay in kernel space?
Is this really what we want? I mean, isn't syscall tracing in the kernel done by a flag set to the task's structure. If the task has a flag set, then it does the slow (ptrace) path which handles the breakpoint for the user.
But here, there's no prejudice between tasks. All tasks will now hit the breakpoint regardless of if it is being traced or not.
-- Steve
Quoted 3 lines
arch/x86/kernel/hw_breakpoint.c +0
-0} int arch_bp_generic_fields(int x86_len, int x86_type,
Quoted 26 lines · Steven Rostedt
Quoted 24 lines · Oleg Nesterov
Just I think Amnon has a point, shouldn't we change this change like below? (on top of this fixlet).
Oleg.
arch/x86/kernel/hw_breakpoint.c +5
-0@@ -188,6 +188,11 @@ static int get_hbp_len(u8 hbp_len)return len_in_bytes; } +static inline bool bp_in_gate (unsigned long start,unsigned long end) +{ +return in_gate_area_no_mm (start) &&in_gate_area_no_mm (end); +} +/* * Check for virtual address in kernel space. */ @@ -200,7 +205,8 @@ int arch_check_bp_in_kernelspace(struct va = info->address; len =get_hbp_len (info->len);
Quoted 6 lines
arch/x86/kernel/hw_breakpoint.c int arch_check_bp_in_kernelspace(struct · line 209
Quoted 3 lines
arch/x86/kernel/hw_breakpoint.c +2
-1-return (va >=TASK_SIZE ) || ((va + len -1 ) >=TASK_SIZE ); +return ((va >=TASK_SIZE ) || ((va + len -1 ) >=TASK_SIZE )) && + !bp_in_gate (va, va + len -1 );So we want to allow non privileged to add a breakpoint in a vsyscall area even if it happens to lay in kernel space?
Yes,
Quoted 1 line
Is this really what we want?
I am not sure, that is why I am asking.
Hmm... I have to admit, I didn't even know this code was completely rewritten, and a long ago... and in the default mode it works via emulate_vsyscall() from page-fault, iow not in user_mode().
Quoted 4 lines
I mean, isn't syscall tracing in the kernel
done by a flag set to the task's structure. If the task has a flag set, then it does the slow (ptrace) path which handles the breakpoint for the user.
Well yes, with the new implementation __vsyscall_page simply does syscall, so I guess (say) strace will "just work". But, afaics, only if vsyscall_mode == NATIVE.
So perhaps bp in vsyscall_page still makes sense...
Quoted 2 lines
But here, there's no prejudice between tasks. All tasks will now hit the breakpoint regardless of if it is being traced or not.
^^^^^^^^^^
This is hardware breakpoint, it is per-task.
Oleg.
Quoted 5 lines · Oleg Nesterov
Quoted 2 lines
But here, there's no prejudice between tasks. All tasks will now hit the breakpoint regardless of if it is being traced or not.
^^^^^^^^^^
This is hardware breakpoint, it is per-task.
I forgot that hw breakpoints are swapped out at context switch (as Amnon informed me).
OK, that makes a big difference.
Thanks,
-- Steve
Quoted 6 lines · Oleg Nesterov
Quoted 2 lines · Steven Rostedt
Is this really what we want?
I am not sure, that is why I am asking.
Yes.
And,
Quoted 5 lines
Well yes, with the new implementation
__vsyscall_pagesimply does syscall, so I guess (say) strace will "just work". But, afaics, only ifvsyscall_mode== NATIVE.So perhaps bp in
vsyscall_pagestill makes sense...
Or. Perhaps we can define TRAP_VSYSCALL and change emulate_vsyscall() to do
if (current->ptrace && test_thread_flag(TIF_SYSCALL_TRACE)) send_sigtrap(TRAP_VSYSCALL, ...);
if it returns true?
This way the debugger doesn't need to play with the debug registers, it can use ptrace(PTRACE_SYSCALL). The tracee will report SIGTRAP after vsyscall, debugger can detect this case looking at info->si_code.
Yes, the tracee won't report _before_ it calls the function, but perhaps this is enough? Amnon?
Oleg.
Hi Oleg,
Quoted 9 lines
Or. Perhaps we can define
TRAP_VSYSCALLand changeemulate_vsyscall()to doif (current->ptrace && test_thread_flag(TIF_SYSCALL_TRACE)) send_sigtrap(TRAP_VSYSCALL, ...);if it returns true?
I wish it were possible, but the vsyscall page is entered in user-mode, where it is not possible to read either "current" or the per-thread flags.
One nice alternative, however, is to take away the execute permission from the vsyscall page of the traced process, so it will incur a SIGSEGV (which the ptracer can easily handle and cancel).
The drawbacks of this nice-to-have alternative are:
1) It may require a bigger patch.
2) It needs to use a separate ptrace option, because current applications that use PTRACE_SYSCALL (or PTRACE_SYSEMU), including "strace", will not be aware of this new feature, so they can be broken.
Quoted 2 lines
Yes, the tracee won't report _before_ it calls the function, but perhaps this is enough? Amnon?
The vsyscall page was designed in order to avoid user/kernel context switches, which is possible when a system-call is only reading kernel global information, not modifying any. In most cases therefore (with a few exceptions, such as when the hardware clock is broken or misconfigured), system-calls in the vsyscall page never invoke the kernel at all - so no trap would be generated either before or after.
Best Regards,
Amnon.
Quoted 37 lines · Oleg Nesterov
Quoted 6 lines · Steven Rostedt
Quoted 2 lines
Is this really what we want?
I am not sure, that is why I am asking.
Yes.
And,
Quoted 5 lines
Well yes, with the new implementation
__vsyscall_pagesimply does syscall, so I guess (say) strace will "just work". But, afaics, only ifvsyscall_mode== NATIVE.So perhaps bp in
vsyscall_pagestill makes sense...Or. Perhaps we can define
TRAP_VSYSCALLand changeemulate_vsyscall()to doif (current->ptrace && test_thread_flag(TIF_SYSCALL_TRACE)) send_sigtrap(TRAP_VSYSCALL, ...);if it returns true?
This way the debugger doesn't need to play with the debug registers, it can use
ptrace(PTRACE_SYSCALL). The tracee will report SIGTRAP after vsyscall, debugger can detect this case looking atinfo->si_code.Yes, the tracee won't report _before_ it calls the function, but perhaps this is enough? Amnon?
Oleg.
Hi Amnon,
Please read my previous email ;)
http://marc.info/?l=linux-kernel&m=135342649119153
Quoted 7 lines · On 11/21, [email protected] wrote:
Hi Oleg,
Quoted 4 lines
Or. Perhaps we can define
TRAP_VSYSCALLand changeemulate_vsyscall()to do
Quoted 7 lines
Quoted 5 lines
if (current->ptrace && test_thread_flag(TIF_SYSCALL_TRACE)) send_sigtrap(TRAP_VSYSCALL, ...);if it returns true?
I wish it were possible, but the vsyscall page is entered in user-mode,
Only in NATIVE mode. emulate_vsyscall() runs in kernel mode.
And in the NATIVE mode PTRACE_SYSCALL should work just fine, because:
Quoted 2 lines
The vsyscall page was designed in order to avoid user/kernel context switches,
True, it was. But not today. Please look at __vsyscall_page:
__vsyscall_page:
mov $__NR_gettimeofday, %rax
syscall
ret
If you want the "fast" sys_time() without entering the kernel, you can use __vdso_time(). And since vdso has the user-space mapping you can insert "int3" or use hw breakpoints.
At least this is my understanding after I glanced at the new implementation.
However. It is not that I think that TRAP_VSYSCALL is really good idea. At least it needs another option...
Oleg.
Hi Oleg,
Yes, I can see that "arch/x86/kernel/vsyscall_64.c" has changed dramatically since I last looked at it.
Since this is the case, I no longer need to trap the vsyscall page.
Now however, that "vsyscall" was effectively replaced by vdso, it creates a new problem for me and probably for anyone else who uses some form of checkpoint/restore:
Suppose a process is checkpointed because the system needs to reboot for a kernel-upgrade, then restored on the new and different kernel. The new VDSO page may no longer match the new kernel - it could for example fetch data from addresses in the vsyscall page that now contain different things; or in case the hardware also was changed, it may use machine-instructions that are now illegal.
As I don't mind to forego the "fast" sys_time(), my obvious solution is to disable the vdso for traced processes that may be checkpointed.
One way to do it would be by brute-force: straight after "execve" unmap the tracee's vdso page, then manipulate the ELF tables in its memory so the VDSO entry is gone and the library will not go looking for it. Alternately, the function-table within the VDSO page can be erased.
I just wonder whether you know of an easier and more standard way to disable the vdso in user-mode - ideally on a per-process basis, or otherwise, if it's too hard, on the whole computer. I searched the web and found references to "/proc/sys/vm/vdso_enable", but I have no such file or "sysctl" option on my system.
Best Regards,
Amnon.
Quoted 50 lines
Hi Amnon,
Please read my previous email ;)
http://marc.info/?l=linux-kernel&m=135342649119153Quoted 7 lines · On 11/21, [email protected] wrote:
Hi Oleg,
Quoted 4 lines
Or. Perhaps we can define
TRAP_VSYSCALLand changeemulate_vsyscall()to doQuoted 7 lines
Quoted 5 lines
if (current->ptrace && test_thread_flag(TIF_SYSCALL_TRACE)) send_sigtrap(TRAP_VSYSCALL, ...);if it returns true?
I wish it were possible, but the vsyscall page is entered in user-mode,
Only in NATIVE mode.
emulate_vsyscall()runs in kernel mode.And in the NATIVE mode
PTRACE_SYSCALLshould work just fine, because:Quoted 2 lines
The vsyscall page was designed in order to avoid user/kernel context switches,
True, it was. But not today. Please look at
__vsyscall_page:
__vsyscall_page:mov $__NR_gettimeofday, %rax
syscall
retIf you want the "fast"
sys_time()without entering the kernel, you can use__vdso_time(). And since vdso has the user-space mapping you can insert "int3" or use hw breakpoints.At least this is my understanding after I glanced at the new implementation.
However. It is not that I think that
TRAP_VSYSCALLis really good idea. At least it needs another option...Oleg.
vdso && cr (Was: arch_check_bp_in_kernelspace: fix the range check)
Quoted 4 lines · Amnon Shiloh
Now however, that "vsyscall" was effectively replaced by vdso, it creates a new problem for me and probably for anyone else who uses some form of checkpoint/restore:
Oh, sorry, I can't help here. I can only add Cyrill and Pavel, they seem to enjoy trying to solve the c/r problems.
Quoted 6 lines
Suppose a process is checkpointed because the system needs to reboot for a kernel-upgrade, then restored on the new and different kernel. The new VDSO page may no longer match the new kernel - it could for example fetch data from addresses in the vsyscall page that now contain different things; or in case the hardware also was changed, it may use machine-instructions that are now illegal.
Sure. You shouldn't try to save/restore this page(s) directly. But I do not really understand why do you need. IOW, I don't really understand the problem, it depends on what c/r actually does.
Quoted 5 lines
As I don't mind to forego the "fast"
sys_time(), my obvious solution is to disable the vdso for traced processes that may be checkpointed.One way to do it would be by brute-force: straight after "execve" unmap the tracee's vdso page,
Not sure this will be always possible. For example, my (old) glibc assumes that vsyscall() must work, I won't be surprised if some time later it won't work without vdso. But again, I do not know.
Quoted 3 lines
then manipulate the ELF tables in
its memory so the VDSO entry is gone and the library will not go looking for it.
Probably it would be enough to simply erase AT_SYSINFO_EHDR note, but again, I can be easily wrong.
Quoted 2 lines
I just wonder whether you know of an easier and more standard way to disable the vdso in user-mode
Only the kernel parameter, afaics. vdso=0
Quoted 4 lines
- ideally on a per-process basis,
or otherwise, if it's too hard, on the whole computer. I searched the web and found references to "/proc/sys/vm/vdso_enable", but I have no such file or "sysctl" option on my system.
sys/vm/vdso_enabled, but only if CONFIG_X86_32 for some reason. See kernel/sysctl.c
Oleg.
Re: vdso && cr (Was: arch_check_bp_in_kernelspace: fix the range check)
Quoted 8 lines · Oleg Nesterov
Quoted 4 lines · Amnon Shiloh
Now however, that "vsyscall" was effectively replaced by vdso, it creates a new problem for me and probably for anyone else who uses some form of checkpoint/restore:
Oh, sorry, I can't help here. I can only add Cyrill and Pavel, they seem to enjoy trying to solve the c/r problems.
Thank you :)
Quoted 6 lines
Quoted 6 lines
Suppose a process is checkpointed because the system needs to reboot for a kernel-upgrade, then restored on the new and different kernel. The new VDSO page may no longer match the new kernel - it could for example fetch data from addresses in the vsyscall page that now contain different things; or in case the hardware also was changed, it may use machine-instructions that are now illegal.
If we could make VDSO entry points not move across the kernels (iow, make them looks as yet another syscall table) this would help, I suppose.
Quoted 3 lines
Sure. You shouldn't try to save/restore this page(s) directly. But I do not really understand why do you need. IOW, I don't really understand the problem, it depends on what c/r actually does.
Think about it like this -- you stop a process, then change the kern^w VDSO page. Everything should work as it used to be :)
Quoted 2 lines
Quoted 2 lines
As I don't mind to forego the "fast"
sys_time(), my obvious solution is to disable the vdso for traced processes that may be checkpointed.
This is very poor solution from my POV. Nobody wants to have their applications work fast only until it's checkpointed.
Thanks,
Pavel
Re: vdso && cr (Was: arch_check_bp_in_kernelspace: fix the range
Hi Pavel,
Quoted 9 lines
Quoted 7 lines
Quoted 4 lines
Now however, that "vsyscall" was effectively replaced by vdso, it creates a new problem for me and probably for anyone else who uses some form of checkpoint/restore:
Oh, sorry, I can't help here. I can only add Cyrill and Pavel, they seem to enjoy trying to solve the c/r problems.
Thank you :)
Thank YOU for joining!
Quoted 9 lines
Quoted 6 lines
Quoted 6 lines
Suppose a process is checkpointed because the system needs to reboot for a kernel-upgrade, then restored on the new and different kernel. The new VDSO page may no longer match the new kernel - it could for example fetch data from addresses in the vsyscall page that now contain different things; or in case the hardware also was changed, it may use machine-instructions that are now illegal.
If we could make VDSO entry points not move across the kernels (iow, make them looks as yet another syscall table) this would help, I suppose.
It will indeed solve PART of the problem, but there is one more issue:
One obviously cannot c/r a process while it runs in the VDSO page without c/r'ing that page itself, but this can probably be handled by single-stepping the process until it is out of that page (assuming there are no sleeps, pauses or extremely long loops on that page) - but suppose a catched signal interrupts the VDSO code and the process needs to be checkpointed within that interrupt code - eventually it will return ("sigreturn") to the VDSO page... a different page... and probably fall on the wrong machine-instruction (or even between machine-instructions), with all registers scrambled anyway.
The solution can be to hold all catched signals while in the VDSO page. This is not something the application (or library) can reasonably do due to the prohibitive cost of "sigprocmask()" before and after, defying the whole purpose of the VDSO page, but could be achieved by some new 'prctl' option (or perhaps even be the default).
In my specific case, because the checkpointed process is ptraced, and assuming VDSO entry points are fixed, the ptracer can postpone all catched signals that occur within the VDSO page, but for others who write/maintain a c/r package, that's probably not an option.
Quoted 7 lines
Quoted 4 lines
Sure. You shouldn't try to save/restore this page(s) directly. But I do not really understand why do you need. IOW, I don't really understand the problem, it depends on what c/r actually does.
Think about it like this -- you stop a process, then change the kern^w VDSO page. Everything should work as it used to be :)
There are two reasons one may need to save/restore this page:
1) Entry points are not fixed (yet).
2) In case the process needs to return to it back from an interrupt.
Quoted 6 lines
Quoted 3 lines
Quoted 3 lines
As I don't mind to forego the "fast"
sys_time(), my obvious solution is to disable the vdso for traced processes that may be checkpointed.This is very poor solution from my POV. Nobody wants to have their applications work fast only until it's checkpointed.
I know, but it's a price I must and am willing to pay until a solution is found that prevents catching signals within the VDSO page.
I made a small experiment and just zeroed out the whole VDSO page straight after "execve" (brute force, easier than having to study the internal format of the VDSO page). The program worked, using the glibc version of "gettimeofday()" instead (which used "vsyscall", but probably for not much longer).
So consider my immediate personal problem solved - what I'll do next is to compile a special temporary kernel with all vdso functions (__vdso_gettimeofday, __vdso_time, __vdso_clock_gettime, __vdso_getcpu) reduced to system-calls, so they become kernel/hardware-independent, then I'll save and set aside the resulting VDSO page and always replace original VDSO pages with "my-vdso" after "execve".
However, this doesn't solve the problem for other c/r packages that do not ptrace their processes all the time, and therefore unable to replace the VDSO page immediately after each "execve".
For them you will need to either:
1) fix the VDSO entry points + introduce a kernel feature to prevent catching signals within the VDSO page (probably a new prctl, or make it the default) ; or
2) Introduce a kernel feature (probably a new prctl, so long as it is not reset across fork/clone/exec) for those programs who request it to load a "slow-but-sure", kernel/hardware-independent version of the VDSO page.
Quoted 4 lines
Thanks,
Pavel
Thank you and Best Regards,
Amnon.
Re: vdso && cr (Was: arch_check_bp_in_kernelspace: fix the range
Amnon,
I am going to "ignore" this thread because this is not my area and I can't help anyway. Just one note:
Quoted 7 lines · Amnon Shiloh
The solution can be to hold all catched signals while in the VDSO page.
...1) + introduce a kernel feature to prevent
catching signals within the VDSO page (probably a new prctl, or make it the default)
Sorry, never ;)
Oleg.
Re: vdso && cr (Was: arch_check_bp_in_kernelspace: fix the range
Hi Oleg,
Quoted 10 lines
Amnon,
I am going to "ignore" this thread because this is not my area and I can't help anyway. Just one note:
Quoted 4 lines · Amnon Shiloh
The solution can be to hold all catched signals while in the VDSO page.
...
Quoted 7 lines
Quoted 3 lines
1) + introduce a kernel feature to prevent
catching signals within the VDSO page (probably a new prctl, or make it the default)Sorry, never ;)
Oleg.
It's OK with me because I already found a way to work around this that works for me, but I suspect that other people who write checkpoint/restore packages may not be able to use my soltion and so they will have a problem with interrupts occuring within the VDSO page.
I therefore suggested an alternate solution, for all such systems where applications can be checkpointed on one kernel and restarted on another:
to allow the user to ask for an ultra-compatible VDSO version, which would be exactly the same on all kernels (from a given point in time) and all kernel configurations, even if it means a loss of performance. This is needed for systems where applications can be checkpointed on one kernel and restarted on another.
It could even be a kernel configuration option: CONFIG_ULTRA_COMPAT_VDSO, but ideally it should be the user's choice.
Best Regards,
Amnon.
Re: vdso && cr (Was: arch_check_bp_in_kernelspace: fix the range check)
In reply to Pavel EmelyanovQuoted 9 lines · Pavel Emelyanov
Quoted 3 lines · Oleg Nesterov
Sure. You shouldn't try to save/restore this page(s) directly. But I do not really understand why do you need. IOW, I don't really understand the problem, it depends on what c/r actually does.
Think about it like this -- you stop a process, then change the kern^w VDSO page. Everything should work as it used to be :)
I understand. But again, this depends on how you restore. For example, if you do not "transfer" libc/ld code, then probably vdso is not a problem. Just you need to ensure the task was not stopped "inside" vdso. Yes, yes, I understand that this is too limited, you probably want to transfer "everything".
Oleg.
Dear Oleg,
After the detour into the VDSO page, which is really a separate issue, but one which I was able to work around in user-mode (for my particular needs, not yet for all others who write checkpoint/restore pacakges), I am sad to report that despite my previous post, the "vsyscall" problem was not solved after all.
I made some further tests, without the fix that allows a hardware breakpoint in the kernel, hoping that fixing the VDSO issue solves it all, but alas, current libraries still call the vsyscall page even when the VDSO page is present.
My dynamic glibc library calls call the VDSO version of "gettimeofday()", but still uses the vsyscall version of "time()", while the static library uses vsyscall for both.
What I discovered now, is that PTRACE_SYSCALL (also PTRACE_SINGLESTEP) does not work within the vsyscall page, so I cannot trap the kernel-calls there (this is very simple to verify using "gdb" or "strace").
I suspect that statically-linked executables will be around for a while, long after the rest of the glibc library moves to VDSO, hence I still need to place hardware breakpoints in the vsyscall page.
The necessary patch was already discussed and is very simple.
Or, there is an alternative: if only I (the ptracer or the traced process) was allowed to munmap the vsyscall page, just get rid of that page altogether, or at least make it non-executable, that would be fine too for me, because then the process will get a SIGSEGV signal, which the ptracer can easily handle.
Best Regards,
Amnon.
Quoted 53 lines · Amnon Shiloh
Quoted 4 lines
Now however, that "vsyscall" was effectively replaced by vdso, it creates a new problem for me and probably for anyone else who uses some form of checkpoint/restore:
Oh, sorry, I can't help here. I can only add Cyrill and Pavel, they seem to enjoy trying to solve the c/r problems.
Quoted 6 lines
Suppose a process is checkpointed because the system needs to reboot for a kernel-upgrade, then restored on the new and different kernel. The new VDSO page may no longer match the new kernel - it could for example fetch data from addresses in the vsyscall page that now contain different things; or in case the hardware also was changed, it may use machine-instructions that are now illegal.
Sure. You shouldn't try to save/restore this page(s) directly. But I do not really understand why do you need. IOW, I don't really understand the problem, it depends on what c/r actually does.
Quoted 5 lines
As I don't mind to forego the "fast"
sys_time(), my obvious solution is to disable the vdso for traced processes that may be checkpointed.One way to do it would be by brute-force: straight after "execve" unmap the tracee's vdso page,
Not sure this will be always possible. For example, my (old) glibc assumes that
vsyscall()must work, I won't be surprised if some time later it won't work without vdso. But again, I do not know.Quoted 3 lines
then manipulate the ELF tables in
its memory so the VDSO entry is gone and the library will not go looking for it.Probably it would be enough to simply erase
AT_SYSINFO_EHDRnote, but again, I can be easily wrong.Quoted 2 lines
I just wonder whether you know of an easier and more standard way to disable the vdso in user-mode
Only the kernel parameter, afaics. vdso=0
Quoted 4 lines
- ideally on a per-process basis,
or otherwise, if it's too hard, on the whole computer. I searched the web and found references to "/proc/sys/vm/vdso_enable", but I have no such file or "sysctl" option on my system.sys/vm/vdso_enabled, but only if
CONFIG_X86_32for some reason. Seekernel/sysctl.cOleg.
Hello Amnon,
I am a bit confused,
Quoted 4 lines · Amnon Shiloh
What I discovered now, is that
PTRACE_SYSCALL(alsoPTRACE_SINGLESTEP) does not work within the vsyscall page, so I cannot trap the kernel-calls there (this is very simple to verify using "gdb" or "strace").
Sure, but we alredy discussed this?
Once again, PTRACE_SYSCALL should work in the NATIVE mode. Obviously it won't work in EMULATE mode but we can change emulate_vsyscall() to report TRAP_VSYSCALL or even introduce PTRACE_EVENT_VSYSCALL.
Quoted 1 line
The necessary patch was already discussed and is very simple.
Do you mean TRAP_VSYSCALL/PTRACE_EVENT_VSYSCALL above or additional in_gate_area_no_mm() check to allow the hw bp?
Quoted 2 lines
Or, there is an alternative: if only I (the ptracer or the traced process) was allowed to munmap the vsyscall page,
It is not possible to unmap it. The kernel (swapper_pg_dir) has this mapping, not the process. Unlike vdso. IOW, you can only "unmap" it globally and obviously you can't do this from the userspace.
Oleg.
forgot to mention...
Quoted 9 lines · Oleg Nesterov
Quoted 3 lines · Amnon Shiloh
Or, there is an alternative: if only I (the ptracer or the traced process) was allowed to munmap the vsyscall page,
It is not possible to unmap it. The kernel (
swapper_pg_dir) has this mapping, not the process. Unlike vdso. IOW, you can only "unmap" it globally and obviously you can't do this from the userspace.
And even if this were possible, this can't help. Please look at __bad_area_nosemaphore()->emulate_vsyscall(), the process won't get SIGSEGV. IOW, in fact EMULATE already "unmaps" this page (sets _NX) to trigger the fault.
Sure, we can do something like below, but it doesn't look very nice too.
Oleg.
arch/x86/mm/fault.c +2 -1
@@ -744,7 +744,8 @@ __bad_area_nosemaphore(struct pt_regs *r*/ if (unlikely ((error_code &PF_INSTR ) && ((address & ~0xfff ) ==VSYSCALL_START ))) { -if (emulate_vsyscall (regs, address)) +if (!(tsk->ptrace &PTRACE_O_DONTEMULATE ) && +emulate_vsyscall (regs, address))return ; }#endif
Hi Oleg,
This patch may look ugly, but it is one way to solve my problem.
This way, "strace" too, which is broken since the introduction of the vsyscall page, will again be able to report when the program calls "time()" or "gettimeofday()" - currently it cannot!
I think that allowing to set the x86 debug-registers to the vsyscall page is more elegant - but do whatever you prefer.
Best Regards,
Amnon.
Quoted 37 lines
forgot to mention...
Quoted 9 lines · Oleg Nesterov
Quoted 3 lines · Amnon Shiloh
Or, there is an alternative: if only I (the ptracer or the traced process) was allowed to munmap the vsyscall page,
It is not possible to unmap it. The kernel (
swapper_pg_dir) has this mapping, not the process. Unlike vdso. IOW, you can only "unmap" it globally and obviously you can't do this from the userspace.And even if this were possible, this can't help. Please look at __bad_area_nosemaphore()->emulate_vsyscall(), the process won't get SIGSEGV. IOW, in fact EMULATE already "unmaps" this page (sets
_NX) to trigger the fault.Sure, we can do something like below, but it doesn't look very nice too.
Oleg.
arch/x86/mm/fault.c +2
-1@@ -744,7 +744,8 @@ __bad_area_nosemaphore(struct pt_regs *r*/ if (unlikely ((error_code &PF_INSTR ) && ((address & ~0xfff ) ==VSYSCALL_START ))) { -if (emulate_vsyscall (regs, address)) +if (!(tsk->ptrace &PTRACE_O_DONTEMULATE ) && +emulate_vsyscall (regs, address))return ; }#endif
Hi Oleg,
Quoted 3 lines
Hello Amnon,
I am a bit confused,
So let's get things in order.
1) I asked for the ability to set hardware breakpoints on the vsyscall page (x86 debug registers), so that the ptracer can stop the process whenever it attempts to jump there, then the ptracer can emulate those system calls instead (gettimeofday, time, getcpu).
That would solve all my problems, because the traced process will never even enter the vsyscall page (the ptracer will adjust its program-counter).
2) I was then told (in my own words): "oh, don't worry, the vsyscall page has now been minimized, all it contains now is *real* system calls, and it always calls them".
[as a side-issue I was introduced to the new VDSO, had some issues there
and solved them separately, so we are back on the original topic]
3) I was thinking to myself - well, that's fine, if the vsyscall now always invokes a *real* system-call (and nothing else), then the ptracer can catch it just like any other system-call using PTRACE_SYSCALL (or PTRACE_SYSEMU), and emulate it as usual, vsyscall-or-no-vsyscall.
4) I made some tests and found that I was wrong in my assumption:
PTRACE_SYSCALL does NOT work within the vsyscall page (nor does PTRACE_SINGLESTEP). Ptracers are not even aware that their tracee ever issued a system call there (despite using PTRACE_SYSCALL or PTRACE_SYSEMU), so they are unable to emulate it (or even to report it, in the case of "strace").
5) Therefore, I still need the original feature - to relax "arch_check_bp_in_kernelspace()", or whatever else will allow me to set the x86 debug-registers to trap all attempts to enter the vsyscall page.
6) I just suggested an alternative: to have the whole vsyscall page removed on a per-process basis. I accept your reply that this is not possible.
7) I suggested a third alternative: to have the vsyscall page be unexecutable on a per-process basis, so attempts to use it will
incur SIGSEGV. I understand that this option is still under
discussion.
8) Any solution that allows a ptracer to prevent its traced process from entering the vsyscall page and execute there system-calls unchecked (thus in effect escape its jailer), would do for me.
Best Regards,
Amnon.
Quoted 28 lines · Amnon Shiloh
Quoted 4 lines
What I discovered now, is that
PTRACE_SYSCALL(alsoPTRACE_SINGLESTEP) does not work within the vsyscall page, so I cannot trap the kernel-calls there (this is very simple to verify using "gdb" or "strace").Sure, but we alredy discussed this?
Once again,
PTRACE_SYSCALLshould work in the NATIVE mode. Obviously it won't work in EMULATE mode but we can changeemulate_vsyscall()to reportTRAP_VSYSCALLor even introducePTRACE_EVENT_VSYSCALL.Quoted 1 line
The necessary patch was already discussed and is very simple.
Do you mean TRAP_VSYSCALL/PTRACE_EVENT_VSYSCALL above or additional
in_gate_area_no_mm()check to allow the hw bp?Quoted 2 lines
Or, there is an alternative: if only I (the ptracer or the traced process) was allowed to munmap the vsyscall page,
It is not possible to unmap it. The kernel (
swapper_pg_dir) has this mapping, not the process. Unlike vdso. IOW, you can only "unmap" it globally and obviously you can't do this from the userspace.Oleg.
Quoted 4 lines · Amnon Shiloh
2) I was then told (in my own words): "oh, don't worry, the vsyscall page has now been minimized, all it contains now is *real* system calls, and it always calls them".
Not sure where did you get this idea ;) From the very beginning you were told that EMULATE mode doesn't do this.
The NATIVE mode should be fine, yes.
Quoted 3 lines
6) I just suggested an alternative: to have the whole vsyscall page removed on a per-process basis. I accept your reply that this is not possible.
Yes, this is not possible.
Quoted 2 lines
7) I suggested a third alternative: to have the vsyscall page be unexecutable on a per-process basis,
Like above, this is simply not possible. And at the same time the vsyscall page is already unexecutable in EMULATE mode, but globally.
Quoted 3 lines
8) Any solution that allows a ptracer to prevent its traced process from entering the vsyscall page and execute there system-calls unchecked (thus in effect escape its jailer), would do for me.
Well. I am even more confused... probably this was already discussed and I missed this, but.
Why do you need to _prevent_, say, sys_gettimeofday()? Why we can't change emulate_vsyscall() to respect PTRACE_SYSCALL and report TRAP_VSYSCALL or PTRACE_EVENT_VSYSCALL as I tried to suggest in
http://marc.info/?l=linux-kernel&m=135343635523715 ?
You previously replied that this can not work. Now that you see that this _can_ work, could you please explain why this is not enough?
Oleg.
Hi Oleg,
Quoted 6 lines
Quoted 3 lines
2) I was then told (in my own words): "oh, don't worry, the vsyscall page has now been minimized, all it contains now is *real* system calls, and it always calls them".
Not sure where did you get this idea ;) From the very beginning you were told that EMULATE mode doesn't do this.
Sorry, I was not aware of the existence of "EMULATE" at the time, or that it was the default, so I lived in a "NATIVE" world... and was content that yesterday's problem was solved... I just looked at the vsyscall page itself, found the system-calls there and was "happy" with it, that I could now catch them like anywhere else.
Quoted 7 lines
Quoted 3 lines
8) Any solution that allows a ptracer to prevent its traced process from entering the vsyscall page and execute there system-calls unchecked (thus in effect escape its jailer), would do for me.
Well. I am even more confused... probably this was already discussed and I missed this, but.
Quoted 7 lines
Why do you need to _prevent_, say,
sys_gettimeofday()? Why we can't changeemulate_vsyscall()to respectPTRACE_SYSCALLand reportTRAP_VSYSCALLorPTRACE_EVENT_VSYSCALLas I tried to suggest in
http://marc.info/?l=linux-kernel&m=135343635523715 ?Oleg.
For my own application, I would be happy with this.
But I suspect it might break current versions of "strace", or similar programs that expect to find the program-counter pointing at a "syscall" instruction.
At present "strace" fails to report "gettimeofday()", but at least it does not crash. Surely "strace" can and should be enhanced to handle this, but existing versions may suffer.
Quoted 3 lines
You previously replied that this can not work. Now that you see that this _can_ work, could you please explain why this is not enough?
I think it COULD work, but not based on PTRACE_SYSCALL
(or PTRACE_SYSEMU) alone. A new ptrace option will be needed, saying:
"Yes, I am aware of TRAP_VSYSCALL and I know how to handle it."
While for my own application, just fixing the range-check in arch_check_bp_in_kernelspace will do, requiring a smaller patch, I agree that fixing this properly by adding a new ptrace option can help other programmers, so they need not bother with the x86 debug-registers (or perhaps they may need them for other purposes).
Best Regards,
Amnon.
PTRACE_SYSCALL && vsyscall (Was: arch_check_bp_in_kernelspace: fix the range check)
Amnon, sorry for delay...
Quoted 10 lines · Amnon Shiloh
Quoted 8 lines
Why do you need to _prevent_, say,
sys_gettimeofday()? Why we can't changeemulate_vsyscall()to respectPTRACE_SYSCALLand reportTRAP_VSYSCALLorPTRACE_EVENT_VSYSCALLas I tried to suggest in
http://marc.info/?l=linux-kernel&m=135343635523715 ?Oleg.
For my own application, I would be happy with this.
OK, good.
Quoted 5 lines
But I suspect it might break current versions of "strace",
...
I think it COULD work, but not based onPTRACE_SYSCALL
(orPTRACE_SYSEMU) alone. A new ptrace option will be needed, saying:
"Yes, I am aware ofTRAP_VSYSCALLand I know how to handle it."
Yes, that is why I said this needs the new option.
However. Of course it would be nice to avoid the new option. IMO it would be better to do nothing ;) vsyscall is deprecated, and EMULATE is x86-specific.
May be we could simply do something like the patch below? (Just in case, this hack is only for illustration, it is not complete).
If the tracer does PTRACE_SYSCALL the tracee reports syscall exit _after_ gettimeofday/etc. The tracer can look at regs->orig_ax == -1 and detect that this is not syscall but vsyscall, it can look at regs->ip then (not with the patch below).
Denys, Jan, Pedro. Do you think this change can break/confuse gdb/strace ?
Quoted 2 lines
While for my own application, just fixing the range-check in
arch_check_bp_in_kernelspacewill do,
You forgot again that EMULATE does not execute the code in the vsyscall page.
Oleg.
arch/x86/kernel/vsyscall_64.c +4 -0
@@ -186,6 +186,8 @@ static bool write_ok_or_segv(unsigned long ptr, size_t size) } } +#include <linux/tracehook.h> +bool emulate_vsyscall (struct pt_regs *regs,unsigned long address) {struct task_struct *tsk;
@@ -312,6 +314,8 @@ do_ret: regs->ip = caller; regs->sp +=8 ; done: +if (test_thread_flag (TIF_SYSCALL_TRACE )) +ptrace_report_syscall (regs);return true; sigsegv:
Re: PTRACE_SYSCALL && vsyscall (Was: arch_check_bp_in_kernelspace: fix the range check)
Hi Oleg,
Quoted 3 lines
However. Of course it would be nice to avoid the new option. IMO it would be better to do nothing ;) vsyscall is deprecated, and EMULATE is x86-specific.
The problem is that the current static glibc invokes the vsyscall page, so statically-linked 3rd-party executables that were distributed only in binary form are not going to stop using vsyscall even in 100 years.
Note also that even now, while the dynamic glibc library uses vDSO for "gettimeofday()" it still uses the vsyscall page for "time()", so even when fixed, it would still take years in any case until all Linux distributions are free of references to the vsyscall page.
Quoted 2 lines
You forgot again that EMULATE does not execute the code in the vsyscall page.
The beauty of using the x86 debug-registers, is that they do not trap the instruction, but rather the fact that the program-counter has a given value. They work like single-stepping, so the condition of attempting to access the vsyscall page is detected in hardware BEFORE attempting to access the vsyscall page itself, BEFORE even discovering that the vsyscall page is inaccessible (in EMULATE mode).
Once trapped of course, the program-counter will be changed by the ptracer, so neither NATIVE nor EMULATE will ever be invoked.
Current versions of "strace" and "gdb" will not automatically benefit from this, but wouldn't be harmed either. Future versions can then be written to make use of the debug-registers to detect a vsyscall.
Best Regards,
Amnon.
Quoted 72 lines
Amnon, sorry for delay...
Quoted 10 lines · Amnon Shiloh
Quoted 8 lines
Why do you need to _prevent_, say,
sys_gettimeofday()? Why we can't changeemulate_vsyscall()to respectPTRACE_SYSCALLand reportTRAP_VSYSCALLorPTRACE_EVENT_VSYSCALLas I tried to suggest in
http://marc.info/?l=linux-kernel&m=135343635523715 ?Oleg.
For my own application, I would be happy with this.
OK, good.
Quoted 5 lines
But I suspect it might break current versions of "strace",
...
I think it COULD work, but not based onPTRACE_SYSCALL
(orPTRACE_SYSEMU) alone. A new ptrace option will be needed, saying:
"Yes, I am aware ofTRAP_VSYSCALLand I know how to handle it."Yes, that is why I said this needs the new option.
However. Of course it would be nice to avoid the new option. IMO it would be better to do nothing ;) vsyscall is deprecated, and EMULATE is x86-specific.
May be we could simply do something like the patch below? (Just in case, this hack is only for illustration, it is not complete).
If the tracer does
PTRACE_SYSCALLthe tracee reports syscall exit _after_ gettimeofday/etc. The tracer can look atregs->orig_ax== -1 and detect that this is not syscall but vsyscall, it can look atregs->ipthen (not with the patch below).Denys, Jan, Pedro. Do you think this change can break/confuse gdb/strace ?
Quoted 2 lines
While for my own application, just fixing the range-check in
arch_check_bp_in_kernelspacewill do,You forgot again that EMULATE does not execute the code in the vsyscall page.
Oleg.
arch/x86/kernel/vsyscall_64.c +2
-0@@ -186,6 +186,8 @@ static bool write_ok_or_segv(unsigned long ptr, size_t size) } } +#include <linux/tracehook.h> +bool emulate_vsyscall (struct pt_regs *regs,unsigned long address) {arch/x86/kernel/vsyscall_64.c +2
-0struct task_struct *tsk;@@ -312,6 +314,8 @@ do_ret: regs->ip = caller; regs->sp +=8 ; done: +if (test_thread_flag (TIF_SYSCALL_TRACE )) +ptrace_report_syscall (regs);return true; sigsegv:
Re: PTRACE_SYSCALL && vsyscall (Was: arch_check_bp_in_kernelspace: fix the range check)
Quoted 6 lines · On 12/03, [email protected] wrote:
Quoted 4 lines
However. Of course it would be nice to avoid the new option. IMO it would be better to do nothing ;) vsyscall is deprecated, and EMULATE is x86-specific.
The problem is that the current static glibc invokes the vsyscall page,
Yes I know.
Still I'd like to avoid to change the ptrace API, even if the change is simple. This emulate_vsyscall() is too "exotic" imho.
Quoted 6 lines
Quoted 2 lines
You forgot again that EMULATE does not execute the code in the vsyscall page.
The beauty of using the x86 debug-registers, is that they do not trap the instruction, but rather the fact that the program-counter has a given value.
Yes, I understand, so DR_RW_EXECUTE should probably work. And I even sent the patch (untested/uncompiled). But given that even the simple bugfix which started this thread was ignored by maintainers, I am not sure how we can convince them this change makes sense ;)
However. This looks like a hack to me, because this code is never executed. But this is sudjective and I am not saying this can't work. And yes, this doesn't add new ptrace hacks.
But If we want to allow to trace vsyscall's, hw bp doesn't look very nice imo. HBP_NUM = 4 and you need to setup 3 bp's to trace them all.
And what about strace? It won't be easy to change it to use hwbp.
That is why I think PTRACE_SYSCALL should "simply work" somehow. And so far I think that "just report syscall_exit with orig_ax = -1" is the best (and simple) solution.
OK. We can do more. We can report both syscall_enter/exit and we can change orig_ax/ax temporary to "fool" the tracer, so that everything will look as a "normal" syscall. Like vsyscall_seccomp() does.
But this needs much more changes.
Oleg.
Re: PTRACE_SYSCALL && vsyscall (Was: arch_check_bp_in_kernelspace: fix the range check)
Dear Oleg,
Quoted 4 lines
Yes, I understand, so
DR_RW_EXECUTEshould probably work. And I even sent the patch (untested/uncompiled). But given that even the simple bugfix which started this thread was ignored by maintainers, I am not sure how we can convince them this change makes sense ;)
Just to confirm, DR_RW_EXECUTE won't only "probably" work - it DOES work, I have tested it.
A fully super-duper automatic and transparent emulation of PTRACE_SYSCALL, including the faking of user-registers, would undoubtedly be great, but it's complex and will require a large patch, while here is a trivial 1-2 line fix which doesn't harm anyone and allows ptracers to trap a vsyscall in no time.
Quoted 2 lines
But If we want to allow to trace vsyscall's, hw bp doesn't look very nice imo.
HBP_NUM= 4 and you need to setup 3 bp's to trace them all.
The next solution in line, in terms of patch-size, if we don't want to waste debug registers, is to have the execute permission of the vsyscall page changed on context switches when a process/ptracer requests so, in a manner similar to prctl(PR_SET_TSC).
Best Regards,
Amnon.
Quoted 49 lines
Quoted 6 lines
Quoted 4 lines
However. Of course it would be nice to avoid the new option. IMO it would be better to do nothing ;) vsyscall is deprecated, and EMULATE is x86-specific.
The problem is that the current static glibc invokes the vsyscall page,
Yes I know.
Still I'd like to avoid to change the ptrace API, even if the change is simple. This
emulate_vsyscall()is too "exotic" imho.Quoted 6 lines
Quoted 2 lines
You forgot again that EMULATE does not execute the code in the vsyscall page.
The beauty of using the x86 debug-registers, is that they do not trap the instruction, but rather the fact that the program-counter has a given value.
Yes, I understand, so
DR_RW_EXECUTEshould probably work. And I even sent the patch (untested/uncompiled). But given that even the simple bugfix which started this thread was ignored by maintainers, I am not sure how we can convince them this change makes sense ;)However. This looks like a hack to me, because this code is never executed. But this is sudjective and I am not saying this can't work. And yes, this doesn't add new ptrace hacks.
But If we want to allow to trace vsyscall's, hw bp doesn't look very nice imo.
HBP_NUM= 4 and you need to setup 3 bp's to trace them all.And what about strace? It won't be easy to change it to use hwbp.
That is why I think
PTRACE_SYSCALLshould "simply work" somehow. And so far I think that "just reportsyscall_exitwithorig_ax= -1" is the best (and simple) solution.OK. We can do more. We can report both syscall_enter/exit and we can change orig_ax/ax temporary to "fool" the tracer, so that everything will look as a "normal" syscall. Like
vsyscall_seccomp()does.But this needs much more changes.
Oleg.
Re: PTRACE_SYSCALL && vsyscall (Was: arch_check_bp_in_kernelspace: fix the range check)
In reply to Oleg NesterovQuoted 2 lines · Oleg Nesterov
But If we want to allow to trace vsyscall's, hw bp doesn't look very nice imo.
HBP_NUM= 4 and you need to setup 3 bp's to trace them all.
Irrespective of the whole syscall tracing issue, allowing HW bkpts in the vsyscall just seems like a bug fix to me.
Quoted 3 lines
That is why I think
PTRACE_SYSCALLshould "simply work" somehow. And so far I think that "just reportsyscall_exitwithorig_ax= -1" is the best (and simple) solution.
If you report exit alone, you'll confuse current GDB into mistaking it for an enter, and all following enter/exits end up swapped/confused. GDB assumes trap/sysgood alternates between enter/exit, and always starts with enter.
(Mildly related, GDB has an old comment in the code (linux-nat.c) that says:
"However, most architectures can't handle a syscall being traced on the way out if it wasn't traced on the way in."
I've no clue if that's still true nowadays.)
Quoted 5 lines
OK. We can do more. We can report both syscall_enter/exit and we can change orig_ax/ax temporary to "fool" the tracer, so that everything will look as a "normal" syscall. Like
vsyscall_seccomp()does.But this needs much more changes.
I'd just like to add, that if any new syscall related option is to be added, can we please just go all the way and add PTRACE_EVENT_SYSCALL_ENTER|PTRACE_EVENT_SYSCALL_EXIT instead?
http://sourceware.org/gdb/wiki/LinuxKernelWishList
Signature · 1 line
Pedro Alves
Re: PTRACE_SYSCALL && vsyscall (Was: arch_check_bp_in_kernelspace: fix the range check)
Quoted 8 lines · Pedro Alves
Quoted 2 lines · Oleg Nesterov
But If we want to allow to trace vsyscall's, hw bp doesn't look very nice imo.
HBP_NUM= 4 and you need to setup 3 bp's to trace them all.Irrespective of the whole syscall tracing issue, allowing HW bkpts in the vsyscall just seems like a bug fix to me.
And I never argued. I sent the patch iirc ;)
Quoted 6 lines
Quoted 3 lines
That is why I think
PTRACE_SYSCALLshould "simply work" somehow. And so far I think that "just reportsyscall_exitwithorig_ax= -1" is the best (and simple) solution.If you report exit alone, you'll confuse current GDB into mistaking it for an enter,
Sure. That is why I asked Jan.
Quoted 9 lines
Quoted 5 lines
OK. We can do more. We can report both syscall_enter/exit and we can change orig_ax/ax temporary to "fool" the tracer, so that everything will look as a "normal" syscall. Like
vsyscall_seccomp()does.But this needs much more changes.
I'd just like to add, that if any new syscall related option is to be added, can we please just go all the way and add PTRACE_EVENT_SYSCALL_ENTER|PTRACE_EVENT_SYSCALL_EXIT instead?
Oh yes, this was suggested many times.
Oleg.
Re: PTRACE_SYSCALL && vsyscall (Was: arch_check_bp_in_kernelspace: fix the range check)
Hi Everyone,
Quoted 11 lines · Pedro Alves
Quoted 8 lines · Oleg Nesterov
Quoted 3 lines
But If we want to allow to trace vsyscall's, hw bp doesn't look very nice imo.
HBP_NUM= 4 and you need to setup 3 bp's to trace them all.Irrespective of the whole syscall tracing issue, allowing HW bkpts in the vsyscall just seems like a bug fix to me.
And I never argued. I sent the patch iirc ;)
Exactly, it is a bug and I am still waiting for it to be fixed in the Linux kernel.
Fully emulating PTRACE_SYSCALL could also provide a suitable way to fix my problem, and it may also help others by saving them the need to program and waste x86 debug registers, but it doesn't change the fact that my problem is caused by a bug in the first place, which should be fixed in any case.
Best Regards,
Amnon.
Quoted 25 lines
Quoted 7 lines
Quoted 4 lines
That is why I think
PTRACE_SYSCALLshould "simply work" somehow. And so far I think that "just reportsyscall_exitwithorig_ax= -1" is the best (and simple) solution.If you report exit alone, you'll confuse current GDB into mistaking it for an enter,
Sure. That is why I asked Jan.
Quoted 9 lines
Quoted 5 lines
OK. We can do more. We can report both syscall_enter/exit and we can change orig_ax/ax temporary to "fool" the tracer, so that everything will look as a "normal" syscall. Like
vsyscall_seccomp()does.But this needs much more changes.
I'd just like to add, that if any new syscall related option is to be added, can we please just go all the way and add PTRACE_EVENT_SYSCALL_ENTER|PTRACE_EVENT_SYSCALL_EXIT instead?
Oh yes, this was suggested many times.
Oleg.
Re: PTRACE_SYSCALL && vsyscall (Was: arch_check_bp_in_kernelspace: fix the range check)
Quoted 10 lines · On 01/10, [email protected] wrote:
Hi Everyone,
Quoted 7 lines · Pedro Alves
Quoted 6 lines · Oleg Nesterov
Quoted 3 lines
But If we want to allow to trace vsyscall's, hw bp doesn't look very nice imo.
HBP_NUM= 4 and you need to setup 3 bp's to trace them all.
Quoted 7 lines
Quoted 4 lines
Quoted 2 lines
Irrespective of the whole syscall tracing issue, allowing HW bkpts in the vsyscall just seems like a bug fix to me.
And I never argued. I sent the patch iirc ;)
Exactly, it is a bug and I am still waiting for it to be fixed in the Linux kernel.
I would not say this is a bug but let me repeat, no need to convince me.
Please feel free to re-send the patch(es) I sent to maintainers. Sorry, I can't push these changes into Linus's tree.
Oleg.
Re: PTRACE_SYSCALL && vsyscall (Was: arch_check_bp_in_kernelspace: fix the range check)
Hi,
Quoted 4 lines
I would not say this is a bug but let me repeat, no need to convince me.
Please feel free to re-send the patch(es) I sent to maintainers. Sorry, I can't push these changes into Linus's tree.
So here again is the patch that I need so badly - clearly it fixes a bug and harms nobody:
-----------------------------------------------------------------------
diff -Naur before/arch/x86/kernel/hw_breakpoint.cafter/arch/x86/kernel/hw_breakpoint.c
--- before/arch/x86/kernel/hw_breakpoint.c 2013-01-14 12:45:20.000000000
+1030
+++ after/arch/x86/kernel/hw_breakpoint.c 2013-01-14 12:46:24.000000000 +1030
@@ -200,7 +200,8 @@
va = info->address;
len = get_hbp_len(info->len);
- return (va >= TASK_SIZE) && ((va + len - 1) >= TASK_SIZE);
+ return (va >= TASK_SIZE) && ((va + len - 1) >= TASK_SIZE) &&
+ !((va >= VSYSCALL_START) && ((va + len - 1) <= VSYSCALL_END));
}
int arch_bp_generic_fields(int x86_len, int x86_type,
-----------------------------------------------------------------------
Where else can I send it?
Amnon.
Quoted 29 lines · On 01/10, [email protected] wrote:
Quoted 12 lines
Hi Everyone,
Quoted 5 lines · Pedro Alves
Quoted 4 lines · Oleg Nesterov
Quoted 2 lines
But If we want to allow to trace vsyscall's, hw bp doesn't look
very
Quoted 1 line
Quoted 1 line
Quoted 1 line
nice imo.
HBP_NUM= 4 and you need to setup 3 bp's to trace themall.
Quoted 1 line
Quoted 1 line
Quoted 7 lines
Quoted 4 lines
Quoted 2 lines
Irrespective of the whole syscall tracing issue, allowing HW bkpts in the vsyscall just seems like a bug fix to me.
And I never argued. I sent the patch iirc ;)
Exactly, it is a bug and I am still waiting for it to be fixed in the Linux kernel.
I would not say this is a bug but let me repeat, no need to convince me.
Please feel free to re-send the patch(es) I sent to maintainers. Sorry, I can't push these changes into Linus's tree.
Oleg.
Re: PTRACE_SYSCALL && vsyscall (Was: arch_check_bp_in_kernelspace: fix the range check)
Quoted 11 lines · On 01/14, [email protected] wrote:
So here again is the patch that I need so badly - clearly it fixes a bug and harms nobody:
-----------------------------------------------------------------------
diff -Naurbefore/arch/x86/kernel/hw_breakpoint.cafter/arch/x86/kernel/hw_breakpoint.c
---before/arch/x86/kernel/hw_breakpoint.c2013-01-14 12:45:20.000000000
+1030
+++after/arch/x86/kernel/hw_breakpoint.c2013-01-14 12:46:24.000000000 +1030
Review line 205
Quoted 7 lines
(quoted diff) +2
-1@@ -200,7 +200,8 @@ va = info->address; len = get_hbp_len(info->len); - return (va >= TASK_SIZE) && ((va + len - 1) >= TASK_SIZE); + return (va >= TASK_SIZE) && ((va + len - 1) >= TASK_SIZE) && + !((va >= VSYSCALL_START) && ((va + len - 1) <= VSYSCALL_END)); }
I meant this one: http://marc.info/?l=linux-kernel&m=135336050319266
on top of http://marc.info/?l=linux-kernel&m=135248575426474
But nobody bothers to take even the trivial bugfix I sent ;)
Oleg.
prctl(PR_SET_MM)
Hello,
The code in "kernel/sys.c" provides the "prctl(PR_SET_MM)" function, which is the only way a process can set or modify the following 11 per-process fields:
start_code, end_code, start_data, end_data, start_brk, brk, start_stack, arg_start, arg_end, env_start, env_end.
Being able to set those fields is important, even crucial, for any conceivable user-level checkpointing software, as well as for migrating processes between different computers.
Unfortunately, this code (essentially "prctl_set_mm()") is presently enclosed in "#ifdef CONFIG_CHECKPOINT_RESTORE" which is configured as "default n" in "init/Kconfig". Many system-administrators who may like to have a checkpoint/restore or process-migration facility, but use standard pre-packaged kernels, find the requirement to configure and compile their own non-standard kernel difficult or too prohibitive.
Would it be possible to have this code enabled by default?
This could be done in one of 4 ways:
1) Having CONFIG_CHECKPOINT_RESTORE enabled by default; or
2) Releasing this code from the "#ifdef CONFIG_CHECK_RESTORE"; or
3) Placing this code within a different kernel-configuration option (say "CONFIG_BASIC_CHECKPOINTING") that is enabled by default; or
4) Placing this code under a dual #if, so instead of:
#ifdef CONFIG_CHECKPOINT_RESTORE
have:
#if defined(CONFIG_CHECKPOINT_RESTORE) || defined(CONFIG_BASIC_CHECKPOINTING)
Thank you,
Amnon.
Re: prctl(PR_SET_MM)
Quoted 29 lines · Amnon Shiloh
Hello,
The code in "
kernel/sys.c" provides the "prctl(PR_SET_MM)" function, which is the only way a process can set or modify the following 11 per-process fields:(quoted diff) +0
-0start_code, end_code, start_data, end_data, start_brk, brk, start_stack, arg_start, arg_end, env_start, env_end.Being able to set those fields is important, even crucial, for any conceivable user-level checkpointing software, as well as for migrating processes between different computers.
Unfortunately, this code (essentially "
prctl_set_mm()") is presently enclosed in "#ifdefCONFIG_CHECKPOINT_RESTORE" which is configured as "default n" in "init/Kconfig". Many system-administrators who may like to have a checkpoint/restore or process-migration facility, but use standard pre-packaged kernels, find the requirement to configure and compile their own non-standard kernel difficult or too prohibitive.Would it be possible to have this code enabled by default?
This could be done in one of 4 ways:
1) HavingCONFIG_CHECKPOINT_RESTOREenabled by default; or
2) Releasing this code from the "#ifdefCONFIG_CHECK_RESTORE"; or
3) Placing this code within a different kernel-configuration option (say "CONFIG_BASIC_CHECKPOINTING") that is enabled by default; or
4) Placing this code under a dual #if, so instead of:
Quoted 3 lines
#ifdef CONFIG_CHECKPOINT_RESTORE have: #if defined(CONFIG_CHECKPOINT_RESTORE) || defined(CONFIG_BASIC_CHECKPOINTING)
This is basically a distro issue. Distros can choose to enable this code by default, but the Linux kernel that Linus maintains does not need to enable it.
Signature · 1 line
~Randy
Re: prctl(PR_SET_MM)
In reply to Amnon ShilohQuoted 9 lines · Amnon Shiloh
Hello,
The code in "
kernel/sys.c" provides the "prctl(PR_SET_MM)" function, which is the only way a process can set or modify the following 11 per-process fields:(quoted diff) +0
-0start_code, end_code, start_data, end_data, start_brk, brk, start_stack, arg_start, arg_end, env_start, env_end.
Quoted 3 lines
Being able to set those fields is important, even crucial, for any conceivable user-level checkpointing software, as well as for migrating processes between different computers.
You're saying that this is useful for code not needing a kernel with CHECKPOINT_RESTORE enabled. Correct?
Quoted 9 lines
Unfortunately, this code (essentially "
prctl_set_mm()") is presently enclosed in "#ifdefCONFIG_CHECKPOINT_RESTORE" which is configured as "default n" in "init/Kconfig". Many system-administrators who may like to have a checkpoint/restore or process-migration facility, but use standard pre-packaged kernels, find the requirement to configure and compile their own non-standard kernel difficult or too prohibitive.
Quoted 4 lines
Would it be possible to have this code enabled by default?
This could be done in one of 4 ways:
1) HavingCONFIG_CHECKPOINT_RESTOREenabled by default; or
Nope, that wont due. Kernel policy is to have things default n. Have an issue with a config, talk with the distribution you are dealing with. They set the policy of what configs get set for their kernels.
Quoted 7 lines
2) Releasing this code from the "#ifdef
CONFIG_CHECK_RESTORE"; or
3) Placing this code within a different kernel-configuration option (say "CONFIG_BASIC_CHECKPOINTING") that is enabled by default; or
4) Placing this code under a dual #if, so instead of:#ifdef CONFIG_CHECKPOINT_RESTORE have: #if defined(CONFIG_CHECKPOINT_RESTORE) || defined(CONFIG_BASIC_CHECKPOINTING)
One of the above 3 can probably be worked out.
-- Steve
Re: prctl(PR_SET_MM)
Quoted 10 lines · Steven Rostedt
Quoted 9 lines · Amnon Shiloh
Hello,
The code in "
kernel/sys.c" provides the "prctl(PR_SET_MM)" function, which is the only way a process can set or modify the following 11 per-process fields:(quoted diff) +0
-0start_code, end_code, start_data, end_data, start_brk, brk, start_stack, arg_start, arg_end, env_start, env_end.
Quoted 6 lines
Quoted 3 lines
Being able to set those fields is important, even crucial, for any conceivable user-level checkpointing software, as well as for migrating processes between different computers.
You're saying that this is useful for code not needing a kernel with
CHECKPOINT_RESTOREenabled. Correct?
Correct, this is an important feature that is useful for a whole general class of applications, not only those needing CHECKPOINT_RESTORE.
Had this not been done as part of the CHECKPOINT_RESTORE project, it would have certainly been done, sooner or later, by some other developers:
it just so happened that the CHECKPOINT_RESTORE people were the first to (publically) fill this gap, but in fact this code in "kernel/sys.c" should be general kernel code, not part of CHECKPOINT_RESTORE.
Quoted 10 lines
Quoted 10 lines
Unfortunately, this code (essentially "
prctl_set_mm()") is presently enclosed in "#ifdefCONFIG_CHECKPOINT_RESTORE" which is configured as "default n" in "init/Kconfig". Many system-administrators who may like to have a checkpoint/restore or process-migration facility, but use standard pre-packaged kernels, find the requirement to configure and compile their own non-standard kernel difficult or too prohibitive.
Quoted 8 lines
Quoted 4 lines
Would it be possible to have this code enabled by default?
This could be done in one of 4 ways:
1) HavingCONFIG_CHECKPOINT_RESTOREenabled by default; orNope, that wont due. Kernel policy is to have things default n. Have an issue with a config, talk with the distribution you are dealing with. They set the policy of what configs get set for their kernels.
Yes, Randy Dunlap already raised this point, but I have no dealings with any particular Linux distribution or the right connections to chase them all, one by one - I develop generic software for the general Linux community, that is intended to work distribution-independently. Even if I had access to all distributions, it may be hard to convince them to configure CONFIG_CHECKPOINT_RESTORE as a whole since it contains so much other code.
BTW, Can anyone explain this policy of "have things default n"? When I go over "init/Kconfig" or most other Kconfig's, I can actually see lots of "default y".
Quoted 9 lines
Quoted 8 lines
2) Releasing this code from the "#ifdef
CONFIG_CHECK_RESTORE"; or
3) Placing this code within a different kernel-configuration option (say "CONFIG_BASIC_CHECKPOINTING") that is enabled by default; or
4) Placing this code under a dual #if, so instead of:#ifdef CONFIG_CHECKPOINT_RESTORE have: #if defined(CONFIG_CHECKPOINT_RESTORE) || defined(CONFIG_BASIC_CHECKPOINTING)
Quoted 3 lines
One of the above 3 can probably be worked out.
-- Steve
Great!
Naturally I prefer option 2 (but the other two will do as well).
Thanks,
Amnon.
Re: prctl(PR_SET_MM)
Quoted 6 lines · Amnon Shiloh
Yes, Randy Dunlap already raised this point, but I have no dealings with any particular Linux distribution or the right connections to chase them all, one by one - I develop generic software for the general Linux community, that is intended to work distribution-independently. Even if I had access to all distributions, it may be hard to convince them to configure
CONFIG_CHECKPOINT_RESTOREas a whole since it contains so much other code.
If only you, or a few people are using it (ie. distros don't see a need), then it will be up to you to make the changes.
Quoted 4 lines
BTW, Can anyone explain this policy of "have things default n"? When I go over "init/Kconfig" or most other Kconfig's, I can actually see lots of "default y".
Linus stated that he doesn't want any new feature default on, unless it gives better performance to the general populace. Because someone's old config should not add new features when they use it for a new kernel. Basically, if something is default on, then it probably shouldn't have a config for it.
Some are on because they were always on (although several were changed to 'n'). Also it's fine to have a default y that depends on something that is default n, if it makes sense.
For example, the function graph tracer is default y, but requires the function tracer to be enabled which is default n. This is because I assumed that you would want the function graph tracer if you enabled function tracing, as the graph tracer gives much more information.
Quoted 10 lines
Quoted 10 lines
Quoted 9 lines
2) Releasing this code from the "#ifdef
CONFIG_CHECK_RESTORE"; or
3) Placing this code within a different kernel-configuration option (say "CONFIG_BASIC_CHECKPOINTING") that is enabled by default; or
4) Placing this code under a dual #if, so instead of:#ifdef CONFIG_CHECKPOINT_RESTORE have: #if defined(CONFIG_CHECKPOINT_RESTORE) || defined(CONFIG_BASIC_CHECKPOINTING)
Quoted 7 lines
Quoted 3 lines
One of the above 3 can probably be worked out.
-- Steve
Great!
Naturally I prefer option 2 (but the other two will do as well).
I have no problems with this out of line.
-- Steve
Re: prctl(PR_SET_MM)
Quoted 2 lines · Steven Rostedt
If only you, or a few people are using it (ie. distros don't see a need), then it will be up to you to make the changes.
I believe that this functionality is of a general nature and is needed by many, not only by myself and by the CRIU group, but by all user-level software packages, past present and future, that provide some form or another of reconstructing a Linux process.
For example:
1) Checkpoint-restore
- the ability to resume a computation after computer crashes.
2) Process-migration
- the ability to have a running computation change computers. (for numerous reasons, including planned shutdown; overheating; load-balancing; increased memory demands; the original computer being required by higher-priority users, etc. etc.)
3) Process-duplication
- the ability to have a running computation continue in parallel from a point in time on two or more computers, so that if one of them fails, at least one copy will still be running (in time-critical missions, a periodic checkpointing may not be sufficient).
To reconstruct Linux process(es), one must be able to restore all their memory contents, states and registers to their original and consistent values.
Other than the code currently enclosed in "CONFIG_CHECKPOINT_RESTORE", nothing else in the kernel provides the ability to set those 11 fields:
start_code, end_code, start_data, end_data, start_brk, brk, start_stack, arg_start, arg_end, env_start, env_end.
There are many possible ways to implement this functionality and if you believe that it would be a good idea, I could instead send a simple, independent kernel patch that sets those 11 fields. It would be shorter than the current and perhaps implemented as a new "ptrace" function, but given that the CRIU group already wrote this code and that it is already in the kernel, I am concerned that trying to duplicate it might interfere with their work, so I first ask for the relevant code in "kernel/sys.c" to no longer be enclosed by an #ifdef. What do you think?
Best Regards,
Amnon.
Re: prctl(PR_SET_MM)
Quoted 4 lines · Amnon Shiloh
To reconstruct Linux process(es), one must be able to restore all their memory contents, states and registers to their original and consistent values.
I personally don't mind if this come become y by default, because it will work for us. Still I guess if you need to reconstruct Linux process(es) plain prctl extension is not enough, you still need a functionality which is enclosed in config-checkpoint-restore (say /proc/pid/map_files, kcmp), no?
Re: prctl(PR_SET_MM)
Hi Cyrill,
Quoted 8 lines · Cyrill Gorcunov
Quoted 4 lines · Amnon Shiloh
To reconstruct Linux process(es), one must be able to restore all their memory contents, states and registers to their original and consistent values.
I personally don't mind if this come become y by default, because it will work for us.
I don't mind either, to say the least, to have CONFIG_CHECKPOINT_RESTORE have a "default y" in "init/Kconfig" - that would solve my problem and make me happy, as well as your group and others, but we are told here that Linus has a policy vetoing such changes and I don't believe either of us can make him change his mind.
As such, we must look at other options, such as having the code in "kernel/sys.c" out in the open, not enclosed by any #ifdef's altogether
- surely you would like that!
Quoted 4 lines
Still I guess if you need to reconstruct Linux process(es) plain prctl extension is not enough, you still need a functionality which is enclosed in config-checkpoint-restore (say
/proc/pid/map_files, kcmp), no?
My process-migration package only reconstructs Linux processes partially:
as it's a bit different than any classical checkpoint-restore, the critical code in "kernel/sys.c" is all I need at the moment (from within CONFIG_CHECKPOINT_RESTORE). I do appreciate that anyone attempting to perform complete, classical, checkpoint-restore operations, needs more than that.
Best Regards,
Amnon.
Re: prctl(PR_SET_MM)
Quoted 8 lines · Amnon Shiloh
Quoted 2 lines
I personally don't mind if this come become y by default, because it will work for us.
I don't mind either, to say the least, to have
CONFIG_CHECKPOINT_RESTOREhave a "default y" in "init/Kconfig" - that would solve my problem and make me happy, as well as your group and others, but we are told here that Linus has a policy vetoing such changes and I don't believe either of us can make him change his mind.
That's perfectly fine for all new features :-)
Quoted 9 lines
As such, we must look at other options, such as having the code in "
kernel/sys.c" out in the open, not enclosed by any #ifdef's altogether
- surely you would like that!Quoted 4 lines
Still I guess if you need to reconstruct Linux process(es) plain prctl extension is not enough, you still need a functionality which is enclosed in config-checkpoint-restore (say
/proc/pid/map_files, kcmp), no?
Quoted 6 lines
My process-migration package only reconstructs Linux processes partially:
as it's a bit different than any classical checkpoint-restore, the critical code in "kernel/sys.c" is all I need at the moment (from withinCONFIG_CHECKPOINT_RESTORE). I do appreciate that anyone attempting to perform complete, classical, checkpoint-restore operations, needs more than that.
I see. Thanks for explanation! Thus we need some new config option which would enable this prctl opcodes (y by default), in turn config-checkpoint-restore kconfig option need to select this feature if set. Sounds reasonable?
Re: prctl(PR_SET_MM)
Hi Cyrill,
Quoted 3 lines · Cyrill Gorcunov
I see. Thanks for explanation! Thus we need some new config option which would enable this prctl opcodes (y by default), in turn config-checkpoint-restore kconfig option need to select this feature if set. Sounds reasonable?
Yes, This would be one possible way to do it.
Another possibility is to not have an #ifdef at all around this code. Another possibility is to have a dual #if:
#if defined(CONFIG_CHECKPOINT_RESTORE) || defined(CONFIG_MM_FIELDS_SETTING)
Best Regards,
Amnon.
Re: prctl(PR_SET_MM)
In reply to Cyrill GorcunovQuoted 7 lines · Cyrill Gorcunov
Quoted 3 lines
Another possibility is to have a dual #if:
#if
defined(CONFIG_CHECKPOINT_RESTORE)||defined(CONFIG_MM_FIELDS_SETTING)Thus this approach looks preferred. And
MM_FIELDS_SETTINGwill be y by default. Mind to cook a patch and lets see if community accept it? Don't forget to CC Andrew Morton.
Very well, patch attached.
Amnon.
init/Kconfig +16 -0
@@ -999,6 +999,22 @@ If unsure, say N here. +config MM_FIELDS_SETTING + bool "Allow modifying per-process memory-region fields" + default y + help + Support "prctl(PR_SET_MM)" which allows applications to modify + the following in their "mm_struct": + + start_code, end_code, start_data, end_data, start_brk, brk, + start_stack, arg_start, arg_end, env_start, env_end. + + Also to modify their executable file ("/proc/self/exe"). + + This option is needed for reconstructing processes (such as when + restoring a process from a checkpoint; duplicating a process; + or migrating it to another computer). + menuconfig NAMESPACES bool "Namespaces support" if EXPERT default !EXPERT
kernel/sys.c +11 -7
@@ -1788,7 +1788,7 @@return mask; } -#ifdef CONFIG_CHECKPOINT_RESTORE +#if defined(CONFIG_CHECKPOINT_RESTORE ) || defined(CONFIG_MM_FIELDS_SETTING )static int prctl_set_mm_exe_file (struct mm_struct *mm,unsigned int fd) {struct fd exe;
@@ -1981,18 +1981,22 @@up_read (&mm->mmap_sem);return error; } +#else /* CONFIG_CHECKPOINT_RESTORE || CONFIG_MM_FIELDS_SETTING */ -static int prctl_get_tid_address (struct task_struct *me,int __user **tid_addr) -{ -return put_user (me->clear_child_tid, tid_addr); -} - -#else /* CONFIG_CHECKPOINT_RESTORE */ static int prctl_set_mm (int opt,unsigned long addr,unsigned long arg4,unsigned long arg5) {return -EINVAL ; } +#endif + +#ifdef CONFIG_CHECKPOINT_RESTORE +static int prctl_get_tid_address (struct task_struct *me,int __user **tid_addr) +{ +return put_user (me->clear_child_tid, tid_addr); +} + +#else static int prctl_get_tid_address (struct task_struct *me,int __user **tid_addr) {return -EINVAL ;
Re: prctl(PR_SET_MM)
Quoted 11 lines · Amnon Shiloh
Quoted 7 lines · Cyrill Gorcunov
Quoted 3 lines
Another possibility is to have a dual #if:
#if
defined(CONFIG_CHECKPOINT_RESTORE)||defined(CONFIG_MM_FIELDS_SETTING)Thus this approach looks preferred. And
MM_FIELDS_SETTINGwill be y by default. Mind to cook a patch and lets see if community accept it? Don't forget to CC Andrew Morton.Very well, patch attached.
Wouldn't the below do the same trick but eliminate OR in preproc code?
---
From: Amnon Shiloh <[email protected]>
Subject: prctl: Make PR_SET_MM being depend on own CONFIG_MM_FIELDS_SETTING
...
--- init/Kconfig | 17 +++++++++++++++++ kernel/sys.c | 16 ++++++++-------- 2 files changed, 25 insertions(+), 8 deletions(-)
init/Kconfig +17 -0
@@ -991,6 +991,7 @@ endif # CGROUPS config CHECKPOINT_RESTORE bool "Checkpoint/restore support" if EXPERT default n + select MM_FIELDS_SETTING help Enables additional kernel features in a sake of checkpoint/restore. In particular it adds auxiliary prctl codes to setup process text,
@@ -999,6 +1000,22 @@ config CHECKPOINT_RESTORE If unsure, say N here. +config MM_FIELDS_SETTING + bool "Allow modifying per-process memory-region fields" + default y + help + Support "prctl(PR_SET_MM)" which allows applications to modify + the following in their "mm_struct": + + start_code, end_code, start_data, end_data, start_brk, brk, + start_stack, arg_start, arg_end, env_start, env_end. + + Also to modify their executable file ("/proc/self/exe"). + + This option is needed for reconstructing processes (such as when + restoring a process from a checkpoint; duplicating a process; + or migrating it to another computer). + menuconfig NAMESPACES bool "Namespaces support" if EXPERT default !EXPERT
kernel/sys.c +8 -8
@@ -1788,7 +1788,7 @@ SYSCALL_DEFINE1(umask, int, mask)return mask; } -#ifdef CONFIG_CHECKPOINT_RESTORE +#ifdef CONFIG_MM_FIELDS_SETTING static int prctl_set_mm_exe_file (struct mm_struct *mm,unsigned int fd) {struct fd exe;
@@ -1981,23 +1981,23 @@ out:up_read (&mm->mmap_sem);return error; } +#else /* CONFIG_MM_FIELDS_SETTING */ -static int prctl_get_tid_address (struct task_struct *me,int __user **tid_addr) -{ -return put_user (me->clear_child_tid, tid_addr); -} - -#else /* CONFIG_CHECKPOINT_RESTORE */ static int prctl_set_mm (int opt,unsigned long addr,unsigned long arg4,unsigned long arg5) {return -EINVAL ; } +#endif +static int prctl_get_tid_address (struct task_struct *me,int __user **tid_addr) { +#ifdef CONFIG_CHECKPOINT_RESTORE +return put_user (me->clear_child_tid, tid_addr); +#else return -EINVAL ; -}#endif +} SYSCALL_DEFINE5(prctl, int, option, unsigned long, arg2, unsigned long, arg3, unsigned long, arg4, unsigned long, arg5)
Re: prctl(PR_SET_MM)
Hi,
Quoted 1 line · Cyrill Gorcunov
Wouldn't the below do the same trick but eliminate OR in preproc code?
Yes it would. I don't mind having it either way.
Best Regards,
Amnon.
Quoted 92 lines
---
From: Amnon Shiloh <[email protected]>
Subject: prctl: MakePR_SET_MMbeing depend on ownCONFIG_MM_FIELDS_SETTING...
Signed-off-by Amnon Shiloh <[email protected]>--- init/Kconfig | 17 +++++++++++++++++ kernel/sys.c | 16 ++++++++-------- 2 files changed, 25 insertions(+), 8 deletions(-)Index: linux-2.6.git/init/Kconfig
===================================================================init/Kconfig +17
-0@@ -991,6 +991,7 @@ endif # CGROUPS config CHECKPOINT_RESTORE bool "Checkpoint/restore support" if EXPERT default n + select MM_FIELDS_SETTING help Enables additional kernel features in a sake of checkpoint/restore. In particular it adds auxiliary prctl codes to setup process text,@@ -999,6 +1000,22 @@ config CHECKPOINT_RESTORE If unsure, say N here. +config MM_FIELDS_SETTING + bool "Allow modifying per-process memory-region fields" + default y + help + Support "prctl(PR_SET_MM)" which allows applications to modify + the following in their "mm_struct": + + start_code, end_code, start_data, end_data, start_brk, brk, + start_stack, arg_start, arg_end, env_start, env_end. + + Also to modify their executable file ("/proc/self/exe"). + + This option is needed for reconstructing processes (such as when + restoring a process from a checkpoint; duplicating a process; + or migrating it to another computer). + menuconfig NAMESPACES bool "Namespaces support" if EXPERT default !EXPERTIndex:
linux-2.6.git/kernel/sys.c
===================================================================kernel/sys.c +8
-8@@ -1788,7 +1788,7 @@ SYSCALL_DEFINE1(umask, int, mask)return mask; } -#ifdef CONFIG_CHECKPOINT_RESTORE +#ifdef CONFIG_MM_FIELDS_SETTING static int prctl_set_mm_exe_file (struct mm_struct *mm,unsigned int fd) {struct fd exe;@@ -1981,23 +1981,23 @@ out:up_read (&mm->mmap_sem);return error; } +#else /* CONFIG_MM_FIELDS_SETTING */ -static int prctl_get_tid_address (struct task_struct *me,int __user **tid_addr) -{ -return put_user (me->clear_child_tid, tid_addr); -} - -#else /* CONFIG_CHECKPOINT_RESTORE */ static int prctl_set_mm (int opt,unsigned long addr,unsigned long arg4,unsigned long arg5) {return -EINVAL ; } +#endif +static int prctl_get_tid_address (struct task_struct *me,int __user **tid_addr) { +#ifdef CONFIG_CHECKPOINT_RESTORE +return put_user (me->clear_child_tid, tid_addr); +#else return -EINVAL ; -}#endif +} SYSCALL_DEFINE5(prctl, int, option, unsigned long, arg2, unsigned long, arg3, unsigned long, arg4, unsigned long, arg5)
Re: prctl(PR_SET_MM)
Quoted 7 lines · Amnon Shiloh
Hi,
Quoted 1 line · Cyrill Gorcunov
Wouldn't the below do the same trick but eliminate OR in preproc code?
Yes it would. I don't mind having it either way.
OK, lets wait for opinions and see if this approach is acceptable.
Re: prctl(PR_SET_MM)
In reply to Cyrill GorcunovQuoted 6 lines · On Thu, 21 Feb 2013 12:00:28 +0400 Cyrill Gorcunov <[email protected]> wrote:
From: Amnon Shiloh <[email protected]>
Subject: prctl: MakePR_SET_MMbeing depend on ownCONFIG_MM_FIELDS_SETTING...
Signed-off-by Amnon Shiloh <[email protected]>
The "..." makes me sad.
If/when this patch gets sent for real, please explain the reasons? AFAICT it permits the enabling of prctl(PR_SET_MM) in CONFIG_CHECKPOINT_RESTORE=n kernels. If that was indeed the intent, why?
Re: prctl(PR_SET_MM)
Quoted 8 lines · Andrew Morton
Quoted 5 lines · On Thu, 21 Feb 2013 12:00:28 +0400 Cyrill Gorcunov <[email protected]> wrote:
From: Amnon Shiloh <[email protected]>
Subject: prctl: MakePR_SET_MMbeing depend on ownCONFIG_MM_FIELDS_SETTING...
Quoted 8 lines
Quoted 1 line
Signed-off-by Amnon Shiloh <[email protected]>The "..." makes me sad.
If/when this patch gets sent for real, please explain the reasons? AFAICT it permits the enabling of
prctl(PR_SET_MM)inCONFIG_CHECKPOINT_RESTORE=nkernels. If that was indeed the intent, why?
Sorry for this "...", it was a draft version for Amnon, not for inclusion. As far as I understand Amnon needs these prctl opcodes to be enabled by default (but still turnable off in Kconfig if needed) for his minimal c/r software, he do not need the whole c/r functionality (procfs map-files, get-tid-address,kcmp and such). That is the idea if I understand correctly.
Quoting Amnon
| | Correct, this is an important feature that is useful for a whole | general class of applications, not only those needing CHECKPOINT_RESTORE. | | Had this not been done as part of the CHECKPOINT_RESTORE project, it | would have certainly been done, sooner or later, by some other developers: | it just so happened that the CHECKPOINT_RESTORE people were the first to | (publically) fill this gap, but in fact this code in "kernel/sys.c" should | be general kernel code, not part of CHECKPOINT_RESTORE. |
I personally don't mind if this code become y by default (it requires cap-sys-resource capability granted anyway), but for normal c/r this prctl opcodes only is not enough and CHECKPOINT_RESTORE should be set. Thus, if people agree with enabling prctl extension by default I certainly won't object.
Re: prctl(PR_SET_MM)
In reply to Andrew MortonDear Andrew,
The code in "kernel/sys.c" that is currently within CONFIG_CHECKPOINT_RESTORE is in fact, as I explain below, one possible solution to a general issue, required by a wide class of applications. It just so happened that the CRIU group were the first to place this, or an equivalent code, in the kernel, that allows a privileged process to set its 11 per-process memory-region fields:
start_code, end_code, start_data, end_data, start_brk, brk, start_stack, arg_start, arg_end, env_start, env_end.
Contrary to the rest of the CHECKPOINT_RESTORE code, which is specific to the CRIU package, the code in "kernel/sys.c" (or its equivalent) is needed by ANY application or package that needs to reconstruct Linux processes, that means, starting them from the middle rather than from an executable file.
That includes user-level checkpointing (any, not just CRIU's), process-migration (to other computers, as my own package does) and process duplication (for high-availability/reliability) - in fact even for starting a process from an executable format that is not supported by Linux, thus requiring a "manual execve" by a user-level utility.
My first preference is to remove that "#ifdef CONFIG_CHECKPOINT_RESTORE" altogether. Note that there are no security issues because this code is already restricted to "capable(CAP_SYS_RESOURCE)".
Short of that is the proposed patch.
Best Regards,
Amnon.
Quoted 19 lines · Andrew Morton
Quoted 6 lines · On Thu, 21 Feb 2013 12:00:28 +0400 Cyrill Gorcunov <[email protected]> wrote:
From: Amnon Shiloh <[email protected]>
Subject: prctl: MakePR_SET_MMbeing depend on ownCONFIG_MM_FIELDS_SETTING...
Signed-off-by Amnon Shiloh <[email protected]>The "..." makes me sad.
If/when this patch gets sent for real, please explain the reasons? AFAICT it permits the enabling of
prctl(PR_SET_MM)inCONFIG_CHECKPOINT_RESTORE=nkernels. If that was indeed the intent, why?
Re: prctl(PR_SET_MM)
In reply to Amnon ShilohQuoted 9 lines · Amnon Shiloh
Quoted 2 lines · Steven Rostedt
If only you, or a few people are using it (ie. distros don't see a need), then it will be up to you to make the changes.
I believe that this functionality is of a general nature and is needed by many, not only by myself and by the CRIU group, but by all user-level software packages, past present and future, that provide some form or another of reconstructing a Linux process.
That's what "RESTORE" part of CONFIG_CHECKPOINT_RESTORE refers to:
the ability to restore (reconstruct) a process.
If you want to be able to restore a process, you need RESTORE feature. It's that simple.
Why do you want yet another config option for it? What's the problem if you simply enable CONFIG_CHECKPOINT_RESTORE?
The only problem I can imagine is "CONFIG_CHECKPOINT_RESTORE enables too many things I don't need".
Frankly, I find it not very likely, unless you are planning on working on resource-constrained machines (like mobile phone).
Signature · 1 line
vda
Re: PTRACE_SYSCALL && vsyscall (Was: arch_check_bp_in_kernelspace: fix the range check)
In reply to [email protected]Quoted 1 line · Oleg Nesterov
Yes, that is why I said this needs the new option.
I do not mind new options although personally I do not find them meaningful for an already deprecated ABI compatibility-only issue.
Quoted 4 lines
If the tracer does
PTRACE_SYSCALLthe tracee reports syscall exit _after_ gettimeofday/etc. The tracer can look atregs->orig_ax== -1 and detect that this is not syscall but vsyscall, it can look atregs->ipthen (not with the patch below).
I believe applications just call PTRACE_SYSCALL twice, without checking orig_eax. At least strace and its TCB_INSYSCALL looks so.
Quoted 1 line · On Mon, 03 Dec 2012 00:54:58 +0100, [email protected] wrote:
The beauty of using the x86 debug-registers,
x86 debug registers are already very scarce. Besides that userland applications know they have 4 of them available so it would also break them.
Regards,
Jan
Re: PTRACE_SYSCALL && vsyscall (Was: arch_check_bp_in_kernelspace: fix the range check)
Dear Jan,
Quoted 3 lines
x86 debug registers are already very scarce. Besides that userland applications know they have 4 of them available so it would also break them.
If a userland application wants to cheat, then it has no need to bypass the debug registers: even if there were 4096 of them, covering the whole vsyscall page, it could simply copy the whole vsyscall page somewhere else, then run (or emulate) it, or look directly at the raw data within the vsyscall page. The only way to overcome that would be to make the vsyscall page either non-existent or unreadable.
Personally, allowing userland applications to read the vsyscall page can't hurt me and my applications, but if someone else is concerned with such malicious programs (does anyone?), if they need to construct the strictest-of-strict jail, where jailed applications cannot glimpse any information from the kernel they run on no matter how hard they try, then they must at least make the vsyscall page unreadable, then rely either on kernel emulation or a SIGSEGV (the later would be quite sufficient for my own needs as a substitute for debug-registers, but unfortunately not for the current version of "strace").
If, as I was told, it's too hard to remove the vsyscall page on a per-process basis, then it's sufficient to make it unreadable on context-switch.
My concern, however, is not with the bad guys, but with good honest programs that would run incorrectly if allowed to call "time()" or "gettimeofday()" unsupervised. No good program or library jumps into the vsyscall page except into its 3 official entry points.
In summary, it should be decided:
If it is important enough for Linux to support paranoidically strict jails, then full kernel emulation of PTRACE_SYSCALL (and PTRACE_SYSEMU) is inescapable.
If, on the other hand, there is only a need to allow applications such as mine and "strace"/"gdb" to trap system-calls that occur via the vsyscall page, then in principle a variety of options are possible:
1. Allow setting the x86 hardware-debug registers into the vsyscall page.
2. Optional (per-process) removal of execute-permission from the vsyscall page.
3. Optional (per-process) removal of both read and execute permissions from the vsyscall page.
4. Optional (per-process) elimination of the vsyscall page altogether.
5. Kernel vsyscall emulation code to send some signal or event to traced processes if the ptracer asked for it (using a new ptrace option).
6. Complete and transparent emulation of PTRACE_SYSCALL/PTRACE_SYSEMU.
Option #1 requires the least effort (a 2-line fix). Option #6 requires the most effort.
Best Regards,
Amnon.
Quoted 28 lines · Oleg Nesterov
Quoted 1 line
Yes, that is why I said this needs the new option.
I do not mind new options although personally I do not find them meaningful
for an already deprecated ABI compatibility-only issue.Quoted 4 lines
If the tracer does
PTRACE_SYSCALLthe tracee reports syscall exit _after_ gettimeofday/etc. The tracer can look atregs->orig_ax== -1 and detect that this is not syscall but vsyscall, it can look atregs->ipthen (not with the patch below).I believe applications just call
PTRACE_SYSCALLtwice, without checkingorig_eax. At least strace and itsTCB_INSYSCALLlooks so.Quoted 1 line · On Mon, 03 Dec 2012 00:54:58 +0100, [email protected] wrote:
The beauty of using the x86 debug-registers,
x86 debug registers are already very scarce. Besides that userland applications know they have 4 of them available so it would also break them.
Regards,
Jan
Re: vdso && cr (Was: arch_check_bp_in_kernelspace: fix the range check)
In reply to Oleg NesterovQuoted 8 lines · Oleg Nesterov
Quoted 4 lines · Amnon Shiloh
Now however, that "vsyscall" was effectively replaced by vdso, it creates a new problem for me and probably for anyone else who uses some form of checkpoint/restore:
Oh, sorry, I can't help here. I can only add Cyrill and Pavel, they seem to enjoy trying to solve the c/r problems.
Hi Oleg, Amnon, sorry for delay on this message. First of all, I'm not vDSO specialist but as to c/r aspect of it I've had in mind the the following scenario: we dump vDSO area either complete euther simply remember the functions addresses it provides, then on restore we replace the functions prologue with jmp instruction which would point to the vDSO entries provided us by a kernel. But again, I didn't spend much time for vDSO yet.
Cyrill
Re: vdso && cr (Was: arch_check_bp_in_kernelspace: fix the range check)
2012/11/26 Cyrill Gorcunov <[email protected]>:
Quoted 10 lines · Oleg Nesterov
Quoted 8 lines · Amnon Shiloh
Quoted 4 lines
Now however, that "vsyscall" was effectively replaced by vdso, it creates a new problem for me and probably for anyone else who uses some form of checkpoint/restore:
Oh, sorry, I can't help here. I can only add Cyrill and Pavel, they seem to enjoy trying to solve the c/r problems.
Quoted 7 lines
Hi Oleg, Amnon, sorry for delay on this message. First of all, I'm not vDSO specialist but as to c/r aspect of it I've had in mind the the following scenario: we dump vDSO area either complete euther simply remember the functions addresses it provides, then on restore we replace the functions prologue with jmp instruction which would point to the vDSO entries provided us by a kernel. But again, I didn't spend much time for vDSO yet.
I think this approach should work. Here is a bit more details:
1. A task will be not dumped in vdso code. If a task is in vdso code, we will try to catch it again.
2. Only addresses of vdso symbols will be dumped.
3. On restore we will compare addresses of symbols. If addresses are not changes, a new vdso will be mapped instead of old one. If they are changed, a new vdso will be mapped in a free space and the old vdso will be replaced on a proxy library, where all functions are replaced on jumps to suitable functions in the new vdso.
Looks simple and does not required to hack a kernel.
Quoted 2 lines
Cyrill
Re: vdso && cr (Was: arch_check_bp_in_kernelspace: fix the range check)
Hi Andrey,
So what do you do if a catched interrupt occured inside vdso code?
You can easily detect that the task is currently in vdso code, then delay its dump, but how do you detect whether a sigreturn() or even a series of sigreturn()s won't bring it back to the middle of some old vdso code?
You could of course keep that old code and modify only the very first instruction of each routine into a jump instruction, but then the code to which the process returns may not be compatible with the new kernel and/or hardware configuration.
You cannot even rely on a vdso enter/exit counter, because interrupt code can use "longjmp()".
My idea was to introduce a kernel option saying "don't send me any catched signals while the program-counter is in this range (eg. the vdso page), but I was told that it is not feasible to implement it.
Regards,
Amnon.
Quoted 34 lines
2012/11/26 Cyrill Gorcunov <[email protected]>:
Quoted 10 lines · Oleg Nesterov
Quoted 8 lines · Amnon Shiloh
Quoted 4 lines
Now however, that "vsyscall" was effectively replaced by vdso, it creates a new problem for me and probably for anyone else who uses some form of checkpoint/restore:
Oh, sorry, I can't help here. I can only add Cyrill and Pavel, they seem to enjoy trying to solve the c/r problems.
Quoted 7 lines
Hi Oleg, Amnon, sorry for delay on this message. First of all, I'm not vDSO specialist but as to c/r aspect of it I've had in mind the the following scenario: we dump vDSO area either complete euther simply remember the functions addresses it provides, then on restore we replace the functions prologue with jmp instruction which would point to the vDSO entries provided us by a kernel. But again, I didn't spend much time for vDSO yet.
I think this approach should work. Here is a bit more details:
1. A task will be not dumped in vdso code. If a task is in vdso code, we will try to catch it again.
2. Only addresses of vdso symbols will be dumped.
3. On restore we will compare addresses of symbols. If addresses are not changes, a new vdso will be mapped instead of old one. If they are changed, a new vdso will be mapped in a free space and the old vdso will be replaced on a proxy library, where all functions are replaced on jumps to suitable functions in the new vdso.Looks simple and does not required to hack a kernel.
Quoted 2 lines
Cyrill
Re: vdso && cr (Was: arch_check_bp_in_kernelspace: fix the range check)
Quoted 5 lines · Amnon Shiloh
You could of course keep that old code and modify only the very first instruction of each routine into a jump instruction, but then the code to which the process returns may not be compatible with the new kernel and/or hardware configuration.
For sure there will be some limitations but I fear we can't do that much with it. I don't expect the regular program to use sigreturn for jumping into vdso code, but I could be wrong.
Cyrill
Re: vdso && cr (Was: arch_check_bp_in_kernelspace: fix the range
Hi Cyrill,
Programmers don't (and the manual-page says they shouldn't even try) call "sigreturn" directly.
If an interrupt happens, by bad luck, to occur while the process is running vdso code, then eventually, once signal-processing is complete, "sigreturn" (issued by glibc) will take the process back to where it was before the interrupt happend, inside the vdso page.
Best Regards,
Amnon.
Quoted 13 lines · Amnon Shiloh
Quoted 5 lines
You could of course keep that old code and modify only the very first instruction of each routine into a jump instruction, but then the code to which the process returns may not be compatible with the new kernel and/or hardware configuration.
For sure there will be some limitations but I fear we can't do that much with it. I don't expect the regular program to use sigreturn for jumping into vdso code, but I could be wrong.
Cyrill
Re: vdso && cr
Quoted 7 lines · Amnon Shiloh
Programmers don't (and the manual-page says they shouldn't even try) call "sigreturn" directly.
If an interrupt happens, by bad luck, to occur while the process is running vdso code, then eventually, once signal-processing is complete, "sigreturn" (issued by glibc) will take the process back to where it was before the interrupt happend, inside the vdso page.
Hi Amnon, good point, need to think. Frankly I would like to escape kernel patching as long as possible ;)