Annotation of src/sys/dev/verified_exec.c, Revision 1.52
1.52 ! elad 1: /* $NetBSD: verified_exec.c,v 1.51 2006/11/30 01:09:47 elad Exp $ */
1.1 blymn 2:
3: /*-
1.38 elad 4: * Copyright 2005 Elad Efrat <elad@NetBSD.org>
1.7 blymn 5: * Copyright 2005 Brett Lymn <blymn@netbsd.org>
1.1 blymn 6: *
1.7 blymn 7: * This code is derived from software contributed to The NetBSD Foundation
8: * by Brett Lymn and Elad Efrat
1.1 blymn 9: *
10: * Redistribution and use in source and binary forms, with or without
11: * modification, are permitted provided that the following conditions
12: * are met:
13: * 1. Redistributions of source code must retain the above copyright
14: * notice, this list of conditions and the following disclaimer.
1.7 blymn 15: * 2. Neither the name of The NetBSD Foundation nor the names of its
16: * contributors may be used to endorse or promote products derived
17: * from this software without specific prior written permission.
1.1 blymn 18: *
1.7 blymn 19: * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
20: * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21: * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22: * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23: * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24: * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25: * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26: * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27: * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28: * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29: * POSSIBILITY OF SUCH DAMAGE.
1.1 blymn 30: */
1.4 lukem 31:
32: #include <sys/cdefs.h>
1.7 blymn 33: #if defined(__NetBSD__)
1.52 ! elad 34: __KERNEL_RCSID(0, "$NetBSD: verified_exec.c,v 1.51 2006/11/30 01:09:47 elad Exp $");
1.7 blymn 35: #else
1.52 ! elad 36: __RCSID("$Id: verified_exec.c,v 1.51 2006/11/30 01:09:47 elad Exp $\n$NetBSD: verified_exec.c,v 1.51 2006/11/30 01:09:47 elad Exp $");
1.7 blymn 37: #endif
1.1 blymn 38:
39: #include <sys/param.h>
40: #include <sys/errno.h>
1.51 elad 41: #include <sys/conf.h>
42: #include <sys/vnode.h>
43: #include <sys/fcntl.h>
44: #include <sys/namei.h>
45: #include <sys/verified_exec.h>
46: #include <sys/kauth.h>
47: #include <sys/syslog.h>
1.7 blymn 48:
49: #ifdef __FreeBSD__
50: #include <sys/kernel.h>
51: #include <sys/device_port.h>
52: #include <sys/ioccom.h>
53: #else
1.1 blymn 54: #include <sys/ioctl.h>
55: #include <sys/device.h>
1.7 blymn 56: #define DEVPORT_DEVICE struct device
57: #endif
58:
1.50 elad 59: #include <prop/proplib.h>
60:
1.7 blymn 61: struct veriexec_softc {
62: DEVPORT_DEVICE veriexec_dev;
1.1 blymn 63: };
64:
1.7 blymn 65: #if defined(__FreeBSD__)
66: # define CDEV_MAJOR 216
67: # define BDEV_MAJOR -1
68: #endif
69:
70: const struct cdevsw veriexec_cdevsw = {
71: veriexecopen,
72: veriexecclose,
73: noread,
74: nowrite,
75: veriexecioctl,
76: #ifdef __NetBSD__
77: nostop,
78: notty,
79: #endif
80: nopoll,
81: nommap,
82: #if defined(__NetBSD__)
83: nokqfilter,
1.42 christos 84: D_OTHER,
1.7 blymn 85: #elif defined(__FreeBSD__)
86: nostrategy,
87: "veriexec",
88: CDEV_MAJOR,
89: nodump,
90: nopsize,
91: 0, /* flags */
92: BDEV_MAJOR
93: #endif
1.1 blymn 94: };
95:
1.50 elad 96: static int veriexec_query(prop_dictionary_t, prop_dictionary_t, struct lwp *);
1.52 ! elad 97: static int veriexec_delete(prop_dictionary_t, struct lwp *);
1.50 elad 98:
1.51 elad 99: /* count of number of times device is open (we really only allow one open) */
100: static unsigned int veriexec_dev_usage;
101:
1.1 blymn 102: void
1.48 christos 103: veriexecattach(DEVPORT_DEVICE *parent, DEVPORT_DEVICE *self,
104: void *aux)
1.7 blymn 105: {
106: veriexec_dev_usage = 0;
1.18 elad 107:
108: if (veriexec_verbose >= 2)
1.36 elad 109: log(LOG_DEBUG, "Veriexec: Pseudo-device attached.\n");
1.7 blymn 110: }
111:
112: int
1.48 christos 113: veriexecopen(dev_t dev, int flags,
114: int fmt, struct lwp *l)
1.1 blymn 115: {
1.17 elad 116: if (veriexec_verbose >= 2) {
1.36 elad 117: log(LOG_DEBUG, "Veriexec: Pseudo-device open attempt by "
118: "uid=%u, pid=%u. (dev=%u)\n",
1.39 ad 119: kauth_cred_geteuid(l->l_cred), l->l_proc->p_pid,
1.36 elad 120: dev);
1.17 elad 121: }
1.7 blymn 122:
1.39 ad 123: if (kauth_authorize_generic(l->l_cred, KAUTH_GENERIC_ISSUSER,
124: &l->l_acflag) != 0)
1.13 elad 125: return (EPERM);
126:
1.7 blymn 127: if (veriexec_dev_usage > 0) {
1.18 elad 128: if (veriexec_verbose >= 2)
1.36 elad 129: log(LOG_ERR, "Veriexec: pseudo-device already in "
130: "use.\n");
1.18 elad 131:
1.7 blymn 132: return(EBUSY);
133: }
134:
135: veriexec_dev_usage++;
136: return (0);
1.1 blymn 137: }
138:
139: int
1.48 christos 140: veriexecclose(dev_t dev, int flags, int fmt,
141: struct lwp *l)
1.1 blymn 142: {
1.7 blymn 143: if (veriexec_dev_usage > 0)
144: veriexec_dev_usage--;
145: return (0);
1.1 blymn 146: }
147:
148: int
1.48 christos 149: veriexecioctl(dev_t dev, u_long cmd, caddr_t data, int flags,
1.36 elad 150: struct lwp *l)
1.1 blymn 151: {
1.50 elad 152: struct plistref *plistref;
153: prop_dictionary_t dict;
1.7 blymn 154: int error = 0;
155:
1.41 elad 156: if (veriexec_strict > VERIEXEC_LEARNING) {
1.36 elad 157: log(LOG_WARNING, "Veriexec: Strict mode, modifying tables not "
158: "permitted.\n");
1.1 blymn 159:
1.7 blymn 160: return (EPERM);
1.1 blymn 161: }
1.34 blymn 162:
1.50 elad 163: plistref = (struct plistref *)data;
164:
1.7 blymn 165: switch (cmd) {
1.27 elad 166: case VERIEXEC_TABLESIZE:
1.50 elad 167: error = prop_dictionary_copyin_ioctl(plistref, cmd, &dict);
168: if (error)
169: break;
170:
1.51 elad 171: error = veriexec_table_add(l, dict);
1.50 elad 172: prop_object_release(dict);
1.7 blymn 173: break;
1.1 blymn 174:
1.27 elad 175: case VERIEXEC_LOAD:
1.50 elad 176: error = prop_dictionary_copyin_ioctl(plistref, cmd, &dict);
177: if (error)
178: break;
179:
1.51 elad 180: error = veriexec_file_add(l, dict);
1.50 elad 181: prop_object_release(dict);
1.7 blymn 182: break;
1.5 perry 183:
1.28 elad 184: case VERIEXEC_DELETE:
1.50 elad 185: error = prop_dictionary_copyin_ioctl(plistref, cmd, &dict);
186: if (error)
187: break;
188:
1.52 ! elad 189: error = veriexec_delete(dict, l);
1.50 elad 190: prop_object_release(dict);
1.28 elad 191: break;
192:
1.50 elad 193: case VERIEXEC_QUERY: {
194: prop_dictionary_t rdict;
195:
196: error = prop_dictionary_copyin_ioctl(plistref, cmd, &dict);
197: if (error)
198: return (error);
199:
200: rdict = prop_dictionary_create();
201: if (rdict == NULL) {
202: error = ENOMEM;
203: break;
204: }
205:
206: error = veriexec_query(dict, rdict, l);
207: if (error == 0) {
208: error = prop_dictionary_copyout_ioctl(plistref, cmd,
209: rdict);
210: }
211:
212: prop_object_release(rdict);
213: prop_object_release(dict);
214:
1.31 elad 215: break;
1.50 elad 216: }
1.31 elad 217:
1.1 blymn 218: default:
1.7 blymn 219: /* Invalid operation. */
1.1 blymn 220: error = ENODEV;
1.7 blymn 221: break;
1.1 blymn 222: }
223:
224: return (error);
225: }
226:
1.7 blymn 227: #if defined(__FreeBSD__)
228: static void
1.48 christos 229: veriexec_drvinit(void *unused)
1.7 blymn 230: {
231: make_dev(&verifiedexec_cdevsw, 0, UID_ROOT, GID_WHEEL, 0600,
1.36 elad 232: "veriexec");
1.7 blymn 233: verifiedexecattach(0, 0, 0);
234: }
235:
236: SYSINIT(veriexec, SI_SUB_PSEUDO, SI_ORDER_ANY, veriexec_drvinit, NULL);
237: #endif
1.27 elad 238:
1.50 elad 239: static int
1.52 ! elad 240: veriexec_delete(prop_dictionary_t dict, struct lwp *l)
! 241: {
! 242: struct nameidata nid;
! 243: int error;
! 244:
! 245: NDINIT(&nid, LOOKUP, FOLLOW, UIO_SYSSPACE,
! 246: prop_string_cstring_nocopy(prop_dictionary_get(dict, "file")), l);
! 247: error = namei(&nid);
! 248: if (error)
! 249: return (error);
! 250:
! 251: /* XXX this should be done differently... */
! 252: if (nid.ni_vp->v_type == VREG)
! 253: error = veriexec_file_delete(nid.ni_vp);
! 254: else if (nid.ni_vp->v_type == VDIR)
! 255: error = veriexec_table_delete(nid.ni_vp->v_mount);
! 256:
! 257: vrele(nid.ni_vp);
! 258:
! 259: return (error);
! 260: }
! 261:
! 262: static int
1.50 elad 263: veriexec_query(prop_dictionary_t dict, prop_dictionary_t rdict, struct lwp *l)
1.31 elad 264: {
1.35 elad 265: struct nameidata nid;
1.31 elad 266: int error;
267:
1.50 elad 268: NDINIT(&nid, LOOKUP, FOLLOW, UIO_SYSSPACE,
269: prop_string_cstring_nocopy(prop_dictionary_get(dict, "file")), l);
1.35 elad 270: error = namei(&nid);
271: if (error)
272: return (error);
273:
1.52 ! elad 274: error = veriexec_convert(nid.ni_vp, rdict);
! 275:
1.51 elad 276: vrele(nid.ni_vp);
277:
1.31 elad 278: return (error);
279: }
CVSweb <webmaster@jp.NetBSD.org>