Bug 836508 - Segmentation fault after receiving SIGHUP signal in i386 compatible mode
Segmentation fault after receiving SIGHUP signal in i386 compatible mode
Product: Red Hat Enterprise Linux 5
Classification: Red Hat
Component: kernel (Show other bugs)
x86_64 Linux
unspecified Severity urgent
: rc
: ---
Assigned To: Red Hat Kernel Manager
Red Hat Kernel QE team
Depends On:
  Show dependency treegraph
Reported: 2012-06-29 06:07 EDT by bolt liu
Modified: 2012-06-29 08:18 EDT (History)
0 users

See Also:
Fixed In Version:
Doc Type: Bug Fix
Doc Text:
Story Points: ---
Clone Of:
Last Closed: 2012-06-29 08:18:35 EDT
Type: Bug
Regression: ---
Mount Type: ---
Documentation: ---
Verified Versions:
Category: ---
oVirt Team: ---
RHEL 7.3 requirements from Atomic Host:
Cloudforms Team: ---

Attachments (Terms of Use)
segfault.c (674 bytes, application/octet-stream)
2012-06-29 06:07 EDT, bolt liu
no flags Details

  None (edit)
Description bolt liu 2012-06-29 06:07:11 EDT
Created attachment 595249 [details]

Description of problem:

I have a simple program(see it in attachment) which installs a signal handler for SIGHUP, however, it will get segmentation fault after receiving SIGHUP signal. the program is compiled for i386, and the OS is x86-64.

it will not fail if the array size is 2048.

Version-Release number of selected component (if applicable):

How reproducible:

Steps to Reproduce:
1. compile the segfault.c using 32-bit gcc (gcc version 4.1.2 20071124 (Red Hat 4.1.2-42))
2. run the program in the 64-bit Linux kernel 2.6.18-308.1.1
3. send the SIGNUP signal to the process
Actual results:
get Segmentation fault, dmesg shows:
bad[3487]: segfault at 0000000000000003 rip 0000000000000003 rsp 00000000ffd3b8b0 error 14

Expected results:
the process continue to run

Additional info:
1. all the other applications, libs are 32-bit, only the kernel is 64-bit,
   the kernel is installed with --ignorearch
Comment 1 Jes Sorensen 2012-06-29 08:18:35 EDT
I doubt the kernel is at fault here.

The man page for sigaction has the following snippet:

       The sigaction structure is defined as something like:

           struct sigaction {
               void     (*sa_handler)(int);
               void     (*sa_sigaction)(int, siginfo_t *, void *);
               sigset_t   sa_mask;
               int        sa_flags;
               void     (*sa_restorer)(void);

       On  some  architectures  a  union  is  involved:  do not assign to both
       sa_handler and sa_sigaction.

While your code does this:

  int main(int argc, char **argv)
  #ifdef GOOD
      char large[2048];
      char large[2000];
      struct sigaction sig_action;
      sig_action.sa_handler = signalHandler;

Since you allocate the struct sigaction on the stack and you only clear
sa_handler and sa_flags in the setup, you end up with whatever was previous
in memory for sa_sigaction, sa_mask, and sa_restorer.

Changing the size of the array just moves things arround so you probably
end up hitting memory that was zeroed out by chance.

Try memset()'ing the struct sig_action first - that ought to fix it.


Note You need to log in before you can comment on or make changes to this bug.