From: <da...@us...> - 2003-06-28 06:59:54
|
Update of /cvsroot/cerber/cerb-ng/kcerb In directory sc8-pr-cvs1:/tmp/cvs-serv24832/kcerb Modified Files: Makefile cerb_action.c cerb_globals.h cerb_macros.h cerb_main.c cerb_operations.master cerb_sysctl.c cerb_sysctl.h cerb_urules.c Added Files: cerb_usersysctl.c cerb_usersysctl.h Log Message: - Implemented new functionality - usersysctls - avaliable via two new operations: + crsysctl(), + rmsysctl(). - New sysctl: cerb.misc.usersysctl_string_size. - Documented new operations and sysctl in -PL documentation. - Added new policy: usersysctl-sample.cb to show how now mechanism works. - Implement MCB_VALIDADDR() and MCB_VALIDSPACE() macro as inline functions. Now we don't have to afraid if there is really -1 at given address. - Allow ca_scalls to be NULL when calling cerb syscall. - Bumper cerb's version to note about scall(), crsysctl() and rmsysctl() operations and cerb.misc.usersysctl_string_size sysctl. - Fixed some typos. --- NEW FILE: cerb_usersysctl.c --- /* * cerb_usersysctl.c - runtime sysctl creation/deletion * * (c) 2003 Pawel Jakub Dawidek <ni...@ga...> * * $Id: cerb_usersysctl.c,v 1.1 2003/06/28 06:59:49 dawidek Exp $ * */ #include <sys/param.h> #include <sys/kernel.h> #include <sys/proc.h> #include <sys/libkern.h> #include <sys/sysctl.h> #include <sys/queue.h> #include <sys/syslog.h> #include "cerb_globals.h" #include "cerb_macros.h" #include "cerb_malloc.h" #include "cerb_sysctl.h" #include "cerb_usersysctl.h" #include "libkcerb.h" #ifdef CERB_USERSYSCTL extern int name2oid(char *name, int *oid, int *len, struct sysctl_oid **oidpp); struct scb_lock vcb_scnlock; LIST_HEAD(, scb_scnode) vcb_scnode_head; static int fcb_name2oid(char *name, struct sysctl_oid **oidpp) { int oid[CTL_MAXNAME], len; return (name2oid(name, oid, &len, oidpp)); } /* Caller should hold scnlock. */ static struct sysctl_ctx_list * fcb_oid2list(struct sysctl_oid *oidp) { struct sysctl_ctx_entry *entry; struct scb_scnode *scn; LIST_FOREACH(scn, &vcb_scnode_head, scn_next) { if (scn->scn_type != CTLTYPE_NODE) continue; entry = sysctl_ctx_entry_find(&scn->scn_list, oidp); if (entry == NULL) continue; if (oidp == entry->entry) return (&scn->scn_list); } return (NULL); } static int fcb_allocate_topnode(void) { struct sysctl_oid *oidp; struct scb_scnode *scn; int error; error = fcb_name2oid("cerb", &oidp); if (error != 0) return (error); scn = fcb_malloc("user sysctl scnode", sizeof(struct scb_scnode)); sysctl_ctx_init(&scn->scn_list); oidp = SYSCTL_ADD_NODE(&scn->scn_list, SYSCTL_CHILDREN(oidp), OID_AUTO, "user", CTLFLAG_RW, 0, "cerb.user level"); if (oidp == NULL) { printf("CerbNG: SYSCTL_ADD_NODE(%s) failed!\n", "cerb.user"); fcb_free(scn); return (EINVAL); } scn->scn_type = CTLTYPE_NODE; scn->scn_oidp = oidp; MCB_USERSYSCTL_LOCK(); LIST_INSERT_HEAD(&vcb_scnode_head, scn, scn_next); MCB_USERSYSCTL_UNLOCK(); #ifdef CB_DEBUG_USERSYSCTL MCB_DEBUG("Created topnode."); #endif return (0); } static size_t fcb_fullname(char *inname, char **name) { size_t size; if (strncmp(inname, "cerb.user.", 10 /* strlen("cerb.user.") */) == 0) { size = strlen(inname) + 1; *name = fcb_malloc("user sysctl name", size); strlcpy(*name, inname, size); } else { size = strlen(inname) + 10 + 1; *name = fcb_malloc("user sysctl name", size); strlcpy(*name, "cerb.user.", size); strlcat(*name, inname, size); } return (size); } int fcb_usersysctl_init(void) { fcb_lockinit(&vcb_scnlock, "scnlock"); LIST_INIT(&vcb_scnode_head); return (fcb_allocate_topnode()); } void fcb_usersysctl_clear(int all) { struct scb_scnode *scn1, *scn2; MCB_USERSYSCTL_LOCK(); scn1 = LIST_FIRST(&vcb_scnode_head); while (scn1 != NULL) { scn2 = LIST_NEXT(scn1, scn_next); switch (scn1->scn_type) { case CTLTYPE_NODE: sysctl_ctx_free(&scn1->scn_list); break; case CTLTYPE_STRING: fcb_free(scn1->scn_str); break; } fcb_free(scn1); scn1 = scn2; } LIST_INIT(&vcb_scnode_head); MCB_USERSYSCTL_UNLOCK(); if (!all) fcb_allocate_topnode(); } int fcb_usersysctl_add(char *inname, u_int type, u_int perm, struct scb_val *valp) { struct sysctl_ctx_list *list; struct sysctl_oid *oidp; struct scb_scnode *scn; char *node, *name, *tmpstr; size_t size; int error; if (perm != CTLFLAG_RW && perm != CTLFLAG_RD) return (EINVAL); size = fcb_fullname(inname, &node); #ifdef CB_DEBUG_USERSYSCTL MCB_DEBUG("Adding: %s", node); #endif tmpstr = fcb_malloc("tmp string", size); strlcpy(tmpstr, node, size); if (fcb_name2oid(tmpstr, &oidp) == 0) { fcb_free(tmpstr); fcb_free(node); return (EEXIST); } name = node + size - 1; for (; *name != '.'; --name) ; *name++ = '\0'; strlcpy(tmpstr, node, size); error = fcb_name2oid(tmpstr, &oidp); fcb_free(tmpstr); if (error != 0) { fcb_free(node); return (error); } if ((oidp->oid_kind & CTLTYPE) != CTLTYPE_NODE) { fcb_free(node); return (EINVAL); } MCB_USERSYSCTL_LOCK(); list = fcb_oid2list(oidp); MCB_USERSYSCTL_UNLOCK(); if (list == NULL) { fcb_free(node); return (ENOENT); } scn = fcb_malloc("user sysctl node", sizeof(struct scb_scnode)); scn->scn_type = type; switch (type) { case CTLTYPE_NODE: sysctl_ctx_init(&scn->scn_list); oidp = SYSCTL_ADD_NODE(&scn->scn_list, SYSCTL_CHILDREN(oidp), OID_AUTO, name, CTLFLAG_RW, 0, "user sysctl node"); break; case CTLTYPE_INT: scn->scn_val = valp->v_val; oidp = SYSCTL_ADD_INT(list, SYSCTL_CHILDREN(oidp), OID_AUTO, name, perm, &scn->scn_val, 0, "user sysctl int"); break; case CTLTYPE_UINT: scn->scn_uval = valp->v_uval; oidp = SYSCTL_ADD_UINT(list, SYSCTL_CHILDREN(oidp), OID_AUTO, name, perm, &scn->scn_val, 0, "user sysctl uint"); break; case CTLTYPE_STRING: { size_t size; size = ccb_misc_usersysctl_size; scn->scn_str = fcb_malloc("user sysctl string", size); strlcpy(scn->scn_str, valp->v_str, size); oidp = SYSCTL_ADD_STRING(list, SYSCTL_CHILDREN(oidp), OID_AUTO, name, perm, scn->scn_str, size, "user sysctl string"); if (oidp == NULL) fcb_free(scn->scn_str); break; } default: oidp = NULL; } if (oidp == NULL) { fcb_free(scn); fcb_free(node); return (EINVAL); } fcb_free(node); scn->scn_oidp = oidp; MCB_USERSYSCTL_LOCK(); LIST_INSERT_HEAD(&vcb_scnode_head, scn, scn_next); MCB_USERSYSCTL_UNLOCK(); return (0); } int fcb_usersysctl_del(char *inname) { struct sysctl_ctx_list *list; struct sysctl_oid *oidp; struct scb_scnode *scn; char *name; size_t size; int error; size = fcb_fullname(inname, &name); #ifdef CB_DEBUG_USERSYSCTL MCB_DEBUG("Deleting: %s", name); #endif error = fcb_name2oid(name, &oidp); fcb_free(name); if (error != 0) return (error); if ((oidp->oid_kind & CTLTYPE) == CTLTYPE_NODE) { if (!SLIST_EMPTY((struct sysctl_oid_list *)oidp->oid_arg1)) return (ENOTEMPTY); } MCB_USERSYSCTL_LOCK(); LIST_FOREACH(scn, &vcb_scnode_head, scn_next) { if (scn->scn_oidp == oidp) { list = fcb_oid2list(oidp); MCB_ASSERT(list != NULL, "sysctl_ctx_list for %s is " "NULL", oidp->oid_name); error = sysctl_ctx_entry_del(list, oidp); MCB_ASSERT(error == 0, "sysctl_ctx_entry_del returned " "%d.", error); error = sysctl_remove_oid(oidp, 1, 0); if (error == 0) { LIST_REMOVE(scn, scn_next); if (scn->scn_type == CTLTYPE_STRING) fcb_free(scn->scn_str); fcb_free(scn); } MCB_USERSYSCTL_UNLOCK(); return (error); } } MCB_USERSYSCTL_UNLOCK(); return (ENOENT); } #endif /* CERB_USERSYSCTL */ --- NEW FILE: cerb_usersysctl.h --- /* * cerb_usersysctl.h - header file for cerb_usersysctl.c * * (c) 2003 Pawel Jakub Dawidek <ni...@ga...> * * $Id: cerb_usersysctl.h,v 1.1 2003/06/28 06:59:49 dawidek Exp $ * */ #ifndef _CERB_USERSYSCTL_H_ #define _CERB_USERSYSCTL_H_ #include <sys/param.h> #include <sys/sysctl.h> #include <sys/queue.h> #include "cerb_globals.h" #include "cerb_rules.h" #ifdef CERB_USERSYSCTL struct scb_scnode { u_int scn_type; struct sysctl_oid *scn_oidp; union { struct sysctl_ctx_list __u_list; int __u_val; u_int __u_uval; char *__u_str; } __union_scnode; LIST_ENTRY(scb_scnode) scn_next; }; #define scn_list __union_scnode.__u_list #define scn_val __union_scnode.__u_val #define scn_uval __union_scnode.__u_uval #define scn_str __union_scnode.__u_str #define MCB_USERSYSCTL_LOCK() fcb_lock(curproc, &vcb_scnlock, "scnode_lock") #define MCB_USERSYSCTL_UNLOCK() fcb_unlock(curproc, &vcb_scnlock, "scnode_lock") int fcb_usersysctl_init(void); void fcb_usersysctl_clear(int all); int fcb_usersysctl_add(char *inname, u_int type, u_int perm, struct scb_val *valp); int fcb_usersysctl_del(char *inname); #else /* !CERB_USERSYCTL */ #define fcb_usersysctl_init() #define fcb_usersysctl_clear(all) #endif #endif /* _CERB_USERSYSCTL_H_ */ Index: Makefile =================================================================== RCS file: /cvsroot/cerber/cerb-ng/kcerb/Makefile,v retrieving revision 1.42 retrieving revision 1.43 diff -u -d -r1.42 -r1.43 --- Makefile 27 Jun 2003 01:13:22 -0000 1.42 +++ Makefile 28 Jun 2003 06:59:49 -0000 1.43 @@ -51,6 +51,8 @@ cerb_addons.h \ cerb_string.c \ cerb_string.h \ + cerb_usersysctl.c \ + cerb_usersysctl.h \ cerb_thread.c \ cerb_thread.h \ cerb_fdesc.c \ Index: cerb_action.c =================================================================== RCS file: /cvsroot/cerber/cerb-ng/kcerb/cerb_action.c,v retrieving revision 1.116 retrieving revision 1.117 diff -u -d -r1.116 -r1.117 --- cerb_action.c 27 Jun 2003 01:13:22 -0000 1.116 +++ cerb_action.c 28 Jun 2003 06:59:49 -0000 1.117 @@ -49,6 +49,7 @@ #include "cerb_trace.h" #include "cerb_ask.h" #include "cerb_operations.h" +#include "cerb_usersysctl.h" #include "cerb_action.h" #include "libkcerb.h" @@ -2700,7 +2701,7 @@ if (!MCB_ISVAL(v[1]->v_type)) { MCB_XCONFERR(th, EINVAL, "Invalid type of argument %u: %s " - "(should be %s or %s).", 0, tcb_typename[v[0]->v_type], + "(should be %s or %s).", 1, tcb_typename[v[1]->v_type], tcb_typename[CB_DEF_T], tcb_typename[CB_UDEF_T]); } @@ -2887,6 +2888,10 @@ fcb_op_trace(CB_OPARGS) { +#ifndef CERB_TRACE + MCB_XCONFERR(th, EOPNOTSUPP, "Trace functionality not avaliable. " + "Recompile cerb with CERB_TRACE."); +#else if (nvals != 0) { MCB_XCONFERR(th, EINVAL, "Invalid number of arguments: %u " "(no arguments required).", nvals); @@ -2897,10 +2902,6 @@ retv->v_uval = 0; retv->v_size = 0; -#ifndef CERB_TRACE - MCB_DEBUG("Trace functionality not avaliable. Recompile cerb with " - "CERB_TRACE."); -#else fcb_trace_gen(th); #endif } @@ -2980,4 +2981,117 @@ error); fcb_mtemp_add(th, retv->v_str); retv->v_size = strlen(retv->v_str) + 1; +} + +void +fcb_op_crsysctl(CB_OPARGS) +{ +#ifndef CERB_USERSYSCTL + MCB_XCONFERR(th, EOPNOTSUPP, "User sysctl functionality not avaliable. " + "Recompile cerb with CERB_USERSYSCTL."); +#else /* CERB_USERSYSCTL */ + struct scb_val val, *valp; + + if (nvals != 3 && nvals != 4) { + MCB_XCONFERR(th, EINVAL, "Invalid number of arguments: %u " + "(should be %u or %u).", nvals, 3, 4); + } + if (v[0]->v_type != CB_STR_T) { + MCB_XCONFERR(th, EINVAL, "Invalid type of argument %u: %s " + "(should be %s).", 0, tcb_typename[v[0]->v_type], + tcb_typename[CB_STR_T]); + } + if (!MCB_ISVAL(v[1]->v_type)) { + MCB_XCONFERR(th, EINVAL, "Invalid type of argument %u: %s " + "(should be %s or %s).", 1, tcb_typename[v[1]->v_type], + tcb_typename[CB_DEF_T], tcb_typename[CB_UDEF_T]); + } + if (!MCB_ISVAL(v[2]->v_type)) { + MCB_XCONFERR(th, EINVAL, "Invalid type of argument %u: %s " + "(should be %s or %s).", 2, tcb_typename[v[2]->v_type], + tcb_typename[CB_DEF_T], tcb_typename[CB_UDEF_T]); + } + retv->v_id = ECB_CONST_I; + retv->v_type = CB_DEF_T; + retv->v_size = 0; + if (nvals == 4) { + switch (v[1]->v_uval) { + case CTLTYPE_INT: + if (!MCB_ISVAL(v[3]->v_type)) { + retv->v_val = EINVAL; + return; + } + break; + case CTLTYPE_UINT: + if (!MCB_ISVAL(v[3]->v_type)) { + retv->v_val = EINVAL; + return; + } + break; + case CTLTYPE_STRING: + if (v[3]->v_type != CB_STR_T) { + retv->v_val = EINVAL; + return; + } + break; + default: + retv->v_val = EINVAL; + return; + } + valp = v[3]; + } else { + val.v_id = ECB_CONST_I; + switch (v[1]->v_uval) { + case CTLTYPE_INT: + val.v_val = 0; + val.v_type = CB_DEF_T; + val.v_size = 0; + break; + case CTLTYPE_UINT: + val.v_uval = 0; + val.v_type = CB_UDEF_T; + val.v_size = 0; + break; + case CTLTYPE_STRING: + val.v_str = '\0'; + val.v_type = CB_STR_T; + val.v_size = 1; + break; + case CTLTYPE_NODE: + break; + default: + retv->v_val = EINVAL; + return; + } + valp = &val; + } + + retv->v_val = fcb_usersysctl_add(v[0]->v_str, v[1]->v_uval, + v[2]->v_uval, valp); +#endif /* CERB_USERSYSCTL */ +} + +void +fcb_op_rmsysctl(CB_OPARGS) +{ + +#ifndef CERB_USERSYSCTL + MCB_XCONFERR(th, EOPNOTSUPP, "User sysctl functionality not avaliable. " + "Recompile cerb with CERB_USERSYSCTL."); +#else /* CERB_USERSYSCTL */ + if (nvals != 1) { + MCB_XCONFERR(th, EINVAL, "Invalid number of arguments: %u " + "(should be %u).", nvals, 1); + } + if (v[0]->v_type != CB_STR_T) { + MCB_XCONFERR(th, EINVAL, "Invalid type of argument %u: %s " + "(should be %s).", 0, tcb_typename[v[0]->v_type], + tcb_typename[CB_STR_T]); + } + + retv->v_id = ECB_CONST_I; + retv->v_type = CB_DEF_T; + retv->v_size = 0; + retv->v_val = fcb_usersysctl_del(v[0]->v_str); +#endif /* CERB_USERSYSCTL */ } Index: cerb_globals.h =================================================================== RCS file: /cvsroot/cerber/cerb-ng/kcerb/cerb_globals.h,v retrieving revision 1.62 retrieving revision 1.63 diff -u -d -r1.62 -r1.63 --- cerb_globals.h 18 Jun 2003 17:34:55 -0000 1.62 +++ cerb_globals.h 28 Jun 2003 06:59:49 -0000 1.63 @@ -15,7 +15,7 @@ #define CB_VERSION_G "CURRENT" /* CerbNG version. */ -#define CERB_VERSION 2003060401 +#define CERB_VERSION 2003062801 #define CB_NREGS_G 50 /* How many registers (in rules) should be allocated */ @@ -59,6 +59,9 @@ #define CB_MAXSUSPENDED_G 64 /* Maximum number of processes that could sleep when waiting on ask() operation. */ +#define CB_USERSYSCTL_STRING_SIZE 256 /* Size of string that will be allocated + with crsysctl() operation. */ + #define CB_NULLSTR_G "[null]" #define CB_UNKNOWNSTR_G "[unknown]" @@ -97,6 +100,7 @@ #define CERB_SAFEMALLOC #define CERB_TRACE #define CERB_INITRUN +#define CERB_USERSYSCTL #undef CERB_NATIVE_LOCKS /* Debugs: */ @@ -109,6 +113,7 @@ #undef CB_DEBUG_USM /* debug for memory allocations in userland */ #undef CB_DEBUG_ASK /* debug for ask mechanism */ #define CB_DEBUG_ASK +#undef CB_DEBUG_USERSYSCTL /* debug for user sysctl functions */ #undef CB_DEBUG_GETVAL /* debug for fcb_getval() function */ #undef CB_DEBUG_OPERR /* debug for operations errors */ Index: cerb_macros.h =================================================================== RCS file: /cvsroot/cerber/cerb-ng/kcerb/cerb_macros.h,v retrieving revision 1.38 retrieving revision 1.39 diff -u -d -r1.38 -r1.39 --- cerb_macros.h 26 Jun 2003 22:34:42 -0000 1.38 +++ cerb_macros.h 28 Jun 2003 06:59:49 -0000 1.39 @@ -49,13 +49,34 @@ /* * This macro checks if given address is in vmspace of current process. */ -#define MCB_VALIDADDR(addr) (fusword(addr) != -1) +static __inline int +icb_validaddr(void *addr) +{ + char buf; + + if (copyin(addr, &buf, sizeof(buf)) == 0) + return (1); + else + return (0); +} +#define MCB_VALIDADDR(addr) icb_validaddr(addr) /* * This macro checks if given space is in vmspace of current process. */ -#define MCB_VALIDSPACE(p, addr, size) \ - (fubyte(addr) != -1 && fubyte((char *)(addr) + (size) - 1) != -1) +static __inline int +icb_validspace(struct proc *p, void *addr, size_t size) +{ + char buf; + + if (copyin(addr, &buf, sizeof(buf)) == 0 && + copyin((char *)addr + size - 1, &buf, sizeof(buf)) == 0) { + return (1); + } else { + return (0); + } +} +#define MCB_VALIDSPACE(p, addr, size) icb_validspace(p, addr, size) /* * This macro returns number of arguments for specified syscall. @@ -94,7 +115,7 @@ * Macro for debugging. */ #define MCB_DEBUG(fmt, args...) \ - log(LOG_DEBUG, "kcerb:DEBUG:%s: " fmt "[%s:%u]\n", \ + log(LOG_DEBUG, "kcerb:DEBUG:%s: " fmt " [%s:%u]\n", \ __func__ ,##args, __FILE__, __LINE__) /* * Macro used to inform about errors in configs. Index: cerb_main.c =================================================================== RCS file: /cvsroot/cerber/cerb-ng/kcerb/cerb_main.c,v retrieving revision 1.38 retrieving revision 1.39 diff -u -d -r1.38 -r1.39 --- cerb_main.c 18 Jun 2003 17:34:55 -0000 1.38 +++ cerb_main.c 28 Jun 2003 06:59:49 -0000 1.39 @@ -26,6 +26,8 @@ #include "cerb_rules.h" #include "cerb_urules.h" #include "cerb_thread.h" +#include "cerb_sysctl.h" +#include "cerb_usersysctl.h" #include "cerb_gregs.h" #include "cerb_fdesc.h" #include "cerb_ask.h" @@ -72,6 +74,7 @@ fcb_malloc_init(); #endif fcb_sysctl_init(); + fcb_usersysctl_init(); fcb_fdesc_init(); fcb_thread_init(); fcb_gregs_init(); @@ -102,6 +105,8 @@ fcb_rule_clear(); fcb_thread_clear(); fcb_gregs_clear(); + /* 1 means remove all user sysctls and cerb.user node */ + fcb_usersysctl_clear(1); fcb_sysctl_clear(); #ifdef CERB_SAFEMALLOC fcb_malloc_clear(); Index: cerb_operations.master =================================================================== RCS file: /cvsroot/cerber/cerb-ng/kcerb/cerb_operations.master,v retrieving revision 1.40 retrieving revision 1.41 diff -u -d -r1.40 -r1.41 --- cerb_operations.master 8 Jun 2003 16:18:52 -0000 1.40 +++ cerb_operations.master 28 Jun 2003 06:59:49 -0000 1.41 @@ -148,6 +148,8 @@ "size" typesize SIZE "basename" basedirname BASENAME "dirname" basedirname DIRNAME +"crsysctl" crsysctl CRSYSCTL +"rmsysctl" rmsysctl RMSYSCTL "tmp" tmp TMP # Parser's functions "GET_UID" USERLAND Index: cerb_sysctl.c =================================================================== RCS file: /cvsroot/cerber/cerb-ng/kcerb/cerb_sysctl.c,v retrieving revision 1.30 retrieving revision 1.31 diff -u -d -r1.30 -r1.31 --- cerb_sysctl.c 18 Jun 2003 17:34:55 -0000 1.30 +++ cerb_sysctl.c 28 Jun 2003 06:59:49 -0000 1.31 @@ -54,11 +54,14 @@ * cerb.trace.on_error #endif * cerb.misc.off_on_error + * cerb.misc.usersysctl_string_size * cerb.version.number * cerb.version.string */ u_int ccb_off_on_error = 1; +u_int ccb_misc_usersysctl_size = CB_USERSYSCTL_STRING_SIZE; + static u_int ccb_version_number = CERB_VERSION; static char *ccb_version_string = CB_VERSION_G; @@ -450,7 +453,7 @@ int fcb_sysctl_init(void) { - static struct sysctl_oid *root, *n_root; + struct sysctl_oid *root, *n_root; sysctl_ctx_init(&sctl_cerb); root = SYSCTL_ADD_NODE(&sctl_cerb, @@ -591,6 +594,9 @@ SYSCTL_ADD_PROC(&sctl_cerb_misc, SYSCTL_CHILDREN(n_root), OID_AUTO, "off_on_error", CTLTYPE_UINT | CTLFLAG_RW, 0, 0, sysctl_cb_misc_off_on_error, "I", "Turn off cerb on error?"); + SYSCTL_ADD_UINT(&sctl_cerb_misc, SYSCTL_CHILDREN(n_root), OID_AUTO, + "usersysctl_string_size", CTLFLAG_RW, &ccb_misc_usersysctl_size, 0, + "Size of strings that will be allocated via crsysctl() operation."); sysctl_ctx_init(&sctl_cerb_version); n_root = SYSCTL_ADD_NODE(&sctl_cerb_version, SYSCTL_CHILDREN(root), Index: cerb_sysctl.h =================================================================== RCS file: /cvsroot/cerber/cerb-ng/kcerb/cerb_sysctl.h,v retrieving revision 1.3 retrieving revision 1.4 diff -u -d -r1.3 -r1.4 --- cerb_sysctl.h 8 Apr 2003 13:35:02 -0000 1.3 +++ cerb_sysctl.h 28 Jun 2003 06:59:49 -0000 1.4 @@ -11,7 +11,9 @@ #ifndef _CERB_SYSCTL_H_ #define _CERB_SYSCTL_H_ -extern u_int ccb_off_on_error; +extern u_int ccb_off_on_error; +extern u_int ccb_misc_usersysctl_size; + int fcb_sysctl_init(void); int fcb_sysctl_clear(void); Index: cerb_urules.c =================================================================== RCS file: /cvsroot/cerber/cerb-ng/kcerb/cerb_urules.c,v retrieving revision 1.73 retrieving revision 1.74 diff -u -d -r1.73 -r1.74 --- cerb_urules.c 26 Jun 2003 22:34:42 -0000 1.73 +++ cerb_urules.c 28 Jun 2003 06:59:49 -0000 1.74 @@ -27,13 +27,14 @@ #include <errno.h> #endif +#include "cerb_globals.h" #ifdef _KERNEL #include "cerb_macros.h" #include "cerb_malloc.h" #include "cerb_lock.h" #include "cerb_syscalls.h" +#include "cerb_usersysctl.h" #endif -#include "cerb_globals.h" #include "cerb_rules.h" #include "cerb_const.h" #include "cerb_operations.h" @@ -108,7 +109,8 @@ goto fail; } - if (!MCB_VALIDADDR(uap->ca_scalls)) { + if (!MCB_VALIDADDR(uap->ca_scalls) && + (uap->ca_scalls != NULL && uap->ca_nscalls != 0)) { MCB_XERROR("Bad address of ca_scalls: %p.", uap->ca_scalls); error = EFAULT; goto fail; @@ -130,19 +132,23 @@ error = EINVAL; goto fail; } - scalls = MCB_MALLOC_L("Temporary syscalls table", - nscalls * sizeof(int)); - if (scalls == NULL) { - MCB_XERROR("Cannot allocate memory for temporary syscalls " - "table."); - error = ENOMEM; - goto fail; - } - ADD_APTR(scalls, ap, CB_CLEAR_ALWAYS); - error = copyin(uap->ca_scalls, scalls, nscalls * sizeof(int)); - if (error != 0) { - MCB_XERROR("Cannot copy syscalls from userland."); - goto fail; + if (nscalls == 0) + scalls = NULL; + else { + scalls = MCB_MALLOC_L("Temporary syscalls table", + nscalls * sizeof(int)); + if (scalls == NULL) { + MCB_XERROR("Cannot allocate memory for temporary syscalls " + "table."); + error = ENOMEM; + goto fail; + } + ADD_APTR(scalls, ap, CB_CLEAR_ALWAYS); + error = copyin(uap->ca_scalls, scalls, nscalls * sizeof(int)); + if (error != 0) { + MCB_XERROR("Cannot copy syscalls from userland."); + goto fail; + } } nrules = uap->ca_nrules; @@ -240,15 +246,14 @@ tcb_tabs[ntab].t_rules = addr; tcb_tabs[ntab].t_nrules = nrules; /* Filling syscalls numbers. */ + bzero(tcb_tabs[ntab].t_scalls, sizeof(tcb_tabs[ntab].t_scalls)); for (i = 0; i < nscalls; ++i) { - if (!fcb_urule_validscall((u_int)scalls[i])) { + if (fcb_urule_validscall((u_int)scalls[i])) + tcb_tabs[ntab].t_scalls[(u_int)scalls[i]] = 1; #ifdef CB_DEBUG_OTHER + else MCB_DEBUG("Invalid syscall: %u.", scalls[i]); #endif - tcb_tabs[ntab].t_scalls[(u_int)scalls[i]] = 0; - continue; - } - tcb_tabs[ntab].t_scalls[(u_int)scalls[i]] = 1; } if (ccb_ntab == ntab) { MCB_GIANT_LOCK(); @@ -284,6 +289,9 @@ SLIST_INIT(&vcb_aptrs_head); fcb_unlock(p, &vcb_aptrslock, "aptrs_lock"); + + /* 0 means remove all user sysctls, but don't remove cerb.user node */ + fcb_usersysctl_clear(0); #ifdef CERB_INITRUN if (ccb_ntab == ntab) |