walnux/include
Gregory Nutt 8868c58720 Fix Deadloop in VFS if CONFIG_CANCELLATION_POINTS is enabled
If cancellation points are enabled, then the following logic is activated in sem_wait().  This causes ECANCELED to be returned every time that sem_wait is called.

    int sem_wait(FAR sem_t *sem)
    {
      ...

      /* sem_wait() is a cancellation point */

      if (enter_cancellation_point())
        {
    #ifdef CONFIG_CANCELLATION_POINTS
          /* If there is a pending cancellation, then do not perform
           * the wait.  Exit now with ECANCELED.
           */

          errcode = ECANCELED;
          goto errout_with_cancelpt;
    #endif
        }
      ...

Normally this works fine.  sem_wait() is the OS API called by the application and will cancel the thread just before it returns to the application.  Since it is cancellation point, it should never be called from within the OS.

There there is is one perverse cases where sem_wait() may be nested within another cancellation point.  If open() is called, it will attempt to lock a VFS data structure and will eventually call nxmutex_lock().  nxmutex_lock() waits on a semaphore:

   int nxmutex_lock(FAR mutex_t *mutex)
   {
     ...

     for (; ; )
       {
         /* Take the semaphore (perhaps waiting) */

         ret = _SEM_WAIT(&mutex->sem);
         if (ret >= 0)
           {
             mutex->holder = _SCHED_GETTID();
             break;
           }

         ret = _SEM_ERRVAL(ret);
         if (ret != -EINTR && ret != -ECANCELED)
           {
             break;
           }
       }
   ...
}

In the FLAT build, _SEM_WAIT expands to sem_wait().  That causes the error in the logic:  It should always expand to nxsem_wait().  That is because sem_wait() is cancellation point and should never be called from with the OS or the C library internally.

The failure occurs because the cancellation point logic in sem_wait() returns -ECANCELED (via _SEM_ERRVAL) because sem_wait() is nested; it needs to return the -ECANCELED error to the outermost cancellation point which is open() in this case.  Returning -ECANCELED then causes an infinite loop to occur in nxmutex_lock().

The correct behavior in this case is to call nxsem_wait() instead of sem_wait().  nxsem_wait() is identical to sem_wait() except that it is not a cancelation point.  It will return -ECANCELED if the thread is canceled, but only once.  So no infinite loop results.

In addition, an nxsem_wait() system call was added to support the call from nxmutex_lock().

This resolves Issue #9695
2023-07-06 14:20:29 -03:00
..
android libc/misc: add fdsan module 2023-05-17 10:24:42 +08:00
arpa Net thread-safe ntoa functions 2022-08-02 21:04:19 +08:00
crypto crypto:support crypto can handle streaming data 2023-01-17 01:19:38 +08:00
cxx libc: Implement quick_exit and at_quick_exit 2023-01-25 14:31:37 +02:00
net ethernet: add ETHERTYPE define 2023-05-04 19:38:57 +08:00
netinet Indent the define statement by two spaces 2023-05-21 09:52:08 -03:00
netpacket netlink: add RTM_NEWADDR, RTM_DELADDR and RTM_GETADDR 2023-04-22 01:35:18 +08:00
nuttx libc/modlib: Replace nx_stat with file_stat 2023-07-06 09:20:24 -03:00
ssp
sys Fix Deadloop in VFS if CONFIG_CANCELLATION_POINTS is enabled 2023-07-06 14:20:29 -03:00
.gitignore Add Embedded Template Library (ETL) support 2022-08-05 09:38:48 +08:00
aio.h fs: Undefine CONFIG_FS_LARGEFILE if compiler doesn't support long long 2023-03-02 09:37:58 +01:00
alloca.h
assert.h assert: disable function/line print if DEBUG_ASSERTIONS_FILENAME disabled 2023-06-12 13:36:08 +08:00
byteswap.h
ctype.h
debug.h assert: disable function/line print if DEBUG_ASSERTIONS_FILENAME disabled 2023-06-12 13:36:08 +08:00
dirent.h fs: Undefine CONFIG_FS_LARGEFILE if compiler doesn't support long long 2023-03-02 09:37:58 +01:00
dlfcn.h
dsp.h libdsp: Add average filter 2023-06-12 08:39:38 +02:00
dspb16.h
elf.h Add support for the loading of ET_DYN objects 2023-07-06 09:13:38 -03:00
elf32.h
elf64.h
endian.h libc: Add sys/endian.h to improve the compatiblity with bionic libc 2023-01-15 12:26:15 -03:00
err.h include/err: Enforce c linkage for err and warn functions. 2023-05-01 12:48:55 +08:00
errno.h errno: Adjust help string for EALREADY and ESTALE 2023-07-03 13:38:02 +08:00
execinfo.h Indent the define statement by two spaces 2023-05-21 09:52:08 -03:00
fcntl.h include: Fix nxstyle errors 2023-05-04 02:07:01 +08:00
fixedmath.h
fnmatch.h
ftw.h fs: Undefine CONFIG_FS_LARGEFILE if compiler doesn't support long long 2023-03-02 09:37:58 +01:00
getopt.h
glob.h
grp.h
hex2bin.h libc/hex2bin: Remove the unused declaration 2022-12-05 10:42:22 +01:00
iconv.h libc/locale: support iconv_open,iconv,iconv_close 2023-04-25 19:12:53 +01:00
ifaddrs.h
inttypes.h fs: Undefine CONFIG_FS_LARGEFILE if compiler doesn't support long long 2023-03-02 09:37:58 +01:00
iso646.h
langinfo.h
libgen.h
libintl.h compiler.h: Add _ between format|printf|syslog|scanf|strftime and like 2022-12-21 01:05:19 +02:00
limits.h Indent the define statement by two spaces 2023-05-21 09:52:08 -03:00
locale.h
lzf.h Indent the define statement by two spaces 2023-05-21 09:52:08 -03:00
malloc.h mm: Rename PID_MM_INVALID to PID_MM_LEAK 2023-06-18 14:26:07 +03:00
mqueue.h include: Fix nxstyle errors 2023-05-04 02:07:01 +08:00
netdb.h libc/netdb: add proto.c 2022-12-10 02:36:24 +08:00
nl_types.h
nxflat.h
obstack.h compiler.h: Add _ between format|printf|syslog|scanf|strftime and like 2022-12-21 01:05:19 +02:00
poll.h
pthread.h sched/tls: remove PTHREAD_CLEANUP from Kconfig 2023-06-14 12:00:48 +08:00
pty.h drivers/serial: Always support c_oflag, c_iflag and c_lflag in termios 2023-03-19 14:54:59 -06:00
pwd.h Indent the define statement by two spaces 2023-05-21 09:52:08 -03:00
regex.h include/regex.h: add missing FAR 2023-05-19 02:40:38 +08:00
resolv.h
sched.h include: Fix nxstyle errors 2023-05-04 02:07:01 +08:00
semaphore.h semaphore: Optimize priority inheritance with only one holder 2023-06-17 08:26:46 +03:00
signal.h signal: correct to const pointer for sigorset and sigandset 2023-07-05 16:26:18 +08:00
spawn.h sched/spawn: Rename task_spawnattr_[get|set]stack[size|addr] to posix_spawnattr_[get|set]stack[size|addr] 2022-11-01 09:51:18 +09:00
stdbool.h
stddef.h
stdint.h include/stdint.h: add sig_atomic_t limits 2022-10-02 22:30:54 +08:00
stdio.h Support gcc FORTIFY_SOURCE features for nuttx libc 2023-06-22 20:38:45 +08:00
stdlib.h Support gcc FORTIFY_SOURCE features for nuttx libc 2023-06-22 20:38:45 +08:00
stdnoreturn.h
string.h Support gcc FORTIFY_SOURCE features for nuttx libc 2023-06-22 20:38:45 +08:00
strings.h Support gcc FORTIFY_SOURCE features for nuttx libc 2023-06-22 20:38:45 +08:00
syscall.h syscall: export UP_WRAPSYM/UP_REALSYM macro 2022-12-30 22:13:34 +08:00
syslog.h syslog: add syslog option definition 2023-05-05 18:36:36 +08:00
termios.h
threads.h sched/getpid: replace syscall getpid/tid/ppid() to kernel version 2023-02-02 10:33:01 +08:00
time.h sched/clock/clock_getcpuclockid: add clock_getcpuclockid implementation 2023-07-05 00:32:11 +08:00
unistd.h sched/clock/clock_getres: add two CPUTIME_ID res support 2023-07-03 23:11:00 +03:00
utime.h
uuid.h
wchar.h Support gcc FORTIFY_SOURCE features for nuttx libc 2023-06-22 20:38:45 +08:00
wctype.h libc: Remove the unnecessary include from wchar and wctype 2022-07-27 10:55:37 +03:00