This is the mail archive of the libc-alpha@sourceware.org mailing list for the glibc project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH 00/13] nptl: Fix Race conditions in pthread cancellation (BZ#12683)


Hi all,

This is an updated version of my previous patchset to fix BZ#12683 [1] and
it superseeds the previous one. The differences from previous version are:

- Mark lseek/llseek as non-cancellable to make it consistent on all supported
  architectures.  It also simplifies the bug fix since there is no need to
  change the __syscall_cancel_arch return type since all cancellable functions
  does not return types larger than long int for ILP32 ports [2].
- Updated the port status wiki page with required steps [3].
- Fix the non-threaded version for __syscall_cancel.
- Moved i386 code from powerpc32 patch.

The patchset fixes the x86_64, i386, x32, powerpc32, powerpc64{le}, aarch64,
and ARM port and also include the fix for s390 and s390x from Stefan Liebler.

It will require some help for alpha, hppa, ia64, m68k, microblaze, nios2, mips,
sh, sparc, and tile. I summarized in wiki page [2] the steps required to adjust
the remaining architectures, but based on arm/aarch64 the minimal adjustments
required are:

1. Write a new syscall implementation at sysdeps/unix/sysv/linux/<arch>/syscall_cancel.S
   that basically do:

long int __syscall_cancel_arch (volatile unsigned int *cancelhandling,
  __syscall_arg_t nr, __syscall_arg_t arg1, __syscall_arg_t arg2,
  __syscall_arg_t arg3, __syscall_arg_t arg4, __syscall_arg_t arg5,
  __syscall_arg_t arg6)
{
  if (*cancelhandling & CANCELED_BITMASK)
    __syscall_do_cancel()

  INTERNAL_SYSCALL_DECL (err);
  result = INTERNAL_SYSCALL_NCS (nr, err, 6, a1, a2, a3, a4, a5, a6);
  if (INTERNAL_SYSCALL_ERROR_P (result, err))
    return -INTERNAL_SYSCALL_ERRNO (result, err);
  return result;
}

2. Adjust sysdeps/unix/sysv/linux/<arch>/sysdep-cancel.h to make cancellable
   syscalls to call __syscall_cancel instead of *_{enable,disable}_asynccancel.

3. Create a function to get current IP address based on ucontext_t:

static inline
long int __pthread_get_ip (const struct ucontext *uc)
{
  // TODO: return current IP based on uc.
}

4. Define both SYSCALL_CANCEL_ERROR(__val) and SYSCALL_CANCEL_ERRNO(__val)
   macros.

These are to be used in the new SYSCALL_CANCEL definition:

#define SYSCALL_CANCEL(name, args...)                                   \
  ({                                                                    \
    long int sc_ret = SYSCALL_CANCEL_NCS (name, args);                  \
    if (SYSCALL_CANCEL_ERROR (sc_ret))                                  \
      {                                                                 \
        __set_errno (SYSCALL_CANCEL_ERRNO (sc_ret));                    \
        sc_ret = -1L;                                                   \
      }                                                                 \
    sc_ret;                                                             \
  })

So it should be modelled using similar semantics as INTERNAL_SYSCALL_ERROR_P
and INTERNAL_SYSCALL_ERRNO.


For x86_64 and i386 implementation my approach was to just remove the
pthread_cond_{timed}wait assembly implementation and use default C code, but
since Torvald Riegel new condvar implementation [3] also removed them this
patchset do not contain such removals. Also, this fix is easy to adjust
to new futex API also proposed by Torvalds and I can adjust the patch when
the new API is pushed upstream. The bulk of implementation just depend of a
cancellable futex call done by new mechanism which is orthogonal of the new
proposed futex API.

The idea is try to push it for 2.23 and I have a personal branch [4] with
a working tree for the aforementioned architectures.

[1] https://sourceware.org/ml/libc-alpha/2015-09/msg00411.html
[2] https://sourceware.org/ml/libc-alpha/2015-09/msg00624.html
[3] https://sourceware.org/glibc/wiki/PortStatus
[4] https://sourceware.org/ml/libc-alpha/2015-05/msg00287.htm
[5] https://sourceware.org/git/?p=glibc.git;a=shortlog;h=refs/heads/azanella/bz12683


Adhemerval Zanella (13):
  nptl: Add NPTL cases for cancellation failures cases
  nptl: Fix testcases for new pthread cancellation mechanism
  Mark lseek/llseek as non-cancellable
  nptl: Fix Race conditions in pthread cancellation (BZ#12683)
  nptl: powerpc64: Fix Race conditions in pthread cancellation
    (BZ#12683)
  nptl: x86_64: Fix Race conditions in pthread cancellation (BZ#12683)
  nptl: x32: Fix Race conditions in pthread cancellation (BZ#12683)
  nptl: i386: Fix Race conditions in pthread cancellation (BZ#12683)
  nptl: ppc32: Fix Race conditions in pthread cancellation (BZ#12683)
  nptl: aarch64: Fix Race conditions in pthread cancellation (BZ#12683)
  nptl: arm: Fix Race conditions in pthread cancellation (BZ#12683)
  nptl: s390: Fix Race conditions in pthread cancellation (BZ#12683)
  nptl: s390x: Fix Race conditions in pthread cancellation (BZ#12683)

 ChangeLog                                          | 217 +++++++++++++++++++++
 io/creat.c                                         |   3 -
 io/ppoll.c                                         |   2 -
 misc/pselect.c                                     |   2 -
 nptl/Makefile                                      |  22 +--
 nptl/Versions                                      |   3 +
 nptl/cancellation.c                                | 101 ----------
 nptl/descr.h                                       |  15 +-
 nptl/libc-cancellation.c                           |  66 ++++++-
 nptl/lll_timedlock_wait.c                          |   2 +-
 nptl/lll_timedwait_tid.c                           |   3 +-
 nptl/nptl-init.c                                   |  65 +++---
 nptl/pthreadP.h                                    |  73 +++----
 nptl/pthread_cancel.c                              |  73 +------
 nptl/pthread_cond_timedwait.c                      |  31 ++-
 nptl/pthread_cond_wait.c                           |  20 +-
 nptl/pthread_create.c                              |   6 +-
 nptl/pthread_exit.c                                |   9 +-
 nptl/pthread_join.c                                |   9 +-
 nptl/pthread_timedjoin.c                           |   8 -
 nptl/sem_wait.c                                    |   8 +-
 nptl/tst-cancel-wrappers.sh                        |  92 ---------
 nptl/tst-cancel2.c                                 |   3 +
 nptl/tst-cancel20.c                                |   6 +-
 nptl/tst-cancel21.c                                |   5 +
 nptl/tst-cancel26.c                                |  68 +++++++
 nptl/tst-cancel27.c                                |  70 +++++++
 nptl/tst-cancel28.c                                |  98 ++++++++++
 nptl/tst-cancel4.c                                 | 128 +++++++++++-
 rt/Makefile                                        |   1 -
 sysdeps/generic/sysdep-cancel.h                    |   3 -
 sysdeps/i386/nptl/tls.h                            |  11 --
 sysdeps/nptl/Makefile                              |   3 +-
 sysdeps/nptl/aio_misc.h                            |  13 +-
 sysdeps/nptl/gai_misc.h                            |  13 +-
 sysdeps/nptl/librt-cancellation.c                  |  24 ---
 sysdeps/nptl/lowlevellock.h                        |   2 +-
 sysdeps/posix/open64.c                             |  12 +-
 sysdeps/posix/pause.c                              |   2 -
 sysdeps/posix/sigpause.c                           |  11 +-
 sysdeps/posix/sigwait.c                            |   9 +-
 sysdeps/posix/waitid.c                             |  11 +-
 sysdeps/unix/sysdep.h                              |  68 +++++--
 sysdeps/unix/sysv/linux/aarch64/syscall_cancel.S   |  61 ++++++
 sysdeps/unix/sysv/linux/aarch64/sysdep-cancel.h    |  95 ++++-----
 sysdeps/unix/sysv/linux/aarch64/sysdep.h           |   8 +
 sysdeps/unix/sysv/linux/arm/syscall_cancel.S       |  72 +++++++
 sysdeps/unix/sysv/linux/arm/sysdep-cancel.h        | 181 ++++-------------
 sysdeps/unix/sysv/linux/arm/sysdep.h               |   8 +
 sysdeps/unix/sysv/linux/clock_nanosleep.c          |  17 +-
 sysdeps/unix/sysv/linux/fcntl.c                    |  33 ++--
 sysdeps/unix/sysv/linux/futex-internal.h           |  18 +-
 sysdeps/unix/sysv/linux/generic/creat.c            |   3 -
 .../unix/sysv/linux/generic/wordsize-32/fcntl.c    |  30 +--
 sysdeps/unix/sysv/linux/i386/Makefile              |   1 +
 sysdeps/unix/sysv/linux/i386/fcntl.c               |   4 +-
 sysdeps/unix/sysv/linux/i386/lowlevellock.h        |   2 +-
 sysdeps/unix/sysv/linux/i386/syscall_cancel.S      | 105 ++++++++++
 sysdeps/unix/sysv/linux/i386/sysdep-cancel.h       | 144 +++++---------
 sysdeps/unix/sysv/linux/i386/sysdep.h              |  65 ++++--
 sysdeps/unix/sysv/linux/lowlevellock-futex.h       |  46 ++++-
 sysdeps/unix/sysv/linux/mips/mips64/syscalls.list  |   2 +-
 .../sysv/linux/powerpc/powerpc32/sysdep-cancel.h   | 131 ++++++-------
 sysdeps/unix/sysv/linux/powerpc/powerpc32/sysdep.h |   8 +
 sysdeps/unix/sysv/linux/powerpc/powerpc64/fcntl.c  |   4 +-
 .../sysv/linux/powerpc/powerpc64/sysdep-cancel.h   | 137 ++++---------
 sysdeps/unix/sysv/linux/powerpc/powerpc64/sysdep.h |   9 +
 sysdeps/unix/sysv/linux/powerpc/syscall_cancel.S   |  63 ++++++
 sysdeps/unix/sysv/linux/powerpc/sysdep.c           |  11 ++
 sysdeps/unix/sysv/linux/pthread_kill.c             |   5 +-
 .../unix/sysv/linux/s390/s390-32/syscall_cancel.S  |  85 ++++++++
 .../unix/sysv/linux/s390/s390-32/sysdep-cancel.h   | 128 ++++++------
 sysdeps/unix/sysv/linux/s390/s390-32/sysdep.h      |   8 +
 .../unix/sysv/linux/s390/s390-64/syscall_cancel.S  |  87 +++++++++
 .../unix/sysv/linux/s390/s390-64/sysdep-cancel.h   | 116 ++++++-----
 sysdeps/unix/sysv/linux/s390/s390-64/sysdep.h      |   8 +
 sysdeps/unix/sysv/linux/sigwait.c                  |  36 +---
 sysdeps/unix/sysv/linux/socketcall.h               |  37 +++-
 sysdeps/unix/sysv/linux/wordsize-64/syscalls.list  |   2 +-
 sysdeps/unix/sysv/linux/x86_64/cancellation.S      | 117 -----------
 sysdeps/unix/sysv/linux/x86_64/libc-cancellation.S |  21 --
 .../unix/sysv/linux/x86_64/librt-cancellation.S    |  21 --
 sysdeps/unix/sysv/linux/x86_64/lowlevellock.h      |   8 +-
 sysdeps/unix/sysv/linux/x86_64/syscall_cancel.S    |  62 ++++++
 sysdeps/unix/sysv/linux/x86_64/sysdep-cancel.h     |  73 +++----
 sysdeps/unix/sysv/linux/x86_64/sysdep.h            |   8 +
 sysdeps/unix/sysv/linux/x86_64/x32/lseek.S         |   2 +-
 sysdeps/unix/sysv/linux/x86_64/x32/sysdep.h        |  21 ++
 sysdeps/x86_64/nptl/tcb-offsets.sym                |   1 -
 sysdeps/x86_64/nptl/tls.h                          |  11 --
 90 files changed, 2034 insertions(+), 1472 deletions(-)
 delete mode 100644 nptl/cancellation.c
 delete mode 100644 nptl/tst-cancel-wrappers.sh
 create mode 100644 nptl/tst-cancel26.c
 create mode 100644 nptl/tst-cancel27.c
 create mode 100644 nptl/tst-cancel28.c
 delete mode 100644 sysdeps/nptl/librt-cancellation.c
 create mode 100644 sysdeps/unix/sysv/linux/aarch64/syscall_cancel.S
 create mode 100644 sysdeps/unix/sysv/linux/arm/syscall_cancel.S
 create mode 100644 sysdeps/unix/sysv/linux/i386/syscall_cancel.S
 create mode 100644 sysdeps/unix/sysv/linux/powerpc/syscall_cancel.S
 create mode 100644 sysdeps/unix/sysv/linux/s390/s390-32/syscall_cancel.S
 create mode 100644 sysdeps/unix/sysv/linux/s390/s390-64/syscall_cancel.S
 delete mode 100644 sysdeps/unix/sysv/linux/x86_64/cancellation.S
 delete mode 100644 sysdeps/unix/sysv/linux/x86_64/libc-cancellation.S
 delete mode 100644 sysdeps/unix/sysv/linux/x86_64/librt-cancellation.S
 create mode 100644 sysdeps/unix/sysv/linux/x86_64/syscall_cancel.S

-- 
1.9.1


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]