From 344f7bc9f61d139b932bf6c6a5001e7a8e54409d Mon Sep 17 00:00:00 2001 From: Gregory Nutt Date: Thu, 28 Nov 2019 10:51:29 -0600 Subject: [PATCH] include/nuttx/sched.h: Add storage for a previous signal mask. arch/: In all syscall implemenations, block all signals before dispatching a system call; resotre signal mask when the system call returnes. --- arch/arm/src/armv6-m/up_svcall.c | 14 +++++++++++++- arch/arm/src/armv7-a/arm_syscall.c | 15 ++++++++++++++- arch/arm/src/armv7-m/up_svcall.c | 14 +++++++++++++- arch/arm/src/armv7-r/arm_syscall.c | 16 ++++++++++++++-- arch/mips/src/mips32/up_swint0.c | 14 +++++++++++++- arch/misoc/src/lm32/lm32_swint.c | 14 +++++++++++++- arch/misoc/src/minerva/minerva_swint.c | 12 ++++++++++++ arch/risc-v/src/rv32im/up_swint.c | 14 +++++++++++++- include/nuttx/sched.h | 5 ++++- net/netlink/netlink_conn.c | 4 ++-- 10 files changed, 111 insertions(+), 11 deletions(-) diff --git a/arch/arm/src/armv6-m/up_svcall.c b/arch/arm/src/armv6-m/up_svcall.c index f964248cbc..e11cecad05 100644 --- a/arch/arm/src/armv6-m/up_svcall.c +++ b/arch/arm/src/armv6-m/up_svcall.c @@ -1,7 +1,7 @@ /**************************************************************************** * arch/arm/src/armv6-m/up_svcall.c * - * Copyright (C) 2013-2014 Gregory Nutt. All rights reserved. + * Copyright (C) 2013-2014, 2019 Gregory Nutt. All rights reserved. * Author: Gregory Nutt * * Redistribution and use in source and binary forms, with or without @@ -46,6 +46,7 @@ #include #include +#include #ifdef CONFIG_LIB_SYSCALL # include @@ -269,6 +270,11 @@ int up_svcall(int irq, FAR void *context, FAR void *arg) */ regs[REG_R0] = regs[REG_R2]; + + /* Restore the signal mask when the syscall returns */ + + (void)nxsig_procmask(SIG_SETMASK, &rtcb->sigoldmask, NULL); + sigemptyset(rtcb->sigoldmask); } break; #endif @@ -415,6 +421,7 @@ int up_svcall(int irq, FAR void *context, FAR void *arg) #ifdef CONFIG_LIB_SYSCALL FAR struct tcb_s *rtcb = sched_self(); int index = rtcb->xcp.nsyscalls; + sigset_t set; /* Verify that the SYS call number is within range */ @@ -438,6 +445,11 @@ int up_svcall(int irq, FAR void *context, FAR void *arg) /* Offset R0 to account for the reserved values */ regs[REG_R0] -= CONFIG_SYS_RESERVED; + + /* Block all signals while the system call runs */ + + sigfillset(&set); + (void)nxsig_procmask(SIG_BLOCK, &set, &rtcb->sigoldmask); #else svcerr("ERROR: Bad SYS call: %d\n", regs[REG_R0]); #endif diff --git a/arch/arm/src/armv7-a/arm_syscall.c b/arch/arm/src/armv7-a/arm_syscall.c index 00e4f43c6b..e31c50c364 100644 --- a/arch/arm/src/armv7-a/arm_syscall.c +++ b/arch/arm/src/armv7-a/arm_syscall.c @@ -1,7 +1,7 @@ /**************************************************************************** * arch/arm/src/armv7-a/arm_syscall.c * - * Copyright (C) 2013-2014, 2016 Gregory Nutt. All rights reserved. + * Copyright (C) 2013-2014, 2016, 2019 Gregory Nutt. All rights reserved. * Author: Gregory Nutt * * Redistribution and use in source and binary forms, with or without @@ -47,6 +47,7 @@ #include #include +#include #include #include "arm.h" @@ -219,6 +220,11 @@ uint32_t *arm_syscall(uint32_t *regs) /* Save the new SYSCALL nesting level */ rtcb->xcp.nsyscalls = index; + + /* Restore the signal mask when the syscall returns */ + + (void)nxsig_procmask(SIG_SETMASK, &rtcb->sigoldmask, NULL); + sigemptyset(rtcb->sigoldmask); } break; @@ -424,6 +430,7 @@ uint32_t *arm_syscall(uint32_t *regs) #ifdef CONFIG_LIB_SYSCALL FAR struct tcb_s *rtcb = sched_self(); int index = rtcb->xcp.nsyscalls; + sigset_t set; /* Verify that the SYS call number is within range */ @@ -450,6 +457,11 @@ uint32_t *arm_syscall(uint32_t *regs) /* Offset R0 to account for the reserved values */ regs[REG_R0] -= CONFIG_SYS_RESERVED; + + /* Block all signals while the system call runs */ + + sigfillset(&set); + (void)nxsig_procmask(SIG_BLOCK, &set, &rtcb->sigoldmask); #else svcerr("ERROR: Bad SYS call: %d\n", regs[REG_R0]); #endif @@ -465,6 +477,7 @@ uint32_t *arm_syscall(uint32_t *regs) regs[REG_SP] = (uint32_t)rtcb->xcp.kstack + ARCH_KERNEL_STACKSIZE; } #endif + /* Save the new SYSCALL nesting level */ rtcb->xcp.nsyscalls = index + 1; diff --git a/arch/arm/src/armv7-m/up_svcall.c b/arch/arm/src/armv7-m/up_svcall.c index 50897568cb..5c60aca5b7 100644 --- a/arch/arm/src/armv7-m/up_svcall.c +++ b/arch/arm/src/armv7-m/up_svcall.c @@ -1,7 +1,7 @@ /**************************************************************************** * arch/arm/src/armv7-m/up_svcall.c * - * Copyright (C) 2009, 2011-2015 Gregory Nutt. All rights reserved. + * Copyright (C) 2009, 2011-2015, 2019 Gregory Nutt. All rights reserved. * Author: Gregory Nutt * * Redistribution and use in source and binary forms, with or without @@ -46,6 +46,7 @@ #include #include +#include #include #ifdef CONFIG_LIB_SYSCALL @@ -269,6 +270,11 @@ int up_svcall(int irq, FAR void *context, FAR void *arg) */ regs[REG_R0] = regs[REG_R2]; + + /* Restore the signal mask when the syscall returns */ + + (void)nxsig_procmask(SIG_SETMASK, &rtcb->sigoldmask, NULL); + sigemptyset(rtcb->sigoldmask); } break; #endif @@ -415,6 +421,7 @@ int up_svcall(int irq, FAR void *context, FAR void *arg) #ifdef CONFIG_LIB_SYSCALL FAR struct tcb_s *rtcb = sched_self(); int index = rtcb->xcp.nsyscalls; + sigset_t set; /* Verify that the SYS call number is within range */ @@ -438,6 +445,11 @@ int up_svcall(int irq, FAR void *context, FAR void *arg) /* Offset R0 to account for the reserved values */ regs[REG_R0] -= CONFIG_SYS_RESERVED; + + /* Block all signals while the system call runs */ + + sigfillset(&set); + (void)nxsig_procmask(SIG_BLOCK, &set, &rtcb->sigoldmask); #else svcerr("ERROR: Bad SYS call: %d\n", regs[REG_R0]); #endif diff --git a/arch/arm/src/armv7-r/arm_syscall.c b/arch/arm/src/armv7-r/arm_syscall.c index 3abc36df90..737ea6e1ff 100644 --- a/arch/arm/src/armv7-r/arm_syscall.c +++ b/arch/arm/src/armv7-r/arm_syscall.c @@ -1,7 +1,7 @@ /**************************************************************************** * arch/arm/src/armv7-r/arm_syscall.c * - * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Copyright (C) 2015, 2019 Gregory Nutt. All rights reserved. * Author: Gregory Nutt * * Redistribution and use in source and binary forms, with or without @@ -47,6 +47,7 @@ #include #include +#include #include "arm.h" #include "svcall.h" @@ -217,6 +218,11 @@ uint32_t *arm_syscall(uint32_t *regs) /* Save the new SYSCALL nesting level */ rtcb->xcp.nsyscalls = index; + + /* Restore the signal mask when the syscall returns */ + + (void)nxsig_procmask(SIG_SETMASK, &rtcb->sigoldmask, NULL); + sigemptyset(rtcb->sigoldmask); } break; @@ -351,7 +357,7 @@ uint32_t *arm_syscall(uint32_t *regs) regs[REG_R3] = regs[REG_R4]; /* ucontext */ #ifdef CONFIG_ARCH_KERNEL_STACK - /* If we are signalling a user process, then we must be operating + /* If we are signaling a user process, then we must be operating * on the kernel stack now. We need to switch back to the user * stack before dispatching the signal handler to the user code. * The existence of an allocated kernel stack is sufficient @@ -422,6 +428,7 @@ uint32_t *arm_syscall(uint32_t *regs) #ifdef CONFIG_LIB_SYSCALL FAR struct tcb_s *rtcb = sched_self(); int index = rtcb->xcp.nsyscalls; + sigset_t set; /* Verify that the SYS call number is within range */ @@ -448,6 +455,11 @@ uint32_t *arm_syscall(uint32_t *regs) /* Offset R0 to account for the reserved values */ regs[REG_R0] -= CONFIG_SYS_RESERVED; + + /* Block all signals while the system call runs */ + + sigfillset(&set); + (void)nxsig_procmask(SIG_BLOCK, &set, &rtcb->sigoldmask); #else svcerr("ERROR: Bad SYS call: %d\n", regs[REG_R0]); #endif diff --git a/arch/mips/src/mips32/up_swint0.c b/arch/mips/src/mips32/up_swint0.c index 67b2278b69..6b96c9e330 100644 --- a/arch/mips/src/mips32/up_swint0.c +++ b/arch/mips/src/mips32/up_swint0.c @@ -1,7 +1,7 @@ /**************************************************************************** * arch/mips/src/mips32/up_swint0.c * - * Copyright (C) 2011-2012, 2015 Gregory Nutt. All rights reserved. + * Copyright (C) 2011-2012, 2015, 2019 Gregory Nutt. All rights reserved. * Author: Gregory Nutt * * Redistribution and use in source and binary forms, with or without @@ -46,6 +46,7 @@ #include #include +#include #include #include @@ -225,6 +226,11 @@ int up_swint0(int irq, FAR void *context, FAR void *arg) g_current_regs[REG_EPC] = rtcb->xcp.syscall[index].sysreturn; #error "Missing logic -- need to restore the original mode" rtcb->xcp.nsyscalls = index; + + /* Restore the signal mask when the syscall returns */ + + (void)nxsig_procmask(SIG_SETMASK, &rtcb->sigoldmask, NULL); + sigemptyset(rtcb->sigoldmask); } break; #endif @@ -239,6 +245,7 @@ int up_swint0(int irq, FAR void *context, FAR void *arg) #ifdef CONFIG_BUILD_KERNEL FAR struct tcb_s *rtcb = sched_self(); int index = rtcb->xcp.nsyscalls; + sigset_t set; /* Verify that the SYS call number is within range */ @@ -262,6 +269,11 @@ int up_swint0(int irq, FAR void *context, FAR void *arg) /* Offset R0 to account for the reserved values */ g_current_regs[REG_R0] -= CONFIG_SYS_RESERVED; + + /* Block all signals while the system call runs */ + + sigfillset(&set); + (void)nxsig_procmask(SIG_BLOCK, &set, &rtcb->sigoldmask); #else svcerr("ERROR: Bad SYS call: %d\n", regs[REG_A0]); #endif diff --git a/arch/misoc/src/lm32/lm32_swint.c b/arch/misoc/src/lm32/lm32_swint.c index 54e17dc150..31d289d940 100644 --- a/arch/misoc/src/lm32/lm32_swint.c +++ b/arch/misoc/src/lm32/lm32_swint.c @@ -1,7 +1,7 @@ /**************************************************************************** * arch/misoc/src/lm32/lm32_swint.c * - * Copyright (C) 2016 Gregory Nutt. All rights reserved. + * Copyright (C) 2016. 2019 Gregory Nutt. All rights reserved. * Author: Gregory Nutt * Ramtin Amin * @@ -47,6 +47,7 @@ #include #include +#include #include #include "lm32.h" @@ -226,6 +227,11 @@ int lm32_swint(int irq, FAR void *context, FAR void *arg) g_current_regs[REG_EPC] = rtcb->xcp.syscall[index].sysreturn; #error "Missing logic -- need to restore the original mode" rtcb->xcp.nsyscalls = index; + + /* Restore the signal mask when the syscall returns */ + + (void)nxsig_procmask(SIG_SETMASK, &rtcb->sigoldmask, NULL); + sigemptyset(rtcb->sigoldmask); } break; #endif @@ -240,6 +246,7 @@ int lm32_swint(int irq, FAR void *context, FAR void *arg) #ifdef CONFIG_BUILD_KERNEL FAR struct tcb_s *rtcb = sched_self(); int index = rtcb->xcp.nsyscalls; + sigset_t set; /* Verify that the SYS call number is within range */ @@ -263,6 +270,11 @@ int lm32_swint(int irq, FAR void *context, FAR void *arg) /* Offset R0 to account for the reserved values */ g_current_regs[REG_A0] -= CONFIG_SYS_RESERVED; + + /* Block all signals while the system call runs */ + + sigfillset(&set); + (void)nxsig_procmask(SIG_BLOCK, &set, &rtcb->sigoldmask); #else svcerr("ERROR: Bad SYS call: %d\n", regs[REG_A0]); #endif diff --git a/arch/misoc/src/minerva/minerva_swint.c b/arch/misoc/src/minerva/minerva_swint.c index 4404cbae60..ef0521f4eb 100644 --- a/arch/misoc/src/minerva/minerva_swint.c +++ b/arch/misoc/src/minerva/minerva_swint.c @@ -47,6 +47,7 @@ #include #include +#include #include #include "minerva.h" @@ -213,6 +214,11 @@ int minerva_swint(int irq, FAR void *context, FAR void *arg) g_current_regs[REG_CSR_MEPC] = rtcb->xcp.syscall[index].sysreturn; #error "Missing logic -- need to restore the original mode" rtcb->xcp.nsyscalls = index; + + /* Restore the signal mask when the syscall returns */ + + (void)nxsig_procmask(SIG_SETMASK, &rtcb->sigoldmask, NULL); + sigemptyset(rtcb->sigoldmask); } break; #endif @@ -227,6 +233,7 @@ int minerva_swint(int irq, FAR void *context, FAR void *arg) #ifdef CONFIG_BUILD_KERNEL FAR struct tcb_s *rtcb = sched_self(); int index = rtcb->xcp.nsyscalls; + sigset_t set; /* Verify that the SYS call number is within range */ @@ -251,6 +258,11 @@ int minerva_swint(int irq, FAR void *context, FAR void *arg) /* Offset R0 to account for the reserved values */ g_current_regs[REG_A0] -= CONFIG_SYS_RESERVED; + + /* Block all signals while the system call runs */ + + sigfillset(&set); + (void)nxsig_procmask(SIG_BLOCK, &set, &rtcb->sigoldmask); #else svcerr("ERROR: Bad SYS call: %d\n", regs[REG_A0]); #endif diff --git a/arch/risc-v/src/rv32im/up_swint.c b/arch/risc-v/src/rv32im/up_swint.c index e1b8dca8ad..76ee857dce 100644 --- a/arch/risc-v/src/rv32im/up_swint.c +++ b/arch/risc-v/src/rv32im/up_swint.c @@ -1,7 +1,7 @@ /**************************************************************************** * arch/riscv/src/rv32im/up_swint.c * - * Copyright (C) 2011-2012, 2015 Gregory Nutt. All rights reserved. + * Copyright (C) 2011-2012, 2015, 2019 Gregory Nutt. All rights reserved. * Author: Gregory Nutt * * Redistribution and use in source and binary forms, with or without @@ -46,6 +46,7 @@ #include #include +#include #include @@ -223,6 +224,11 @@ int up_swint(int irq, FAR void *context, FAR void *arg) g_current_regs[REG_EPC] = rtcb->xcp.syscall[index].sysreturn; #error "Missing logic -- need to restore the original mode" rtcb->xcp.nsyscalls = index; + + /* Restore the signal mask when the syscall returns */ + + (void)nxsig_procmask(SIG_SETMASK, &rtcb->sigoldmask, NULL); + sigemptyset(rtcb->sigoldmask); } break; #endif @@ -237,6 +243,7 @@ int up_swint(int irq, FAR void *context, FAR void *arg) #ifdef CONFIG_BUILD_KERNEL FAR struct tcb_s *rtcb = sched_self(); int index = rtcb->xcp.nsyscalls; + sigset_t set; /* Verify that the SYS call number is within range */ @@ -262,6 +269,11 @@ int up_swint(int irq, FAR void *context, FAR void *arg) g_current_regs[REG_A0] -= CONFIG_SYS_RESERVED; #else svcerr("ERROR: Bad SYS call: %d\n", regs[REG_A0]); + + /* Block all signals while the system call runs */ + + sigfillset(&set); + (void)nxsig_procmask(SIG_BLOCK, &set, &rtcb->sigoldmask); #endif } break; diff --git a/include/nuttx/sched.h b/include/nuttx/sched.h index 7ec687ac44..dd4dc83856 100644 --- a/include/nuttx/sched.h +++ b/include/nuttx/sched.h @@ -675,11 +675,14 @@ struct tcb_s /* POSIX Semaphore Control Fields *********************************************/ - sem_t *waitsem; /* Semaphore ID waiting on */ + FAR sem_t *waitsem; /* Semaphore ID waiting on */ /* POSIX Signal Control Fields ************************************************/ sigset_t sigprocmask; /* Signals that are blocked */ +#ifdef CONFIG_LIB_SYSCALL + sigset_t sigoldmask; /* Signals previously blocked */ +#endif sigset_t sigwaitmask; /* Waiting for pending signals */ sq_queue_t sigpendactionq; /* List of pending signal actions */ sq_queue_t sigpostedq; /* List of posted signals */ diff --git a/net/netlink/netlink_conn.c b/net/netlink/netlink_conn.c index 61030ea3e2..f974f5d833 100644 --- a/net/netlink/netlink_conn.c +++ b/net/netlink/netlink_conn.c @@ -127,8 +127,8 @@ static void netlink_notify_waiters(FAR struct netlink_conn_s *conn) int i; /* Notify every pending thread. Lock the scheduler while we do this so - * there there is no thrashing: All waiters will be restarted, but only - * the highest priority waiter will get to run and will receive the + * that there is no thrashing: All waiters will be restarted, but only + * the highest priority waiter will get to run and it will receive the * response. */