Date: Wed, 4 Dec 2002 16:40:42 -0800 (PST) From: Chris Vance <cvance@FreeBSD.org> To: Perforce Change Reviews <perforce@freebsd.org> Subject: PERFORCE change 21944 for review Message-ID: <200212050040.gB50egD4074264@repoman.freebsd.org>
next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=21944 Change 21944 by cvance@cvance_laptop on 2002/12/04 16:39:57 - Add labeling of devfs devices and directories; however, symlinks created after boot are not yet supported. - Reorganize and better group hook functions - Fix a few of the glaringly obvious style errors Affected files ... .. //depot/projects/trustedbsd/mac/sys/security/sebsd/sebsd.c#60 edit Differences ... ==== //depot/projects/trustedbsd/mac/sys/security/sebsd/sebsd.c#60 (text+ko) ==== @@ -48,6 +48,9 @@ #include <sys/systm.h> #include <sys/sysproto.h> #include <sys/vnode.h> +#include <sys/dirent.h> + +#include <fs/devfs/devfs.h> #include <vm/vm.h> @@ -89,17 +92,23 @@ task = SLOT(&cred->cr_label); target = SLOT(&proc->p_ucred->cr_label); - return avc_has_perm_ref(task->sid, target->sid, SECCLASS_PROCESS, - perm, &target->avcr); + return (avc_has_perm_ref(task->sid, target->sid, SECCLASS_PROCESS, + perm, &target->avcr)); } -#if 0 static int -thread_has_perm(struct thread *td, struct proc *proc, access_vector_t perm) +mount_has_perm(struct ucred *cred, struct mount *mp, access_vector_t perm, + avc_audit_data_t *ad) { - return (cred_has_perm(td->td_proc->p_ucred, proc, perm)); + struct mount_security_struct *sbsec; + struct task_security_struct *task; + + task = SLOT(&cred->cr_label); + sbsec = SLOT(&mp->mnt_mntlabel); + + return (avc_has_perm_audit(task->sid, sbsec->sid, SECCLASS_FILESYSTEM, + perm, ad)); } -#endif static int cred_has_system(struct ucred *cred, access_vector_t perm) @@ -144,6 +153,32 @@ return SECCLASS_FILE; } +static __inline security_class_t +dirent_type_to_security_class(__uint8_t type) +{ + switch (type) { + case DT_REG: + return SECCLASS_FILE; + case DT_DIR: + return SECCLASS_DIR; + case DT_BLK: + return SECCLASS_BLK_FILE; + case DT_CHR: + return SECCLASS_CHR_FILE; + case DT_LNK: + return SECCLASS_LNK_FILE; + case DT_SOCK: + return SECCLASS_SOCK_FILE; + case DT_FIFO: + return SECCLASS_FIFO_FILE; + case DT_UNKNOWN: + case DT_WHT: + return SECCLASS_FILE; + } + + return SECCLASS_FILE; +} + static __inline access_vector_t file_mask_to_av(enum vtype vt, int mask) { @@ -213,6 +248,138 @@ } static void +sebsd_init_mount_label(struct label *label) +{ + struct mount_security_struct *sbsec; + + sbsec = malloc(sizeof(*sbsec), M_SEBSD, M_ZERO | M_WAITOK); + memset(sbsec, 0, sizeof(struct mount_security_struct)); + sbsec->sid = SECINITSID_UNLABELED; + SLOT(label) = sbsec; +} + +static void +sebsd_init_mount_fs_label(struct label *label) +{ + + /* TBD: Currently Unecessary */ + SLOT(label) = NULL; +} + +static void +sebsd_init_vnode_label(struct label *label) +{ + struct vnode_security_struct *vsec; + + vsec = malloc(sizeof(*vsec), M_SEBSD, M_ZERO | M_WAITOK); + vsec->sid = SECINITSID_UNLABELED; + vsec->task_sid = SECINITSID_UNLABELED; + SLOT(label) = vsec; +} + +static void +sebsd_destroy_label(struct label *label) +{ + free(SLOT(label), M_SEBSD); + SLOT(label) = NULL; +} + +static void +sebsd_relabel_cred(struct ucred *cred, struct label *newlabel) +{ + printf("sebsd_relabel_cred:: This does nothing\n"); +} + +static void +sebsd_associate_vnode_devfs(struct mount *mp, struct label *fslabel, + struct devfs_dirent *de, struct label *delabel, struct vnode *vp, + struct label *vlabel) +{ + struct vnode_security_struct *vsec, *dsec; + + dsec = SLOT(delabel); + vsec = SLOT(vlabel); + + vsec->sid = dsec->sid; + vsec->task_sid = dsec->task_sid; + vsec->sclass = dsec->sclass; + + /* + * This is a no-op for now, but when devfs_dirents do contain + * labels, they should be copied to the vp here as per how + * sebsd_update_vnode_from_extattr() functions. They will be + * kept synchronized from here on automatically with the vnode + * relabel calls. + */ + +} + +static int +sebsd_associate_vnode_extattr(struct mount *mp, struct label *fslabel, + struct vnode *vp, struct label *vlabel) +{ + struct vnode_security_struct *vsec; + /* TBD: Need to limit size of contexts used in extattr labels */ + char context[128]; + u_int32_t context_len; + int error; + + vsec = SLOT(vlabel); + + context_len = sizeof(context); /* TBD: bad fixed length */ + error = vn_extattr_get(vp, IO_NODELOCKED, + SEBSD_MAC_EXTATTR_NAMESPACE, + SEBSD_MAC_EXTATTR_NAME, + &context_len, context, curthread); + if (error == ENOATTR || error == EOPNOTSUPP) { + vsec->sid = SECINITSID_UNLABELED; /* Use the default label */ + struct vattr va; + + (void)VOP_GETATTR(vp, &va, curthread->td_ucred, curthread); + printf("sebsd_update_vnode_from_extattr: no label for " + "inode=%ld, fsid=%d\n", va.va_fileid, va.va_fsid); + goto dosclass; + } + if (error) { + printf("sebsd_update_vnode_from_extattr: ERROR %d returned " + " by vn_extattr_get()\n", error); + return (error); /* Fail closed */ + } + if (sebsd_verbose > 1) { + struct vattr va; + + VOP_GETATTR(vp, &va, curthread->td_ucred, curthread); + printf("sebsd_vnode_from_extattr: len=%d: context=%.*s " + "inode=%ld, fsid=%d\n", context_len, context_len, + context, va.va_fileid, va.va_fsid); + } + + error = security_context_to_sid(context, context_len, &vsec->sid); + if (error) { + printf("sebsd_update_vnode_from_extattr: ERROR mapping " + "context to sid: %.*s\n", context_len, context); + return (0); /* TBD bad, bad, bad */ + } + +dosclass: + /* TBD: */ + vsec->sclass = vnode_type_to_security_class(vp->v_type); + if (vsec->sclass == 0) { + printf("sebsd_update_vnode_from_extattr:: sclass is 0\n"); + } + + return (0); +} + +static void +sebsd_associate_vnode_singlelabel(struct mount *mp, struct label *fslabel, + struct vnode *vp, struct label *vlabel) +{ + + /* TBD, default to SECINITSID_UNLABELED. */ +} + +static void sebsd_create_cred(struct ucred *cred_parent, struct ucred *cred_child) { int rc; @@ -232,33 +399,131 @@ return; } -/* - * SEBSD does not support the relabeling of processes without - * transitioning. - */ -static int -sebsd_check_cred_relabel(struct ucred *cred, struct label *newlabel) +static void +sebsd_create_devfs_device(struct mount *mp, dev_t dev, + struct devfs_dirent *devfs_dirent, struct label *label) { - struct task_security_struct *nsec, *tsec; + char *path; + int rc; + security_id_t newsid; + struct mount_security_struct *sbsec; + struct vnode_security_struct *dirent; + + dirent = SLOT(label); + sbsec = SLOT(&mp->mnt_mntlabel); + + /* Default to the filesystem SID. */ + dirent->sid = sbsec->sid; + dirent->task_sid = SECINITSID_KERNEL; + dirent->sclass = + dirent_type_to_security_class(devfs_dirent->de_dirent->d_type); + + /* Obtain a SID based on the fstype, path, and class. */ + path = malloc(strlen(dev->si_name) + 2, M_SEBSD, M_ZERO | M_WAITOK); + path[0] = '/'; + strcpy(&path[1], dev->si_name); + rc = security_genfs_sid(mp->mnt_vfc->vfc_name, path, dirent->sclass, + &newsid); + if (rc == 0) + dirent->sid = newsid; - nsec = SLOT(newlabel); - tsec = SLOT(&cred->cr_label); - if (nsec != NULL && nsec->sid != tsec->sid) - return EPERM; - return 0; + /* TBD: debugging */ + if (sebsd_verbose > 1) { + printf("sebsd_create_devfs_device(%s): sbsid=%d, " + "mountpoint=%s, rc=%d, sclass=%d, computedsid=%d, " + "dirent=%d\n", path, sbsec->sid, mp->mnt_stat.f_mntonname, + rc, dirent->sclass, newsid, dirent->sid); + } + free(path, M_SEBSD); } static void -sebsd_relabel_cred(struct ucred *cred, struct label *newlabel) +sebsd_create_devfs_directory(struct mount *mp, char *dirname, + int dirnamelen, struct devfs_dirent *devfs_dirent, struct label *label) { - printf("sebsd_relabel_cred:: This does nothing\n"); + char *path; + int rc; + security_id_t newsid; + struct mount_security_struct *sbsec; + struct vnode_security_struct *dirent; + + dirent = SLOT(label); + sbsec = SLOT(&mp->mnt_mntlabel); + + /* Default to the filesystem SID. */ + dirent->sid = sbsec->sid; + dirent->task_sid = SECINITSID_KERNEL; + dirent->sclass = SECCLASS_DIR; + + /* Obtain a SID based on the fstype, path, and class. */ + path = malloc(dirnamelen + 2, M_SEBSD, M_ZERO | M_WAITOK); + path[0] = '/'; + strncpy(&path[1], dirname, dirnamelen); + path[dirnamelen+1] = '\0'; + rc = security_genfs_sid(mp->mnt_vfc->vfc_name, path, dirent->sclass, + &newsid); + if (rc == 0) + dirent->sid = newsid; + + /* TBD: debugging */ + if (sebsd_verbose > 1) { + printf("%s(%s): sbsid=%d, mountpoint=%s, " + "rc=%d, sclass=%d, computedsid=%d, dirent=%d\n", + __func__, path, sbsec->sid, mp->mnt_stat.f_mntonname, rc, + dirent->sclass, newsid, dirent->sid); + } + free(path, M_SEBSD); } static void -sebsd_destroy_cred_label(struct label *label) +sebsd_create_devfs_symlink(struct mount *mp, struct ucred *cred, + struct devfs_dirent *dd, struct label *ddlabel, struct devfs_dirent *de, + struct label *delabel) { - free(SLOT(label), M_SEBSD); - SLOT(label) = NULL; + +#if 0 + /* TBD: path info not available (and the code below is broken) */ + char *path; + int rc; + security_id_t newsid; + struct vnode_security_struct *lnksec; + struct vnode_security_struct *dirsec; + + dirsec= SLOT(ddlabel); + lnksec = SLOT(delabel); + + /* Default to the filesystem SID. */ + lnksec->sid = dirsec->sid; + lnksec->task_sid = SECINITSID_KERNEL; + lnksec->sclass = SECCLASS_LNK_FILE; + + printf("%s: dirsec->sid=%d, de->de_symlink=%s\n", + __func__, dirsec->sid, de->de_symlink?de->de_symlink:"NULL"); + + if (dd->de_dirent) { + printf("%s: dd->de_dirent->d_name=%s\n", + __func__, dd->de_dirent->d_name?dd->de_dirent->d_name:"NULL"); + } +#ifdef FLUFFY + /* Obtain a SID based on the fstype, path, and class. */ + path = malloc(strlen(dd->si_name) + 2, M_SEBSD, M_ZERO | M_WAITOK); + path[0] = '/'; + strcpy(&path[1], dev->si_name); + rc = security_genfs_sid(mp->mnt_vfc->vfc_name, path, dirent->sclass, + &newsid); + if (rc == 0) + dirent->sid = newsid; + + /* TBD: debugging */ + if (sebsd_verbose > 1) { + printf("sebsd_create_devfs_device(%s): sbsid=%d, " + "mountpoint=%s, rc=%d, sclass=%d, computedsid=%d, " + "dirent=%d\n", path, sbsec->sid, mp->mnt_stat.f_mntonname, + rc, dirent->sclass, newsid, dirent->sid); + } + free(path, M_SEBSD); +#endif /* FLUFFY */ +#endif /* 0 */ } static void @@ -284,7 +549,162 @@ SECINITSID_INIT); } +static void +sebsd_create_mount(struct ucred *cred, struct mount *mp, + struct label *mntlabel, struct label *fslabel) +{ + struct mount_security_struct *sbsec; + int behavior, rc; + + sbsec = SLOT(mntlabel); + /* TBD TBD TBD */ + rc = security_fs_use(mp->mnt_vfc->vfc_name, &behavior, &sbsec->sid); + if (rc) { + printf("sebsd_create_mount: security_fs_use(%s) returned %d\n", + mp->mnt_vfc->vfc_name, rc); + behavior = SECURITY_FS_USE_NONE; + } else { + /* TBD: debugging only */ + printf("sebsd_create_mount: security_fs_use(%s) behavior %d, sid %d\n", + mp->mnt_vfc->vfc_name, behavior, sbsec->sid); + } + + switch (behavior) { + case SECURITY_FS_USE_PSID: + /* PSIDs only work for persistent file systems with + unique and persistent inode numbers. */ + sbsec->uses_psids = 1; + break; + case SECURITY_FS_USE_TRANS: + /* Transition SIDs are used for pseudo filesystems like + devpts and tmpfs where you want the SID to be derived + from the SID of the creating process and the SID of + the filesystem. */ + sbsec->uses_trans = 1; + break; + case SECURITY_FS_USE_TASK: + /* Task SIDs are used for pseudo filesystems like pipefs + and sockfs where you want the objects to be labeled + with the SID of the creating process. */ + sbsec->uses_task = 1; + break; + case SECURITY_FS_USE_GENFS: + /* genfs_contexts handles everything else, like devfs, + usbdevfs, driverfs, and portions of proc. */ + sbsec->uses_genfs = 1; + break; + case SECURITY_FS_USE_NONE: + /* No labeling support configured for this filesystem type. + Don't appear to require labeling for binfmt_misc, bdev, + or rootfs. */ + break; + default: + printf("%s: security_fs_use(%s) returned unrecognized " + "behavior %d\n", __FUNCTION__, mp->mnt_vfc->vfc_name, + behavior); + behavior = SECURITY_FS_USE_NONE; + break; + } +} + +/* + * Initialize the SEBSD security server after the root partition has + * been mounted; policy is located on root partition. + */ +static void +sebsd_create_root_mount(struct ucred *cred, struct mount *mp, + struct label *mntlabel, struct label *fslabel) +{ + struct vnode *vp, *nvp; + + avc_init(); + if (security_init()) { + panic("SEBSD: couldn't read policy file"); + } + /* + * Go through all open vnodes and reload their labels. + */ + mtx_lock(&mntvnode_mtx); + vp = TAILQ_FIRST(&mp->mnt_nvnodelist); + do { + nvp = TAILQ_NEXT(vp, v_nmntvnodes); + VI_LOCK(vp); + mtx_unlock(&mntvnode_mtx); + vn_lock(vp, LK_INTERLOCK | LK_EXCLUSIVE | LK_RETRY, curthread); + (void)sebsd_associate_vnode_extattr(mp, fslabel, vp, + &vp->v_label); + VOP_UNLOCK(vp, 0, curthread); + mtx_lock(&mntvnode_mtx); + vp = nvp; + } while (vp != NULL); + mtx_unlock(&mntvnode_mtx); +} + static int +sebsd_create_vnode_extattr(struct ucred *cred, struct mount *mp, + struct label *fslabel, struct vnode *parent, struct label *parentlabel, + struct vnode *child, struct label *childlabel, struct componentname *cnp) +{ + struct vnode_security_struct *dir, *vsec; + struct task_security_struct *task; + security_context_t context; + u_int32_t context_len; + security_id_t newsid; + int error; + + task = SLOT(&cred->cr_label); + dir = SLOT(parentlabel); + vsec = SLOT(childlabel); + + error = security_transition_sid(task->sid, dir->sid, SECCLASS_FILE, + &newsid); + if (error) + return (error); + + vsec->sid = newsid; + vsec->task_sid = task->sid; + vsec->sclass = vnode_type_to_security_class(child->v_type); + + /* store label in vnode */ + error = security_sid_to_context(vsec->sid, &context, + &context_len); + if (error) + return (error); + + error = vn_extattr_set(child, IO_NODELOCKED, + SEBSD_MAC_EXTATTR_NAMESPACE, + SEBSD_MAC_EXTATTR_NAME, + context_len, context, curthread); + + security_free_context(context); + return (error); +} + +/* + * SEBSD does not support the relabeling of processes without + * transitioning. + */ +static int +sebsd_check_cred_relabel(struct ucred *cred, struct label *newlabel) +{ + struct task_security_struct *nsec, *tsec; + + nsec = SLOT(newlabel); + tsec = SLOT(&cred->cr_label); + if (nsec != NULL && nsec->sid != tsec->sid) + return EPERM; + return 0; +} + +static int +sebsd_check_mount_stat(struct ucred *cred, struct mount *mp, + struct label *mntlabel) +{ + + return (mount_has_perm(cred, mp, FILESYSTEM__GETATTR, NULL)); +} + +static int sebsd_check_proc_signal(struct ucred *cred, struct proc *proc, int signum) { access_vector_t perm; @@ -350,10 +770,8 @@ static int sebsd_execve_will_transition(struct ucred *old, struct vnode *vp, - struct label *vnodelabel, - struct label *interpvnodelabel, - struct image_params *imgp, - struct label *execlabel) + struct label *vnodelabel, struct label *interpvnodelabel, + struct image_params *imgp, struct label *execlabel) { struct task_security_struct *task; struct vnode_security_struct *file; @@ -380,159 +798,11 @@ return (newsid != task->sid); } -static void -sebsd_init_vnode_label(struct label *label) -{ - struct vnode_security_struct *vsec; - - vsec = malloc(sizeof(*vsec), M_SEBSD, M_ZERO | M_WAITOK); - vsec->sid = SECINITSID_UNLABELED; - /* TBD: we want this initialized! */ -/* vsec->sclass = vnode_type_to_security_class(vp->v_type); */ - - /* - * TBD: should actually set this from the task sid - */ - vsec->task_sid = SECINITSID_UNLABELED; - - SLOT(label) = vsec; -} - -static void -sebsd_destroy_vnode_label(struct label *label) -{ - free(SLOT(label), M_SEBSD); - SLOT(label) = NULL; -} - -static int -sebsd_create_vnode_extattr(struct ucred *cred, struct mount *mp, - struct label *fslabel, struct vnode *parent, - struct label *parentlabel, struct vnode *child, - struct label *childlabel, - struct componentname *cnp) -{ - struct vnode_security_struct *dir, *vsec; - struct task_security_struct *task; - security_context_t context; - u_int32_t context_len; - security_id_t newsid; - int error; - - task = SLOT(&cred->cr_label); - dir = SLOT(parentlabel); - vsec = SLOT(childlabel); - - error = security_transition_sid(task->sid, dir->sid, SECCLASS_FILE, - &newsid); - if (error) - return (error); - - vsec->sid = newsid; - vsec->task_sid = task->sid; - vsec->sclass = vnode_type_to_security_class(child->v_type); - - /* store label in vnode */ - error = security_sid_to_context(vsec->sid, &context, - &context_len); - if (error) - return (error); - - error = vn_extattr_set(child, IO_NODELOCKED, - SEBSD_MAC_EXTATTR_NAMESPACE, - SEBSD_MAC_EXTATTR_NAME, - context_len, context, curthread); - - security_free_context(context); - return (error); -} - -static void -sebsd_associate_vnode_devfs(struct mount *mp, struct label *fslabel, - struct devfs_dirent *de, struct label *delabel, - struct vnode *vp, struct label *vlabel) -{ - - /* TBD, default to SECINITSID_UNLABELED. */ - /* - * This is a no-op for now, but when devfs_dirents do contain - * labels, they should be copied to the vp here as per how - * sebsd_update_vnode_from_extattr() functions. They will be - * kept synchronized from here on automatically with the vnode - * relabel calls. - */ -} - static int -sebsd_associate_vnode_extattr(struct mount *mp, struct label *fslabel, - struct vnode *vp, struct label *vlabel) -{ - struct vnode_security_struct *vsec; - /* TBD: Need to limit size of contexts used in extattr labels */ - char context[128]; - u_int32_t context_len; - int error; - - vsec = SLOT(vlabel); - - context_len = sizeof(context); /* TBD: bad fixed length */ - error = vn_extattr_get(vp, IO_NODELOCKED, - SEBSD_MAC_EXTATTR_NAMESPACE, - SEBSD_MAC_EXTATTR_NAME, - &context_len, context, curthread); - if (error == ENOATTR || error == EOPNOTSUPP) { - vsec->sid = SECINITSID_UNLABELED; /* Use the default label */ - struct vattr va; - - (void)VOP_GETATTR(vp, &va, curthread->td_ucred, curthread); - printf("sebsd_update_vnode_from_extattr: no label for " - "inode=%ld, fsid=%d\n", va.va_fileid, va.va_fsid); - goto dosclass; - } - if (error) { - printf("sebsd_update_vnode_from_extattr: ERROR %d returned " - " by vn_extattr_get()\n", error); - return (error); /* Fail closed */ - } - if (sebsd_verbose > 1) { - struct vattr va; - - VOP_GETATTR(vp, &va, curthread->td_ucred, curthread); - printf("sebsd_vnode_from_extattr: len=%d: context=%.*s " - "inode=%ld, fsid=%d\n", context_len, context_len, - context, va.va_fileid, va.va_fsid); - } - - error = security_context_to_sid(context, context_len, &vsec->sid); - if (error) { - printf("sebsd_update_vnode_from_extattr: ERROR mapping " - "context to sid: %.*s\n", context_len, context); - return (0); /* TBD bad, bad, bad */ - } - -dosclass: - /* TBD: */ - vsec->sclass = vnode_type_to_security_class(vp->v_type); - if (vsec->sclass == 0) { - printf("sebsd_update_vnode_from_extattr:: sclass is 0\n"); - } - - return (0); -} - -static void -sebsd_associate_vnode_singlelabel(struct mount *mp, struct label *fslabel, - struct vnode *vp, struct label *vlabel) -{ - - /* TBD, default to SECINITSID_UNLABELED. */ -} - -static int sebsd_internalize_sid(security_id_t *sidp, char *element_name, char *element_data, int *claimed) { - char context[128]; + char context[128]; /* TBD: contexts aren't fixed size */ size_t context_len; if (strcmp("sebsd", element_name) != 0) @@ -571,7 +841,7 @@ static void sebsd_relabel_vnode(struct ucred *cred, struct vnode *vp, - struct label *vnodelabel, struct label *label) + struct label *vnodelabel, struct label *label) { struct vnode_security_struct *source, *dest; @@ -592,17 +862,16 @@ static int sebsd_setlabel_vnode_extattr(struct ucred *cred, struct vnode *vp, - struct label *vlabel, struct label *intlabel) + struct label *vlabel, struct label *intlabel) { - struct vnode_security_struct *source, *dest; + struct vnode_security_struct *newlabel; security_context_t context; u_int32_t context_len; int error; - source = SLOT(intlabel); - dest = SLOT(vlabel); + newlabel = SLOT(intlabel); - error = security_sid_to_context(source->sid, &context, + error = security_sid_to_context(newlabel->sid, &context, &context_len); if (error) return (error); @@ -611,35 +880,36 @@ SEBSD_MAC_EXTATTR_NAMESPACE, SEBSD_MAC_EXTATTR_NAME, context_len, context, curthread); - if (error == 0) - dest->sid = source->sid; security_free_context(context); return (error); } static int sebsd_check_vnode_access(struct ucred *cred, struct vnode *vp, - struct label *label, int acc_mode) + struct label *label, int acc_mode) { + if (!acc_mode) return 0; - return vnode_has_perm(cred, vp, file_mask_to_av(vp->v_type, acc_mode), - NULL); + return (vnode_has_perm(cred, vp, file_mask_to_av(vp->v_type, acc_mode), + NULL)); } static int sebsd_check_vnode_chdir(struct ucred *cred, struct vnode *dvp, - struct label *dlabel) + struct label *dlabel) { + /* MAY_EXEC ~= DIR__SEARCH */ return vnode_has_perm(cred, dvp, DIR__SEARCH, NULL); } static int sebsd_check_vnode_chroot(struct ucred *cred, struct vnode *dvp, - struct label *dlabel) + struct label *dlabel) { + /* TBD: Incomplete, SELinux also check capability(CAP_SYS_CHROOT)) */ /* MAY_EXEC ~= DIR__SEARCH */ return vnode_has_perm(cred, dvp, DIR__SEARCH, NULL); @@ -647,8 +917,7 @@ static int sebsd_check_vnode_create(struct ucred *cred, struct vnode *dvp, - struct label *dlabel, struct componentname *cnp, - struct vattr *vap) + struct label *dlabel, struct componentname *cnp, struct vattr *vap) { struct task_security_struct *task; struct vnode_security_struct *dir; @@ -695,8 +964,8 @@ static int sebsd_check_vnode_delete(struct ucred *cred, struct vnode *dvp, - struct label *dlabel, struct vnode *vp, - struct label *label, struct componentname *cnp) + struct label *dlabel, struct vnode *vp, struct label *label, + struct componentname *cnp) { struct task_security_struct *task; struct vnode_security_struct *dir, *file; @@ -729,15 +998,14 @@ static int sebsd_check_vnode_deleteacl(struct ucred *cred, struct vnode *vp, - struct label *label, acl_type_t type) + struct label *label, acl_type_t type) { return vnode_has_perm(cred, vp, FILE__SETATTR, NULL); } static int sebsd_check_vnode_exec(struct ucred *cred, struct vnode *vp, - struct label *label, struct image_params *imgp, - struct label *execlabel) + struct label *label, struct image_params *imgp, struct label *execlabel) { struct task_security_struct *task; struct vnode_security_struct *file; @@ -799,36 +1067,39 @@ static int sebsd_check_vnode_getacl(struct ucred *cred, struct vnode *vp, - struct label *label, acl_type_t type) + struct label *label, acl_type_t type) { - return vnode_has_perm(cred, vp, FILE__GETATTR, NULL); + + return (vnode_has_perm(cred, vp, FILE__GETATTR, NULL)); } static int sebsd_check_vnode_getextattr(struct ucred *cred, struct vnode *vp, - struct label *label, int attrnamespace, - const char *name, struct uio *uio) + struct label *label, int attrnamespace, const char *name, struct uio *uio) { - return vnode_has_perm(cred, vp, FILE__GETATTR, NULL); + + return (vnode_has_perm(cred, vp, FILE__GETATTR, NULL)); } static int sebsd_check_vnode_lookup(struct ucred *cred, struct vnode *dvp, - struct label *dlabel, struct componentname *cnp) + struct label *dlabel, struct componentname *cnp) { + /* TBD: DIR__READ as well? */ - return vnode_has_perm(cred, dvp, DIR__SEARCH, NULL); + return (vnode_has_perm(cred, dvp, DIR__SEARCH, NULL)); } static int sebsd_check_vnode_open(struct ucred *cred, struct vnode *vp, - struct label *filelabel, int acc_mode) + struct label *filelabel, int acc_mode) { + if (!acc_mode) return 0; - return vnode_has_perm(cred, vp, file_mask_to_av(vp->v_type, acc_mode), - NULL); + return (vnode_has_perm(cred, vp, file_mask_to_av(vp->v_type, acc_mode), + NULL)); } static int @@ -1156,50 +1427,22 @@ *(struct vnode_security_struct *)SLOT(src); } -/* - * Initialize the SEBSD security server after the root partition has - * been mounted; policy is located on root partition. - */ -static void -sebsd_create_root_mount(struct ucred *cred, struct mount *mp, - struct label *mntlabel, struct label *fslabel) -{ - struct vnode *vp, *nvp; - - avc_init(); - if (security_init()) { - panic("SEBSD: couldn't read policy file"); - } - /* - * Go through all open vnodes and reload their labels. - */ - mtx_lock(&mntvnode_mtx); - vp = TAILQ_FIRST(&mp->mnt_nvnodelist); - do { - nvp = TAILQ_NEXT(vp, v_nmntvnodes); - VI_LOCK(vp); - mtx_unlock(&mntvnode_mtx); - vn_lock(vp, LK_INTERLOCK | LK_EXCLUSIVE | LK_RETRY, curthread); - (void)sebsd_associate_vnode_extattr(mp, fslabel, vp, - &vp->v_label); - VOP_UNLOCK(vp, 0, curthread); - mtx_lock(&mntvnode_mtx); - vp = nvp; - } while (vp != NULL); - mtx_unlock(&mntvnode_mtx); -} - static struct mac_policy_ops sebsd_ops = { - .mpo_destroy = sebsd_destroy, - /* Init Labels */ .mpo_init = sebsd_init, .mpo_init_cred_label = sebsd_init_cred_label, + .mpo_init_devfsdirent_label = sebsd_init_vnode_label, + .mpo_init_mount_label = sebsd_init_mount_label, + .mpo_init_mount_fs_label = sebsd_init_mount_fs_label, .mpo_init_vnode_label = sebsd_init_vnode_label, /* Destroy Labels */ - .mpo_destroy_cred_label = sebsd_destroy_cred_label, - .mpo_destroy_vnode_label = sebsd_destroy_vnode_label, + .mpo_destroy = sebsd_destroy, + .mpo_destroy_cred_label = sebsd_destroy_label, + .mpo_destroy_devfsdirent_label = sebsd_destroy_label, + .mpo_destroy_mount_label = sebsd_destroy_label, + .mpo_destroy_mount_fs_label = sebsd_destroy_label, + .mpo_destroy_vnode_label = sebsd_destroy_label, /* Copy labels */ .mpo_copy_vnode_label = sebsd_copy_vnode_label, @@ -1212,8 +1455,13 @@ /* Create Labels */ .mpo_create_cred = sebsd_create_cred, + .mpo_create_devfs_device = sebsd_create_devfs_device, + .mpo_create_devfs_directory = sebsd_create_devfs_directory, + .mpo_create_devfs_symlink = sebsd_create_devfs_symlink, .mpo_create_proc0 = sebsd_create_proc0, .mpo_create_proc1 = sebsd_create_proc1, + .mpo_create_mount = sebsd_create_mount, + .mpo_create_root_mount = sebsd_create_root_mount, .mpo_create_vnode_extattr = sebsd_create_vnode_extattr, .mpo_associate_vnode_devfs = sebsd_associate_vnode_devfs, .mpo_associate_vnode_singlelabel = sebsd_associate_vnode_singlelabel, @@ -1221,7 +1469,9 @@ /* Check Labels */ .mpo_check_cred_relabel = sebsd_check_cred_relabel, + .mpo_check_mount_stat = sebsd_check_mount_stat, .mpo_check_proc_signal = sebsd_check_proc_signal, + .mpo_check_system_swapon = sebsd_check_system_swapon, .mpo_check_vnode_access = sebsd_check_vnode_access, .mpo_check_vnode_chdir = sebsd_check_vnode_chdir, .mpo_check_vnode_chroot = sebsd_check_vnode_chroot, @@ -1250,7 +1500,6 @@ .mpo_check_vnode_setowner = sebsd_check_vnode_setowner, .mpo_check_vnode_setutimes = sebsd_check_vnode_setutimes, .mpo_check_vnode_stat = sebsd_check_vnode_stat, - .mpo_check_system_swapon = sebsd_check_system_swapon, .mpo_check_vnode_write = sebsd_check_vnode_write, /* Misc */ @@ -1261,8 +1510,6 @@ .mpo_setlabel_vnode_extattr = sebsd_setlabel_vnode_extattr, .mpo_syscall = sebsd_syscall, - - .mpo_create_root_mount = sebsd_create_root_mount, }; MAC_POLICY_SET(&sebsd_ops, sebsd, "NSA/NAI Labs Security Enhanced BSD", To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe p4-projects" in the body of the message
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200212050040.gB50egD4074264>