summaryrefslogtreecommitdiffstats
path: root/sys/compat/svr4
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/compat/svr4
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/compat/svr4')
-rw-r--r--sys/compat/svr4/svr4_misc.c14
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);
}
OpenPOWER on IntegriCloud