PERFORCE change 16997 for review

Chris Vance cvance at freebsd.org
Tue Sep 3 15:53:11 GMT 2002


http://people.freebsd.org/~peter/p4db/chv.cgi?CH=16997

Change 16997 by cvance at 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 at trustedbsd.org
with "unsubscribe trustedbsd-cvs" in the body of the message



More information about the trustedbsd-cvs mailing list