Bug 1820095
| Summary: | kernel: execve synthesizes SIGSEGV when failing to load main program segments | ||
|---|---|---|---|
| Product: | Red Hat Enterprise Linux 8 | Reporter: | Florian Weimer <fweimer> |
| Component: | kernel | Assignee: | core-kernel-bot <core-kernel-mgr> |
| kernel sub component: | Process management | QA Contact: | Kernel General QE <kernel-general-qe> |
| Status: | CLOSED CANTFIX | Docs Contact: | |
| Severity: | unspecified | ||
| Priority: | unspecified | CC: | efuller, jbastian, onestero |
| Version: | 8.2 | ||
| Target Milestone: | rc | ||
| Target Release: | 8.0 | ||
| Hardware: | Unspecified | ||
| OS: | Unspecified | ||
| Whiteboard: | |||
| Fixed In Version: | Doc Type: | If docs needed, set a value | |
| Doc Text: | Story Points: | --- | |
| Clone Of: | Environment: | ||
| Last Closed: | 2020-04-02 10:28:28 UTC | Type: | Bug |
| Regression: | --- | Mount Type: | --- |
| Documentation: | --- | CRM: | |
| Verified Versions: | Category: | --- | |
| oVirt Team: | --- | RHEL 7.3 requirements from Atomic Host: | |
| Cloudforms Team: | --- | Target Upstream Version: | |
| Embargoed: | |||
|
Description
Florian Weimer
2020-04-02 09:02:57 UTC
(In reply to Florian Weimer from comment #0) > > char large_data[1LL << 39]; > > int > main (void) > { > } > > Steps to Reproduce: > 1. gcc reproducer.c > 2. ./a.out > > Actual results: > > The shell reports: Segmentation fault Yes, > Expected results: > > The execve system call should fail with ENOMEM, resulting in a more > understandable error message from the shell. but this is impossible :/ The old VM was already destroyed, the process simply cannot return to userspace. Yuck, I didn't consider this. Thanks. Would it be possible to communicate somehow the cause of the SIGSEGV in the siginfo_t value provided by waitid? (In reply to Florian Weimer from comment #2) > > Would it be possible to communicate somehow the cause of the SIGSEGV in the > siginfo_t value provided by waitid? Unfortunately no. The only additional info you can get from this siginfo_t (compared to wait(&status)) is pid/uid. The ENOMEM from execve is visible in strace output immediately before strace reports the SIGSEGV, so while the shell can't easily report it, it can be seen with suitable tool usage. The SIGSEGV comes from search_binary_handler (the force_sigsegv(SIGSEGV, current) line), called by exec_binprm, called by __do_execve_file, in fs/exec.c; I have not yet found documentation for this behavior, unless https://lkml.org/lkml/2013/2/15/572 qualifies as such. It appears there was already precedent for killing processes in response to execve failures, but the patch in that message (or something very similar like https://github.com/torvalds/linux/commit/19d860a140beac48a1377f179e693abe86a9dac9) seems mostly responsible for the present behavior. (In reply to Eirik Fuller from comment #4) > > The ENOMEM from execve is visible in strace output immediately before strace > reports the SIGSEGV, so while the shell can't easily report it, it can be > seen with suitable tool usage. Yes, > It appears there was already precedent for killing processes in response to > execve failures, but the patch in that message (or something very similar > like > https://github.com/torvalds/linux/commit/ > 19d860a140beac48a1377f179e693abe86a9dac9) seems mostly responsible for the > present behavior. No really, this patch cleanups the "suicide" logic we always had. Once again, the execing task simply can't return to usermode after de_thread/ exec_mmap, sys_execve() does return the error code, strace can report it, but this task can't. IOW, consider sys_execve(...); printf("exec failed"); if execve fails after original VM is already destroyed, the code above no longer exist, its page is already freed. |