allow the kernel to free policies for users; kernel informs userland

which policy has been freed;  replacement is LRU
This commit is contained in:
provos 2003-06-03 05:24:00 +00:00
parent 5c0f142820
commit f858b1eac4
2 changed files with 53 additions and 12 deletions

View File

@ -1,4 +1,4 @@
/* $NetBSD: kern_systrace.c,v 1.27 2003/04/20 20:30:34 provos Exp $ */
/* $NetBSD: kern_systrace.c,v 1.28 2003/06/03 05:24:01 provos Exp $ */
/*
* Copyright 2002, 2003 Niels Provos <provos@citi.umich.edu>
@ -31,7 +31,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: kern_systrace.c,v 1.27 2003/04/20 20:30:34 provos Exp $");
__KERNEL_RCSID(0, "$NetBSD: kern_systrace.c,v 1.28 2003/06/03 05:24:01 provos Exp $");
#include "opt_systrace.h"
@ -164,6 +164,7 @@ int systrace_insert_process(struct fsystrace *, struct proc *,
struct str_process **);
struct str_policy *systrace_newpolicy(struct fsystrace *, int);
int systrace_msg_child(struct fsystrace *, struct str_process *, pid_t);
int systrace_msg_policyfree(struct fsystrace *, struct str_policy *);
int systrace_msg_ask(struct fsystrace *, struct str_process *,
int, size_t, register_t []);
int systrace_msg_result(struct fsystrace *, struct str_process *,
@ -1452,8 +1453,23 @@ systrace_newpolicy(struct fsystrace *fst, int maxents)
struct str_policy *pol;
int i;
if (fst->npolicies > SYSTR_MAX_POLICIES && !fst->issuser)
return (NULL);
if (fst->npolicies > SYSTR_MAX_POLICIES && !fst->issuser) {
struct str_policy *tmp;
/* Try to find a policy for freeing */
TAILQ_FOREACH(tmp, &fst->policies, next) {
if (tmp->refcount == 1)
break;
}
if (tmp == NULL)
return (NULL);
/* Notify userland about freed policy */
systrace_msg_policyfree(fst, tmp);
/* Free this policy */
systrace_closepolicy(fst, tmp);
}
pol = pool_get(&systr_policy_pl, PR_NOWAIT);
if (pol == NULL)
@ -1582,7 +1598,7 @@ systrace_make_msg(struct str_process *strp, int type, struct str_message *tmsg)
while (1) {
st = tsleep(strp, PWAIT | PCATCH, "systrmsg", 0);
if (st != 0)
return (EINTR);
return (ERESTART);
/* If we detach, then everything is permitted */
if ((strp = curproc->p_systrace) == NULL)
return (0);
@ -1625,3 +1641,26 @@ systrace_msg_child(struct fsystrace *fst, struct str_process *strp, pid_t npid)
return (0);
}
int
systrace_msg_policyfree(struct fsystrace *fst, struct str_policy *strpol)
{
struct str_msgcontainer *cont;
struct str_message *msg;
cont = pool_get(&systr_msgcontainer_pl, PR_WAITOK);
memset(cont, 0, sizeof(struct str_msgcontainer));
msg = &cont->msg;
DPRINTF(("%s: free %d\n", __func__, strpol->nr));
msg->msg_type = SYSTR_MSG_POLICYFREE;
msg->msg_policy = strpol->nr;
TAILQ_INSERT_TAIL(&fst->messages, cont, next);
systrace_wakeup(fst);
return (0);
}

View File

@ -1,4 +1,4 @@
/* $NetBSD: systrace.h,v 1.9 2003/03/30 00:40:05 provos Exp $ */
/* $NetBSD: systrace.h,v 1.10 2003/06/03 05:24:00 provos Exp $ */
/*
* Copyright 2002 Niels Provos <provos@citi.umich.edu>
@ -65,14 +65,16 @@ struct str_msg_child {
pid_t new_pid;
};
#define SYSTR_MSG_ASK 1
#define SYSTR_MSG_RES 2
#define SYSTR_MSG_EMUL 3
#define SYSTR_MSG_CHILD 4
#define SYSTR_MSG_UGID 5
#define SYSTR_MSG_ASK 1
#define SYSTR_MSG_RES 2
#define SYSTR_MSG_EMUL 3
#define SYSTR_MSG_CHILD 4
#define SYSTR_MSG_UGID 5
#define SYSTR_MSG_POLICYFREE 6
#define SYSTR_MSG_NOPROCESS(x) \
((x)->msg.msg_type == SYSTR_MSG_CHILD)
((x)->msg.msg_type == SYSTR_MSG_CHILD || \
(x)->msg.msg_type == SYSTR_MSG_POLICYFREE)
struct str_message {
int32_t msg_type;