summaryrefslogtreecommitdiffstats
path: root/sys/amd64/linux32/linux32_machdep.c
diff options
context:
space:
mode:
authorkib <kib@FreeBSD.org>2015-05-10 09:00:40 +0000
committerkib <kib@FreeBSD.org>2015-05-10 09:00:40 +0000
commitf3713229833ccaa3860b3ed139ae4c79f529646e (patch)
tree064d76e5d8ad1ce92f3fa8db469f737a43503979 /sys/amd64/linux32/linux32_machdep.c
parent00145bc0e070efc612952cdad12ecdb18cd7629a (diff)
downloadFreeBSD-src-f3713229833ccaa3860b3ed139ae4c79f529646e.zip
FreeBSD-src-f3713229833ccaa3860b3ed139ae4c79f529646e.tar.gz
On exec, single-threading must be enforced before arguments space is
allocated from exec_map. If many threads try to perform execve(2) in parallel, the exec map is exhausted and some threads sleep uninterruptible waiting for the map space. Then, the thread which won the race for the space allocation, cannot single-thread the process, causing deadlock. Reported and tested by: pho (previous version) Sponsored by: The FreeBSD Foundation MFC after: 2 weeks
Diffstat (limited to 'sys/amd64/linux32/linux32_machdep.c')
-rw-r--r--sys/amd64/linux32/linux32_machdep.c10
1 files changed, 9 insertions, 1 deletions
diff --git a/sys/amd64/linux32/linux32_machdep.c b/sys/amd64/linux32/linux32_machdep.c
index 2b955d0..155e90b 100644
--- a/sys/amd64/linux32/linux32_machdep.c
+++ b/sys/amd64/linux32/linux32_machdep.c
@@ -137,6 +137,7 @@ int
linux_execve(struct thread *td, struct linux_execve_args *args)
{
struct image_args eargs;
+ struct vmspace *oldvmspace;
char *path;
int error;
@@ -147,12 +148,17 @@ linux_execve(struct thread *td, struct linux_execve_args *args)
printf(ARGS(execve, "%s"), path);
#endif
+ error = pre_execve(td, &oldvmspace);
+ if (error != 0) {
+ free(path, M_TEMP);
+ return (error);
+ }
error = freebsd32_exec_copyin_args(&eargs, path, UIO_SYSSPACE,
args->argp, args->envp);
free(path, M_TEMP);
if (error == 0)
error = kern_execve(td, &eargs, NULL);
- if (error == 0)
+ if (error == 0) {
/* Linux process can execute FreeBSD one, do not attempt
* to create emuldata for such process using
* linux_proc_init, this leads to a panic on KASSERT
@@ -160,6 +166,8 @@ linux_execve(struct thread *td, struct linux_execve_args *args)
*/
if (SV_PROC_ABI(td->td_proc) == SV_ABI_LINUX)
error = linux_proc_init(td, 0, 0);
+ }
+ post_execve(td, error, oldvmspace);
return (error);
}
OpenPOWER on IntegriCloud