PERFORCE change 109953 for review
Todd Miller
millert at FreeBSD.org
Tue Nov 14 18:39:36 UTC 2006
http://perforce.freebsd.org/chv.cgi?CH=109953
Change 109953 by millert at millert_g5tower on 2006/11/14 18:38:53
Move mmap checks from vnode to file.
Add file_has_perm to sebsd.c that checks both the fd label and
the underlying vnode label, similar to what SELinux does.
Affected files ...
.. //depot/projects/trustedbsd/sedarwin8/darwin/xnu/bsd/kern/kern_mman.c#4 edit
.. //depot/projects/trustedbsd/sedarwin8/darwin/xnu/security/mac_file.c#5 edit
.. //depot/projects/trustedbsd/sedarwin8/darwin/xnu/security/mac_framework.h#12 edit
.. //depot/projects/trustedbsd/sedarwin8/darwin/xnu/security/mac_policy.h#20 edit
.. //depot/projects/trustedbsd/sedarwin8/darwin/xnu/security/mac_vfs.c#15 edit
.. //depot/projects/trustedbsd/sedarwin8/darwin/xnu/security/sorted-policynames.vim#2 edit
.. //depot/projects/trustedbsd/sedarwin8/policies/color/mac_color.c#10 edit
.. //depot/projects/trustedbsd/sedarwin8/policies/mls/mac_mls.c#18 edit
.. //depot/projects/trustedbsd/sedarwin8/policies/readonly/mac_readonly.c#7 edit
.. //depot/projects/trustedbsd/sedarwin8/policies/sedarwin/sedarwin/sebsd.c#34 edit
.. //depot/projects/trustedbsd/sedarwin8/policies/vanity/vanity.c#7 edit
Differences ...
==== //depot/projects/trustedbsd/sedarwin8/darwin/xnu/bsd/kern/kern_mman.c#4 (text+ko) ====
@@ -373,8 +373,8 @@
handle = (void *)vp;
#ifdef MAC
- error = mac_vnode_check_mmap(vfs_context_ucred(&context),
- vp, prot, flags, &maxprot);
+ error = mac_file_check_mmap(vfs_context_ucred(&context),
+ fp->f_fglob, prot, flags, &maxprot);
if (error) {
(void)vnode_put(vp);
goto bad;
==== //depot/projects/trustedbsd/sedarwin8/darwin/xnu/security/mac_file.c#5 (text+ko) ====
@@ -221,3 +221,39 @@
MAC_CHECK(file_check_set, cred, fg, buf, buflen);
return (error);
}
+
+/*
+ * On some platforms, VM_PROT_READ implies VM_PROT_EXECUTE. If that is true,
+ * both prot and maxprot will have VM_PROT_EXECUTE set after file_check_mmap
+ * if VM_PROT_READ is set.
+ *
+ * The type of maxprot in file_check_mmap must be equivalent to vm_prot_t *
+ * (defined in <mach/vm_prot.h>). mac_policy.h does not include any header
+ * files, so cannot use the typedef itself.
+ */
+int
+mac_file_check_mmap(struct ucred *cred, struct fileglob *fg, int prot,
+ int flags, int *maxprot)
+{
+ int error;
+ int maxp;
+
+ maxp = *maxprot;
+ MAC_CHECK(file_check_mmap, cred, fg, fg->fg_label, prot, flags, &maxp);
+ if ((maxp | *maxprot) != *maxprot)
+ panic("file_check_mmap increased max protections");
+ *maxprot = maxp;
+ return (error);
+}
+
+void
+mac_file_check_mmap_downgrade(struct ucred *cred, struct fileglob *fg,
+ int *prot)
+{
+ int result = *prot;
+
+ MAC_PERFORM(file_check_mmap_downgrade, cred, fg, fg->fg_label,
+ &result);
+
+ *prot = result;
+}
==== //depot/projects/trustedbsd/sedarwin8/darwin/xnu/security/mac_framework.h#12 (text+ko) ====
@@ -310,6 +310,10 @@
struct fileglob *fg, char oldflags, char newflags);
int mac_file_check_get_offset(struct ucred *cred, struct fileglob *fg);
int mac_file_check_change_offset(struct ucred *cred, struct fileglob *fg);
+int mac_file_check_mmap(struct ucred *cred, struct fileglob *fg,
+ int prot, int flags, int *maxprot);
+void mac_file_check_mmap_downgrade(struct ucred *cred, struct fileglob *fg,
+ int *prot);
int mac_file_check_set(struct ucred *cred, struct fileglob *fg,
char *buf, int buflen);
int mac_sysvsem_check_semget(struct ucred *cred,
@@ -407,10 +411,6 @@
int mac_vnode_check_listextattr(struct ucred *cred, struct vnode *vp);
int mac_vnode_check_lookup(struct ucred *cred, struct vnode *dvp,
struct componentname *cnp);
-int mac_vnode_check_mmap(struct ucred *cred, struct vnode *vp,
- int prot, int flags, int *maxprot);
-void mac_vnode_check_mmap_downgrade(struct ucred *cred, struct vnode *vp,
- int *prot);
int mac_vnode_check_mprotect(struct ucred *cred, struct vnode *vp,
int prot);
int mac_vnode_check_open(struct ucred *cred, struct vnode *vp,
==== //depot/projects/trustedbsd/sedarwin8/darwin/xnu/security/mac_policy.h#20 (text+ko) ====
@@ -3901,6 +3901,51 @@
);
/**
+ @brief Access control check for mapping a file
+ @param cred Subject credential
+ @param fg fileglob representing file to map
+ @param label Policy label associated with vp
+ @param prot mmap protections; see mmap(2)
+ @param flags Type of mapped object; see mmap(2)
+ @param maxprot Maximum rights
+
+ Determine whether the subject identified by the credential should be
+ allowed to map the file represented by fg with the protections specified
+ in prot. The maxprot field holds the maximum permissions on the new
+ mapping, a combination of VM_PROT_READ, VM_PROT_WRITE, and VM_PROT_EXECUTE.
+ To avoid overriding prior access control checks, a policy should only
+ remove flags from maxprot.
+
+ @return Return 0 if access is granted, otherwise an appropriate value for
+ errno should be returned. Suggested failure: EACCES for label mismatch or
+ EPERM for lack of privilege.
+*/
+typedef int mpo_file_check_mmap_t(
+ struct ucred *cred,
+ struct fileglob *fg,
+ struct label *label,
+ int prot,
+ int flags,
+ int *maxprot
+);
+
+/**
+ @brief Downgrade the mmap protections
+ @param cred Subject credential
+ @param fg file to map
+ @param label Policy label associated with vp
+ @param prot mmap protections to be downgraded
+
+ Downgrade the mmap protections based on the subject and object labels.
+*/
+typedef void mpo_file_check_mmap_downgrade_t(
+ struct ucred *cred,
+ struct fileglob *fg,
+ struct label *label,
+ int *prot
+);
+
+/**
@brief Access control for changing the offset of a file descriptor
@param cred Subject credential
@param fg Fileglob structure
@@ -4634,51 +4679,6 @@
);
/**
- @brief Access control check for mapping the vnode
- @param cred Subject credential
- @param vp vnode to map
- @param label Policy label associated with vp
- @param prot mmap protections; see mmap(2)
- @param flags Type of mapped object; see mmap(2)
- @param maxprot Maximum rights
-
- Determine whether the subject identified by the credential should be
- allowed to map the vnode vp with the protections specified in prot.
- The maxprot field holds the maximum permissions on the new mapping,
- a combination of VM_PROT_READ, VM_PROT_WRITE, and VM_PROT_EXECUTE.
- To avoid overriding prior access control checks, a policy should only
- remove flags from maxprot.
-
- @return Return 0 if access is granted, otherwise an appropriate value for
- errno should be returned. Suggested failure: EACCES for label mismatch or
- EPERM for lack of privilege.
-*/
-typedef int mpo_vnode_check_mmap_t(
- struct ucred *cred,
- struct vnode *vp,
- struct label *label,
- int prot,
- int flags,
- int *maxprot
-);
-
-/**
- @brief Downgrade the mmap protections
- @param cred Subject credential
- @param vp vnode to map
- @param label Policy label associated with vp
- @param prot mmap protections to be downgraded
-
- Downgrade the mmap protections based on the subject and object labels.
-*/
-typedef void mpo_vnode_check_mmap_downgrade_t(
- struct ucred *cred,
- struct vnode *vp,
- struct label *label,
- int *prot
-);
-
-/**
@brief Access control check for setting memory protections
@param cred Subject credential
@param vp Mapped vnode
@@ -5529,10 +5529,12 @@
mpo_file_check_get_flags_t *mpo_file_check_get_flags;
mpo_file_check_get_offset_t *mpo_file_check_get_offset;
mpo_file_check_get_ofileflags_t *mpo_file_check_get_ofileflags;
+ mpo_file_check_get_t *mpo_file_check_get;
mpo_file_check_inherit_t *mpo_file_check_inherit;
mpo_file_check_ioctl_t *mpo_file_check_ioctl;
+ mpo_file_check_mmap_downgrade_t *mpo_file_check_mmap_downgrade;
+ mpo_file_check_mmap_t *mpo_file_check_mmap;
mpo_file_check_receive_t *mpo_file_check_receive;
- mpo_file_check_get_t *mpo_file_check_get;
mpo_file_check_set_t *mpo_file_check_set;
mpo_port_check_method_t *mpo_port_check_method;
mpo_posixsem_check_create_t *mpo_posixsem_check_create;
@@ -5613,8 +5615,6 @@
mpo_vnode_check_link_t *mpo_vnode_check_link;
mpo_vnode_check_listextattr_t *mpo_vnode_check_listextattr;
mpo_vnode_check_lookup_t *mpo_vnode_check_lookup;
- mpo_vnode_check_mmap_t *mpo_vnode_check_mmap;
- mpo_vnode_check_mmap_downgrade_t *mpo_vnode_check_mmap_downgrade;
mpo_vnode_check_mprotect_t *mpo_vnode_check_mprotect;
mpo_vnode_check_open_t *mpo_vnode_check_open;
mpo_vnode_check_read_t *mpo_vnode_check_read;
==== //depot/projects/trustedbsd/sedarwin8/darwin/xnu/security/mac_vfs.c#15 (text+ko) ====
@@ -513,42 +513,6 @@
return (error);
}
-/*
- * On some platforms, VM_PROT_READ implies VM_PROT_EXECUTE. If that is true,
- * both prot and maxprot will have VM_PROT_EXECUTE set after vnode_check_mmap
- * if VM_PROT_READ is set.
- *
- * The type of maxprot in vnode_check_mmap must be equivalent to vm_prot_t *
- * (defined in <mach/vm_prot.h>). mac_policy.h does not include any header files,
- * so cannot use the typedef itself.
- */
-
-int
-mac_vnode_check_mmap(struct ucred *cred, struct vnode *vp, int prot, int flags,
- int *maxprot)
-{
- int error;
- int maxp;
-
- maxp = *maxprot;
- MAC_CHECK(vnode_check_mmap, cred, vp, vp->v_label, prot, flags, &maxp);
- if ((maxp | *maxprot) != *maxprot)
- panic("vnode_check_mmap increased max protections");
- *maxprot = maxp;
- return (error);
-}
-
-void
-mac_vnode_check_mmap_downgrade(struct ucred *cred, struct vnode *vp, int *prot)
-{
- int result = *prot;
-
- MAC_PERFORM(vnode_check_mmap_downgrade, cred, vp, vp->v_label,
- &result);
-
- *prot = result;
-}
-
int
mac_vnode_check_mprotect(struct ucred *cred, struct vnode *vp, int prot)
{
==== //depot/projects/trustedbsd/sedarwin8/darwin/xnu/security/sorted-policynames.vim#2 (text+ko) ====
@@ -25,6 +25,8 @@
typedef mpo_devfs_label_update_t(
typedef mpo_file_check_fcntl_t(
typedef mpo_file_check_get_t(
+typedef mpo_file_check_mmap_downgrade_t(
+typedef mpo_file_check_mmap_t(
typedef mpo_file_check_set_t(
typedef mpo_iokit_check_device_t(
typedef mpo_lctx_check_label_update_t(
@@ -210,8 +212,6 @@
typedef mpo_vnode_check_link_t(
typedef mpo_vnode_check_listextattr_t(
typedef mpo_vnode_check_lookup_t(
-typedef mpo_vnode_check_mmap_downgrade_t(
-typedef mpo_vnode_check_mmap_t(
typedef mpo_vnode_check_mprotect_t(
typedef mpo_vnode_check_open_t(
typedef mpo_vnode_check_read_t(
==== //depot/projects/trustedbsd/sedarwin8/policies/color/mac_color.c#10 (text+ko) ====
@@ -502,7 +502,7 @@
}
static int
-color_vnode_check_mmap(struct ucred *cred, struct vnode *vp,
+color_file_check_mmap(struct ucred *cred, struct fileglob *fg,
struct label *label, int prot, int flags, int *maxprot)
{
@@ -510,7 +510,7 @@
}
static void
-color_vnode_check_mmap_downgrade(struct ucred *cred, struct vnode *vp,
+color_file_check_mmap_downgrade(struct ucred *cred, struct fileglob *fg,
struct label *label, int *prot)
{
@@ -701,6 +701,9 @@
.mpo_cred_check_label_update = color_cred_check_label_update,
+ .mpo_file_check_mmap = color_file_check_mmap,
+ .mpo_file_check_mmap_downgrade = color_file_check_mmap_downgrade,
+
.mpo_lctx_notify_create = color_lctx_notify_create,
.mpo_lctx_notify_join = color_lctx_notify_join,
.mpo_lctx_notify_leave = color_lctx_notify_leave,
@@ -721,8 +724,6 @@
.mpo_vnode_check_link = color_vnode_check_link,
.mpo_vnode_check_listextattr = color_vnode_check_listextattr,
.mpo_vnode_check_lookup = color_vnode_check_lookup,
- .mpo_vnode_check_mmap = color_vnode_check_mmap,
- .mpo_vnode_check_mmap_downgrade = color_vnode_check_mmap_downgrade,
.mpo_vnode_check_mprotect = color_vnode_check_mprotect,
.mpo_vnode_check_open = color_vnode_check_open,
.mpo_vnode_check_read = color_vnode_check_read,
==== //depot/projects/trustedbsd/sedarwin8/policies/mls/mac_mls.c#18 (text+ko) ====
@@ -3444,7 +3444,7 @@
}
static int
-mac_mls_vnode_check_mmap(struct ucred *cred, struct vnode *vp,
+mac_mls_file_check_mmap(struct ucred *cred, struct fileglob *fg,
struct label *label, int prot, int flags, int *maxprot)
{
struct mac_mls *subj, *obj;
@@ -3487,13 +3487,13 @@
* combination of what each policy thinks it should be.
*/
static void
-mac_mls_vnode_check_mmap_downgrade(struct ucred *cred, struct vnode *vp,
+mac_mls_file_check_mmap_downgrade(struct ucred *cred, struct fileglob *fg,
struct label *vlabel, int *prot)
{
if (!mac_mls_enabled)
return;
-#warning Implement mac_mls_vnode_check_mmap_downgrade()
+#warning Implement mac_mls_file_check_mmap_downgrade()
return;
}
@@ -4088,8 +4088,8 @@
.mpo_vnode_check_link = mac_mls_vnode_check_link,
.mpo_vnode_check_listextattr = mac_mls_vnode_check_listextattr,
.mpo_vnode_check_lookup = mac_mls_vnode_check_lookup,
- .mpo_vnode_check_mmap = mac_mls_vnode_check_mmap,
- .mpo_vnode_check_mmap_downgrade = mac_mls_vnode_check_mmap_downgrade,
+ .mpo_file_check_mmap = mac_mls_file_check_mmap,
+ .mpo_file_check_mmap_downgrade = mac_mls_file_check_mmap_downgrade,
.mpo_vnode_check_mprotect = mac_mls_vnode_check_mprotect,
.mpo_vnode_check_open = mac_mls_vnode_check_open,
.mpo_vnode_check_read = mac_mls_vnode_check_read,
==== //depot/projects/trustedbsd/sedarwin8/policies/readonly/mac_readonly.c#7 (text+ko) ====
@@ -1,6 +1,8 @@
#include <sys/types.h>
#include <sys/conf.h>
#include <sys/kernel.h>
+#include <sys/file.h>
+#include <sys/file_internal.h>
#include <sys/malloc.h>
#include <sys/mman.h>
#include <sys/mount.h>
@@ -420,11 +422,14 @@
}
static int
-readonly_vnode_check_mmap(struct ucred *cred, struct vnode *vp,
+readonly_file_check_mmap(struct ucred *cred, struct fileglob *fg,
struct label *label, int prot, int flags, int *maxprot)
{
- return (ro_checkdiraccess(vp, label, (prot & PROT_WRITE) ? FWRITE : FREAD));
+ if (fg->fg_type != DTYPE_VNODE)
+ return (0);
+ return (ro_checkdiraccess((struct vnode *)fg->fg_data, label,
+ (prot & PROT_WRITE) ? FWRITE : FREAD));
}
static int
@@ -502,6 +507,7 @@
.mpo_policy_destroy = readonly_policy_destroy,
.mpo_policy_init = readonly_policy_init,
.mpo_policy_initbsd = readonly_policy_initbsd,
+ .mpo_file_check_mmap = readonly_file_check_mmap,
.mpo_vnode_label_init = readonly_label_init,
.mpo_vnode_label_destroy = readonly_label_destroy,
.mpo_vnode_label_recycle = readonly_label_recycle,
@@ -520,7 +526,6 @@
.mpo_vnode_check_deleteextattr = readonly_vnode_check_deleteextattr,
.mpo_vnode_check_exchangedata = readonly_vnode_check_exchangedata,
.mpo_vnode_check_link = readonly_vnode_check_link,
- .mpo_vnode_check_mmap = readonly_vnode_check_mmap,
.mpo_vnode_check_open = readonly_vnode_check_open,
.mpo_vnode_check_label_update = readonly_vnode_check_label_update,
.mpo_vnode_check_rename_from = readonly_vnode_check_rename_from,
==== //depot/projects/trustedbsd/sedarwin8/policies/sedarwin/sedarwin/sebsd.c#34 (text+ko) ====
@@ -467,6 +467,34 @@
}
static int
+file_has_perm(struct ucred *cred, struct fileglob *fg, struct label *fglabel,
+ u_int32_t perm)
+{
+ struct task_security_struct *tsec;
+ struct file_security_struct *fsec;
+ int rc = 0;
+
+ tsec = SLOT(cred->cr_label);
+ fsec = SLOT(fglabel);
+
+ /* Simple use check if file opened by other sid. */
+ if (tsec->sid != fsec->sid) {
+ rc = avc_has_perm(tsec->sid, fsec->sid, SECCLASS_FD, FD__USE,
+ NULL);
+ if (rc != 0)
+ return (rc);
+ }
+
+ /* Check underlying vnode if there is one. */
+ if (fg->fg_type == DTYPE_VNODE && fg->fg_data != NULL) {
+ rc = vnode_has_perm(cred, (struct vnode *)fg->fg_data,
+ NULL, perm);
+ }
+
+ return (rc);
+}
+
+static int
pipe_has_perm(struct ucred *cred, struct pipe *pipe, u_int32_t perm)
{
struct task_security_struct *task;
@@ -2891,8 +2919,8 @@
}
static int
-sebsd_vnode_check_mmap(struct ucred *cred, struct vnode *vp,
- struct label *label, int prot, int flags, int *maxprot)
+sebsd_file_check_mmap(struct ucred *cred, struct fileglob *fg,
+ struct label *fglabel, int prot, int flags, int *maxprot)
{
u_int32_t av;
@@ -2900,18 +2928,15 @@
* TBD: Incomplete?
* Write access only matters if the mapping is shared.
*/
- if (vp) {
- av = FILE__READ;
+ av = FILE__READ;
- if ((prot & PROT_WRITE) && (flags & MAP_SHARED))
- av |= FILE__WRITE;
+ if ((prot & PROT_WRITE) && (flags & MAP_SHARED))
+ av |= FILE__WRITE;
- if (prot & PROT_EXEC)
- av |= FILE__EXECUTE;
+ if (prot & PROT_EXEC)
+ av |= FILE__EXECUTE;
- return (vnode_has_perm(cred, vp, NULL, av));
- }
- return (0);
+ return (file_has_perm(cred, fg, fglabel, av));
}
static int
@@ -3653,7 +3678,6 @@
// .mpo_vnode_check_kqfilter = sebsd_vnode_check_kqfilter,
.mpo_vnode_check_link = sebsd_vnode_check_link,
.mpo_vnode_check_lookup = sebsd_vnode_check_lookup,
- .mpo_vnode_check_mmap = sebsd_vnode_check_mmap,
.mpo_vnode_check_mprotect = sebsd_vnode_check_mprotect,
.mpo_vnode_check_open = sebsd_vnode_check_open,
.mpo_vnode_check_read = sebsd_vnode_check_read,
@@ -3701,6 +3725,7 @@
.mpo_file_check_inherit = sebsd_file_check_receive,
.mpo_file_check_receive = sebsd_file_check_receive,
.mpo_file_check_dup = sebsd_file_check_dup,
+ .mpo_file_check_mmap = sebsd_file_check_mmap,
/* Mount Points */
.mpo_mount_label_init = sebsd_mount_label_init,
==== //depot/projects/trustedbsd/sedarwin8/policies/vanity/vanity.c#7 (text+ko) ====
@@ -4,6 +4,7 @@
#include <sys/sysctl.h>
#include <sys/proc.h>
+#include <sys/file_internal.h>
#include <sys/mount_internal.h>
#include <sys/vnode_internal.h>
@@ -315,16 +316,20 @@
}
static int
-vanity_vnode_check_mmap(struct ucred *cred, struct vnode *vp, struct label *label, int prot, int flags, int *maxprot)
+vanity_file_check_mmap(struct ucred *cred, struct fileglob *fg,
+ struct label *label, int prot, int flags, int *maxprot)
{
- VANITY(vp);
+ if (fg->fg_type == DTYPE_VNODE)
+ VANITY((struct vnode *)fg->fg_data);
return (0);
}
static void
-vanity_vnode_check_mmap_downgrade(struct ucred *cred, struct vnode *vp, struct label *label, int *prot)
+vanity_file_check_mmap_downgrade(struct ucred *cred, struct fileglob *fg,
+ struct label *label, int *prot)
{
- VANITY(vp);
+ if (fg->fg_type == DTYPE_VNODE)
+ VANITY((struct vnode *)fg->fg_data);
}
static int
@@ -473,6 +478,8 @@
static struct mac_policy_ops mac_vanity_ops = {
.mpo_policy_initbsd = vanity_policy_initbsd,
+ .mpo_file_check_mmap = vanity_file_check_mmap,
+ .mpo_file_check_mmap_downgrade = vanity_file_check_mmap_downgrade,
.mpo_vnode_label_update_extattr = vanity_vnode_label_update_extattr,
.mpo_vnode_label_associate_devfs= vanity_vnode_label_associate_devfs,
.mpo_vnode_label_associate_extattr= vanity_vnode_label_associate_extattr,
@@ -501,8 +508,6 @@
.mpo_vnode_check_link = vanity_vnode_check_link,
.mpo_vnode_check_listextattr = vanity_vnode_check_listextattr,
.mpo_vnode_check_lookup = vanity_vnode_check_lookup,
- .mpo_vnode_check_mmap = vanity_vnode_check_mmap,
- .mpo_vnode_check_mmap_downgrade = vanity_vnode_check_mmap_downgrade,
.mpo_vnode_check_mprotect = vanity_vnode_check_mprotect,
.mpo_vnode_check_open = vanity_vnode_check_open,
.mpo_vnode_check_read = vanity_vnode_check_read,
More information about the trustedbsd-cvs
mailing list