summaryrefslogtreecommitdiff
path: root/sys/dev/systrace.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/dev/systrace.c')
-rw-r--r--sys/dev/systrace.c139
1 files changed, 108 insertions, 31 deletions
diff --git a/sys/dev/systrace.c b/sys/dev/systrace.c
index 0d19bf5bb23..6af4929574f 100644
--- a/sys/dev/systrace.c
+++ b/sys/dev/systrace.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: systrace.c,v 1.35 2004/06/23 05:16:35 marius Exp $ */
+/* $OpenBSD: systrace.c,v 1.36 2004/07/07 07:31:40 marius Exp $ */
/*
* Copyright 2002 Niels Provos <provos@citi.umich.edu>
* All rights reserved.
@@ -118,6 +118,9 @@ struct str_process {
gid_t setegid;
gid_t savegid;
+ int isscript;
+ char scriptname[MAXPATHLEN];
+
struct str_message msg;
};
@@ -140,6 +143,8 @@ systrace_unlock(void)
int systrace_attach(struct fsystrace *, pid_t);
int systrace_detach(struct str_process *);
int systrace_answer(struct str_process *, struct systrace_answer *);
+int systrace_setscriptname(struct str_process *,
+ struct systrace_scriptname *);
int systrace_io(struct str_process *, struct systrace_io *);
int systrace_policy(struct fsystrace *, struct systrace_policy *);
int systrace_preprepl(struct str_process *, struct systrace_replace *);
@@ -283,6 +288,11 @@ systracef_ioctl(fp, cmd, data, p)
if (!pid)
ret = EINVAL;
break;
+ case STRIOCSCRIPTNAME:
+ pid = ((struct systrace_scriptname *)data)->sn_pid;
+ if (!pid)
+ ret = EINVAL;
+ break;
case STRIOCGETCWD:
pid = *(pid_t *)data;
if (!pid)
@@ -337,6 +347,10 @@ systracef_ioctl(fp, cmd, data, p)
case STRIOCIO:
ret = systrace_io(strp, (struct systrace_io *)data);
break;
+ case STRIOCSCRIPTNAME:
+ ret = systrace_setscriptname(strp,
+ (struct systrace_scriptname *)data);
+ break;
case STRIOCPOLICY:
ret = systrace_policy(fst, (struct systrace_policy *)data);
break;
@@ -959,6 +973,15 @@ systrace_answer(struct str_process *strp, struct systrace_answer *ans)
}
int
+systrace_setscriptname(struct str_process *strp, struct systrace_scriptname *ans)
+{
+ strlcpy(strp->scriptname,
+ ans->sn_scriptname, sizeof(strp->scriptname));
+
+ return (0);
+}
+
+int
systrace_policy(struct fsystrace *fst, struct systrace_policy *pol)
{
struct str_policy *strpol;
@@ -1192,37 +1215,49 @@ systrace_attach(struct fsystrace *fst, pid_t pid)
}
void
-systrace_execve(char *path, struct proc *p)
+systrace_execve0(struct proc *p)
+{
+ struct str_process *strp;
+
+ systrace_lock();
+ strp = p->p_systrace;
+ strp->isscript = 0;
+ systrace_unlock();
+}
+
+void
+systrace_execve1(char *path, struct proc *p)
{
- struct str_process *strp;
- struct fsystrace *fst;
- struct str_msg_execve *msg_execve;
-
- do {
- systrace_lock();
- strp = p->p_systrace;
- if (strp == NULL) {
- systrace_unlock();
- return;
- }
-
- msg_execve = &strp->msg.msg_data.msg_execve;
- fst = strp->parent;
- lockmgr(&fst->lock, LK_EXCLUSIVE, NULL, p);
- systrace_unlock();
-
- /*
- * susers will get the execve call anyway. Also, if
- * we're not allowed to control the process, escape.
- */
- if (fst->issuser ||
- fst->p_ruid != p->p_cred->p_ruid ||
- fst->p_rgid != p->p_cred->p_rgid) {
- lockmgr(&fst->lock, LK_RELEASE, NULL, p);
- return;
- }
- strlcpy(msg_execve->path, path, MAXPATHLEN);
- } while (systrace_make_msg(strp, SYSTR_MSG_EXECVE) != 0);
+ struct str_process *strp;
+ struct fsystrace *fst;
+ struct str_msg_execve *msg_execve;
+
+ do {
+ systrace_lock();
+ strp = p->p_systrace;
+ if (strp == NULL) {
+ systrace_unlock();
+ return;
+ }
+
+ msg_execve = &strp->msg.msg_data.msg_execve;
+ fst = strp->parent;
+ lockmgr(&fst->lock, LK_EXCLUSIVE, NULL, p);
+ systrace_unlock();
+
+ /*
+ * susers will get the execve call anyway. Also, if
+ * we're not allowed to control the process, escape.
+ */
+
+ if (fst->issuser ||
+ fst->p_ruid != p->p_cred->p_ruid ||
+ fst->p_rgid != p->p_cred->p_rgid) {
+ lockmgr(&fst->lock, LK_RELEASE, NULL, p);
+ return;
+ }
+ strlcpy(msg_execve->path, path, MAXPATHLEN);
+ } while (systrace_make_msg(strp, SYSTR_MSG_EXECVE) != 0);
}
/* Prepare to replace arguments */
@@ -1352,6 +1387,44 @@ systrace_replacefree(struct str_process *strp)
strp->fname[strp->nfname] = NULL;
}
}
+int
+systrace_scriptname(struct proc *p, char *dst)
+{
+ struct str_process *strp;
+ struct fsystrace *fst;
+ int error = 0;
+
+ systrace_lock();
+ strp = p->p_systrace;
+ fst = strp->parent;
+
+ lockmgr(&fst->lock, LK_EXCLUSIVE, NULL, p);
+ systrace_unlock();
+
+ if (!fst->issuser && (ISSET(p->p_flag, P_SUGID) ||
+ ISSET(p->p_flag, P_SUGIDEXEC) ||
+ fst->p_ruid != p->p_cred->p_ruid ||
+ fst->p_rgid != p->p_cred->p_rgid)) {
+ error = EPERM;
+ goto out;
+ }
+
+ if (strp != NULL) {
+ if (strp->scriptname[0] == '\0') {
+ error = ENOENT;
+ goto out;
+ }
+
+ strlcpy(dst, strp->scriptname, MAXPATHLEN);
+ strp->isscript = 1;
+ }
+
+ out:
+ strp->scriptname[0] = '\0';
+ lockmgr(&fst->lock, LK_RELEASE, NULL, p);
+
+ return (error);
+}
void
systrace_namei(struct nameidata *ndp)
@@ -1375,6 +1448,10 @@ systrace_namei(struct nameidata *ndp)
break;
}
+ if (!hamper && strp->isscript &&
+ strcmp(cnp->cn_pnbuf, strp->scriptname) == 0)
+ hamper = 1;
+
lockmgr(&fst->lock, LK_RELEASE, NULL, curproc);
} else
systrace_unlock();