Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F148143407
D30675.id90885.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
9 KB
Referenced Files
None
Subscribers
None
D30675.id90885.diff
View Options
diff --git a/sys/amd64/linux/linux_sysvec.c b/sys/amd64/linux/linux_sysvec.c
--- a/sys/amd64/linux/linux_sysvec.c
+++ b/sys/amd64/linux/linux_sysvec.c
@@ -752,7 +752,8 @@
.sv_setregs = linux_exec_setregs,
.sv_fixlimit = NULL,
.sv_maxssiz = NULL,
- .sv_flags = SV_ABI_LINUX | SV_LP64 | SV_SHP,
+ .sv_flags = SV_ABI_LINUX | SV_LP64 | SV_SHP | SV_SIG_DISCIGN |
+ SV_SIG_WAITNDQ,
.sv_set_syscall_retval = linux_set_syscall_retval,
.sv_fetch_syscall_args = linux_fetch_syscall_args,
.sv_syscallnames = NULL,
diff --git a/sys/amd64/linux32/linux32_sysvec.c b/sys/amd64/linux32/linux32_sysvec.c
--- a/sys/amd64/linux32/linux32_sysvec.c
+++ b/sys/amd64/linux32/linux32_sysvec.c
@@ -919,7 +919,8 @@
.sv_setregs = linux_exec_setregs,
.sv_fixlimit = linux32_fixlimit,
.sv_maxssiz = &linux32_maxssiz,
- .sv_flags = SV_ABI_LINUX | SV_ILP32 | SV_IA32 | SV_SHP,
+ .sv_flags = SV_ABI_LINUX | SV_ILP32 | SV_IA32 | SV_SHP |
+ SV_SIG_DISCIGN | SV_SIG_WAITNDQ,
.sv_set_syscall_retval = linux32_set_syscall_retval,
.sv_fetch_syscall_args = linux32_fetch_syscall_args,
.sv_syscallnames = NULL,
diff --git a/sys/arm64/linux/linux_sysvec.c b/sys/arm64/linux/linux_sysvec.c
--- a/sys/arm64/linux/linux_sysvec.c
+++ b/sys/arm64/linux/linux_sysvec.c
@@ -429,7 +429,8 @@
.sv_setregs = linux_exec_setregs,
.sv_fixlimit = NULL,
.sv_maxssiz = NULL,
- .sv_flags = SV_ABI_LINUX | SV_LP64 | SV_SHP,
+ .sv_flags = SV_ABI_LINUX | SV_LP64 | SV_SHP | SV_SIG_DISCIGN |
+ SV_SIG_WAITNDQ,
.sv_set_syscall_retval = linux_set_syscall_retval,
.sv_fetch_syscall_args = linux_fetch_syscall_args,
.sv_syscallnames = NULL,
diff --git a/sys/i386/linux/linux_sysvec.c b/sys/i386/linux/linux_sysvec.c
--- a/sys/i386/linux/linux_sysvec.c
+++ b/sys/i386/linux/linux_sysvec.c
@@ -859,7 +859,8 @@
.sv_setregs = linux_exec_setregs,
.sv_fixlimit = NULL,
.sv_maxssiz = NULL,
- .sv_flags = SV_ABI_LINUX | SV_AOUT | SV_IA32 | SV_ILP32,
+ .sv_flags = SV_ABI_LINUX | SV_AOUT | SV_IA32 | SV_ILP32 |
+ SV_SIG_IGNIGN | SV_SIG_WAITNDQ,
.sv_set_syscall_retval = linux_set_syscall_retval,
.sv_fetch_syscall_args = linux_fetch_syscall_args,
.sv_syscallnames = NULL,
@@ -897,7 +898,8 @@
.sv_setregs = linux_exec_setregs,
.sv_fixlimit = NULL,
.sv_maxssiz = NULL,
- .sv_flags = SV_ABI_LINUX | SV_IA32 | SV_ILP32 | SV_SHP,
+ .sv_flags = SV_ABI_LINUX | SV_IA32 | SV_ILP32 | SV_SHP |
+ SV_SIG_DISCIGN | SV_SIG_WAITNDQ,
.sv_set_syscall_retval = linux_set_syscall_retval,
.sv_fetch_syscall_args = linux_fetch_syscall_args,
.sv_syscallnames = NULL,
diff --git a/sys/kern/kern_exit.c b/sys/kern/kern_exit.c
--- a/sys/kern/kern_exit.c
+++ b/sys/kern/kern_exit.c
@@ -105,6 +105,11 @@
&kern_kill_on_dbg_exit, 0,
"Kill ptraced processes when debugger exits");
+static bool kern_wait_dequeue_sigchld = 1;
+SYSCTL_BOOL(_kern, OID_AUTO, wait_dequeue_sigchld, CTLFLAG_RWTUN,
+ &kern_wait_dequeue_sigchld, 0,
+ "Dequeue SIGCHLD on wait(2) for live process");
+
struct proc *
proc_realparent(struct proc *child)
{
@@ -1207,9 +1212,12 @@
p->p_flag &= ~P_CONTINUED;
else
p->p_flag |= P_WAITED;
- PROC_LOCK(td->td_proc);
- sigqueue_take(p->p_ksi);
- PROC_UNLOCK(td->td_proc);
+ if (kern_wait_dequeue_sigchld &&
+ (td->td_proc->p_sysent->sv_flags & SV_SIG_WAITNDQ) == 0) {
+ PROC_LOCK(td->td_proc);
+ sigqueue_take(p->p_ksi);
+ PROC_UNLOCK(td->td_proc);
+ }
}
sx_xunlock(&proctree_lock);
if (siginfo != NULL) {
diff --git a/sys/kern/kern_sig.c b/sys/kern/kern_sig.c
--- a/sys/kern/kern_sig.c
+++ b/sys/kern/kern_sig.c
@@ -163,6 +163,12 @@
"Fetch sigfastblock word on each syscall entry for proper "
"blocking semantic");
+static bool kern_sig_discard_ign = true;
+SYSCTL_BOOL(_kern, OID_AUTO, sig_discard_ign, CTLFLAG_RWTUN,
+ &kern_sig_discard_ign, 0,
+ "Discard ignored signals on delivery, otherwise queue them to "
+ "the target queue");
+
SYSINIT(signal, SI_SUB_P1003_1B, SI_ORDER_FIRST+3, sigqueue_start, NULL);
/*
@@ -1167,10 +1173,15 @@
error = kern_sigtimedwait(td, set, &ksi, NULL);
if (error) {
+ /*
+ * sigwait() function shall not return EINTR, but
+ * the syscall does. Non-ancient libc provides the
+ * wrapper which hides EINTR. Otherwise, EINTR return
+ * is used by libthr to handle required cancellation
+ * point in the sigwait().
+ */
if (error == EINTR && td->td_proc->p_osrel < P_OSREL_SIGWAIT)
- error = ERESTART;
- if (error == ERESTART)
- return (error);
+ return (ERESTART);
td->td_retval[0] = error;
return (0);
}
@@ -1285,6 +1296,9 @@
PROC_LOCK(p);
saved_mask = td->td_sigmask;
SIGSETNAND(td->td_sigmask, waitset);
+ if ((p->p_sysent->sv_flags & SV_SIG_DISCIGN) != 0 ||
+ !kern_sig_discard_ign)
+ td->td_pflags2 |= TDP2_SIGWAIT;
for (;;) {
mtx_lock(&ps->ps_mtx);
sig = cursig(td);
@@ -1329,15 +1343,13 @@
error = msleep(ps, &p->p_mtx, PPAUSE|PCATCH, "sigwait", timo);
- if (timeout != NULL) {
- if (error == ERESTART) {
- /* Timeout can not be restarted. */
- error = EINTR;
- } else if (error == EAGAIN) {
- /* We will calculate timeout by ourself. */
- error = 0;
- }
- }
+ /* The syscalls can not be restarted. */
+ if (error == ERESTART)
+ error = EINTR;
+
+ /* We will calculate timeout by ourself. */
+ if (timeout != NULL && error == EAGAIN)
+ error = 0;
/*
* If PTRACE_SCE or PTRACE_SCX were set after
@@ -1349,6 +1361,7 @@
if (error == 0 && (p->p_ptevents & PTRACE_SYSCALL) != 0)
traced = true;
}
+ td->td_pflags2 &= ~TDP2_SIGWAIT;
new_block = saved_mask;
SIGSETNAND(new_block, td->td_sigmask);
@@ -2197,22 +2210,25 @@
SDT_PROBE3(proc, , , signal__send, td, p, sig);
/*
- * If the signal is being ignored,
- * then we forget about it immediately.
- * (Note: we don't set SIGCONT in ps_sigignore,
- * and if it is set to SIG_IGN,
- * action will be SIG_DFL here.)
+ * If the signal is being ignored, then we forget about it
+ * immediately, except when the target process executes
+ * sigwait(). (Note: we don't set SIGCONT in ps_sigignore,
+ * and if it is set to SIG_IGN, action will be SIG_DFL here.)
*/
mtx_lock(&ps->ps_mtx);
if (SIGISMEMBER(ps->ps_sigignore, sig)) {
- SDT_PROBE3(proc, , , signal__discard, td, p, sig);
+ if (kern_sig_discard_ign &&
+ (p->p_sysent->sv_flags & SV_SIG_DISCIGN) == 0) {
+ SDT_PROBE3(proc, , , signal__discard, td, p, sig);
- mtx_unlock(&ps->ps_mtx);
- if (ksi && (ksi->ksi_flags & KSI_INS))
- ksiginfo_tryfree(ksi);
- return (ret);
- }
- if (SIGISMEMBER(td->td_sigmask, sig))
+ mtx_unlock(&ps->ps_mtx);
+ if (ksi && (ksi->ksi_flags & KSI_INS))
+ ksiginfo_tryfree(ksi);
+ return (ret);
+ } else {
+ action = SIG_CATCH;
+ }
+ } else if (SIGISMEMBER(td->td_sigmask, sig))
action = SIG_HOLD;
else if (SIGISMEMBER(ps->ps_sigcatch, sig))
action = SIG_CATCH;
@@ -2947,11 +2963,13 @@
}
/*
- * We should see pending but ignored signals
- * only if P_TRACED was on when they were posted.
+ * We should allow pending but ignored signals below
+ * only if there is sigwait() active, or P_TRACED was
+ * on when they were posted.
*/
if (SIGISMEMBER(ps->ps_sigignore, sig) &&
- (p->p_flag & P_TRACED) == 0) {
+ (p->p_flag & P_TRACED) == 0 &&
+ (td->td_pflags2 & TDP2_SIGWAIT) == 0) {
sigqueue_delete(&td->td_sigqueue, sig);
sigqueue_delete(&p->p_sigqueue, sig);
continue;
@@ -3063,10 +3081,11 @@
PROC_SUNLOCK(p);
mtx_lock(&ps->ps_mtx);
goto next;
- } else if (prop & SIGPROP_IGNORE) {
+ } else if ((prop & SIGPROP_IGNORE) != 0 &&
+ (td->td_pflags2 & TDP2_SIGWAIT) == 0) {
/*
- * Except for SIGCONT, shouldn't get here.
- * Default action is to ignore; drop it.
+ * Default action is to ignore; drop it if
+ * not in kern_sigtimedwait().
*/
break; /* == ignore */
} else
@@ -3074,15 +3093,10 @@
/*NOTREACHED*/
case (intptr_t)SIG_IGN:
- /*
- * Masking above should prevent us ever trying
- * to take action on an ignored signal other
- * than SIGCONT, unless process is traced.
- */
- if ((prop & SIGPROP_CONT) == 0 &&
- (p->p_flag & P_TRACED) == 0)
- printf("issignal\n");
- break; /* == ignore */
+ if ((td->td_pflags2 & TDP2_SIGWAIT) == 0)
+ break; /* == ignore */
+ else
+ return (sig);
default:
/*
diff --git a/sys/sys/proc.h b/sys/sys/proc.h
--- a/sys/sys/proc.h
+++ b/sys/sys/proc.h
@@ -529,6 +529,7 @@
#define TDP2_SBPAGES 0x00000001 /* Owns sbusy on some pages */
#define TDP2_COMPAT32RB 0x00000002 /* compat32 ABI for robust lists */
#define TDP2_ACCT 0x00000004 /* Doing accounting */
+#define TDP2_SIGWAIT 0x00000008 /* Ignore ignored signals */
/*
* Reasons that the current thread can not be run yet.
diff --git a/sys/sys/sysent.h b/sys/sys/sysent.h
--- a/sys/sys/sysent.h
+++ b/sys/sys/sysent.h
@@ -161,6 +161,8 @@
#define SV_TIMEKEEP 0x040000 /* Shared page timehands. */
#define SV_ASLR 0x080000 /* ASLR allowed. */
#define SV_RNG_SEED_VER 0x100000 /* random(4) reseed generation. */
+#define SV_SIG_DISCIGN 0x200000 /* Do not discard ignored signals */
+#define SV_SIG_WAITNDQ 0x400000 /* Wait does not dequeue SIGCHLD */
#define SV_ABI_MASK 0xff
#define SV_PROC_FLAG(p, x) ((p)->p_sysent->sv_flags & (x))
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Tue, Mar 17, 1:23 AM (17 h, 48 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
29800451
Default Alt Text
D30675.id90885.diff (9 KB)
Attached To
Mode
D30675: Fix two issues with Linuxolator signals
Attached
Detach File
Event Timeline
Log In to Comment