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