1 /* $NetBSD: verified_exec.c,v 1.65 2009/05/12 14:16:35 cegger Exp $ */
4 * Copyright (c) 2005, 2006 Elad Efrat <elad@NetBSD.org>
5 * Copyright (c) 2005, 2006 Brett Lymn <blymn@NetBSD.org>
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
16 * 3. The name of the authors may not be used to endorse or promote products
17 * derived from this software without specific prior written permission.
19 * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR
20 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
21 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
22 * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT,
23 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
24 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
28 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 #include <sys/cdefs.h>
32 __KERNEL_RCSID(0, "$NetBSD: verified_exec.c,v 1.65 2009/05/12 14:16:35 cegger Exp $");
34 #include <sys/param.h>
35 #include <sys/errno.h>
37 #include <sys/vnode.h>
38 #include <sys/fcntl.h>
39 #include <sys/namei.h>
40 #include <sys/verified_exec.h>
41 #include <sys/kauth.h>
42 #include <sys/syslog.h>
46 #include <sys/kernel.h>
47 #include <sys/device_port.h>
48 #include <sys/ioccom.h>
50 #include <sys/ioctl.h>
51 #include <sys/device.h>
52 #define DEVPORT_DEVICE struct device
55 #include <prop/proplib.h>
57 void veriexecattach(device_t
, device_t
, void *);
58 static dev_type_open(veriexecopen
);
59 static dev_type_close(veriexecclose
);
60 static dev_type_ioctl(veriexecioctl
);
62 struct veriexec_softc
{
63 DEVPORT_DEVICE veriexec_dev
;
66 #if defined(__FreeBSD__)
67 # define CDEV_MAJOR 216
68 # define BDEV_MAJOR -1
71 const struct cdevsw veriexec_cdevsw
= {
83 #if defined(__NetBSD__)
86 #elif defined(__FreeBSD__)
97 /* count of number of times device is open (we really only allow one open) */
98 static unsigned int veriexec_dev_usage
= 0;
101 veriexecattach(DEVPORT_DEVICE
*parent
, DEVPORT_DEVICE
*self
, void *aux
)
103 veriexec_dev_usage
= 0;
107 veriexecopen(dev_t dev
, int flags
, int fmt
, struct lwp
*l
)
109 if (kauth_authorize_generic(l
->l_cred
, KAUTH_GENERIC_ISSUSER
, NULL
))
112 if (veriexec_dev_usage
> 0)
115 veriexec_dev_usage
++;
120 veriexecclose(dev_t dev
, int flags
, int fmt
, struct lwp
*l
)
122 if (veriexec_dev_usage
> 0)
123 veriexec_dev_usage
--;
128 veriexec_delete(prop_dictionary_t dict
, struct lwp
*l
)
134 if (!prop_dictionary_get_cstring_nocopy(dict
, "file", &file
))
137 error
= namei_simple_kernel(file
, NSM_FOLLOW_NOEMULROOT
, &vp
);
141 /* XXX this should be done differently... */
142 if (vp
->v_type
== VREG
)
143 error
= veriexec_file_delete(l
, vp
);
144 else if (vp
->v_type
== VDIR
)
145 error
= veriexec_table_delete(l
, vp
->v_mount
);
153 veriexec_query(prop_dictionary_t dict
, prop_dictionary_t rdict
, struct lwp
*l
)
159 if (!prop_dictionary_get_cstring_nocopy(dict
, "file", &file
))
162 error
= namei_simple_kernel(file
, NSM_FOLLOW_NOEMULROOT
, &vp
);
166 error
= veriexec_convert(vp
, rdict
);
174 veriexecioctl(dev_t dev
, u_long cmd
, void *data
, int flags
, struct lwp
*l
)
176 extern int veriexec_strict
;
177 struct plistref
*plistref
;
178 prop_dictionary_t dict
;
181 /* XXX This should be replaced with a kauth(9) request. */
183 case VERIEXEC_TABLESIZE
:
185 case VERIEXEC_DELETE
:
187 if (!(flags
& FWRITE
))
190 if (veriexec_strict
> VERIEXEC_LEARNING
) {
191 log(LOG_WARNING
, "Veriexec: Strict mode, modifying "
192 "tables not permitted.\n");
201 if (!(flags
& FREAD
))
207 /* Invalid operation. */
211 plistref
= (struct plistref
*)data
;
214 case VERIEXEC_TABLESIZE
:
215 /* Do nothing. Kept for binary compatibility. */
219 error
= prop_dictionary_copyin_ioctl(plistref
, cmd
, &dict
);
223 error
= veriexec_file_add(l
, dict
);
224 prop_object_release(dict
);
227 case VERIEXEC_DELETE
:
228 error
= prop_dictionary_copyin_ioctl(plistref
, cmd
, &dict
);
232 error
= veriexec_delete(dict
, l
);
233 prop_object_release(dict
);
236 case VERIEXEC_QUERY
: {
237 prop_dictionary_t rdict
;
239 error
= prop_dictionary_copyin_ioctl(plistref
, cmd
, &dict
);
243 rdict
= prop_dictionary_create();
245 prop_object_release(dict
);
250 error
= veriexec_query(dict
, rdict
, l
);
252 error
= prop_dictionary_copyout_ioctl(plistref
, cmd
,
256 prop_object_release(rdict
);
257 prop_object_release(dict
);
262 case VERIEXEC_DUMP
: {
265 rarray
= prop_array_create();
266 if (rarray
== NULL
) {
271 error
= veriexec_dump(l
, rarray
);
273 error
= prop_array_copyout_ioctl(plistref
, cmd
,
277 prop_object_release(rarray
);
283 error
= veriexec_flush(l
);
287 /* Invalid operation. */
295 #if defined(__FreeBSD__)
297 veriexec_drvinit(void *unused
)
299 make_dev(&verifiedexec_cdevsw
, 0, UID_ROOT
, GID_WHEEL
, 0600,
301 verifiedexecattach(0, 0, 0);
304 SYSINIT(veriexec
, SI_SUB_PSEUDO
, SI_ORDER_ANY
, veriexec_drvinit
, NULL
);