From owner-p4-projects Tue Sep 3 8:54: 6 2002 Delivered-To: p4-projects@freebsd.org Received: by hub.freebsd.org (Postfix, from userid 32767) id D51AD37B400; Tue, 3 Sep 2002 08:53:20 -0700 (PDT) Delivered-To: perforce@freebsd.org Received: from mx1.FreeBSD.org (mx1.FreeBSD.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id 5F09837B401 for ; Tue, 3 Sep 2002 08:53:20 -0700 (PDT) Received: from freefall.freebsd.org (freefall.FreeBSD.org [216.136.204.21]) by mx1.FreeBSD.org (Postfix) with ESMTP id 971CF43E3B for ; Tue, 3 Sep 2002 08:53:19 -0700 (PDT) (envelope-from cvance@tislabs.com) Received: from freefall.freebsd.org (perforce@localhost [127.0.0.1]) by freefall.freebsd.org (8.12.4/8.12.4) with ESMTP id g83FrJJU040953 for ; Tue, 3 Sep 2002 08:53:19 -0700 (PDT) (envelope-from cvance@tislabs.com) Received: (from perforce@localhost) by freefall.freebsd.org (8.12.4/8.12.4/Submit) id g83FrBFr040946 for perforce@freebsd.org; Tue, 3 Sep 2002 08:53:11 -0700 (PDT) Date: Tue, 3 Sep 2002 08:53:11 -0700 (PDT) Message-Id: <200209031553.g83FrBFr040946@freefall.freebsd.org> X-Authentication-Warning: freefall.freebsd.org: perforce set sender to cvance@tislabs.com using -f From: Chris Vance Subject: PERFORCE change 16997 for review To: Perforce Change Reviews Sender: owner-p4-projects@FreeBSD.ORG Precedence: bulk List-ID: List-Archive: (Web Archive) List-Help: (List Instructions) List-Subscribe: List-Unsubscribe: X-Loop: FreeBSD.ORG http://people.freebsd.org/~peter/p4db/chv.cgi?CH=16997 Change 16997 by cvance@cvance_laptop on 2002/09/03 08:52:36 Mildly ugly reorganization of function ordering. Alphabetical order will make it easier to sync up in the future. Assign initial security class to vnodes during creation Add helper functions to check vnode perms Add stubs for missing check_vnode_xxx operations Add permission checks for rename operations Affected files ... .. //depot/projects/trustedbsd/mac/sys/security/sebsd/sebsd.c#23 edit Differences ... ==== //depot/projects/trustedbsd/mac/sys/security/sebsd/sebsd.c#23 (text+ko) ==== @@ -114,6 +114,20 @@ return (cred_has_system(td->td_proc->p_ucred, perm)); } +static int +vnode_has_perm(struct ucred *cred, struct vnode *vp, access_vector_t perm, + avc_entry_ref_t *aeref) +{ + struct task_security_struct *task; + struct vnode_security_struct *file; + + task = SLOT(&cred->cr_label); + file = SLOT(&vp->v_label); + + /* TBD: audit? */ + return avc_has_perm_ref(task->sid, file->sid, file->sclass, + perm, aeref ? aeref : &file->avcr); +} static void sebsd_init_cred(struct ucred *ucred, struct label *label) @@ -292,6 +306,32 @@ SLOT(label) = NULL; } +static inline security_class_t +vnode_mode_to_security_class(struct vnode *vp) +{ + switch (vp->v_type) { + case VREG: + return SECCLASS_FILE; + case VDIR: + return SECCLASS_DIR; + case VBLK: + return SECCLASS_BLK_FILE; + case VCHR: + return SECCLASS_CHR_FILE; + case VLNK: + return SECCLASS_LNK_FILE; + case VSOCK: + return SECCLASS_SOCK_FILE; + case VFIFO: + return SECCLASS_FIFO_FILE; + } + + /* + * VNON and VBAD + */ + return SECCLASS_FILE; +} + static void sebsd_create_vnode(struct ucred *cred, struct vnode *parent, struct label *parentlabel, struct vnode *child, @@ -312,6 +352,7 @@ &newsid); vsec->sid = newsid; vsec->task_sid = task->sid; + vsec->sclass = vnode_mode_to_security_class(child); if ((child->v_mount->mnt_flag & MNT_MULTILABEL) == 0) { return; @@ -336,31 +377,52 @@ } } - static int -sebsd_check_vnode_rename_from(struct ucred *cred, struct vnode *dvp, - struct label *dlabel, struct vnode *vp, - struct label *label) +sebsd_update_vnode_from_extattr(struct vnode *vp, struct label *vnodelabel, + struct mount *mp, struct label *fslabel) { - /* TBD: Not Implemented */ - return 0; -} + 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(vnodelabel); + + context_len = 128; /* 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) { + vsec->sid = SECINITSID_UNLABELED; /* Use the default label */ + struct vattr va; + + VOP_GETATTR(vp, &va, curthread->td_ucred, curthread); + printf("sebsd_update_vnode_from_extattr: no label for inode=%d, fsid=%d\n", va.va_fileid, va.va_fsid); + + return (0); + } + if (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=%d, fsid=%d\n", 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); + return (0); /* TBD bad, bad, bad */ + } -static int -sebsd_check_vnode_rename_to(struct ucred *cred, struct vnode *dvp, - struct label *dlabel, struct vnode *vp, - struct label *label, int samedir) -{ - /* TBD: Not Implemented */ - return 0; -} + vsec->sclass = vnode_mode_to_security_class(vp); -static int -sebsd_check_vnode_relabel(struct ucred *cred, struct vnode *vp, - struct label *oldlabel, struct label *newlabel) -{ - /* TBD: Not Implemented */ - return 0; + return (0); } static void @@ -411,6 +473,31 @@ } static int +sebsd_check_vnode_access(struct ucred *cred, struct vnode *vp, + struct label *label, mode_t flags) +{ + + /* TBD: Not Implemented */ + return (0); +} + +static int +sebsd_check_vnode_chdir(struct ucred *cred, struct vnode *dvp, + struct label *dlabel) +{ + /* TBD: Not Implemented */ + return 0; +} + +static int +sebsd_check_vnode_chroot(struct ucred *cred, struct vnode *dvp, + struct label *dlabel) +{ + /* TBD: Not Implemented */ + return 0; +} + +static int sebsd_check_vnode_create(struct ucred *cred, struct vnode *dvp, struct label *dlabel, struct vattr *vap) { @@ -424,49 +511,20 @@ } static int -sebsd_update_vnode_from_extattr(struct vnode *vp, struct label *vnodelabel, - struct mount *mp, struct label *fslabel) +sebsd_check_vnode_delete(struct ucred *cred, struct vnode *dvp, + struct label *dlabel, struct vnode *vp, + struct label *label) { - 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; + /* TBD: Not Implemented */ + return 0; +} - vsec = SLOT(vnodelabel); - - context_len = 128; /* 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) { - vsec->sid = SECINITSID_UNLABELED; /* Use the default label */ - struct vattr va; - - VOP_GETATTR(vp, &va, curthread->td_ucred, curthread); - printf("sebsd_update_vnode_from_extattr: no label for inode=%d, fsid=%d\n", va.va_fileid, va.va_fsid); - - return (0); - } - if (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=%d, fsid=%d\n", 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); - return (0); /* TBD bad, bad, bad */ - } - - return (0); +static int +sebsd_check_vnode_deleteacl(struct ucred *cred, struct vnode *vp, + struct label *label, acl_type_t type) +{ + /* TBD: Not Implemented */ + return 0; } static int @@ -536,6 +594,144 @@ } static int +sebsd_check_vnode_lookup(struct ucred *cred, struct vnode *dvp, + struct label *dlabel, struct componentname *cnp) +{ + /* TBD: Not Implemented */ + return 0; +} + +static int +sebsd_check_vnode_open(struct ucred *cred, struct vnode *vp, + struct label *filelabel, mode_t acc_mode) +{ + /* TBD: Not Implemented */ + return 0; +} + +static int +sebsd_check_vnode_poll(struct ucred *active_cred, struct ucred *file_cred, + struct vnode *vp, struct label *label) +{ + /* TBD: Not Implemented */ + return 0; +} + +static int +sebsd_check_vnode_read(struct ucred *active_cred, struct ucred *file_cred, + struct vnode *vp, struct label *label) +{ + /* TBD: Not Implemented */ + return 0; +} + +static int +sebsd_check_vnode_readdir(struct ucred *cred, struct vnode *dvp, + struct label *dlabel) +{ + /* TBD: Not Implemented */ + return 0; +} + +static int +sebsd_check_vnode_readlink(struct ucred *cred, struct vnode *vp, + struct label *label) +{ + /* TBD: Not Implemented */ + return 0; +} + +static int +sebsd_check_vnode_relabel(struct ucred *cred, struct vnode *vp, + struct label *oldlabel, struct label *newlabel) +{ + /* TBD: Not Implemented */ + return 0; +} + +static int +sebsd_check_vnode_rename_from(struct ucred *cred, struct vnode *dvp, + struct label *dlabel, struct vnode *vp, + struct label *label) +{ + struct task_security_struct *task; + struct vnode_security_struct *old_dir, old_file; + int rc; + + task = SLOT(&cred->cr_label); + old_dir = SLOT(dlabel); + old_file = SLOT(label); + + /* TBD: audit data? */ + rc = avc_has_perm_ref(task->sid, old_dir->sid, SECCLASS_DIR, + DIR__REMOVE_NAME | DIR__SEARCH, + old_dirsec->avcr); + if (rc) + return (rc); + rc = avc_has_perm_ref(task->sid, old_file->sid, old_file->sclass, + FILE__RENAME, &old_file->avcr); + if (rc) + return (rc); + + return (0); +} + +static int +sebsd_check_vnode_rename_to(struct ucred *cred, struct vnode *dvp, + struct label *dlabel, struct vnode *vp, + struct label *label, int samedir) +{ + struct task_security_struct *task; + struct vnode_security_struct *new_dir, new_file; + access_vector_t av; + int rc; + + task = SLOT(&cred->cr_label); + new_dir = SLOT(dlabel); + +#ifdef notdef + /* + * We don't have the right information available to make this + * test. TBD - find a way! + */ + if (vp->v_type == VDIR && !samedir) { + rc = avc_has_perm_ref(task->sid, old_file->sid, + old_file->sclass, DIR__REPARENT, + &old_file->avcr); + if (rc) + return (rc); + } +#endif + + av = DIR__ADD_NAME | DIR__SEARCH; + if (vp) + av |= DIR__REMOVE_NAME; + + /* TBD: audit */ + rc = avc_has_perm_ref(task->sid, new_dir->sid, SECCLASS_DIR, + av, &new_dir->avcr); + if (rc) + return (rc); + + if (vp) { + new_file = SLOT(label); + if (vp->v_type == VDIR) { + rc = avc_has_perm_ref(task->sid, new_file->sid, + new_file->sclass, + DIR__RMDIR, &new_file->avcr); + } else { + rc = avc_has_perm_ref(task->sid, new_file->sid, + new_file->sclass, + FILE__UNLINK, &new_file->avcr); + } + if (rc) + return (rc); + } + + return (0); +} + +static int sebsd_check_vnode_revoke(struct ucred *cred, struct vnode *vp, struct label *label) { @@ -602,39 +798,22 @@ } static int -sebsd_check_vnode_chdir(struct ucred *cred, struct vnode *dvp, - struct label *dlabel) +sebsd_check_vnode_write(struct ucred *active_cred, struct ucred *file_cred, + struct vnode *vp, struct label *label) { /* TBD: Not Implemented */ return 0; } -static int -sebsd_check_vnode_delete(struct ucred *cred, struct vnode *dvp, - struct label *dlabel, struct vnode *vp, - struct label *label) +static vm_prot_t +sebsd_check_vnode_mmap_perms(struct ucred *cred, struct vnode *vp, + struct label *label, int newmapping) { /* TBD: Not Implemented */ return 0; } static int -sebsd_check_vnode_deleteacl(struct ucred *cred, struct vnode *vp, - struct label *label, acl_type_t type) -{ - /* TBD: Not Implemented */ - return 0; -} - -static int -sebsd_check_vnode_open(struct ucred *cred, struct vnode *vp, - struct label *filelabel, mode_t acc_mode) -{ - /* TBD: Not Implemented */ - return 0; -} - -static int sebsd_externalize(struct label *label, struct mac *extmac) { /* TBD: this assumes vnodes only and only stores '5' */ @@ -692,64 +871,76 @@ } static struct mac_policy_op_entry sebsd_ops[] = { - { MAC_INIT, - (macop_t)sebsd_init }, { MAC_DESTROY, (macop_t)sebsd_destroy }, - { MAC_SYSCALL, - (macop_t)sebsd_syscall }, - - /* Process operations */ + /* Init Labels */ + { MAC_INIT, + (macop_t)sebsd_init }, { MAC_INIT_CRED, (macop_t)sebsd_init_cred }, - { MAC_CREATE_CRED, - (macop_t)sebsd_create_cred }, - { MAC_CHECK_CRED_RELABEL, - (macop_t)sebsd_check_cred_relabel }, - { MAC_RELABEL_CRED, - (macop_t)sebsd_relabel_cred }, + { MAC_INIT_VNODE, + (macop_t)sebsd_init_vnode }, + + /* Destroy Labels */ { MAC_DESTROY_CRED, (macop_t)sebsd_destroy_cred }, + { MAC_DESTROY_VNODE, + (macop_t)sebsd_destroy_vnode }, + + /* In/Out */ + { MAC_EXTERNALIZE, + (macop_t)sebsd_externalize }, + { MAC_EXTERNALIZE_PID, + (macop_t)sebsd_externalize_pid }, + /* Create Labels */ + { MAC_CREATE_CRED, + (macop_t)sebsd_create_cred }, { MAC_CREATE_PROC0, (macop_t)sebsd_create_proc0 }, { MAC_CREATE_PROC1, (macop_t)sebsd_create_proc1 }, - { MAC_CHECK_PROC_SIGNAL, - (macop_t)sebsd_check_proc_signal }, - - - /* file operations */ - { MAC_INIT_VNODE, - (macop_t)sebsd_init_vnode }, - { MAC_DESTROY_VNODE, - (macop_t)sebsd_destroy_vnode }, { MAC_CREATE_VNODE, (macop_t)sebsd_create_vnode }, - { MAC_UPDATE_VNODE_FROM_EXTATTR, - (macop_t)sebsd_update_vnode_from_extattr }, - { MAC_RELABEL_VNODE, - (macop_t)sebsd_relabel_vnode }, - { MAC_CHECK_VNODE_EXEC, - (macop_t)sebsd_check_vnode_exec }, - { MAC_CHECK_VNODE_CREATE, - (macop_t)sebsd_check_vnode_create }, - { MAC_CHECK_VNODE_STAT, - (macop_t)sebsd_check_vnode_stat }, + /* Check Labels */ + { MAC_CHECK_CRED_RELABEL, + (macop_t)sebsd_check_cred_relabel }, + { MAC_CHECK_PROC_SIGNAL, + (macop_t)sebsd_check_proc_signal }, + { MAC_CHECK_VNODE_ACCESS, + (macop_t)sebsd_check_vnode_access }, { MAC_CHECK_VNODE_CHDIR, (macop_t)sebsd_check_vnode_chdir }, + { MAC_CHECK_VNODE_CHROOT, + (macop_t)sebsd_check_vnode_chroot }, + { MAC_CHECK_VNODE_CREATE, + (macop_t)sebsd_check_vnode_create }, { MAC_CHECK_VNODE_DELETE, (macop_t)sebsd_check_vnode_delete }, { MAC_CHECK_VNODE_DELETEACL, (macop_t)sebsd_check_vnode_deleteacl }, + { MAC_CHECK_VNODE_EXEC, + (macop_t)sebsd_check_vnode_exec }, { MAC_CHECK_VNODE_GETACL, (macop_t)sebsd_check_vnode_getacl }, { MAC_CHECK_VNODE_GETEXTATTR, (macop_t)sebsd_check_vnode_getextattr }, + { MAC_CHECK_VNODE_LOOKUP, + (macop_t)sebsd_check_vnode_lookup }, { MAC_CHECK_VNODE_OPEN, (macop_t)sebsd_check_vnode_open }, + { MAC_CHECK_VNODE_POLL, + (macop_t)sebsd_check_vnode_poll }, + { MAC_CHECK_VNODE_READ, + (macop_t)sebsd_check_vnode_read }, + { MAC_CHECK_VNODE_READDIR, + (macop_t)sebsd_check_vnode_readdir }, + { MAC_CHECK_VNODE_READLINK, + (macop_t)sebsd_check_vnode_readlink }, + { MAC_CHECK_VNODE_RELABEL, + (macop_t)sebsd_check_vnode_relabel }, { MAC_CHECK_VNODE_RENAME_FROM, (macop_t)sebsd_check_vnode_rename_from }, { MAC_CHECK_VNODE_RENAME_TO, @@ -768,18 +959,27 @@ (macop_t)sebsd_check_vnode_setowner }, { MAC_CHECK_VNODE_SETUTIMES, (macop_t)sebsd_check_vnode_setutimes }, - { MAC_CHECK_VNODE_RELABEL, - (macop_t)sebsd_check_vnode_relabel }, + { MAC_CHECK_VNODE_STAT, + (macop_t)sebsd_check_vnode_stat }, + { MAC_CHECK_VNODE_WRITE, + (macop_t)sebsd_check_vnode_write }, + { MAC_CHECK_VNODE_MMAP_PERMS, + (macop_t)sebsd_check_vnode_mmap_perms }, + /* Misc */ { MAC_EXECVE_TRANSITION, (macop_t)sebsd_execve_transition }, { MAC_EXECVE_WILL_TRANSITION, (macop_t)sebsd_execve_will_transition }, + { MAC_RELABEL_CRED, + (macop_t)sebsd_relabel_cred }, + { MAC_RELABEL_VNODE, + (macop_t)sebsd_relabel_vnode }, + { MAC_UPDATE_VNODE_FROM_EXTATTR, + (macop_t)sebsd_update_vnode_from_extattr }, - { MAC_EXTERNALIZE, - (macop_t)sebsd_externalize }, - { MAC_EXTERNALIZE_PID, - (macop_t)sebsd_externalize_pid }, + { MAC_SYSCALL, + (macop_t)sebsd_syscall }, { MAC_CREATE_ROOT_MOUNT, (macop_t)sebsd_create_root_mount }, { MAC_OP_LAST, NULL } To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe p4-projects" in the body of the message