Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F159771711
D57482.id179333.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
6 KB
Referenced Files
None
Subscribers
None
D57482.id179333.diff
View Options
diff --git a/sys/compat/linux/linux_fork.c b/sys/compat/linux/linux_fork.c
--- a/sys/compat/linux/linux_fork.c
+++ b/sys/compat/linux/linux_fork.c
@@ -486,8 +486,8 @@
* exit via pthread_exit() try thr_exit() first.
*/
kern_thr_exit(td);
- exit1(td, args->rval, 0);
- /* NOTREACHED */
+ kern_exit(td, args->rval, 0);
+ return (0);
}
int
diff --git a/sys/compat/linux/linux_misc.c b/sys/compat/linux/linux_misc.c
--- a/sys/compat/linux/linux_misc.c
+++ b/sys/compat/linux/linux_misc.c
@@ -1545,8 +1545,8 @@
* SIGNAL_EXIT_GROUP is set. We ignore that (temporarily?)
* as it doesnt occur often.
*/
- exit1(td, args->error_code, 0);
- /* NOTREACHED */
+ kern_exit(td, args->error_code, 0);
+ return (0);
}
#define _LINUX_CAPABILITY_VERSION_1 0x19980330
diff --git a/sys/kern/kern_exec.c b/sys/kern/kern_exec.c
--- a/sys/kern/kern_exec.c
+++ b/sys/kern/kern_exec.c
@@ -341,11 +341,11 @@
}
/*
- * kern_execve() has the astonishing property of not always returning to
- * the caller. If sufficiently bad things happen during the call to
- * do_execve(), it can end up calling exit1(); as a result, callers must
- * avoid doing anything which they might need to undo (e.g., allocating
- * memory).
+ * kern_execve() has the astonishing property of not always returning
+ * to the caller. If sufficiently bad things happen during the call
+ * to do_execve(), it can end up calling exit2(). Callers must avoid
+ * doing anything which they might need to undo (e.g., allocating
+ * memory), unless called from the ptrace(PT_SC_REMOTERQ) handler.
*/
int
kern_execve(struct thread *td, struct image_args *args, struct mac *mac_p,
@@ -1042,7 +1042,7 @@
if (error && imgp->vmspace_destroyed) {
/* sorry, no more process anymore. exit gracefully */
exec_cleanup(td, oldvmspace);
- exit1(td, 0, SIGABRT);
+ kern_exit(td, 0, SIGABRT);
/* NOT REACHED */
}
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
@@ -204,9 +204,8 @@
int
sys__exit(struct thread *td, struct _exit_args *uap)
{
-
- exit1(td, uap->rval, 0);
- __unreachable();
+ kern_exit(td, uap->rval, 0);
+ return (0);
}
void
@@ -216,6 +215,47 @@
p->p_flag2 |= P2_WEXIT;
}
+static void
+ast_async_exit(struct thread *td, int asts)
+{
+ struct proc *p;
+
+ p = td->td_proc;
+ if ((p->p_flag & P_ASYNC_EXIT) != 0)
+ exit1(td, p->p_xexit, p->p_asig);
+}
+
+/*
+ * The variation on exit1() intended to be used in the syscall
+ * handlers. Unlike exit1(), it might delay the current process exit
+ * to ast. This is needed e.g. when _exit(2) is executed due to the
+ * ptrace(PT_SC_REMOTERQ), which must do more work after the syscall
+ * handler call.
+ */
+void
+kern_exit(struct thread *td, int rval, int signo)
+{
+ struct proc *p;
+
+ KASSERT(rval == 0 || signo == 0, ("exit2 rv %d sig %d", rval, signo));
+
+ p = td->td_proc;
+ if ((td->td_dbgflags & TDB_SCREMOTEREQ) != 0) {
+ PROC_LOCK(p);
+ p->p_xexit = rval;
+ p->p_asig = signo;
+ p->p_flag |= P_ASYNC_EXIT;
+ ast_sched(td, TDA_ASYNC_EXIT);
+ PROC_UNLOCK(p);
+ return;
+ }
+ if ((p->p_flag & P_ASYNC_EXIT) != 0) {
+ rval = p->p_xexit;
+ signo = p->p_asig;
+ }
+ exit1(td, rval, signo);
+}
+
/*
* Exit: deallocate address space and other resources, change proc state to
* zombie, and unlink proc from allproc and parent's lists. Save exit status
@@ -231,6 +271,7 @@
mtx_assert(&Giant, MA_NOTOWNED);
KASSERT(rval == 0 || signo == 0, ("exit1 rv %d sig %d", rval, signo));
+ MPASS((td->td_dbgflags & TDB_SCREMOTEREQ) == 0);
TSPROCEXIT(td->td_proc->p_pid);
p = td->td_proc;
@@ -828,7 +869,7 @@
sbuf_delete(sb);
PROC_LOCK(p);
sigexit(td, sig);
- /* NOTREACHED */
+ return (0);
}
#ifdef COMPAT_43
@@ -1627,3 +1668,10 @@
if (set_oppid)
child->p_oppid = parent->p_pid;
}
+
+static void
+initexit(void *dummy __unused)
+{
+ ast_register(TDA_ASYNC_EXIT, ASTR_ASTF_REQUIRED, 0, ast_async_exit);
+}
+SYSINIT(exit, SI_SUB_EXEC, SI_ORDER_ANY, initexit, NULL);
diff --git a/sys/kern/kern_ucoredump.c b/sys/kern/kern_ucoredump.c
--- a/sys/kern/kern_ucoredump.c
+++ b/sys/kern/kern_ucoredump.c
@@ -46,6 +46,7 @@
#include <sys/racct.h>
#include <sys/resourcevar.h>
#include <sys/rmlock.h>
+#include <sys/syscallsubr.h>
#include <sys/sysctl.h>
#include <sys/syslog.h>
#include <sys/ucoredump.h>
@@ -197,8 +198,7 @@
err != NULL ? err : "");
} else
PROC_UNLOCK(p);
- exit1(td, 0, sig);
- /* NOTREACHED */
+ kern_exit(td, 0, sig);
}
diff --git a/sys/sys/proc.h b/sys/sys/proc.h
--- a/sys/sys/proc.h
+++ b/sys/sys/proc.h
@@ -504,6 +504,7 @@
TDA_MOD3, /* .. and after */
TDA_MOD4,
TDA_SCHED_PRIV,
+ TDA_ASYNC_EXIT,
TDA_MAX,
};
#define TDAI(tda) (1U << (tda))
@@ -777,6 +778,7 @@
TAILQ_HEAD(, kq_timer_cb_data) p_kqtim_stop; /* (c) */
LIST_ENTRY(proc) p_jaillist; /* (d) Jail process linkage. */
+ u_int p_asig; /* (c) ASYNCEXIT pending signal. */
};
#define p_session p_pgrp->pg_session
@@ -842,7 +844,7 @@
#define P_INEXEC 0x04000000 /* Process is in execve(). */
#define P_STATCHILD 0x08000000 /* Child process stopped or exited. */
#define P_INMEM 0x10000000 /* Loaded into memory, always set. */
-#define P_UNUSED1 0x20000000 /* --available-- */
+#define P_ASYNC_EXIT 0x20000000 /* XXX */
#define P_UNUSED2 0x40000000 /* --available-- */
#define P_PPTRACE 0x80000000 /* PT_TRACEME by vforked child. */
diff --git a/sys/sys/signalvar.h b/sys/sys/signalvar.h
--- a/sys/sys/signalvar.h
+++ b/sys/sys/signalvar.h
@@ -399,7 +399,7 @@
int sig_ast_checksusp(struct thread *td);
int sig_ast_needsigchk(struct thread *td);
void sig_drop_caught(struct proc *p);
-void sigexit(struct thread *td, int sig) __dead2;
+void sigexit(struct thread *td, int sig);
int sigev_findtd(struct proc *p, struct sigevent *sigev, struct thread **);
void sigfastblock_clear(struct thread *td);
void sigfastblock_fetch(struct thread *td);
diff --git a/sys/sys/syscallsubr.h b/sys/sys/syscallsubr.h
--- a/sys/sys/syscallsubr.h
+++ b/sys/sys/syscallsubr.h
@@ -136,6 +136,7 @@
int kern_dup(struct thread *td, u_int mode, int flags, int old, int new);
int kern_execve(struct thread *td, struct image_args *args,
struct mac *mac_p, struct vmspace *oldvmspace);
+void kern_exit(struct thread *, int, int);
int kern_extattr_delete_fd(struct thread *td, int fd, int attrnamespace,
const char *attrname);
int kern_extattr_delete_path(struct thread *td, const char *path,
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Fri, Jun 19, 1:26 AM (12 h, 45 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
34064208
Default Alt Text
D57482.id179333.diff (6 KB)
Attached To
Mode
D57482: exit1(9): do not deadlock if exit is called due to PT_SC_REMOTERQ
Attached
Detach File
Event Timeline
Log In to Comment