summaryrefslogtreecommitdiffstats
path: root/sys/kern/uipc_sem.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/kern/uipc_sem.c')
-rw-r--r--sys/kern/uipc_sem.c65
1 files changed, 56 insertions, 9 deletions
diff --git a/sys/kern/uipc_sem.c b/sys/kern/uipc_sem.c
index ea5dedc..394b6cb 100644
--- a/sys/kern/uipc_sem.c
+++ b/sys/kern/uipc_sem.c
@@ -1,8 +1,14 @@
/*-
* Copyright (c) 2002 Alfred Perlstein <alfred@FreeBSD.org>
+ * Copyright (c) 2003-2005 SPARTA, Inc.
* Copyright (c) 2005 Robert N. M. Watson
* All rights reserved.
*
+ * This software was developed for the FreeBSD Project in part by Network
+ * Associates Laboratories, the Security Research Division of Network
+ * Associates, Inc. under DARPA/SPAWAR contract N66001-01-C-8035 ("CBOSS"),
+ * as part of the DARPA CHATS research program.
+ *
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
@@ -28,6 +34,7 @@
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
+#include "opt_mac.h"
#include "opt_posix.h"
#include <sys/param.h>
@@ -47,6 +54,7 @@ __FBSDID("$FreeBSD$");
#include <sys/sysent.h>
#include <sys/sysctl.h>
#include <sys/time.h>
+#include <sys/mac.h>
#include <sys/malloc.h>
#include <sys/fcntl.h>
@@ -210,6 +218,10 @@ sem_create(td, name, ksret, mode, value)
ret->ks_onlist = 0;
cv_init(&ret->ks_cv, "sem");
LIST_INIT(&ret->ks_users);
+#ifdef MAC
+ mac_init_posix_sem(ret);
+ mac_create_posix_sem(uc, ret);
+#endif
if (name != NULL)
sem_enter(td->td_proc, ret);
*ksret = ret;
@@ -385,17 +397,20 @@ kern_sem_open(td, dir, name, oflag, mode, value, idp)
ksnew->ks_onlist = 1;
DP(("sem_create: done, about to unlock...\n"));
}
- mtx_unlock(&sem_lock);
} else {
+#ifdef MAC
+ error = mac_check_posix_sem_open(td->td_ucred, ks);
+ if (error)
+ goto err_open;
+#endif
/*
* if we aren't the creator, then enforce permissions.
*/
error = sem_perm(td, ks);
- if (!error)
- sem_ref(ks);
- mtx_unlock(&sem_lock);
if (error)
- return (error);
+ goto err_open;
+ sem_ref(ks);
+ mtx_unlock(&sem_lock);
id = SEM_TO_ID(ks);
if (dir == UIO_USERSPACE) {
error = copyout(&id, idp, sizeof(id));
@@ -411,8 +426,9 @@ kern_sem_open(td, dir, name, oflag, mode, value, idp)
sem_enter(td->td_proc, ks);
mtx_lock(&sem_lock);
sem_rel(ks);
- mtx_unlock(&sem_lock);
}
+err_open:
+ mtx_unlock(&sem_lock);
return (error);
}
@@ -545,10 +561,17 @@ kern_sem_unlink(td, name)
mtx_lock(&sem_lock);
ks = sem_lookup_byname(name);
- if (ks == NULL)
- error = ENOENT;
- else
+ if (ks != NULL) {
+#ifdef MAC
+ error = mac_check_posix_sem_unlink(td->td_ucred, ks);
+ if (error) {
+ mtx_unlock(&sem_lock);
+ return (error);
+ }
+#endif
error = sem_perm(td, ks);
+ } else
+ error = ENOENT;
DP(("sem_unlink: '%s' ks = %p, error = %d\n", name, ks, error));
if (error == 0) {
LIST_REMOVE(ks, ks_entry);
@@ -620,6 +643,11 @@ kern_sem_post(td, id)
error = EINVAL;
goto err;
}
+#ifdef MAC
+ error = mac_check_posix_sem_post(td->td_ucred, ks);
+ if (error)
+ goto err;
+#endif
if (ks->ks_value == SEM_VALUE_MAX) {
error = EOVERFLOW;
goto err;
@@ -720,6 +748,13 @@ kern_sem_wait(td, id, tryflag, abstime)
error = EINVAL;
goto err;
}
+#ifdef MAC
+ error = mac_check_posix_sem_wait(td->td_ucred, ks);
+ if (error) {
+ DP(("kern_sem_wait mac failed\n"));
+ goto err;
+ }
+#endif
DP(("kern_sem_wait value = %d, tryflag %d\n", ks->ks_value, tryflag));
if (ks->ks_value == 0) {
ks->ks_waiters++;
@@ -778,6 +813,13 @@ ksem_getvalue(td, uap)
mtx_unlock(&sem_lock);
return (EINVAL);
}
+#ifdef MAC
+ error = mac_check_posix_sem_getvalue(td->td_ucred, ks);
+ if (error) {
+ mtx_unlock(&sem_lock);
+ return (error);
+ }
+#endif
val = ks->ks_value;
mtx_unlock(&sem_lock);
error = copyout(&val, uap->val, sizeof(val));
@@ -805,6 +847,11 @@ ksem_destroy(td, uap)
error = EINVAL;
goto err;
}
+#ifdef MAC
+ error = mac_check_posix_sem_destroy(td->td_ucred, ks);
+ if (error)
+ goto err;
+#endif
if (ks->ks_waiters != 0) {
error = EBUSY;
goto err;
OpenPOWER on IntegriCloud