diff options
author | jamie <jamie@FreeBSD.org> | 2009-07-17 14:48:21 +0000 |
---|---|---|
committer | jamie <jamie@FreeBSD.org> | 2009-07-17 14:48:21 +0000 |
commit | 9f81cbd9ecbd42ba9494b4d36a79e700e9e3a74f (patch) | |
tree | 2512a1900a6519091f682eeddcd7ff520f3a76ae | |
parent | d77b22ca313fa4061782d2b1677a768149593534 (diff) | |
download | FreeBSD-src-9f81cbd9ecbd42ba9494b4d36a79e700e9e3a74f.zip FreeBSD-src-9f81cbd9ecbd42ba9494b4d36a79e700e9e3a74f.tar.gz |
Remove the interim vimage containers, struct vimage and struct procg,
and the ioctl-based interface that supported them.
Approved by: re (kib), bz (mentor)
-rw-r--r-- | sys/kern/init_main.c | 7 | ||||
-rw-r--r-- | sys/kern/kern_exit.c | 5 | ||||
-rw-r--r-- | sys/kern/kern_fork.c | 4 | ||||
-rw-r--r-- | sys/kern/kern_jail.c | 4 | ||||
-rw-r--r-- | sys/kern/kern_linker.c | 12 | ||||
-rw-r--r-- | sys/kern/kern_prot.c | 16 | ||||
-rw-r--r-- | sys/kern/kern_vimage.c | 373 | ||||
-rw-r--r-- | sys/net/if.c | 17 | ||||
-rw-r--r-- | sys/sys/sockio.h | 4 | ||||
-rw-r--r-- | sys/sys/ucred.h | 4 | ||||
-rw-r--r-- | sys/sys/vimage.h | 86 | ||||
-rw-r--r-- | tools/tools/vimage/Makefile | 2 | ||||
-rw-r--r-- | tools/tools/vimage/vimage.c | 154 |
13 files changed, 124 insertions, 564 deletions
diff --git a/sys/kern/init_main.c b/sys/kern/init_main.c index c84b189..abc16e1 100644 --- a/sys/kern/init_main.c +++ b/sys/kern/init_main.c @@ -74,7 +74,6 @@ __FBSDID("$FreeBSD$"); #include <sys/malloc.h> #include <sys/conf.h> #include <sys/cpuset.h> -#include <sys/vimage.h> #include <machine/cpu.h> @@ -454,12 +453,6 @@ proc0_init(void *dummy __unused) p->p_ucred->cr_uidinfo = uifind(0); p->p_ucred->cr_ruidinfo = uifind(0); p->p_ucred->cr_prison = &prison0; -#ifdef VIMAGE - KASSERT(LIST_FIRST(&vimage_head) != NULL, ("vimage_head empty")); - P_TO_VIMAGE(p) = LIST_FIRST(&vimage_head); /* set ucred->cr_vimage */ - refcount_acquire(&P_TO_VIMAGE(p)->vi_ucredrefc); - LIST_FIRST(&vprocg_head)->nprocs++; -#endif #ifdef AUDIT audit_cred_kproc0(p->p_ucred); #endif diff --git a/sys/kern/kern_exit.c b/sys/kern/kern_exit.c index cb6e7b2..36a074d 100644 --- a/sys/kern/kern_exit.c +++ b/sys/kern/kern_exit.c @@ -69,7 +69,6 @@ __FBSDID("$FreeBSD$"); #include <sys/sdt.h> #include <sys/shm.h> #include <sys/sem.h> -#include <sys/vimage.h> #ifdef KTRACE #include <sys/ktrace.h> #endif @@ -687,7 +686,6 @@ static void proc_reap(struct thread *td, struct proc *p, int *status, int options, struct rusage *rusage) { - INIT_VPROCG(P_TO_VPROCG(p)); struct proc *q, *t; sx_assert(&proctree_lock, SA_XLOCKED); @@ -791,9 +789,6 @@ proc_reap(struct thread *td, struct proc *p, int *status, int options, uma_zfree(proc_zone, p); sx_xlock(&allproc_lock); nprocs--; -#ifdef VIMAGE - vprocg->nprocs--; -#endif sx_xunlock(&allproc_lock); } diff --git a/sys/kern/kern_fork.c b/sys/kern/kern_fork.c index 65fd09d..4e2eaa9 100644 --- a/sys/kern/kern_fork.c +++ b/sys/kern/kern_fork.c @@ -67,7 +67,6 @@ __FBSDID("$FreeBSD$"); #include <sys/sdt.h> #include <sys/sx.h> #include <sys/signalvar.h> -#include <sys/vimage.h> #include <security/audit/audit.h> #include <security/mac/mac_framework.h> @@ -363,9 +362,6 @@ norfproc_fail: * are hard-limits as to the number of processes that can run. */ nprocs++; -#ifdef VIMAGE - P_TO_VPROCG(p1)->nprocs++; -#endif /* * Find an unused process ID. We remember a range of unused IDs diff --git a/sys/kern/kern_jail.c b/sys/kern/kern_jail.c index c96307d..5c36758 100644 --- a/sys/kern/kern_jail.c +++ b/sys/kern/kern_jail.c @@ -3243,10 +3243,6 @@ int prison_check(struct ucred *cred1, struct ucred *cred2) { -#ifdef VIMAGE - if (cred2->cr_vimage->v_procg != cred1->cr_vimage->v_procg) - return (ESRCH); -#endif return ((cred1->cr_prison == cred2->cr_prison || prison_ischild(cred1->cr_prison, cred2->cr_prison)) ? 0 : ESRCH); } diff --git a/sys/kern/kern_linker.c b/sys/kern/kern_linker.c index 1768e69..e0c50fe3 100644 --- a/sys/kern/kern_linker.c +++ b/sys/kern/kern_linker.c @@ -992,12 +992,6 @@ kern_kldload(struct thread *td, const char *file, int *fileid) if ((error = priv_check(td, PRIV_KLD_LOAD)) != 0) return (error); -#ifdef VIMAGE - /* Only the default vimage is permitted to kldload modules. */ - if (!IS_DEFAULT_VIMAGE(TD_TO_VIMAGE(td))) - return (EPERM); -#endif - /* * It is possible that kldloaded module will attach a new ifnet, * so vnet context must be set when this ocurs. @@ -1069,12 +1063,6 @@ kern_kldunload(struct thread *td, int fileid, int flags) if ((error = priv_check(td, PRIV_KLD_UNLOAD)) != 0) return (error); -#ifdef VIMAGE - /* Only the default vimage is permitted to kldunload modules. */ - if (!IS_DEFAULT_VIMAGE(TD_TO_VIMAGE(td))) - return (EPERM); -#endif - CURVNET_SET(TD_TO_VNET(td)); KLD_LOCK(); lf = linker_find_file_by_id(fileid); diff --git a/sys/kern/kern_prot.c b/sys/kern/kern_prot.c index 453d5f2..709bcb0 100644 --- a/sys/kern/kern_prot.c +++ b/sys/kern/kern_prot.c @@ -68,7 +68,6 @@ __FBSDID("$FreeBSD$"); #include <sys/socketvar.h> #include <sys/syscallsubr.h> #include <sys/sysctl.h> -#include <sys/vimage.h> #if defined(INET) || defined(INET6) #include <netinet/in.h> @@ -1762,11 +1761,7 @@ p_canwait(struct thread *td, struct proc *p) KASSERT(td == curthread, ("%s: td not curthread", __func__)); PROC_LOCK_ASSERT(p, MA_OWNED); - if ( -#ifdef VIMAGE /* XXX temporary until struct vimage goes away */ - !vi_child_of(TD_TO_VIMAGE(td), P_TO_VIMAGE(p)) && -#endif - (error = prison_check(td->td_ucred, p->p_ucred))) + if ((error = prison_check(td->td_ucred, p->p_ucred))) return (error); #ifdef MAC if ((error = mac_proc_check_wait(td->td_ucred, p))) @@ -1836,11 +1831,6 @@ crfree(struct ucred *cr) */ if (cr->cr_prison != NULL) prison_free(cr->cr_prison); -#ifdef VIMAGE - /* XXX TODO: find out why and when cr_vimage can be NULL here! */ - if (cr->cr_vimage != NULL) - refcount_release(&cr->cr_vimage->vi_ucredrefc); -#endif #ifdef AUDIT audit_cred_destroy(cr); #endif @@ -1877,10 +1867,6 @@ crcopy(struct ucred *dest, struct ucred *src) uihold(dest->cr_uidinfo); uihold(dest->cr_ruidinfo); prison_hold(dest->cr_prison); -#ifdef VIMAGE - KASSERT(src->cr_vimage != NULL, ("cr_vimage == NULL")); - refcount_acquire(&dest->cr_vimage->vi_ucredrefc); -#endif #ifdef AUDIT audit_cred_copy(src, dest); #endif diff --git a/sys/kern/kern_vimage.c b/sys/kern/kern_vimage.c index daa9b9f..328b2ba 100644 --- a/sys/kern/kern_vimage.c +++ b/sys/kern/kern_vimage.c @@ -36,14 +36,11 @@ __FBSDID("$FreeBSD$"); #include <sys/param.h> #include <sys/jail.h> #include <sys/kernel.h> -#include <sys/linker.h> #include <sys/lock.h> #include <sys/malloc.h> #include <sys/socket.h> #include <sys/sockio.h> #include <sys/sx.h> -#include <sys/priv.h> -#include <sys/refcount.h> #include <sys/vimage.h> #ifdef DDB #include <ddb/ddb.h> @@ -53,9 +50,7 @@ __FBSDID("$FreeBSD$"); #include <net/route.h> #include <net/vnet.h> -MALLOC_DEFINE(M_VIMAGE, "vimage", "vimage resource container"); MALLOC_DEFINE(M_VNET, "vnet", "network stack control block"); -MALLOC_DEFINE(M_VPROCG, "vprocg", "process group control block"); static TAILQ_HEAD(vnet_modlink_head, vnet_modlink) vnet_modlink_head; static TAILQ_HEAD(vnet_modpending_head, vnet_modlink) vnet_modpending_head; @@ -63,12 +58,6 @@ static void vnet_mod_complete_registration(struct vnet_modlink *); static int vnet_mod_constructor(struct vnet_modlink *); static int vnet_mod_destructor(struct vnet_modlink *); -static struct vimage *vi_alloc(struct vimage *, char *); -static int vi_destroy(struct vimage *); -static struct vimage *vimage_get_next(struct vimage *, struct vimage *, int); -static void vimage_relative_name(struct vimage *, struct vimage *, - char *, int); - #define VNET_LIST_WLOCK() \ mtx_lock(&vnet_list_refc_mtx); \ while (vnet_list_refc != 0) \ @@ -77,82 +66,45 @@ static void vimage_relative_name(struct vimage *, struct vimage *, #define VNET_LIST_WUNLOCK() \ mtx_unlock(&vnet_list_refc_mtx); -struct vimage_list_head vimage_head; struct vnet_list_head vnet_head; -struct vprocg_list_head vprocg_head; -struct vprocg vprocg_0; struct cv vnet_list_condvar; struct mtx vnet_list_refc_mtx; int vnet_list_refc = 0; -static u_int last_vi_id = 0; -static u_int last_vprocg_id = 0; - struct vnet *vnet0; /* - * Move an ifnet to or from another vnet, specified by the jail id. If a - * vi_req is passed in, it is used to find the interface and a vimage - * containing the vnet (a vimage name of ".." stands for the parent vnet). + * Move an ifnet to or from another vnet, specified by the jail id. */ int -vi_if_move(struct thread *td, struct ifnet *ifp, char *ifname, int jid, - struct vi_req *vi_req) +vi_if_move(struct thread *td, struct ifnet *ifp, char *ifname, int jid) { struct ifnet *t_ifp; struct prison *pr; - struct vimage *new_vip, *my_vip; struct vnet *new_vnet; int error; - if (vi_req != NULL) { - /* SIOCSIFVIMAGE */ - pr = NULL; - /* Check for API / ABI version mismatch. */ - if (vi_req->vi_api_cookie != VI_API_COOKIE) - return (EDOOFUS); - - /* Find the target vnet. */ - my_vip = TD_TO_VIMAGE(td); - if (strcmp(vi_req->vi_name, "..") == 0) { - if (IS_DEFAULT_VIMAGE(my_vip)) - return (ENXIO); - new_vnet = my_vip->vi_parent->v_net; - } else { - new_vip = vimage_by_name(my_vip, vi_req->vi_name); - if (new_vip == NULL) - return (ENXIO); - new_vnet = new_vip->v_net; - } - - /* Try to find the target ifnet by name. */ - ifname = vi_req->vi_if_xname; - ifp = ifunit(ifname); - if (ifp == NULL) - return (ENXIO); + sx_slock(&allprison_lock); + pr = prison_find_child(td->td_ucred->cr_prison, jid); + sx_sunlock(&allprison_lock); + if (pr == NULL) + return (ENXIO); + prison_hold_locked(pr); + mtx_unlock(&pr->pr_mtx); + if (ifp != NULL) { + /* SIOCSIFVNET */ + new_vnet = pr->pr_vnet; } else { - sx_slock(&allprison_lock); - pr = prison_find_child(td->td_ucred->cr_prison, jid); - sx_sunlock(&allprison_lock); - if (pr == NULL) + /* SIOCSIFRVNET */ + new_vnet = TD_TO_VNET(td); + CURVNET_SET(pr->pr_vnet); + ifp = ifunit(ifname); + CURVNET_RESTORE(); + if (ifp == NULL) { + prison_free(pr); return (ENXIO); - prison_hold_locked(pr); - mtx_unlock(&pr->pr_mtx); - if (ifp != NULL) { - /* SIOCSIFVNET */ - new_vnet = pr->pr_vnet; - } else { - /* SIOCSIFRVNET */ - new_vnet = TD_TO_VNET(td); - CURVNET_SET(pr->pr_vnet); - ifp = ifunit(ifname); - CURVNET_RESTORE(); - if (ifp == NULL) { - prison_free(pr); - return (ENXIO); - } } } @@ -175,215 +127,10 @@ vi_if_move(struct thread *td, struct ifnet *ifp, char *ifname, int jid, sprintf(ifname, "%s", ifp->if_xname); } } - if (pr != NULL) - prison_free(pr); + prison_free(pr); return (error); } -/* - * Interim userspace interface - will be replaced by jail soon. - */ - -int -vi_td_ioctl(u_long cmd, struct vi_req *vi_req, struct thread *td) -{ - int error = 0; - struct vimage *vip = TD_TO_VIMAGE(td); - struct vimage *vip_r = NULL; - - /* Check for API / ABI version mismatch. */ - if (vi_req->vi_api_cookie != VI_API_COOKIE) - return (EDOOFUS); - - error = priv_check(td, PRIV_REBOOT); /* XXX temp. priv abuse */ - if (error) - return (error); - - vip_r = vimage_by_name(vip, vi_req->vi_name); - if (vip_r == NULL && !(vi_req->vi_req_action & VI_CREATE)) - return (ESRCH); - if (vip_r != NULL && vi_req->vi_req_action & VI_CREATE) - return (EADDRINUSE); - if (vi_req->vi_req_action == VI_GETNEXT) { - vip_r = vimage_get_next(vip, vip_r, 0); - if (vip_r == NULL) - return (ESRCH); - } - if (vi_req->vi_req_action == VI_GETNEXT_RECURSE) { - vip_r = vimage_get_next(vip, vip_r, 1); - if (vip_r == NULL) - return (ESRCH); - } - - if (vip_r && !vi_child_of(vip, vip_r) && /* XXX delete the rest? */ - vi_req->vi_req_action != VI_GET && - vi_req->vi_req_action != VI_GETNEXT) - return (EPERM); - - switch (cmd) { - - case SIOCGPVIMAGE: - vimage_relative_name(vip, vip_r, vi_req->vi_name, - sizeof (vi_req->vi_name)); - vi_req->vi_proc_count = vip_r->v_procg->nprocs; - vi_req->vi_if_count = vip_r->v_net->ifcnt; - vi_req->vi_sock_count = vip_r->v_net->sockcnt; - break; - - case SIOCSPVIMAGE: - if (vi_req->vi_req_action == VI_DESTROY) { - error = vi_destroy(vip_r); - break; - } - - if (vi_req->vi_req_action == VI_SWITCHTO) { - struct proc *p = td->td_proc; - struct ucred *oldcred, *newcred; - - /* - * XXX priv_check()? - * XXX allow only a single td per proc here? - */ - newcred = crget(); - PROC_LOCK(p); - oldcred = p->p_ucred; - setsugid(p); - crcopy(newcred, oldcred); - refcount_release(&newcred->cr_vimage->vi_ucredrefc); - newcred->cr_vimage = vip_r; - refcount_acquire(&newcred->cr_vimage->vi_ucredrefc); - p->p_ucred = newcred; - PROC_UNLOCK(p); - sx_xlock(&allproc_lock); - oldcred->cr_vimage->v_procg->nprocs--; - refcount_release(&oldcred->cr_vimage->vi_ucredrefc); - P_TO_VPROCG(p)->nprocs++; - sx_xunlock(&allproc_lock); - crfree(oldcred); - break; - } - - if (vi_req->vi_req_action & VI_CREATE) { - char *dotpos; - - dotpos = strrchr(vi_req->vi_name, '.'); - if (dotpos != NULL) { - *dotpos = 0; - vip = vimage_by_name(vip, vi_req->vi_name); - if (vip == NULL) - return (ESRCH); - dotpos++; - vip_r = vi_alloc(vip, dotpos); - } else - vip_r = vi_alloc(vip, vi_req->vi_name); - if (vip_r == NULL) - return (ENOMEM); - } - } - return (error); -} - -int -vi_child_of(struct vimage *parent, struct vimage *child) -{ - - if (child == parent) - return (0); - for (; child; child = child->vi_parent) - if (child == parent) - return (1); - return (0); -} - -struct vimage * -vimage_by_name(struct vimage *top, char *name) -{ - struct vimage *vip; - char *next_name; - int namelen; - - next_name = strchr(name, '.'); - if (next_name != NULL) { - namelen = next_name - name; - next_name++; - if (namelen == 0) { - if (strlen(next_name) == 0) - return (top); /* '.' == this vimage */ - else - return (NULL); - } - } else - namelen = strlen(name); - if (namelen == 0) - return (NULL); - LIST_FOREACH(vip, &top->vi_child_head, vi_sibling) { - if (strlen(vip->vi_name) == namelen && - strncmp(name, vip->vi_name, namelen) == 0) { - if (next_name != NULL) - return (vimage_by_name(vip, next_name)); - else - return (vip); - } - } - return (NULL); -} - -static void -vimage_relative_name(struct vimage *top, struct vimage *where, - char *buffer, int bufflen) -{ - int used = 1; - - if (where == top) { - sprintf(buffer, "."); - return; - } else - *buffer = 0; - - do { - int namelen = strlen(where->vi_name); - - if (namelen + used + 1 >= bufflen) - panic("buffer overflow"); - - if (used > 1) { - bcopy(buffer, &buffer[namelen + 1], used); - buffer[namelen] = '.'; - used++; - } else - bcopy(buffer, &buffer[namelen], used); - bcopy(where->vi_name, buffer, namelen); - used += namelen; - where = where->vi_parent; - } while (where != top); -} - -static struct vimage * -vimage_get_next(struct vimage *top, struct vimage *where, int recurse) -{ - struct vimage *next; - - if (recurse) { - /* Try to go deeper in the hierarchy */ - next = LIST_FIRST(&where->vi_child_head); - if (next != NULL) - return (next); - } - - do { - /* Try to find next sibling */ - next = LIST_NEXT(where, vi_sibling); - if (!recurse || next != NULL) - return (next); - - /* Nothing left on this level, go one level up */ - where = where->vi_parent; - } while (where != top->vi_parent); - - /* Nothing left to be visited, we are done */ - return (NULL); -} - /* * Kernel interfaces and handlers. @@ -409,7 +156,7 @@ vnet_mod_register_multi(const struct vnet_modinfo *vmi, void *iarg, if (vml_iter != NULL) panic("registering an already registered vnet module: %s", vml_iter->vml_modinfo->vmi_name); - vml = malloc(sizeof(struct vnet_modlink), M_VIMAGE, M_NOWAIT); + vml = malloc(sizeof(struct vnet_modlink), M_VNET, M_NOWAIT); /* * XXX we support only statically assigned module IDs at the time. @@ -513,7 +260,7 @@ vnet_mod_deregister_multi(const struct vnet_modinfo *vmi, void *iarg, } TAILQ_REMOVE(&vnet_modlink_head, vml, vml_mod_le); - free(vml, M_VIMAGE); + free(vml, M_VNET); } static int @@ -625,75 +372,6 @@ vnet_foreach(void (*vnet_foreach_fn)(struct vnet *, void *), void *arg) VNET_LIST_RUNLOCK(); } -static struct vimage * -vi_alloc(struct vimage *parent, char *name) -{ - struct vimage *vip; - struct vprocg *vprocg; - - vip = malloc(sizeof(struct vimage), M_VIMAGE, M_NOWAIT | M_ZERO); - if (vip == NULL) - panic("vi_alloc: malloc failed for vimage \"%s\"\n", name); - vip->vi_id = last_vi_id++; - LIST_INIT(&vip->vi_child_head); - sprintf(vip->vi_name, "%s", name); - vip->vi_parent = parent; - /* XXX locking */ - if (parent != NULL) - LIST_INSERT_HEAD(&parent->vi_child_head, vip, vi_sibling); - else if (!LIST_EMPTY(&vimage_head)) - panic("there can be only one default vimage!"); - LIST_INSERT_HEAD(&vimage_head, vip, vi_le); - - vip->v_net = vnet_alloc(); - - vprocg = malloc(sizeof(struct vprocg), M_VPROCG, M_NOWAIT | M_ZERO); - if (vprocg == NULL) - panic("vi_alloc: malloc failed for vprocg \"%s\"\n", name); - vip->v_procg = vprocg; - vprocg->vprocg_id = last_vprocg_id++; - - /* XXX locking */ - LIST_INSERT_HEAD(&vprocg_head, vprocg, vprocg_le); - - return (vip); -} - -/* - * Destroy a vnet - unlink all linked lists, hashtables etc., free all - * the memory, stop all the timers... - */ -static int -vi_destroy(struct vimage *vip) -{ - struct vprocg *vprocg = vip->v_procg; - - /* XXX Beware of races -> more locking to be done... */ - if (!LIST_EMPTY(&vip->vi_child_head)) - return (EBUSY); - - if (vprocg->nprocs != 0) - return (EBUSY); - -#ifdef INVARIANTS - if (vip->vi_ucredrefc != 0) - printf("vi_destroy: %s ucredrefc %d\n", - vip->vi_name, vip->vi_ucredrefc); -#endif - - /* Point with no return - cleanup MUST succeed! */ - vnet_destroy(vip->v_net); - - LIST_REMOVE(vip, vi_le); - LIST_REMOVE(vip, vi_sibling); - LIST_REMOVE(vprocg, vprocg_le); - - free(vprocg, M_VPROCG); - free(vip, M_VIMAGE); - - return (0); -} - static void vi_init(void *unused) { @@ -701,22 +379,17 @@ vi_init(void *unused) TAILQ_INIT(&vnet_modlink_head); TAILQ_INIT(&vnet_modpending_head); - LIST_INIT(&vimage_head); - LIST_INIT(&vprocg_head); LIST_INIT(&vnet_head); mtx_init(&vnet_list_refc_mtx, "vnet_list_refc_mtx", NULL, MTX_DEF); cv_init(&vnet_list_condvar, "vnet_list_condvar"); - /* Default image has no parent and no name. */ - vi_alloc(NULL, ""); - /* * We MUST clear curvnet in vi_init_done() before going SMP, * otherwise CURVNET_SET() macros would scream about unnecessary * curvnet recursions. */ - curvnet = prison0.pr_vnet = vnet0 = LIST_FIRST(&vnet_head); + curvnet = prison0.pr_vnet = vnet0 = vnet_alloc(); } static void diff --git a/sys/net/if.c b/sys/net/if.c index f8d2fb1..e779e60 100644 --- a/sys/net/if.c +++ b/sys/net/if.c @@ -2008,7 +2008,7 @@ ifhwioctl(u_long cmd, struct ifnet *ifp, caddr_t data, struct thread *td) error = priv_check(td, PRIV_NET_SETIFVNET); if (error) return (error); - error = vi_if_move(td, ifp, ifr->ifr_name, ifr->ifr_jid, NULL); + error = vi_if_move(td, ifp, ifr->ifr_name, ifr->ifr_jid); break; #endif @@ -2202,20 +2202,7 @@ ifioctl(struct socket *so, u_long cmd, caddr_t data, struct thread *td) error = priv_check(td, PRIV_NET_SETIFVNET); if (error) return (error); - return (vi_if_move(td, NULL, ifr->ifr_name, ifr->ifr_jid, - NULL)); - /* - * XXX vnet creation will be implemented through the new jail - * framework - this is just a temporary hack for testing the - * vnet create / destroy mechanisms. - */ - case SIOCSIFVIMAGE: - error = vi_if_move(td, NULL, NULL, 0, (struct vi_req *) data); - return (error); - case SIOCSPVIMAGE: - case SIOCGPVIMAGE: - error = vi_td_ioctl(cmd, (struct vi_req *) data, td); - return (error); + return (vi_if_move(td, NULL, ifr->ifr_name, ifr->ifr_jid)); #endif case SIOCIFCREATE: case SIOCIFCREATE2: diff --git a/sys/sys/sockio.h b/sys/sys/sockio.h index efaab91..a5911b7 100644 --- a/sys/sys/sockio.h +++ b/sys/sys/sockio.h @@ -111,10 +111,6 @@ #define SIOCSIFVNET _IOWR('i', 90, struct ifreq) /* move IF jail/vnet */ #define SIOCSIFRVNET _IOWR('i', 91, struct ifreq) /* reclaim vnet IF */ -#define SIOCSPVIMAGE _IOW('i', 101, struct vi_req) /* set proc vimage */ -#define SIOCGPVIMAGE _IOWR('i', 102, struct vi_req) /* get proc vimage */ -#define SIOCSIFVIMAGE _IOWR('i', 103, struct vi_req) /* set ifc vi/net */ - #define SIOCSDRVSPEC _IOW('i', 123, struct ifdrv) /* set driver-specific parameters */ #define SIOCGDRVSPEC _IOWR('i', 123, struct ifdrv) /* get driver-specific diff --git a/sys/sys/ucred.h b/sys/sys/ucred.h index c7474b7..a8934ce 100644 --- a/sys/sys/ucred.h +++ b/sys/sys/ucred.h @@ -54,9 +54,9 @@ struct ucred { struct uidinfo *cr_uidinfo; /* per euid resource consumption */ struct uidinfo *cr_ruidinfo; /* per ruid resource consumption */ struct prison *cr_prison; /* jail(2) */ - struct vimage *cr_vimage; /* vimage */ + void *cr_pspare; /* general use */ u_int cr_flags; /* credential flags */ - void *cr_pspare[2]; /* general use 2 */ + void *cr_pspare2[2]; /* general use 2 */ #define cr_endcopy cr_label struct label *cr_label; /* MAC label */ struct auditinfo_addr cr_audit; /* Audit properties. */ diff --git a/sys/sys/vimage.h b/sys/sys/vimage.h index cc0d63d..be83516 100644 --- a/sys/sys/vimage.h +++ b/sys/sys/vimage.h @@ -36,42 +36,14 @@ #include <sys/proc.h> #include <sys/queue.h> -/* Interim userspace API. */ -struct vi_req { - int vi_api_cookie; /* Catch API mismatch. */ - int vi_req_action; /* What to do with this request? */ - u_short vi_proc_count; /* Current number of processes. */ - int vi_if_count; /* Current number of ifnets. */ - int vi_sock_count; - char vi_name[MAXPATHLEN]; - char vi_if_xname[MAXPATHLEN]; /* XXX should be IFNAMSIZ */ -}; - -#define VI_CREATE 0x00000001 -#define VI_DESTROY 0x00000002 -#define VI_SWITCHTO 0x00000008 -#define VI_IFACE 0x00000010 -#define VI_GET 0x00000100 -#define VI_GETNEXT 0x00000200 -#define VI_GETNEXT_RECURSE 0x00000300 - -#define VI_API_VERSION 1 /* Bump on struct changes. */ - -#define VI_API_COOKIE ((sizeof(struct vi_req) << 16) | VI_API_VERSION) - #ifdef _KERNEL #ifdef INVARIANTS #define VNET_DEBUG #endif -struct vimage; -struct vprocg; struct vnet; -struct vi_req; struct ifnet; -struct kld_sym_lookup; -struct thread; typedef int vnet_attach_fn(const void *); typedef int vnet_detach_fn(const void *); @@ -128,16 +100,7 @@ struct vnet_modlink { #define VNET_MOD_DYNAMIC_START 32 #define VNET_MOD_MAX 64 -/* Major module IDs for vimage sysctl virtualization. */ -#define V_GLOBAL 0 /* global variable - no indirection */ -#define V_NET 1 -#define V_PROCG 2 - -int vi_td_ioctl(u_long, struct vi_req *, struct thread *); -int vi_if_move(struct thread *, struct ifnet *, char *, int, - struct vi_req *); -int vi_child_of(struct vimage *, struct vimage *); -struct vimage *vimage_by_name(struct vimage *, char *); +int vi_if_move(struct thread *, struct ifnet *, char *, int); void vnet_mod_register(const struct vnet_modinfo *); void vnet_mod_register_multi(const struct vnet_modinfo *, void *, char *); void vnet_mod_deregister(const struct vnet_modinfo *); @@ -149,18 +112,6 @@ void vnet_foreach(void (*vnet_foreach_fn)(struct vnet *, void *), #endif /* VIMAGE */ -struct vimage { - LIST_ENTRY(vimage) vi_le; /* all vimage list */ - LIST_ENTRY(vimage) vi_sibling; /* vimages with same parent */ - LIST_HEAD(, vimage) vi_child_head; /* direct offspring list */ - struct vimage *vi_parent; /* ptr to parent vimage */ - u_int vi_id; /* ID num */ - volatile u_int vi_ucredrefc; /* # of ucreds pointing to us */ - char vi_name[MAXHOSTNAMELEN]; - struct vnet *v_net; - struct vprocg *v_procg; -}; - struct vnet { LIST_ENTRY(vnet) vnet_le; /* all vnets list */ u_int vnet_magic_n; @@ -170,19 +121,6 @@ struct vnet { uintptr_t vnet_data_base; }; -struct vprocg { - LIST_ENTRY(vprocg) vprocg_le; - u_int vprocg_id; /* ID num */ - u_int nprocs; -}; - -#ifdef VIMAGE -LIST_HEAD(vimage_list_head, vimage); -extern struct vimage_list_head vimage_head; -#else /* !VIMAGE */ -extern struct vprocg vprocg_0; -#endif /* VIMAGE */ - #define curvnet curthread->td_vnet #define VNET_MAGIC_N 0x3e0d8f29 @@ -249,39 +187,19 @@ extern struct vnet *vnet0; #endif #ifdef VIMAGE -LIST_HEAD(vprocg_list_head, vprocg); -extern struct vprocg_list_head vprocg_head; -#define INIT_VPROCG(arg) struct vprocg *vprocg = (arg); -#else -#define INIT_VPROCG(arg) -#endif - -#ifdef VIMAGE -#define IS_DEFAULT_VIMAGE(arg) ((arg)->vi_id == 0) #define IS_DEFAULT_VNET(arg) ((arg) == vnet0) #else -#define IS_DEFAULT_VIMAGE(arg) 1 #define IS_DEFAULT_VNET(arg) 1 #endif #ifdef VIMAGE -#define CRED_TO_VNET(cr) \ - (IS_DEFAULT_VIMAGE((cr)->cr_vimage) ? (cr)->cr_prison->pr_vnet \ - : (cr)->cr_vimage->v_net) -#define TD_TO_VIMAGE(td) (td)->td_ucred->cr_vimage +#define CRED_TO_VNET(cr) (cr)->cr_prison->pr_vnet #define TD_TO_VNET(td) CRED_TO_VNET((td)->td_ucred) -#define TD_TO_VPROCG(td) (td)->td_ucred->cr_vimage->v_procg -#define P_TO_VIMAGE(p) (p)->p_ucred->cr_vimage #define P_TO_VNET(p) CRED_TO_VNET((p)->p_ucred) -#define P_TO_VPROCG(p) (p)->p_ucred->cr_vimage->v_procg #else /* !VIMAGE */ #define CRED_TO_VNET(cr) NULL -#define TD_TO_VIMAGE(td) NULL #define TD_TO_VNET(td) NULL -#define P_TO_VIMAGE(p) NULL #define P_TO_VNET(p) NULL -#define TD_TO_VPROCG(td) &vprocg_0 -#define P_TO_VPROCG(p) &vprocg_0 #endif /* VIMAGE */ /* Non-VIMAGE null-macros */ diff --git a/tools/tools/vimage/Makefile b/tools/tools/vimage/Makefile index 3397a34..82f4f47 100644 --- a/tools/tools/vimage/Makefile +++ b/tools/tools/vimage/Makefile @@ -1,6 +1,8 @@ # $FreeBSD$ PROG= vimage +LDADD= -ljail +DPADD= ${LIBJAIL} WARNS?= 2 CFLAGS+= -I../../../sys diff --git a/tools/tools/vimage/vimage.c b/tools/tools/vimage/vimage.c index b332498..e4ab584 100644 --- a/tools/tools/vimage/vimage.c +++ b/tools/tools/vimage/vimage.c @@ -27,122 +27,120 @@ * $FreeBSD$ */ +#include <sys/param.h> #include <sys/types.h> #include <sys/ioctl.h> +#include <sys/jail.h> #include <sys/socket.h> -#include <sys/vimage.h> + +#include <net/if.h> #include <errno.h> +#include <jail.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> -void -vi_print(struct vi_req *vi_req) -{ +#define VI_CREATE 0x00000001 +#define VI_DESTROY 0x00000002 +#define VI_SWITCHTO 0x00000008 +#define VI_IFACE 0x00000010 +#define VI_GET 0x00000100 +#define VI_GETNEXT 0x00000200 - printf("\"%s\":\n", vi_req->vi_name); - printf(" %d sockets, %d ifnets, %d processes\n", - vi_req->vi_sock_count, vi_req->vi_if_count, vi_req->vi_proc_count); -} +static int getjail(char *name, int lastjid, int *vnet); int main(int argc, char **argv) { int s; char *shell; - int cmd = VI_SWITCHTO; - struct vi_req vi_req; + int cmd; + int jid, vnet; + struct ifreq ifreq; + char name[MAXHOSTNAMELEN]; - s = socket(AF_INET, SOCK_DGRAM, 0); - if (s == -1) - goto abort; + switch (argc) { - bzero(&vi_req, sizeof(vi_req)); - strcpy(vi_req.vi_name, "."); /* . = this vimage. */ - - if (argc == 1) - cmd = VI_GET; - - if (argc == 2 && strcmp(argv[1], "-l") == 0) - cmd = VI_GETNEXT; + case 1: + cmd = 0; + break; - if (argc == 2 && strcmp(argv[1], "-lr") == 0) - cmd = VI_GETNEXT_RECURSE; + case 2: + if (strcmp(argv[1], "-l") == 0) + cmd = VI_GETNEXT; + else if (strcmp(argv[1], "-lr") == 0) + cmd = VI_GETNEXT; + else { + strcpy(name, argv[1]); + cmd = VI_SWITCHTO; + } + break; - if (argc == 3) { - strcpy(vi_req.vi_name, argv[2]); + case 3: + strcpy(name, argv[2]); if (strcmp(argv[1], "-l") == 0) cmd = VI_GET; if (strcmp(argv[1], "-c") == 0) cmd = VI_CREATE; if (strcmp(argv[1], "-d") == 0) cmd = VI_DESTROY; - } + break; - if (argc >= 3) { - strcpy(vi_req.vi_name, argv[2]); + default: + strcpy(name, argv[2]); if (strcmp(argv[1], "-c") == 0) cmd = VI_CREATE; if (strcmp(argv[1], "-i") == 0) cmd = VI_IFACE; } - vi_req.vi_api_cookie = VI_API_COOKIE; - vi_req.vi_req_action = cmd; switch (cmd) { case VI_GET: - if (ioctl(s, SIOCGPVIMAGE, (caddr_t)&vi_req) < 0) + jid = getjail(name, -1, &vnet); + if (jid < 0) goto abort; - if (argc == 1) - printf("%s\n", vi_req.vi_name); - else - vi_print(&vi_req); + printf("%d: %s%s\n", jid, name, vnet ? "" : " (no vnet)"); exit(0); case VI_GETNEXT: - case VI_GETNEXT_RECURSE: - vi_req.vi_req_action = VI_GET; - if (ioctl(s, SIOCGPVIMAGE, (caddr_t)&vi_req) < 0) - goto abort; - vi_print(&vi_req); - vi_req.vi_req_action = VI_GETNEXT_RECURSE; - while (ioctl(s, SIOCGPVIMAGE, (caddr_t)&vi_req) == 0) { - vi_print(&vi_req); - vi_req.vi_req_action = cmd; - } + jid = 0; + while ((jid = getjail(name, jid, &vnet)) > 0) + printf("%d: %s%s\n", jid, name, + vnet ? "" : " (no vnet)"); exit(0); case VI_IFACE: - strncpy(vi_req.vi_if_xname, argv[3], - sizeof(vi_req.vi_if_xname)); - if (ioctl(s, SIOCSIFVIMAGE, (caddr_t)&vi_req) < 0) + s = socket(AF_INET, SOCK_DGRAM, 0); + if (s == -1) + goto abort; + jid = jail_getid(name); + if (jid < 0) goto abort; - printf("%s@%s\n", vi_req.vi_if_xname, vi_req.vi_name); + ifreq.ifr_jid = jid; + strncpy(ifreq.ifr_name, argv[3], sizeof(ifreq.ifr_name)); + if (ioctl(s, SIOCSIFVNET, (caddr_t)&ifreq) < 0) + goto abort; + printf("%s@%s\n", ifreq.ifr_name, name); exit(0); case VI_CREATE: - if (ioctl(s, SIOCSPVIMAGE, (caddr_t)&vi_req) < 0) + if (jail_setv(JAIL_CREATE, "name", name, "vnet", NULL, + "host", NULL, "persist", NULL, NULL) < 0) goto abort; exit(0); case VI_SWITCHTO: - strcpy(vi_req.vi_name, argv[1]); - if (ioctl(s, SIOCSPVIMAGE, (caddr_t)&vi_req) < 0) + jid = jail_getid(name); + if (jid < 0) goto abort; - - vi_req.vi_req_action = VI_GET; - strcpy(vi_req.vi_name, "."); - if (ioctl(s, SIOCGPVIMAGE, (caddr_t)&vi_req) < 0) { - printf("XXX this should have not happened!\n"); + if (jail_attach(jid) < 0) goto abort; - } - close(s); if (argc == 2) { - printf("Switched to vimage %s\n", argv[1]); + printf("Switched to jail %s\n", argv[1]); if ((shell = getenv("SHELL")) == NULL) execlp("/bin/sh", argv[0], NULL); else @@ -152,7 +150,10 @@ main(int argc, char **argv) break; case VI_DESTROY: - if (ioctl(s, SIOCSPVIMAGE, (caddr_t)&vi_req) < 0) + jid = jail_getid(name); + if (jid < 0) + goto abort; + if (jail_remove(jid) < 0) goto abort; exit(0); @@ -163,6 +164,35 @@ main(int argc, char **argv) } abort: - perror("Error"); + if (jail_errmsg[0]) + fprintf(stderr, "Error: %s\n", jail_errmsg); + else + perror("Error"); exit(1); } + +static int +getjail(char *name, int lastjid, int *vnet) +{ + struct jailparam params[3]; + int jid; + + if (lastjid < 0) { + jid = jail_getid(name); + if (jid < 0) + return (jid); + jailparam_init(¶ms[0], "jid"); + jailparam_import_raw(¶ms[0], &jid, sizeof jid); + } else { + jailparam_init(¶ms[0], "lastjid"); + jailparam_import_raw(¶ms[0], &lastjid, sizeof lastjid); + } + jailparam_init(¶ms[1], "name"); + jailparam_import_raw(¶ms[1], name, MAXHOSTNAMELEN); + name[0] = 0; + jailparam_init(¶ms[2], "vnet"); + jailparam_import_raw(¶ms[2], vnet, sizeof(*vnet)); + jid = jailparam_get(params, 3, 0); + jailparam_free(params, 3); + return (jid); +} |