[BACK]Return to verified_exec.c CVS log [TXT][DIR] Up to [cvs.NetBSD.org] / src / sys / dev

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>