PERFORCE change 105795 for review

Todd Miller millert at FreeBSD.org
Thu Sep 7 15:14:58 UTC 2006


http://perforce.freebsd.org/chv.cgi?CH=105795

Change 105795 by millert at millert_g5tower on 2006/09/07 15:13:30

	Add mac_get_mount(2), mac_getfsstat(2) and mac_getmntinfo(3).
	Handle union mounts properly when MNT_UPDATE is set.

Affected files ...

.. //depot/projects/trustedbsd/sedarwin8/darwin/libmac/Makefile#2 edit
.. //depot/projects/trustedbsd/sedarwin8/darwin/libmac/mac.3#2 edit
.. //depot/projects/trustedbsd/sedarwin8/darwin/libmac/mac_get.3#2 edit
.. //depot/projects/trustedbsd/sedarwin8/darwin/libmac/mac_getmntinfo.c#1 add
.. //depot/projects/trustedbsd/sedarwin8/darwin/libmac/mac_mount.c#2 edit
.. //depot/projects/trustedbsd/sedarwin8/darwin/xnu/bsd/kern/init_sysent.c#2 edit
.. //depot/projects/trustedbsd/sedarwin8/darwin/xnu/bsd/kern/syscalls.c#2 edit
.. //depot/projects/trustedbsd/sedarwin8/darwin/xnu/bsd/kern/syscalls.master#2 edit
.. //depot/projects/trustedbsd/sedarwin8/darwin/xnu/bsd/miscfs/fdesc/fdesc_vfsops.c#2 edit
.. //depot/projects/trustedbsd/sedarwin8/darwin/xnu/bsd/sys/syscall.h#2 edit
.. //depot/projects/trustedbsd/sedarwin8/darwin/xnu/bsd/sys/sysproto.h#2 edit
.. //depot/projects/trustedbsd/sedarwin8/darwin/xnu/bsd/vfs/vfs_syscalls.c#7 edit
.. //depot/projects/trustedbsd/sedarwin8/darwin/xnu/security/mac.h#7 edit
.. //depot/projects/trustedbsd/sedarwin8/darwin/xnu/security/mac_base.c#9 edit
.. //depot/projects/trustedbsd/sedarwin8/darwin/xnu/security/mac_framework.h#4 edit

Differences ...

==== //depot/projects/trustedbsd/sedarwin8/darwin/libmac/Makefile#2 (text+ko) ====

@@ -5,7 +5,8 @@
 CFLAGS+=	$(DARWIN_HDRS) # -I$(MIGSOURCE)
 
 LIB= mac
-OBJS = mac.o mac_exec.o mac_get.o mac_set.o mac_mount.o security.o
+OBJS = mac.o mac_exec.o mac_get.o mac_set.o mac_mount.o security.o \
+	mac_getmntinfo.o
 AR = ar cq
 RANLIB = ranlib
 INSTALL = install

==== //depot/projects/trustedbsd/sedarwin8/darwin/libmac/mac.3#2 (text+ko) ====

@@ -76,12 +76,24 @@
 and may be used to retrieve the
 MAC label associated with
 a named file.
+.It Fn mac_get_mount
+This function is described in
+.Xr mac_get 3 ,
+and may be used to retrieve the
+MAC label associated with
+a mount point.
 .It Fn mac_get_proc
 This function is described in
 .Xr mac_get 3 ,
 and may be used to retrieve the
 MAC label associated with
 the calling process.
+.It Fn mac_mount
+is an extended form of
+.Xr mount 2 ,
+may be used to set the
+MAC label associated with
+a mount point at mount time.
 .It Fn mac_set_fd
 This function is described in
 .Xr mac_set 3 ,

==== //depot/projects/trustedbsd/sedarwin8/darwin/libmac/mac_get.3#2 (text+ko) ====

@@ -54,6 +54,8 @@
 .Ft int
 .Fn mac_get_lctx "mac_t label"
 .Ft int
+.Fn mac_get_mount "const char *path" "mac_t label"
+.Ft int
 .Fn mac_get_pid "pid_t pid" "mac_t label"
 .Ft int
 .Fn mac_get_proc "mac_t label"
@@ -77,6 +79,15 @@
 .Xr getsockopt 2 .
 .Pp
 The
+.Fn mac_get_mount
+function fills in
+.Fa label
+(which must first be allocated by
+.Xr mac_prepare 3 )
+with the MAC label associated with the mount point referenced by
+.Fa path .
+.Pp
+The
 .Fn mac_get_lctx
 and
 .Fn mac_get_lcid

==== //depot/projects/trustedbsd/sedarwin8/darwin/libmac/mac_mount.c#2 (text+ko) ====

@@ -29,9 +29,16 @@
 #include <security/mac.h>
 
 int
-mac_mount(const char *type, const char *dir, int flags, void *data,
+mac_mount(const char *type, const char *path, int flags, void *data,
     struct mac *label)
 {
 
-	return ((syscall(SYS___mac_mount, type, dir, flags, data, label)));
+	return ((syscall(SYS___mac_mount, type, path, flags, data, label)));
+}
+
+int
+mac_get_mount(const char *path, struct mac *label)
+{
+
+	return ((syscall(SYS___mac_get_mount, path, label)));
 }

==== //depot/projects/trustedbsd/sedarwin8/darwin/xnu/bsd/kern/init_sysent.c#2 (text+ko) ====

@@ -486,5 +486,7 @@
 	{AC(setlcid_args), _SYSCALL_CANCEL_NONE, KERNEL_FUNNEL, (sy_call_t *)setlcid, munge_ww, munge_dd, _SYSCALL_RET_INT_T}, /* 394 = setlcid */
 	{AC(getlcid_args), _SYSCALL_CANCEL_NONE, KERNEL_FUNNEL, (sy_call_t *)getlcid, munge_w, munge_d, _SYSCALL_RET_INT_T}, /* 395 = getlcid */
 	{AC(__mac_mount_args), _SYSCALL_CANCEL_NONE, NO_FUNNEL, (sy_call_t *)__mac_mount, munge_wwwww, munge_ddddd, _SYSCALL_RET_INT_T}, /* 396 = __mac_mount */
+	{AC(__mac_get_mount_args), _SYSCALL_CANCEL_NONE, NO_FUNNEL, (sy_call_t *)__mac_get_mount, munge_ww, munge_dd, _SYSCALL_RET_INT_T}, /* 397 = __mac_get_mount */
+	{AC(__mac_getfsstat_args), _SYSCALL_CANCEL_NONE, NO_FUNNEL, (sy_call_t *)__mac_getfsstat, munge_wwwww, munge_ddddd, _SYSCALL_RET_INT_T}, /* 398 = __mac_getfsstat */
 };
 int	nsysent = sizeof(sysent) / sizeof(sysent[0]);

==== //depot/projects/trustedbsd/sedarwin8/darwin/xnu/bsd/kern/syscalls.c#2 (text+ko) ====

@@ -472,4 +472,6 @@
 	"setlcid",            /* 394 = setlcid */
 	"getlcid",            /* 395 = getlcid */
 	"__mac_mount",        /* 396 = __mac_mount */
+	"__mac_get_mount",    /* 397 = __mac_get_mount */
+	"__mac_getfsstat",    /* 398 = __mac_getfsstat */
 };

==== //depot/projects/trustedbsd/sedarwin8/darwin/xnu/bsd/kern/syscalls.master#2 (text+ko) ====

@@ -499,3 +499,5 @@
 394	NONE	KERN	ALL	{ int setlcid(pid_t pid, pid_t lcid); }
 395	NONE	KERN	ALL	{ int getlcid(pid_t pid); }
 396	NONE	NONE	ALL	{ int __mac_mount(char *type, char *path, int flags, caddr_t data, struct mac *mac_p); } 
+397	NONE	NONE	ALL	{ int __mac_get_mount(char *path, struct mac *mac_p); } 
+398	NONE	NONE	ALL	{ int __mac_getfsstat(user_addr_t buf, int bufsize, user_addr_t mac, int macsize, int flags); } 

==== //depot/projects/trustedbsd/sedarwin8/darwin/xnu/bsd/miscfs/fdesc/fdesc_vfsops.c#2 (text+ko) ====

@@ -90,7 +90,7 @@
 	 * Update is a no-op
 	 */
 	if (mp->mnt_flag & MNT_UPDATE)
-		return (ENOTSUP);
+		return (0);
 
 	error = fdesc_allocvp(Froot, FD_ROOT, mp, &rvp, VDIR);
 	if (error)

==== //depot/projects/trustedbsd/sedarwin8/darwin/xnu/bsd/sys/syscall.h#2 (text+ko) ====

@@ -477,7 +477,9 @@
 #define	SYS_setlcid        394
 #define	SYS_getlcid        395
 #define	SYS___mac_mount    396
-#define	SYS_MAXSYSCALL	397
+#define	SYS___mac_get_mount 397
+#define	SYS___mac_getfsstat 398
+#define	SYS_MAXSYSCALL	399
 
 #endif /* __APPLE_API_PRIVATE */
 #endif /* !_SYS_SYSCALL_H_ */

==== //depot/projects/trustedbsd/sedarwin8/darwin/xnu/bsd/sys/sysproto.h#2 (text+ko) ====

@@ -1377,6 +1377,17 @@
 	char data_l_[PADL_(user_addr_t)]; user_addr_t data; char data_r_[PADR_(user_addr_t)];
 	char mac_p_l_[PADL_(user_addr_t)]; user_addr_t mac_p; char mac_p_r_[PADR_(user_addr_t)];
 };
+struct __mac_get_mount_args {
+	char path_l_[PADL_(user_addr_t)]; user_addr_t path; char path_r_[PADR_(user_addr_t)];
+	char mac_p_l_[PADL_(user_addr_t)]; user_addr_t mac_p; char mac_p_r_[PADR_(user_addr_t)];
+};
+struct __mac_getfsstat_args {
+	char buf_l_[PADL_(user_addr_t)]; user_addr_t buf; char buf_r_[PADR_(user_addr_t)];
+	char bufsize_l_[PADL_(int)]; int bufsize; char bufsize_r_[PADR_(int)];
+	char mac_l_[PADL_(user_addr_t)]; user_addr_t mac; char mac_r_[PADR_(user_addr_t)];
+	char macsize_l_[PADL_(int)]; int macsize; char macsize_r_[PADR_(int)];
+	char flags_l_[PADL_(int)]; int flags; char flags_r_[PADR_(int)];
+};
 int nosys(struct proc *, struct nosys_args *, int *);
 void exit(struct proc *, struct exit_args *, int *);
 int fork(struct proc *, struct fork_args *, int *);
@@ -1680,6 +1691,8 @@
 int setlcid(struct proc *, struct setlcid_args *, int *);
 int getlcid(struct proc *, struct getlcid_args *, int *);
 int __mac_mount(struct proc *, struct __mac_mount_args *, int *);
+int __mac_get_mount(struct proc *, struct __mac_get_mount_args *, int *);
+int __mac_getfsstat(struct proc *, struct __mac_getfsstat_args *, int *);
 
 __END_DECLS
 #undef PAD_

==== //depot/projects/trustedbsd/sedarwin8/darwin/xnu/bsd/vfs/vfs_syscalls.c#7 (text+ko) ====

@@ -195,7 +195,7 @@
 int
 __mac_mount(struct proc *p, register struct __mac_mount_args *uap, __unused register_t *retval)
 {
-	struct vnode *vp;
+	struct vnode *vp, *uvp;
 	struct vnode *devvp = NULLVP;
 	struct vnode *device_vnode = NULLVP;
 #ifdef MAC
@@ -237,12 +237,40 @@
 	if ((vp->v_flag & VROOT) &&
 		(vp->v_mount->mnt_flag & MNT_ROOTFS)) 
 			uap->flags |= MNT_UPDATE;
+
+	error = copyinstr(uap->type, fstypename, MFSNAMELEN, &dummy);
+	if (error)
+		return (error);
 	
 	if (uap->flags & MNT_UPDATE) {
 		if ((vp->v_flag & VROOT) == 0) {
 			error = EINVAL;
 			goto out1;
 		}
+
+		/* Handle UNION mounts */
+		if (strcmp(vp->v_mount->mnt_vtable->vfc_name,
+			   fstypename) != 0) {
+			uvp = vp;
+			/* Walk the stack, looking for our fstypename */
+			while ((uvp = uvp->v_mount->mnt_vnodecovered) != NULL) {
+				if ((uvp->v_flag & VROOT) == 0) {
+					error = EINVAL;
+					goto out1;
+				}
+				if (strcmp(uvp->v_mount->mnt_vtable->vfc_name,
+					   fstypename) != 0)
+					continue;
+
+				if (vnode_getwithvid(uvp, uvp->v_id)) {
+					error = EINVAL;
+					goto out1;
+				}
+				vnode_put(vp);
+				vp = uvp;
+				break;
+			}
+		}
 		mp = vp->v_mount;
 
 		/* unmount in progress return error */
@@ -326,8 +354,6 @@
 		error = ENOTDIR;
 		goto out1;
 	}
-	if ( (error = copyinstr(uap->type, fstypename, MFSNAMELEN, &dummy)) )
-		goto out1;
 
 	/* XXXAUDIT: Should we capture the type on the error path as well? */
 	AUDIT_ARG(text, fstypename);
@@ -548,6 +574,7 @@
 			FREE(labelstr, M_MACTEMP);
 			goto out3;
 		}
+		AUDIT_ARG(mac_string, labelstr);
 	}
 #endif
 	/*
@@ -1276,6 +1303,7 @@
 
 struct getfsstat_struct {
 	user_addr_t	sfsp;
+	user_addr_t	*mp;
 	int		count;
 	int		maxcount;
 	int		flags;
@@ -1318,6 +1346,15 @@
 			return(VFS_RETURNED_DONE);
 		}
 		fstp->sfsp += my_size;
+
+		if (fstp->mp) {
+			error = mac_mount_getlabel(mp, *fstp->mp);
+			if (error) {
+				fstp->error = error;
+				return(VFS_RETURNED_DONE);
+			}
+			fstp->mp++;
+		}
 	}
 	fstp->count++;
 	return(VFS_RETURNED);
@@ -1329,9 +1366,25 @@
 int
 getfsstat(__unused proc_t p, struct getfsstat_args *uap, int *retval)
 {
+	struct __mac_getfsstat_args muap;
+
+	muap.buf = uap->buf;
+	muap.bufsize = uap->bufsize;
+	muap.mac = USER_ADDR_NULL;
+	muap.macsize = 0;
+	muap.flags = uap->flags;
+
+	return (__mac_getfsstat(p, &muap, retval));
+}
+
+int
+__mac_getfsstat(__unused proc_t p, struct __mac_getfsstat_args *uap, int *retval)
+{
 	user_addr_t sfsp;
+	user_addr_t *mp;
 	int count, maxcount;
 	struct getfsstat_struct fst;
+	int error;
 
 	if (IS_64BIT_PROCESS(p)) {
 		maxcount = uap->bufsize / sizeof(struct user_statfs);
@@ -1342,7 +1395,35 @@
 	sfsp = uap->buf;
 	count = 0;
 
+	mp = NULL;
+	if (uap->mac != USER_ADDR_NULL) {
+		u_int32_t *mp0;
+		int i;
+
+		count = (int)(uap->macsize / (IS_64BIT_PROCESS(p) ? 8 : 4));
+		if (count != maxcount)
+			return (EINVAL);
+
+		/* Copy in the array */
+		MALLOC(mp0, u_int32_t *, uap->macsize, M_MACTEMP, M_WAITOK);
+		error = copyin(CAST_USER_ADDR_T(uap->mac), mp0, uap->macsize);
+		if (error)
+			return (error);
+
+		/* Normalize to an array of user_addr_t */
+		MALLOC(mp, user_addr_t *, count * sizeof(user_addr_t), M_MACTEMP, M_WAITOK);
+		for (i = 0; i < count; i++) {
+			if (IS_64BIT_PROCESS(p))
+				mp[i] = ((user_addr_t *)mp0)[i];
+			else
+				mp[i] = (user_addr_t)mp0[i];
+		}
+		FREE(mp0, M_MACTEMP);
+	}
+
+
 	fst.sfsp = sfsp;
+	fst.mp = mp;
 	fst.flags = uap->flags;
 	fst.count = 0;
 	fst.error = 0;
@@ -1351,6 +1432,9 @@
 	
 	vfs_iterate(0, getfsstat_callback, &fst);
 
+	if (mp)
+		FREE(mp, M_MACTEMP);
+
 	if (fst.error ) {
 		KAUTH_DEBUG("ERROR - %s gets %d", p->p_comm, fst.error);
 		return(fst.error);
@@ -5698,9 +5782,9 @@
 			 * disk as they look huge. This change should not affect
 			 * XSAN as they should not setting these to -1..
 			 */
-			 && (sfsp->f_blocks != 0xffffffffffffffff)
-			 && (sfsp->f_bfree != 0xffffffffffffffff)
-			 && (sfsp->f_bavail != 0xffffffffffffffff)) {
+			 && (sfsp->f_blocks != 0xffffffffffffffffULL)
+			 && (sfsp->f_bfree  != 0xffffffffffffffffULL)
+			 && (sfsp->f_bavail != 0xffffffffffffffffULL)) {
 			int		shift;
 
 			/*

==== //depot/projects/trustedbsd/sedarwin8/darwin/xnu/security/mac.h#7 (text+ko) ====

@@ -89,6 +89,7 @@
 int	 mac_get_lctx(mac_t _label);
 int	 mac_get_link(const char *_path, mac_t _label);
 int	 mac_get_peer(int fd, struct mac *label);
+int	 mac_getmntinfo(struct statfs **mntbufp, mac_t **macp, int flags);
 int	 mac_get_pid(pid_t _pid, mac_t _label);
 int	 mac_get_proc(mac_t _label);
 int	 mac_is_present(const char *_policyname);
@@ -100,8 +101,9 @@
 int	 mac_set_file(const char *_path, mac_t _label);
 int	 mac_set_lctx(mac_t _label);
 int	 mac_set_link(const char *_path, mac_t _label);
-int	 mac_mount(const char *type, const char *dir, int flags, void *data,
+int	 mac_mount(const char *type, const char *path, int flags, void *data,
     struct mac *label);
+int	 mac_get_mount(const char *path, struct mac *label);
 int	 mac_set_proc(const mac_t _label);
 int	 mac_syscall(const char *_policyname, int _call, void *_arg);
 int	 mac_to_text(mac_t mac, char **_text);

==== //depot/projects/trustedbsd/sedarwin8/darwin/xnu/security/mac_base.c#9 (text+ko) ====

@@ -1675,6 +1675,70 @@
 	return (error);
 }
 
+int
+mac_mount_getlabel(struct mount *mp, user_addr_t mac_p)
+{
+	char *elements, *buffer;
+	struct label *label;
+	struct mac mac;
+	int error;
+	size_t ulen;
+
+	error = copyin(CAST_USER_ADDR_T(mac_p), &mac, sizeof(mac));
+	if (error)
+		return (error);
+
+	error = mac_check_structmac_consistent(&mac);
+	if (error)
+		return (error);
+
+	MALLOC(elements, char *, mac.m_buflen, M_MACTEMP, M_WAITOK);
+	error = copyinstr(CAST_USER_ADDR_T(mac.m_string), elements,
+	    mac.m_buflen, &ulen);
+	if (error) {
+		FREE(elements, M_MACTEMP);
+		return (error);
+	}
+	AUDIT_ARG(mac_string, elements);
+
+	label = mp->mnt_mntlabel;
+	MALLOC(buffer, char *, mac.m_buflen, M_MACTEMP, M_WAITOK | M_ZERO);
+	error = mac_mount_externalize_label(label, elements, buffer,
+	    mac.m_buflen);
+	FREE(elements, M_MACTEMP);
+
+	if (error == 0)
+		error = copyout(buffer, CAST_USER_ADDR_T(mac.m_string),
+		    strlen(buffer) + 1);
+	FREE(buffer, M_MACTEMP);
+
+	return (error);
+}
+
+int
+__mac_get_mount(struct proc *p __unused, struct __mac_get_mount_args *uap,
+    register_t *ret __unused)
+{
+	struct nameidata nd;
+	struct vfs_context context;
+	struct mount *mp;
+	int error;
+
+	context.vc_proc = p;
+	context.vc_ucred = kauth_cred_get();
+
+	NDINIT(&nd, LOOKUP, FOLLOW | AUDITVNPATH1,
+		UIO_USERSPACE, uap->path, &context);
+	error = namei(&nd);
+	if (error) {
+		return (error);
+	}
+	mp = nd.ni_vp->v_mount;
+	nameidone(&nd);
+
+	return mac_mount_getlabel(mp, uap->mac_p);
+}
+
 #else /* MAC */
 
 int
@@ -1804,4 +1868,12 @@
 
 	return (ENOSYS);
 }
+
+int
+__mac_get_mount(struct proc *p __unused,
+    struct __mac_get_mount_args *uap __unused, register_t *ret __unused)
+{
+
+	return (ENOSYS);
+}
 #endif /* !MAC */

==== //depot/projects/trustedbsd/sedarwin8/darwin/xnu/security/mac_framework.h#4 (text+ko) ====

@@ -123,6 +123,7 @@
 int	mac_mount_internalize_label(struct label *, char *string);
 int	mac_mount_externalize_label(struct label *label, char *elements,
     char *outbuf, size_t outbuflen);
+int	mac_mount_getlabel(struct mount *mp, user_addr_t mac_p);
 
 struct label	*mac_cred_alloc_label(void);
 void		 mac_cred_free_label(struct label *label);


More information about the trustedbsd-cvs mailing list