sgx-lkl icon indicating copy to clipboard operation
sgx-lkl copied to clipboard

[Tests] "write" syscall generates both SIGPIPE and EPIPE

Open shaikshavali1 opened this issue 4 years ago • 8 comments

After analysis, I found that write system call on pipe is generating both SIGPIPE and EPIPE even though we register a sighandler for SIGPIPE. This behaviour differs from pipe documentation of linux(https://www.man7.org/linux/man-pages/man7/pipe.7.html) . Below text is from man page.

“If all file descriptors referring to the write end of a pipe have been closed, then an attempt to read(2) from the pipe will see end-of-file (read(2) will return 0). If all file descriptors referring to the read end of a pipe have been closed, then a write(2) will cause a SIGPIPE signal to be generated for the calling process. If the calling process is ignoring this signal, then write(2) fails with the error EPIPE. An application that uses pipe(2) and fork(2) should use suitable close(2) calls to close unnecessary duplicate file descriptors; this ensures that end-of-file and SIGPIPE/EPIPE are delivered when appropriate.”

shaikshavali1 avatar Jun 16 '20 02:06 shaikshavali1

@SeanTAllen, this looks as if it’s related to the signal delivery. I suspect there may be something in how the syscall handler checks for signals that is wrong here.

davidchisnall avatar Jun 19 '20 07:06 davidchisnall

Assigning myself so I don't lose track of this given it might be related to the signal handling stuff I've been looking at.

SeanTAllen avatar Jun 23 '20 12:06 SeanTAllen

@shaikshavali1 do you have a minimal example that demonstrates the problem?

SeanTAllen avatar Jun 24 '20 14:06 SeanTAllen

Test case Description:

The original test case is to check that the child process is killed due to “broken pipe” or not. Code snippet (original file): https://github.com/linux-test-project/ltp/blob/master/testcases/kernel/syscalls/pipe/pipe02.c

This test case is modified to work as a single process. In modified code, below operations are performed.

  1. Signal handler is registered to catch SIGPIPE
  2. opens the pipe
  3. Perform dummy read and write
  4. Close read descriptor and perform write operation
  5. Check for SIGPIPE and EPIPE error.

Code snippet (modified code patch): https://github.com/lsds/sgx-lkl/blob/89234d3afea356250195964fa70f1bea360312ba/tests/ltp/patches/fix_pipe_pipe02.patch#L88

GDB Logs:

ksys_write (fd=5, buf=0x7fff3dbed274 "aaaaaaaaaa", count=5) at fs/read_write.c:602
(gdb) bt#0  ksys_write (fd=5, buf=0x7fff3dbed274 "aaaaaaaaaa", count=5) at fs/read_write.c:602
 1  0x00007fff00209479 in __do_sys_write (count=<optimized out>, buf=<optimized out>, fd=<optimized out>) at fs/read_write.c:623
2  __se_sys_write (fd=<optimized out>, buf=<optimized out>, count=<optimized out>) at fs/read_write.c:620
3  0x00007fff0018becf in run_syscall (params=<optimized out>, no=<optimized out>) at arch/lkl/kernel/syscalls.c:44
4  lkl_syscall (no=5, params=0x7fff40a72cf0) at arch/lkl/kernel/syscalls.c:192
5  0x00007fff000e52c0 in write ()
6  0x0000000000000005 in ?? ()
7  0x00007fff3dbed274 in ?? ()
8  0x0000000000000005 in ?? ()
9  0x0000000000000000 in ?? ()
(gdb) bt
0  ksys_write (fd=5, buf=0x7fff3dbed274 "aaaaaaaaaa", count=5) at fs/read_write.c:602
 1  0x00007fff00209479 in __do_sys_write (count=<optimized out>, buf=<optimized out>, fd=<optimized out>) at fs/read_write.c:623
2  __se_sys_write (fd=<optimized out>, buf=<optimized out>, count=<optimized out>) at fs/read_write.c:620
3  0x00007fff0018becf in run_syscall (params=<optimized out>, no=<optimized out>) at arch/lkl/kernel/syscalls.c:44
4  lkl_syscall (no=5, params=0x7fff40a72cf0) at arch/lkl/kernel/syscalls.c:192
5  0x00007fff000e52c0 in write ()
6  0x0000000000000005 in ?? ()
7  0x00007fff3dbed274 in ?? ()
8  0x0000000000000005 in ?? ()
9  0x0000000000000000 in ?? ()
(gdb)

As per the man page the write should generate SIGPIPE if signal handler is registered. But, here EPIPE is also returned from write.

shaikshavali1 avatar Jun 30 '20 19:06 shaikshavali1

Thanks. Is the SIGPIPE received?

prp avatar Jun 30 '20 19:06 prp

@prp, Yes SIGPIPE received.

shaikshavali1 avatar Jul 01 '20 12:07 shaikshavali1

I believe the write call should return EINTR. Because signals are not being delivered to the wrong Linux task (#644), we are not setting substituting EINTR for the syscall return value in lkl_syscall. This is probably going to be fixed by the fix #644.

davidchisnall avatar Jul 28 '20 16:07 davidchisnall

Unassigning myself as this is now a p2.

SeanTAllen avatar Aug 03 '20 21:08 SeanTAllen