diff options
author | kib <kib@FreeBSD.org> | 2015-05-10 09:00:40 +0000 |
---|---|---|
committer | kib <kib@FreeBSD.org> | 2015-05-10 09:00:40 +0000 |
commit | f3713229833ccaa3860b3ed139ae4c79f529646e (patch) | |
tree | 064d76e5d8ad1ce92f3fa8db469f737a43503979 /sys/compat/svr4 | |
parent | 00145bc0e070efc612952cdad12ecdb18cd7629a (diff) | |
download | FreeBSD-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/compat/svr4')
-rw-r--r-- | sys/compat/svr4/svr4_misc.c | 14 |
1 files changed, 14 insertions, 0 deletions
diff --git a/sys/compat/svr4/svr4_misc.c b/sys/compat/svr4/svr4_misc.c index cef1b48..c0da170 100644 --- a/sys/compat/svr4/svr4_misc.c +++ b/sys/compat/svr4/svr4_misc.c @@ -167,15 +167,22 @@ svr4_sys_execv(td, uap) struct svr4_sys_execv_args *uap; { struct image_args eargs; + struct vmspace *oldvmspace; char *path; int error; CHECKALTEXIST(td, uap->path, &path); + error = pre_execve(td, &oldvmspace); + if (error != 0) { + free(path, M_TEMP); + return (error); + } error = exec_copyin_args(&eargs, path, UIO_SYSSPACE, uap->argp, NULL); free(path, M_TEMP); if (error == 0) error = kern_execve(td, &eargs, NULL); + post_execve(td, error, oldvmspace); return (error); } @@ -185,16 +192,23 @@ svr4_sys_execve(td, uap) struct svr4_sys_execve_args *uap; { struct image_args eargs; + struct vmspace *oldvmspace; char *path; int error; CHECKALTEXIST(td, uap->path, &path); + error = pre_execve(td, &oldvmspace); + if (error != 0) { + free(path, M_TEMP); + return (error); + } error = exec_copyin_args(&eargs, path, UIO_SYSSPACE, uap->argp, uap->envp); free(path, M_TEMP); if (error == 0) error = kern_execve(td, &eargs, NULL); + post_execve(td, error, oldvmspace); return (error); } |