From owner-trustedbsd-cvs@FreeBSD.ORG Thu Sep 7 15:14:58 2006 Return-Path: X-Original-To: trustedbsd-cvs@freebsd.org Delivered-To: trustedbsd-cvs@freebsd.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id 5650316A4DA for ; Thu, 7 Sep 2006 15:14:58 +0000 (UTC) (envelope-from owner-perforce@freebsd.org) Received: from cyrus.watson.org (cyrus.watson.org [209.31.154.42]) by mx1.FreeBSD.org (Postfix) with ESMTP id 211B943D69 for ; Thu, 7 Sep 2006 15:14:43 +0000 (GMT) (envelope-from owner-perforce@freebsd.org) Received: from mx2.freebsd.org (mx2.freebsd.org [216.136.204.119]) by cyrus.watson.org (Postfix) with ESMTP id 6FB6046D66 for ; Thu, 7 Sep 2006 11:14:41 -0400 (EDT) Received: from hub.freebsd.org (hub.freebsd.org [216.136.204.18]) by mx2.freebsd.org (Postfix) with ESMTP id 63ED255DE3; Thu, 7 Sep 2006 15:14:40 +0000 (GMT) (envelope-from owner-perforce@freebsd.org) Received: by hub.freebsd.org (Postfix, from userid 32767) id 5B20916A4E2; Thu, 7 Sep 2006 15:14:40 +0000 (UTC) X-Original-To: perforce@freebsd.org 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 18A7B16A4DA for ; Thu, 7 Sep 2006 15:14:40 +0000 (UTC) (envelope-from millert@freebsd.org) Received: from repoman.freebsd.org (repoman.freebsd.org [216.136.204.115]) by mx1.FreeBSD.org (Postfix) with ESMTP id 7867643D7B for ; Thu, 7 Sep 2006 15:14:26 +0000 (GMT) (envelope-from millert@freebsd.org) Received: from repoman.freebsd.org (localhost [127.0.0.1]) by repoman.freebsd.org (8.13.6/8.13.6) with ESMTP id k87FEQLL023974 for ; Thu, 7 Sep 2006 15:14:26 GMT (envelope-from millert@freebsd.org) Received: (from perforce@localhost) by repoman.freebsd.org (8.13.6/8.13.4/Submit) id k87FEPdj023971 for perforce@freebsd.org; Thu, 7 Sep 2006 15:14:25 GMT (envelope-from millert@freebsd.org) Date: Thu, 7 Sep 2006 15:14:25 GMT Message-Id: <200609071514.k87FEPdj023971@repoman.freebsd.org> X-Authentication-Warning: repoman.freebsd.org: perforce set sender to millert@freebsd.org using -f From: Todd Miller To: Perforce Change Reviews Cc: Subject: PERFORCE change 105795 for review X-BeenThere: trustedbsd-cvs@FreeBSD.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: TrustedBSD CVS and Perforce commit message list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 07 Sep 2006 15:14:58 -0000 http://perforce.freebsd.org/chv.cgi?CH=105795 Change 105795 by millert@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 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);