--- //depot/vendor/FreeBSD/stable/10/lib/libc/posix1e/Makefile.inc 2013-10-10 17:56:30.000000000 -0600 +++ //SpectraBSD/stable_downstreaming/lib/libc/posix1e/Makefile.inc 2014-12-12 20:42:32.000000000 -0700 @@ -4,9 +4,13 @@ CFLAGS+=-D_ACL_PRIVATE -# Copy kern/subr_acl_nfs4.c to the libc object directory. +# Copy ACL support files shared with the kernel into the libc object directory. subr_acl_nfs4.c: ${.CURDIR}/../../sys/kern/subr_acl_nfs4.c cat ${.ALLSRC} > ${.TARGET} +subr_sd.c: ${.CURDIR}/../../sys/kern/subr_sd.c + cat ${.ALLSRC} > ${.TARGET} +subr_sid.c: ${.CURDIR}/../../sys/kern/subr_sid.c + cat ${.ALLSRC} > ${.TARGET} SRCS+= acl_branding.c \ acl_calc_mask.c \ @@ -35,7 +39,9 @@ mac_exec.c \ mac_get.c \ mac_set.c \ - subr_acl_nfs4.c + subr_acl_nfs4.c \ + subr_sd.c \ + subr_sid.c SYM_MAPS+=${.CURDIR}/posix1e/Symbol.map --- //depot/vendor/FreeBSD/stable/10/lib/libc/posix1e/Symbol.map 2013-10-10 17:56:30.000000000 -0600 +++ //SpectraBSD/stable_downstreaming/lib/libc/posix1e/Symbol.map 2014-12-12 20:42:32.000000000 -0700 @@ -83,4 +83,26 @@ acl_set_flagset_np; acl_strip_np; acl_to_text_np; + sid_ace_alloc; + sid_ace_free; + sid_acl_alloc; + sid_acl_free; + sid_acl_iter_init; + sid_acl_iter_next; + sid_acl_iter_seek; + sid_acl_insert_ace; + sid_acl_remove_ace; + sid_acl_replace_ace; + security_descriptor_init; + security_descriptor_alloc; + security_descriptor_free; + serialized_security_descriptor_free; + security_descriptor_serialize_sid; + security_descriptor_serialize_acl; + security_descriptor_serialize; + security_descriptor_deserialize; + sid_from_string; + sid_from_domain_and_rid; + sid_to_string; + sid_to_domain_and_rid; }; --- //depot/vendor/FreeBSD/stable/10/lib/libc/sys/Symbol.map 2014-12-21 07:58:28.000000000 -0700 +++ //SpectraBSD/stable_downstreaming/lib/libc/sys/Symbol.map 2015-01-14 20:59:00.000000000 -0700 @@ -397,6 +397,10 @@ posix_fadvise; procctl; wait6; + security_descriptor_get_fd; + security_descriptor_get_file; + security_descriptor_set_fd; + security_descriptor_set_file; }; FBSD_1.4 { @@ -881,6 +885,14 @@ __sys_sched_setscheduler; _sched_yield; __sys_sched_yield; + _security_descriptor_get_fd; + __sys_security_descriptor_get_fd; + _security_descriptor_get_file; + __sys_security_descriptor_get_file; + _security_descriptor_set_fd; + __sys_security_descriptor_set_fd; + _security_descriptor_set_file; + __sys_security_descriptor_set_file; _select; __sys_select; _semget; --- //depot/vendor/FreeBSD/stable/10/sys/cddl/compat/opensolaris/kern/opensolaris_acl.c 2013-10-10 17:56:30.000000000 -0600 +++ //SpectraBSD/stable_downstreaming/sys/cddl/compat/opensolaris/kern/opensolaris_acl.c 2014-12-12 20:42:32.000000000 -0700 @@ -68,6 +68,8 @@ ACL_ENTRY_SUCCESSFUL_ACCESS}, {ACE_FAILED_ACCESS_ACE_FLAG, ACL_ENTRY_FAILED_ACCESS}, + {ACE_INHERITED_ACE, + ACL_ENTRY_INHERITED}, {0, 0}}; static int @@ -98,6 +100,30 @@ return (zfs); } +uint32_t +zfs_ace_perms_from_bsd(int bsd) +{ + return (_zfs_from_bsd(bsd, perms)); +} + +int +bsd_ace_perms_from_zfs(uint32_t zfs) +{ + return (_bsd_from_zfs(zfs, perms)); +} + +uint32_t +zfs_ace_flags_from_bsd(int bsd) +{ + return (_zfs_from_bsd(bsd, flags)); +} + +int +bsd_ace_flags_from_zfs(uint32_t zfs) +{ + return (_bsd_from_zfs(zfs, flags)); +} + int acl_from_aces(struct acl *aclp, const ace_t *aces, int nentries) { --- //depot/vendor/FreeBSD/stable/10/sys/cddl/compat/opensolaris/sys/acl.h 2013-10-10 17:56:30.000000000 -0600 +++ //SpectraBSD/stable_downstreaming/sys/cddl/compat/opensolaris/sys/acl.h 2014-12-12 20:42:32.000000000 -0700 @@ -35,5 +35,9 @@ void aces_from_acl(ace_t *aces, int *nentries, const struct acl *aclp); int acl_from_aces(struct acl *aclp, const ace_t *aces, int nentries); +uint32_t zfs_ace_perms_from_bsd(int _bsd); +int bsd_ace_perms_from_zfs(uint32_t _zfs); +uint32_t zfs_ace_flags_from_bsd(int _bsd); +int bsd_ace_flags_from_zfs(uint32_t _zfs); #endif /* OPENSOLARIS_SYS_ACL_H */ --- //depot/vendor/FreeBSD/stable/10/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/zfs_acl.h 2013-10-10 17:56:30.000000000 -0600 +++ //SpectraBSD/stable_downstreaming/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/zfs_acl.h 2014-12-12 21:06:48.000000000 -0700 @@ -33,6 +33,11 @@ #include #include +#ifdef _KERNEL +#include +#include +#endif + #ifdef __cplusplus extern "C" { #endif @@ -236,6 +241,10 @@ uint64_t zfs_mode_compute(uint64_t, zfs_acl_t *, uint64_t *, uint64_t, uint64_t); int zfs_acl_chown_setattr(struct znode *); +int zfs_freebsd_getsidacls(struct znode *, struct sid_acl **, struct sid_acl **, + int, boolean_t, cred_t *); +int zfs_freebsd_sidacls_to_aclp(zfsvfs_t *, vtype_t, struct sid_acl *, + struct sid_acl *, cred_t *, zfs_fuid_info_t **, zfs_acl_t **); #endif --- //depot/vendor/FreeBSD/stable/10/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/zfs_fuid.h 2013-10-10 17:56:30.000000000 -0600 +++ //SpectraBSD/stable_downstreaming/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/zfs_fuid.h 2014-12-12 20:42:32.000000000 -0700 @@ -30,6 +30,7 @@ #ifdef _KERNEL #include #include +#include #include #endif #include @@ -104,10 +105,15 @@ extern void zfs_fuid_node_add(zfs_fuid_info_t **, const char *, uint32_t, uint64_t, uint64_t, zfs_fuid_type_t); extern void zfs_fuid_destroy(zfsvfs_t *); +extern uint64_t zfs_fuid_create_rid_domain(zfsvfs_t *zfsvfs, + zfs_fuid_type_t type, uint32_t rid, const char *domain, + zfs_fuid_info_t **fuidp); extern uint64_t zfs_fuid_create_cred(zfsvfs_t *, zfs_fuid_type_t, cred_t *, zfs_fuid_info_t **); extern uint64_t zfs_fuid_create(zfsvfs_t *, uint64_t, cred_t *, zfs_fuid_type_t, zfs_fuid_info_t **); +extern int zfs_fuid_map_sid(zfsvfs_t *, uint64_t, zfs_fuid_type_t, + struct sid **); extern void zfs_fuid_map_ids(struct znode *zp, cred_t *cr, uid_t *uid, uid_t *gid); extern zfs_fuid_info_t *zfs_fuid_info_alloc(void); --- //depot/vendor/FreeBSD/stable/10/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_acl.c 2013-10-10 17:56:30.000000000 -0600 +++ //SpectraBSD/stable_downstreaming/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_acl.c 2014-12-12 20:42:32.000000000 -0700 @@ -653,7 +653,7 @@ * While processing the ACL each ACE will be validated for correctness. * ACE FUIDs will be created later. */ -int +static int zfs_copy_ace_2_fuid(zfsvfs_t *zfsvfs, vtype_t obj_type, zfs_acl_t *aclp, void *datap, zfs_ace_t *z_acl, uint64_t aclcnt, size_t *size, zfs_fuid_info_t **fuidp, cred_t *cr) @@ -712,7 +712,288 @@ return (0); } +static int +zfs_freebsd_sid_ace_from_ace(zfsvfs_t *zfsvfs, struct sid_acl_entry **pentry, + uint64_t who, uint32_t access_mask, uint16_t iflags, uint16_t type) +{ + struct sid_acl_entry *entry; + struct sid *sid = NULL; + acl_tag_t sae_tag; + int error; + + if (iflags & ACE_OWNER) + sae_tag = ACL_USER_OBJ; + else if (iflags & ACE_GROUP) + sae_tag = ACL_GROUP_OBJ; + else if (iflags & ACE_EVERYONE) + sae_tag = ACL_EVERYONE; + else if (iflags & ACE_IDENTIFIER_GROUP) + sae_tag = ACL_GROUP; + else + sae_tag = ACL_USER; + + if (sae_tag == ACL_USER) { + error = zfs_fuid_map_sid(zfsvfs, who, ZFS_ACE_USER, &sid); + if (error != 0) + return (error); + } + + if (sae_tag == ACL_GROUP) { + error = zfs_fuid_map_sid(zfsvfs, who, ZFS_ACE_GROUP, &sid); + if (error != 0) + return (error); + } + + // Create sidace now that sid is known. + entry = sid_ace_alloc(sid); + sid_free(sid); + + entry->sae_tag = sae_tag; + entry->sae_perm = bsd_ace_perms_from_zfs(access_mask); + entry->sae_flags = bsd_ace_flags_from_zfs(iflags); + + switch (type) { + case ACE_ACCESS_ALLOWED_ACE_TYPE: + entry->sae_entry_type = ACL_ENTRY_TYPE_ALLOW; + break; + case ACE_ACCESS_DENIED_ACE_TYPE: + entry->sae_entry_type = ACL_ENTRY_TYPE_DENY; + break; + case ACE_SYSTEM_AUDIT_ACE_TYPE: + entry->sae_entry_type = ACL_ENTRY_TYPE_AUDIT; + break; + case ACE_SYSTEM_ALARM_ACE_TYPE: + entry->sae_entry_type = ACL_ENTRY_TYPE_ALARM; + break; + default: + panic("%s: a_type is 0x%x", __func__, type); + } + + *pentry = entry; + return (0); +} + /* + * Copy internal ZFS formated ACL into FreeBSD SID format. + */ +static int +zfs_freebsd_copy_fuid_2_sidacls(zfsvfs_t *zfsvfs, vtype_t obj_type, + zfs_acl_t *aclp, struct sid_acl **psid_dacl, struct sid_acl **psid_sacl) +{ + uint64_t who; + uint32_t access_mask; + uint16_t iflags, type; + zfs_ace_hdr_t *zacep = NULL; + uint16_t entry_type; + struct sid_acl_entry *sidace; + int error = 0; + + while (zacep = zfs_acl_next_ace(aclp, zacep, + &who, &access_mask, &iflags, &type)) { + + switch (type) { + case ACE_ACCESS_ALLOWED_ACE_TYPE: + case ACE_ACCESS_DENIED_ACE_TYPE: + case ACE_SYSTEM_AUDIT_ACE_TYPE: + case ACE_SYSTEM_ALARM_ACE_TYPE: + break; + default: + continue; + } + + error = zfs_freebsd_sid_ace_from_ace(zfsvfs, + &sidace, who, access_mask, iflags, type); + if (error != 0) + break; + + switch (type) { + case ACE_ACCESS_ALLOWED_ACE_TYPE: + case ACE_ACCESS_DENIED_ACE_TYPE: + error = sid_acl_append_ace(psid_dacl, sidace); + break; + case ACE_SYSTEM_AUDIT_ACE_TYPE: + case ACE_SYSTEM_ALARM_ACE_TYPE: + error = sid_acl_append_ace(psid_sacl, sidace); + break; + default: + break; + } + sid_ace_free(sidace); + if (error != 0) + break; + } + + return (error); +} + +static void +zfs_freebsd_ace_from_sid_ace(zfs_ace_t *ace, const struct sid_acl_entry *entry) +{ + if (entry->sae_tag == ACL_USER_OBJ) + ace->z_hdr.z_flags = ACE_OWNER; + else if (entry->sae_tag == ACL_GROUP_OBJ) + ace->z_hdr.z_flags = (ACE_GROUP | ACE_IDENTIFIER_GROUP); + else if (entry->sae_tag == ACL_GROUP) + ace->z_hdr.z_flags = ACE_IDENTIFIER_GROUP; + else if (entry->sae_tag == ACL_EVERYONE) + ace->z_hdr.z_flags = ACE_EVERYONE; + else /* ACL_USER */ + ace->z_hdr.z_flags = 0; + + ace->z_hdr.z_access_mask = zfs_ace_perms_from_bsd(entry->sae_perm); + ace->z_hdr.z_flags |= zfs_ace_flags_from_bsd(entry->sae_flags); + + switch (entry->sae_entry_type) { + case ACL_ENTRY_TYPE_ALLOW: + ace->z_hdr.z_type = ACE_ACCESS_ALLOWED_ACE_TYPE; + break; + case ACL_ENTRY_TYPE_DENY: + ace->z_hdr.z_type = ACE_ACCESS_DENIED_ACE_TYPE; + break; + case ACL_ENTRY_TYPE_ALARM: + ace->z_hdr.z_type = ACE_SYSTEM_ALARM_ACE_TYPE; + break; + case ACL_ENTRY_TYPE_AUDIT: + ace->z_hdr.z_type = ACE_SYSTEM_AUDIT_ACE_TYPE; + break; + default: + panic("%s: ae_entry_type is 0x%x", __func__, + entry->sae_entry_type); + } +} + +static int +zfs_freebsd_copy_sidace_2_fuid(zfsvfs_t *zfsvfs, vtype_t obj_type, + const struct sid_acl_entry *sid_ace, zfs_acl_t *aclp, zfs_ace_t **paceptr, + zfs_fuid_info_t **fuidp) +{ + zfs_ace_t *aceptr = *paceptr; + uint16_t entry_type; + + zfs_freebsd_ace_from_sid_ace(aceptr, sid_ace); + entry_type = aceptr->z_hdr.z_flags & ACE_TYPE_FLAGS; + if (entry_type != ACE_OWNER && entry_type != OWNING_GROUP && + entry_type != ACE_EVERYONE) { + char *domain; + uint32_t rid; + int err; + + err = sid_to_domain_and_rid(sid_ace->sae_sid, &domain, + &rid); + if (err != 0) { + sid_string_free(domain); + return (err); + } + + aceptr->z_fuid = zfs_fuid_create_rid_domain(zfsvfs, + (entry_type == 0) ? ZFS_ACE_USER : ZFS_ACE_GROUP, + rid, domain, fuidp); + sid_string_free(domain); + } + + /* XXX Deal with OBJECT aces. */ + + /* + * Make sure ACE is valid + */ + if (zfs_ace_valid(obj_type, aclp, aceptr->z_hdr.z_type, + aceptr->z_hdr.z_flags) != B_TRUE) + return (SET_ERROR(EINVAL)); + + aceptr = (zfs_ace_t *)((caddr_t)aceptr + + aclp->z_ops.ace_size(aceptr)); + *paceptr = aceptr; + return (0); +} + +/* + * Copy FreeBSD ACLs to internal ZFS format. + * + * While processing an ACL each ACE will be validated for correctness. + * ACE FUIDs will be created later. + */ +static int +zfs_freebsd_copy_sidacls_2_fuid(zfsvfs_t *zfsvfs, vtype_t obj_type, + zfs_acl_t *aclp, struct sid_acl *sid_dacl, struct sid_acl *sid_sacl, + zfs_ace_t *z_acl, size_t *size, zfs_fuid_info_t **fuidp, cred_t *cr) +{ + int i; + zfs_ace_t *aceptr = z_acl; + struct sid_acl_iter acl_iter; + struct sid_acl_entry *sid_ace; + zfs_object_ace_t *zobjacep; + ace_object_t *aceobjp; + + if (sid_dacl) { + int error; + + sid_acl_iter_init(&acl_iter, sid_dacl); + while ((sid_ace = sid_acl_iter_next(&acl_iter)) != NULL) { + error = zfs_freebsd_copy_sidace_2_fuid(zfsvfs, + obj_type, sid_ace, aclp, &aceptr, fuidp); + if (error != 0) + return (error); + } + } + + if (sid_sacl) { + int error; + + sid_acl_iter_init(&acl_iter, sid_sacl); + while ((sid_ace = sid_acl_iter_next(&acl_iter)) != NULL) { + error = zfs_freebsd_copy_sidace_2_fuid(zfsvfs, + obj_type, sid_ace, aclp, &aceptr, fuidp); + if (error != 0) + return (error); + } + } + + *size = (caddr_t)aceptr - (caddr_t)z_acl; + + return (0); +} + +int +zfs_freebsd_sidacls_to_aclp(zfsvfs_t *zfsvfs, vtype_t obj_type, + struct sid_acl *sid_dacl, struct sid_acl *sid_sacl, cred_t *cr, + zfs_fuid_info_t **fuidp, zfs_acl_t **zaclp) +{ + zfs_acl_t *aclp; + zfs_acl_node_t *aclnode; + int acecnt = 0; + int error; + + if (sid_dacl) + acecnt += sid_dacl->sacl_ace_cnt; + if (sid_sacl) + acecnt += sid_sacl->sacl_ace_cnt; + + if (acecnt > MAX_ACL_ENTRIES || acecnt == 0) + return (SET_ERROR(EINVAL)); + + aclp = zfs_acl_alloc(zfs_acl_version(zfsvfs->z_version)); + + aclp->z_hints = 0; + aclnode = zfs_acl_node_alloc(acecnt * sizeof (zfs_object_ace_t)); + + if ((error = zfs_freebsd_copy_sidacls_2_fuid(zfsvfs, obj_type, + aclp, sid_dacl, sid_sacl, aclnode->z_acldata, &aclnode->z_size, + fuidp, cr)) != 0) { + zfs_acl_free(aclp); + zfs_acl_node_free(aclnode); + return (error); + } + aclp->z_acl_bytes = aclnode->z_size; + aclnode->z_ace_count = acecnt; + aclp->z_acl_count = acecnt; + list_insert_head(&aclp->z_acl, aclnode); + + *zaclp = aclp; + + return (0); +} + +/* * Copy ZFS ACEs to fixed size ace_t layout */ static void @@ -1108,7 +1389,7 @@ if (znode_acl.z_acl_extern_obj) { error = dmu_read(zp->z_zfsvfs->z_os, znode_acl.z_acl_extern_obj, 0, aclnode->z_size, - aclnode->z_acldata, DMU_READ_PREFETCH); + aclnode->z_acldata, DMU_CTX_FLAG_PREFETCH); } else { bcopy(znode_acl.z_ace_data, aclnode->z_acldata, aclnode->z_size); @@ -1661,11 +1942,30 @@ acl_ids->z_fgid = 0; } if (acl_ids->z_fgid == 0) { + /* + * On BSD, the group of a file is inherited from its + * parent directory regardless of the setgid bit. + */ +#ifndef __FreeBSD__ if (dzp->z_mode & S_ISGID) { +#endif char *domain; uint32_t rid; acl_ids->z_fgid = dzp->z_gid; +#ifdef __FreeBSD__ + /* + * XXX + * gid is used below in security policy checks. + * Use the credential's gid when operating in + * directories owned by a group represented by + * a FUID until we have proper UID mapping + * for use by security policy and other APIs. + */ + if (IS_EPHEMERAL(acl_ids->z_fgid)) + gid = crgetgid(cr); + else +#endif gid = zfs_fuid_map_id(zfsvfs, acl_ids->z_fgid, cr, ZFS_GROUP); @@ -1680,15 +1980,13 @@ FUID_INDEX(acl_ids->z_fgid), acl_ids->z_fgid, ZFS_GROUP); } +#ifndef __FreeBSD__ } else { acl_ids->z_fgid = zfs_fuid_create_cred(zfsvfs, ZFS_GROUP, cr, &acl_ids->z_fuidp); -#ifdef __FreeBSD_kernel__ - gid = acl_ids->z_fgid = dzp->z_gid; -#else - gid = crgetgid(cr); + gid = crgetgid(cr); + } #endif - } } } @@ -1799,7 +2097,9 @@ /* * Scan ACL to determine number of ACEs */ - if ((zp->z_pflags & ZFS_ACL_OBJ_ACE) && !(mask & VSA_ACE_ALLTYPES)) { + if (!(zp->z_pflags & ZFS_ACL_OBJ_ACE)) { + count = (int)aclp->z_acl_count; + } else { void *zacep = NULL; uint64_t who; uint32_t access_mask; @@ -1818,13 +2118,13 @@ count++; } } - vsecp->vsa_aclcnt = count; - } else - count = (int)aclp->z_acl_count; + } + + if (!(mask & VSA_ACE_ALLTYPES)) + largeace = 0; - if (mask & VSA_ACECNT) { - vsecp->vsa_aclcnt = count; - } + if (mask & VSA_ACECNT) + vsecp->vsa_aclcnt = count + largeace; if (mask & VSA_ACE) { size_t aclsz; @@ -2047,7 +2347,7 @@ */ if ((v4_mode & WRITE_MASK_DATA) && (((ZTOV(zp)->v_type != VDIR) && - (zp->z_pflags & (ZFS_READONLY | ZFS_IMMUTABLE))) || + (zp->z_pflags & (ZFS_IMMUTABLE))) || (ZTOV(zp)->v_type == VDIR && (zp->z_pflags & ZFS_IMMUTABLE)))) { return (SET_ERROR(EPERM)); @@ -2066,7 +2366,7 @@ */ if ((v4_mode & ACE_DELETE) && (zp->z_pflags & ZFS_NOUNLINK)) { - return (EPERM); + return (SET_ERROR(EPERM)); } #endif @@ -2591,6 +2891,8 @@ * | * No search privilege, can't even look up file? * + * NOTE: If the parent dir's ACL denies write and execute permissions, + * then it may be impossible to even lookup the file. */ int zfs_zaccess_delete(znode_t *dzp, znode_t *zp, cred_t *cr) @@ -2726,3 +3028,56 @@ return (error); } + +/* + * Retrieve a file's ACL in SID format. + */ +int +zfs_freebsd_getsidacls(znode_t *zp, struct sid_acl **psid_dacl, + struct sid_acl **psid_sacl, int filter, boolean_t skipaclchk, cred_t *cr) +{ + zfs_acl_t *aclp; + struct sid_acl *sid_dacl; + struct sid_acl *sid_sacl; + int error; + int count = 0; + int largeace = 0; + + *psid_dacl = NULL; + *psid_sacl = NULL; + if (error = zfs_zaccess(zp, ACE_READ_ACL, 0, skipaclchk, cr)) + return (error); + + mutex_enter(&zp->z_acl_lock); + + error = zfs_acl_node_read(zp, B_FALSE, &aclp, B_FALSE); + if (error != 0) { + mutex_exit(&zp->z_acl_lock); + return (error); + } + + sid_dacl = sid_acl_alloc(); + sid_sacl = sid_acl_alloc(); + error = zfs_freebsd_copy_fuid_2_sidacls(zp->z_zfsvfs, + ZTOV(zp)->v_type, aclp, &sid_dacl, &sid_sacl); + mutex_exit(&zp->z_acl_lock); + + if (error == 0) { + /* + * Unlike DACLs, an empty and non-existant SACL have + * equivalent semantics. Save space and processing + * in callers by culling empty SACLs here. + */ + if (sid_sacl->sacl_ace_cnt == 0) { + sid_acl_free(sid_sacl); + sid_sacl = NULL; + } + *psid_dacl = sid_dacl; + *psid_sacl = sid_sacl; + } else { + sid_acl_free(sid_dacl); + sid_acl_free(sid_sacl); + } + + return (0); +} --- //depot/vendor/FreeBSD/stable/10/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_fuid.c 2013-10-10 17:56:30.000000000 -0600 +++ //SpectraBSD/stable_downstreaming/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_fuid.c 2014-12-12 21:06:48.000000000 -0700 @@ -36,6 +36,10 @@ #endif #include +#include +#include +#include + /* * FUID Domain table(s). * @@ -132,7 +136,7 @@ packed = kmem_alloc(fuid_size, KM_SLEEP); VERIFY(dmu_read(os, fuid_obj, 0, - fuid_size, packed, DMU_READ_PREFETCH) == 0); + fuid_size, packed, DMU_CTX_FLAG_PREFETCH) == 0); VERIFY(nvlist_unpack(packed, fuid_size, &nvp, 0) == 0); VERIFY(nvlist_lookup_nvlist_array(nvp, FUID_NVP_ARRAY, @@ -311,14 +315,14 @@ * for the user nobody. */ if (domain[0] == '\0') { - if (retdomain) + if (retdomain != NULL) *retdomain = nulldomain; return (0); } searchnode.f_ksid = ksid_lookupdomain(domain); - if (retdomain) - *retdomain = searchnode.f_ksid->kd_name; + if (retdomain != NULL) + *retdomain = NULL; if (!zfsvfs->z_fuid_loaded) zfs_fuid_init(zfsvfs); @@ -326,9 +330,11 @@ rw_enter(&zfsvfs->z_fuid_lock, rw); findnode = avl_find(&zfsvfs->z_fuid_domain, &searchnode, &loc); - if (findnode) { + if (findnode != NULL) { rw_exit(&zfsvfs->z_fuid_lock); ksiddomain_rele(searchnode.f_ksid); + if (retdomain != NULL) + *retdomain = findnode->f_ksid->kd_name; return (findnode->f_idx); } else if (addok) { fuid_domain_t *domnode; @@ -349,6 +355,8 @@ avl_add(&zfsvfs->z_fuid_idx, domnode); zfsvfs->z_fuid_dirty = B_TRUE; rw_exit(&zfsvfs->z_fuid_lock); + if (retdomain != NULL) + *retdomain = domnode->f_ksid->kd_name; return (retidx); } else { rw_exit(&zfsvfs->z_fuid_lock); @@ -360,7 +368,6 @@ * Query domain table by index, returning domain string * * Returns a pointer from an avl node of the domain string. - * */ const char * zfs_fuid_find_by_idx(zfsvfs_t *zfsvfs, uint32_t idx) @@ -385,6 +392,25 @@ return (domain); } +int +zfs_fuid_map_sid(zfsvfs_t *zfsvfs, uint64_t fuid, zfs_fuid_type_t type, + struct sid **psid) +{ + uint32_t index = FUID_INDEX(fuid); + const char *domain; + + /* + * Default to the NULL authority, until mapping + * services are available for POSIX ids. + */ + domain = "S-1-0"; + if (index != 0) + domain = zfs_fuid_find_by_idx(zfsvfs, index); + ASSERT(domain != NULL); + + return (sid_from_domain_and_rid(psid, domain, FUID_RID(fuid))); +} + void zfs_fuid_map_ids(znode_t *zp, cred_t *cr, uid_t *uidp, uid_t *gidp) { @@ -487,6 +513,31 @@ } /* + * Create a file system FUID from domain relative id and domain. + */ +uint64_t +zfs_fuid_create_rid_domain(zfsvfs_t *zfsvfs, zfs_fuid_type_t type, + uint32_t rid, const char *domain, zfs_fuid_info_t **fuidp) +{ + uint64_t idx; + ksid_t *ksid; + char *kdomain; + uid_t id; + + if (!zfsvfs->z_use_fuids) { + id = rid; + + return ((uint64_t)id); + } + + idx = zfs_fuid_find_by_domain(zfsvfs, domain, &kdomain, B_TRUE); + + zfs_fuid_node_add(fuidp, kdomain, rid, idx, id, type); + + return (FUID_ENCODE(idx, rid)); +} + +/* * Create a file system FUID, based on information in the users cred * * If cred contains KSID_OWNER then it should be used to determine --- //depot/vendor/FreeBSD/stable/10/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_log.c 2014-12-22 20:58:51.000000000 -0700 +++ //SpectraBSD/stable_downstreaming/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_log.c 2015-01-14 16:29:29.000000000 -0700 @@ -498,7 +498,7 @@ (write_state == WR_COPIED ? len : 0)); lr = (lr_write_t *)&itx->itx_lr; if (write_state == WR_COPIED && dmu_read(zp->z_zfsvfs->z_os, - zp->z_id, off, len, lr + 1, DMU_READ_NO_PREFETCH) != 0) { + zp->z_id, off, len, lr + 1, /*flags*/0) != 0) { zil_itx_destroy(itx); itx = zil_itx_create(txtype, sizeof (*lr)); lr = (lr_write_t *)&itx->itx_lr; @@ -613,6 +613,56 @@ } /* + * Handles TX_SETATTR transactions caused by security descriptor based updates. + */ +void +zfs_log_sd_setattr(zilog_t *zilog, dmu_tx_t *tx, int txtype, + znode_t *zp, uint_t mask_applied, uint64_t mode, zfs_fuid_info_t *fuidp) +{ + itx_t *itx; + lr_setattr_t *lr; + size_t recsize = sizeof (lr_setattr_t); + void *start; + + if (zil_replaying(zilog, tx) || zp->z_unlinked) + return; + + if (fuidp) + recsize += fuidp->z_domain_str_sz; + + itx = zil_itx_create(txtype, recsize); + lr = (lr_setattr_t *)&itx->itx_lr; + lr->lr_foid = zp->z_id; + + lr->lr_mask = (uint64_t)mask_applied; + lr->lr_mode = (uint64_t)mode; + if (mask_applied & AT_UID) + lr->lr_uid = fuidp->z_fuid_owner; + else + lr->lr_uid = 0; + + if (mask_applied & AT_GID) + lr->lr_gid = fuidp->z_fuid_group; + else + lr->lr_gid = 0; + + lr->lr_size = 0; + lr->lr_atime[0] = lr->lr_atime[1] = 0; + lr->lr_mtime[0] = lr->lr_mtime[1] = 0; + start = (lr_setattr_t *)(lr + 1); + + /* + * Now stick on domain information if any on end + */ + + if (fuidp) + (void) zfs_log_fuid_domains(fuidp, start); + + itx->itx_sync = (zp->z_sync_cnt != 0); + zil_itx_assign(zilog, itx, tx); +} + +/* * Handles TX_ACL transactions. */ void --- //depot/vendor/FreeBSD/stable/10/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vnops.c 2015-01-10 01:01:12.000000000 -0700 +++ //SpectraBSD/stable_downstreaming/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vnops.c 2015-03-17 18:55:36.000000000 -0600 @@ -70,13 +70,17 @@ #include #include #include -#include +#include +#include #include #include #include #include +#include /* + * ZFS VNode operations. Entry points to the ZFS module + * * Programming rules. * * Each vnode op performs some logical unit of work. To do this, the ZPL must @@ -795,7 +856,6 @@ * Timestamps: * vp - ctime|mtime updated if byte count > 0 */ - /* ARGSUSED */ static int zfs_write(vnode_t *vp, uio_t *uio, int ioflag, cred_t *cr, caller_context_t *ct) @@ -847,7 +907,7 @@ /* * If immutable or not appending then return EPERM */ - if ((zp->z_pflags & (ZFS_IMMUTABLE | ZFS_READONLY)) || + if ((zp->z_pflags & (ZFS_IMMUTABLE)) || ((zp->z_pflags & ZFS_APPENDONLY) && !(ioflag & FAPPEND) && (uio->uio_loffset < zp->z_size))) { ZFS_EXIT(zfsvfs); @@ -919,7 +979,7 @@ if (vn_rlimit_fsize(vp, uio, uio->uio_td)) { zfs_range_unlock(rl); ZFS_EXIT(zfsvfs); - return (EFBIG); + return (SET_ERROR(EFBIG)); } if (woff >= limit) { @@ -1243,7 +1303,7 @@ error = SET_ERROR(ENOENT); } else { error = dmu_read(os, object, offset, size, buf, - DMU_READ_NO_PREFETCH); + /*flags*/0); } ASSERT(error == 0 || error == ENOENT); } else { /* indirect write */ @@ -1387,8 +1516,8 @@ znode_t *zdp = VTOZ(dvp); zfsvfs_t *zfsvfs = zdp->z_zfsvfs; int error = 0; - int *direntflags = NULL; - void *realpnp = NULL; + int *direntflags = NULL; /* directory lookup flags */ + void *realpnp = NULL; /* returned pathname */ /* fast path */ if (!(flags & (LOOKUP_XATTR | FIGNORECASE))) { @@ -1565,9 +1679,6 @@ * excl - flag indicating exclusive or non-exclusive mode. * mode - mode to open file with. * cr - credentials of caller. - * flag - large file flag [UNUSED]. - * ct - caller context - * vsecp - ACL to be set * * OUT: vpp - vnode of created or trunc'd entry. * @@ -1575,9 +1686,8 @@ * * Timestamps: * dvp - ctime|mtime updated if new entry created - * vp - ctime|mtime always, atime if new + * vp - ctime|mtime updated always, atime if new */ - /* ARGSUSED */ static int zfs_create(vnode_t *dvp, char *name, vattr_t *vap, int excl, int mode, @@ -2995,22 +3110,22 @@ uint_t mask = vap->va_mask; uint_t saved_mask = 0; uint64_t saved_mode; - int trim_mask = 0; + int trim_mask; uint64_t new_mode; uint64_t new_uid, new_gid; uint64_t xattr_obj; uint64_t mtime[2], ctime[2]; znode_t *attrzp; - int need_policy = FALSE; + int need_policy; int err, err2; - zfs_fuid_info_t *fuidp = NULL; + zfs_fuid_info_t *fuidp; xvattr_t *xvap = (xvattr_t *)vap; /* vap may be an xvattr_t * */ xoptattr_t *xoap; zfs_acl_t *aclp; boolean_t skipaclchk = (flags & ATTR_NOACLCHECK) ? B_TRUE : B_FALSE; - boolean_t fuid_dirtied = B_FALSE; + boolean_t fuid_dirtied; sa_bulk_attr_t bulk[7], xattr_bulk[7]; - int count = 0, xattr_count = 0; + int count, xattr_count; if (mask == 0) return (0); @@ -3064,11 +3179,6 @@ return (SET_ERROR(EPERM)); } - if ((mask & AT_SIZE) && (zp->z_pflags & ZFS_READONLY)) { - ZFS_EXIT(zfsvfs); - return (SET_ERROR(EPERM)); - } - /* * Verify timestamps doesn't overflow 32 bits. * ZFS can handle large timestamps, but 32bit syscalls can't @@ -3084,8 +3194,15 @@ } top: + tx = NULL; + trim_mask = 0; attrzp = NULL; + need_policy = FALSE; + fuidp = NULL; aclp = NULL; + fuid_dirtied = B_FALSE; + count = 0; + xattr_count = 0; /* Can this be moved to before the top label? */ if (zfsvfs->z_vfs->vfs_flag & VFS_RDONLY) { @@ -3326,17 +3443,15 @@ if (err == 0 && xattr_obj) { err = zfs_zget(zp->z_zfsvfs, xattr_obj, &attrzp); if (err) - goto out2; + goto out; } if (mask & AT_UID) { new_uid = zfs_fuid_create(zfsvfs, (uint64_t)vap->va_uid, cr, ZFS_OWNER, &fuidp); if (new_uid != zp->z_uid && zfs_fuid_overquota(zfsvfs, B_FALSE, new_uid)) { - if (attrzp) - VN_RELE(ZTOV(attrzp)); err = SET_ERROR(EDQUOT); - goto out2; + goto out; } } @@ -3345,10 +3460,8 @@ cr, ZFS_GROUP, &fuidp); if (new_gid != zp->z_gid && zfs_fuid_overquota(zfsvfs, B_TRUE, new_gid)) { - if (attrzp) - VN_RELE(ZTOV(attrzp)); err = SET_ERROR(EDQUOT); - goto out2; + goto out; } } } @@ -3413,7 +3526,6 @@ if (err) goto out; - count = 0; /* * Set each attribute requested. * We group settings according to the locks they need to acquire. @@ -3464,17 +3576,17 @@ attrzp->z_gid = new_gid; } } - if (!(mask & AT_MODE)) { - SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_MODE(zfsvfs), - NULL, &new_mode, sizeof (new_mode)); - new_mode = zp->z_mode; - } err = zfs_acl_chown_setattr(zp); ASSERT(err == 0); if (attrzp) { err = zfs_acl_chown_setattr(attrzp); ASSERT(err == 0); } + if (!(mask & AT_MODE)) { + SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_MODE(zfsvfs), + NULL, &new_mode, sizeof (new_mode)); + new_mode = zp->z_mode; + } } if (mask & AT_MODE) { @@ -3490,7 +3602,6 @@ aclp = NULL; } - if (mask & AT_ATIME) { ZFS_TIME_ENCODE(&vap->va_atime, zp->z_atime); SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_ATIME(zfsvfs), NULL, @@ -3589,21 +3700,20 @@ if (aclp) zfs_acl_free(aclp); - if (fuidp) { + if (fuidp) zfs_fuid_info_free(fuidp); - fuidp = NULL; - } - if (err) { - dmu_tx_abort(tx); - if (err == ERESTART) - goto top; - } else { - err2 = sa_bulk_update(zp->z_sa_hdl, bulk, count, tx); - dmu_tx_commit(tx); + if (tx) { + if (err) { + dmu_tx_abort(tx); + if (err == ERESTART) + goto top; + } else { + err2 = sa_bulk_update(zp->z_sa_hdl, bulk, count, tx); + dmu_tx_commit(tx); + } } -out2: if (zfsvfs->z_os->os_sync == ZFS_SYNC_ALWAYS) zil_commit(zilog, 0); @@ -7005,7 +7127,7 @@ return (error); } -int +static int zfs_freebsd_getacl(ap) struct vop_getacl_args /* { struct vnode *vp; @@ -7019,7 +7141,7 @@ vsecattr_t vsecattr; if (ap->a_type != ACL_TYPE_NFS4) - return (EINVAL); + return (SET_ERROR(EINVAL)); vsecattr.vsa_mask = VSA_ACE | VSA_ACECNT; if (error = zfs_getsecattr(ap->a_vp, &vsecattr, 0, ap->a_cred, NULL)) @@ -7032,7 +7154,7 @@ return (error); } -int +static int zfs_freebsd_setacl(ap) struct vop_setacl_args /* { struct vnode *vp; @@ -7048,10 +7170,10 @@ aclent_t *aaclp; if (ap->a_type != ACL_TYPE_NFS4) - return (EINVAL); + return (SET_ERROR(EINVAL)); if (ap->a_aclp->acl_cnt < 1 || ap->a_aclp->acl_cnt > MAX_ACL_ENTRIES) - return (EINVAL); + return (SET_ERROR(EINVAL)); /* * With NFSv4 ACLs, chmod(2) may need to add additional entries, @@ -7060,14 +7182,14 @@ * cause chmod(2) to run out of ACL entries. */ if (ap->a_aclp->acl_cnt * 2 + 6 > ACL_MAX_ENTRIES) - return (ENOSPC); + return (SET_ERROR(ENOSPC)); error = acl_nfs4_check(ap->a_aclp, ap->a_vp->v_type == VDIR); if (error != 0) return (error); vsecattr.vsa_mask = VSA_ACE; - aclbsize = ap->a_aclp->acl_cnt * sizeof(ace_t); + aclbsize = ap->a_aclp->acl_cnt * sizeof (ace_t); vsecattr.vsa_aclentp = kmem_alloc(aclbsize, KM_SLEEP); aaclp = vsecattr.vsa_aclentp; vsecattr.vsa_aclentsz = aclbsize; @@ -7079,7 +7201,7 @@ return (error); } -int +static int zfs_freebsd_aclcheck(ap) struct vop_aclcheck_args /* { struct vnode *vp; @@ -7090,7 +7212,419 @@ } */ *ap; { - return (EOPNOTSUPP); + return (SET_ERROR(EOPNOTSUPP)); +} + +static int +zfs_freebsd_getsd(ap) + struct vop_getsd_args /* { + struct vnode *a_vp; + int a_security_info; + struct security_descriptor **a_sdp; + struct ucred *a_cred; + struct thread *a_td; + } */ *ap; +{ + vnode_t *vp = ap->a_vp; + int sec_info = ap->a_security_info; + struct security_descriptor *sd, **psd = ap->a_sdp; + cred_t *cred = ap->a_cred; + znode_t *zp = VTOZ(vp); + zfsvfs_t *zfsvfs = zp->z_zfsvfs; + struct sid *sid; + int error = 0; + + *psd = NULL; + + if (!(sec_info & + (SD_INFO_OWNER|SD_INFO_GROUP|SD_INFO_DACL|SD_INFO_SACL))) + return (SET_ERROR(EINVAL)); + + sd = security_descriptor_alloc(); + + ZFS_ENTER(zfsvfs); + ZFS_VERIFY_ZP(zp); + + if (sec_info & SD_INFO_OWNER) { + error = zfs_fuid_map_sid(zfsvfs, zp->z_uid, ZFS_OWNER, &sid); + if (error) { + security_descriptor_free(sd); + ZFS_EXIT(zfsvfs); + return (error); + } + security_descriptor_set_owner(sd, sid, /*defaulted*/FALSE); + } + if (sec_info & SD_INFO_GROUP) { + error = zfs_fuid_map_sid(zfsvfs, zp->z_gid, ZFS_GROUP, &sid); + if (error) { + security_descriptor_free(sd); + ZFS_EXIT(zfsvfs); + return (error); + } + security_descriptor_set_group(sd, sid, /*defaulted*/FALSE); + } + if (sec_info & (SD_INFO_DACL|SD_INFO_SACL)) { + struct sid_acl *sid_dacl; + struct sid_acl *sid_sacl; + + error = zfs_freebsd_getsidacls(zp, &sid_dacl, &sid_sacl, + /*filter*/TRUE, /*skipaclchk*/FALSE, cred); + if (error != 0) { + security_descriptor_free(sd); + ZFS_EXIT(zfsvfs); + return (error); + } + + if ((sec_info & SD_INFO_DACL) && sid_dacl != NULL) { + security_descriptor_set_dacl(sd, sid_dacl, + zp->z_pflags & ZFS_ACL_DEFAULTED); + if (zp->z_pflags & ZFS_ACL_PROTECTED) + sd->sd_control |= SD_CTRL_DACL_PROTECTED; + if (zp->z_pflags & ZFS_ACL_AUTO_INHERIT) + sd->sd_control |= SD_CTRL_DACL_AUTO_INHERITED; + } else if (sid_dacl != NULL) { + sid_acl_free(sid_dacl); + } + + if ((sec_info & SD_INFO_SACL) && sid_sacl != NULL) { + security_descriptor_set_sacl(sd, sid_sacl, + zp->z_pflags & ZFS_ACL_DEFAULTED); + if (zp->z_pflags & ZFS_ACL_PROTECTED) + sd->sd_control |= SD_CTRL_SACL_PROTECTED; + if (zp->z_pflags & ZFS_ACL_AUTO_INHERIT) + sd->sd_control |= SD_CTRL_SACL_AUTO_INHERITED; + } else if (sid_sacl != NULL) { + sid_acl_free(sid_sacl); + } + } + + ZFS_EXIT(zfsvfs); + *psd = sd; + return (0); +} + +static int +zfs_freebsd_setsd(ap) + struct vop_setsd_args /* { + struct vnode *a_vp; + int a_security_info; + struct security_descriptor *a_sd; + struct ucred *a_cred; + struct thread *a_td; + } */ *ap; +{ + vnode_t *vp = ap->a_vp; + int sec_info = ap->a_security_info; + struct security_descriptor *sd = ap->a_sd; + cred_t *cred = ap->a_cred; + znode_t *zp = VTOZ(vp); + znode_t *attrzp; + zfsvfs_t *zfsvfs = zp->z_zfsvfs; + zilog_t *zilog; + dmu_tx_t *tx; + sa_bulk_attr_t bulk[7], xattr_bulk[7]; + uint64_t ctime[2]; + uint64_t xattr_obj; + uint64_t new_mode; + uint64_t new_uid, new_gid; + int count, xattr_count, err, err2; + zfs_fuid_info_t *fuidp; + zfs_acl_t *aclp; + boolean_t fuid_dirtied; + uint_t setattrmask; + + if (!sec_info) + return (0); + + if (!(sec_info & + (SD_INFO_OWNER|SD_INFO_GROUP|SD_INFO_DACL|SD_INFO_SACL))) + return (SET_ERROR(EINVAL)); + + /* Only root until the safeguards listed below are in place. */ + if (cred->cr_ruid != 0) + return (SET_ERROR(EPERM)); + + ZFS_ENTER(zfsvfs); + ZFS_VERIFY_ZP(zp); + + if (zfsvfs->z_version < ZPL_VERSION_FUID) { + ZFS_EXIT(zfsvfs); + return (SET_ERROR(EOPNOTSUPP)); + } + + zilog = zfsvfs->z_log; + + getnewvnode_reserve(1); +top: + attrzp = NULL; + tx = NULL; + count = 0; + xattr_count = 0; + fuidp = NULL; + aclp = NULL; + fuid_dirtied = B_FALSE; + setattrmask = 0; + + if (zp->z_pflags & ZFS_IMMUTABLE) { + getnewvnode_drop_reserve(); + ZFS_EXIT(zfsvfs); + return (SET_ERROR(EPERM)); + } + if (zfsvfs->z_vfs->vfs_flag & VFS_RDONLY) { + getnewvnode_drop_reserve(); + ZFS_EXIT(zfsvfs); + return (SET_ERROR(EROFS)); + } + + /* + * Note: Access checks and setuid/setgid clearing on ownership + * change are missing here. They will need to be added + * once FreeBSD gains support for SID based credentials + * and querying of group membership by SID. + */ + + if (sec_info & (SD_INFO_OWNER|SD_INFO_GROUP)) { + + /* Ownership of any extended attributes changes too. */ + err = sa_lookup(zp->z_sa_hdl, SA_ZPL_XATTR(zfsvfs), + &xattr_obj, sizeof (xattr_obj)); + + if (err == 0 && xattr_obj) { + err = zfs_zget(zp->z_zfsvfs, xattr_obj, &attrzp); + if (err) + goto out; + } + if (sec_info & SD_INFO_OWNER) { + char *domain; + uint32_t rid; + + err = sid_to_domain_and_rid(sd->sd_owner, &domain, + &rid); + if (err) + goto out; + + new_uid = zfs_fuid_create_rid_domain(zfsvfs, ZFS_OWNER, + rid, domain, &fuidp); + sid_string_free(domain); + domain = NULL; + if (new_uid != zp->z_uid && + zfs_fuid_overquota(zfsvfs, B_FALSE, new_uid)) { + err = SET_ERROR(EDQUOT); + goto out; + } + } + + if (sec_info & SD_INFO_GROUP) { + char *domain; + uint32_t rid; + + err = sid_to_domain_and_rid(sd->sd_group, &domain, + &rid); + if (err) + goto out; + + new_gid = zfs_fuid_create_rid_domain(zfsvfs, ZFS_GROUP, + rid, domain, &fuidp); + sid_string_free(domain); + domain = NULL; + if (new_gid != zp->z_gid && + zfs_fuid_overquota(zfsvfs, B_TRUE, new_gid)) { + err = SET_ERROR(EDQUOT); + goto out; + } + } + } + + if (sec_info & (SD_INFO_DACL|SD_INFO_SACL)) { + struct sid_acl *cur_dacl; + struct sid_acl *cur_sacl; + struct sid_acl *dacl; + struct sid_acl *sacl; + + cur_dacl = NULL; + cur_sacl = NULL; + dacl = sd->sd_dacl; + sacl = sd->sd_sacl; + + /* + * Since DACLs and SACLs share a single list in ZFS + * and we are rewriting the whole thing, extract and + * use the current version of any ACL that is not being + * explicitly updated so its settings are preserved. + */ + if ((sec_info & (SD_INFO_DACL|SD_INFO_SACL)) != + (SD_INFO_DACL|SD_INFO_SACL)) { + + err = zfs_freebsd_getsidacls(zp, &cur_dacl, &cur_sacl, + /*filter*/TRUE, /*skipaclchk*/FALSE, cred); + if (err) + goto out; + + if (!(sec_info & SD_INFO_DACL)) + dacl = cur_dacl; + if (!(sec_info & SD_INFO_SACL)) + sacl = cur_sacl; + } + + /* + * Convert to ZFS format and discard fetched + * preexisting ACL data. + */ + err = zfs_freebsd_sidacls_to_aclp(zfsvfs, vp->v_type, + dacl, sacl, cred, &fuidp, &aclp); + if (cur_dacl != NULL) + sid_acl_free(cur_dacl); + if (cur_sacl != NULL) + sid_acl_free(cur_sacl); + if (err != 0) + goto out; + + if (sd->sd_control & SD_CTRL_DACL_PROTECTED) + aclp->z_hints |= ZFS_ACL_PROTECTED; + if (sd->sd_control & SD_CTRL_DACL_DEFAULTED) + aclp->z_hints |= ZFS_ACL_DEFAULTED; + if (sd->sd_control & SD_CTRL_DACL_AUTO_INHERITED) + aclp->z_hints |= ZFS_ACL_AUTO_INHERIT; + } + + tx = dmu_tx_create(zfsvfs->z_os); + + dmu_tx_hold_sa(tx, zp->z_sa_hdl, + sec_info & (SD_INFO_DACL|SD_INFO_SACL)); + if (attrzp) + dmu_tx_hold_sa(tx, attrzp->z_sa_hdl, B_FALSE); + + fuid_dirtied = zfsvfs->z_fuid_dirty; + if (fuid_dirtied) + zfs_fuid_txhold(zfsvfs, tx); + + zfs_sa_upgrade_txholds(tx, zp); + + err = dmu_tx_assign(tx, TXG_NOWAIT); + if (err) { + if (err == ERESTART) + dmu_tx_wait(tx); + goto out; + } + + mutex_enter(&zp->z_acl_lock); + mutex_enter(&zp->z_lock); + + SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_FLAGS(zfsvfs), NULL, + &zp->z_pflags, sizeof (zp->z_pflags)); + + if (attrzp) { + mutex_enter(&attrzp->z_acl_lock); + mutex_enter(&attrzp->z_lock); + + /* A NOP until setuid/setgid/sticky bit security is added. */ + SA_ADD_BULK_ATTR(xattr_bulk, xattr_count, + SA_ZPL_FLAGS(zfsvfs), NULL, &attrzp->z_pflags, + sizeof (attrzp->z_pflags)); + + SA_ADD_BULK_ATTR(xattr_bulk, xattr_count, + SA_ZPL_CTIME(zfsvfs), NULL, &ctime, + sizeof (ctime)); + zfs_tstamp_update_setup(attrzp, STATE_CHANGED, + NULL, ctime, B_TRUE); + } + + if (sec_info & (SD_INFO_OWNER|SD_INFO_GROUP)) { + + if (sec_info & SD_INFO_OWNER) { + setattrmask |= AT_UID; + SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_UID(zfsvfs), NULL, + &new_uid, sizeof (new_uid)); + zp->z_uid = new_uid; + if (attrzp) { + SA_ADD_BULK_ATTR(xattr_bulk, xattr_count, + SA_ZPL_UID(zfsvfs), NULL, &new_uid, + sizeof (new_uid)); + attrzp->z_uid = new_uid; + } + } + + if (sec_info & SD_INFO_GROUP) { + setattrmask |= AT_GID; + SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_GID(zfsvfs), + NULL, &new_gid, sizeof (new_gid)); + zp->z_gid = new_gid; + if (attrzp) { + SA_ADD_BULK_ATTR(xattr_bulk, xattr_count, + SA_ZPL_GID(zfsvfs), NULL, &new_gid, + sizeof (new_gid)); + attrzp->z_gid = new_gid; + } + } + err = zfs_acl_chown_setattr(zp); + ASSERT(err == 0); + if (attrzp) { + err = zfs_acl_chown_setattr(attrzp); + ASSERT(err == 0); + } + if (!(sec_info & SD_INFO_DACL)) { + setattrmask |= AT_MODE; + SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_MODE(zfsvfs), + NULL, &new_mode, sizeof (new_mode)); + new_mode = zp->z_mode; + SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_CTIME(zfsvfs), + NULL, &ctime, sizeof (ctime)); + zfs_tstamp_update_setup(zp, STATE_CHANGED, NULL, + ctime, B_TRUE); + } + } + + if (sec_info & (SD_INFO_DACL|SD_INFO_SACL)) { + zfs_aclset_common(zp, aclp, cred, tx); + new_mode = zp->z_mode; + } + + if (fuid_dirtied) + zfs_fuid_sync(zfsvfs, tx); + + zfs_log_sd_setattr(zilog, tx, TX_SETATTR, zp, setattrmask, + new_mode, fuidp); + + mutex_exit(&zp->z_lock); + mutex_exit(&zp->z_acl_lock); + + if (attrzp) { + mutex_exit(&attrzp->z_acl_lock); + mutex_exit(&attrzp->z_lock); + } +out: + if (err == 0 && attrzp) { + err2 = sa_bulk_update(attrzp->z_sa_hdl, xattr_bulk, + xattr_count, tx); + ASSERT(err2 == 0); + } + + if (attrzp) + VN_RELE(ZTOV(attrzp)); + + if (aclp) + zfs_acl_free(aclp); + + if (fuidp) + zfs_fuid_info_free(fuidp); + + if (tx) { + if (err) { + dmu_tx_abort(tx); + if (err == ERESTART) + goto top; + } else { + err2 = sa_bulk_update(zp->z_sa_hdl, bulk, count, tx); + dmu_tx_commit(tx); + } + } + + if (zfsvfs->z_os->os_sync == ZFS_SYNC_ALWAYS) + zil_commit(zilog, 0); + + getnewvnode_drop_reserve(); + ZFS_EXIT(zfsvfs); + return (err); } struct vop_vector zfs_vnodeops; @@ -7138,6 +7672,9 @@ .vop_aclcheck = zfs_freebsd_aclcheck, .vop_getpages = zfs_freebsd_getpages, .vop_putpages = zfs_freebsd_putpages, + .vop_setsd = zfs_freebsd_setsd, + .vop_getsd = zfs_freebsd_getsd, + .vop_advise = zfs_freebsd_advise, }; struct vop_vector zfs_fifoops = { --- //depot/vendor/FreeBSD/stable/10/sys/cddl/contrib/opensolaris/uts/common/sys/acl.h 2013-10-10 17:56:30.000000000 -0600 +++ //SpectraBSD/stable_downstreaming/sys/cddl/contrib/opensolaris/uts/common/sys/acl.h 2014-12-12 20:42:32.000000000 -0700 @@ -31,8 +31,8 @@ #if defined(_KERNEL) /* - * When compiling OpenSolaris kernel code, this file is getting - * included instead of FreeBSD one. Pull the original sys/acl.h as well. + * When compiling OpenSolaris code, this file is included instead of + * the FreeBSD one. Pull the original sys/acl.h as well. */ #undef _SYS_ACL_H #include_next @@ -128,8 +128,6 @@ #define ACL_FLAGS_ALL (ACL_AUTO_INHERIT|ACL_PROTECTED| \ ACL_DEFAULTED) -#ifdef _KERNEL - /* * These are only applicable in a CIFS context. */ @@ -149,6 +147,8 @@ #define ACE_ALL_TYPES 0x001F +#ifdef _KERNEL + typedef struct ace_object { uid_t a_who; /* uid or gid */ uint32_t a_access_mask; /* read,write,... */ --- //depot/vendor/FreeBSD/stable/10/sys/compat/freebsd32/freebsd32_syscall.h 2015-01-11 07:04:18.000000000 -0700 +++ //SpectraBSD/stable_downstreaming/sys/compat/freebsd32/freebsd32_syscall.h 2015-01-14 21:42:13.000000000 -0700 @@ -3,7 +3,7 @@ * * DO NOT EDIT-- this file is automatically generated. * $FreeBSD$ - * created from FreeBSD: stable/10/sys/compat/freebsd32/syscalls.master 276955 2015-01-11 07:02:03Z dchagin + * created from FreeBSD */ #define FREEBSD32_SYS_syscall 0 @@ -455,4 +455,8 @@ #define FREEBSD32_SYS_freebsd32_procctl 544 #define FREEBSD32_SYS_freebsd32_procctl 544 #define FREEBSD32_SYS_freebsd32_ppoll 545 -#define FREEBSD32_SYS_MAXSYSCALL 546 +#define FREEBSD32_SYS_security_descriptor_get_fd 546 +#define FREEBSD32_SYS_security_descriptor_set_fd 547 +#define FREEBSD32_SYS_security_descriptor_get_file 548 +#define FREEBSD32_SYS_security_descriptor_set_file 549 +#define FREEBSD32_SYS_MAXSYSCALL 550 --- //depot/vendor/FreeBSD/stable/10/sys/compat/freebsd32/freebsd32_syscalls.c 2015-01-11 07:04:18.000000000 -0700 +++ //SpectraBSD/stable_downstreaming/sys/compat/freebsd32/freebsd32_syscalls.c 2015-01-14 21:42:13.000000000 -0700 @@ -3,7 +3,7 @@ * * DO NOT EDIT-- this file is automatically generated. * $FreeBSD$ - * created from FreeBSD: stable/10/sys/compat/freebsd32/syscalls.master 276955 2015-01-11 07:02:03Z dchagin + * created from FreeBSD */ const char *freebsd32_syscallnames[] = { @@ -579,4 +579,8 @@ "freebsd32_procctl", /* 544 = freebsd32_procctl */ #endif "freebsd32_ppoll", /* 545 = freebsd32_ppoll */ + "security_descriptor_get_fd", /* 546 = security_descriptor_get_fd */ + "security_descriptor_set_fd", /* 547 = security_descriptor_set_fd */ + "security_descriptor_get_file", /* 548 = security_descriptor_get_file */ + "security_descriptor_set_file", /* 549 = security_descriptor_set_file */ }; --- //depot/vendor/FreeBSD/stable/10/sys/compat/freebsd32/freebsd32_sysent.c 2015-01-11 07:04:18.000000000 -0700 +++ //SpectraBSD/stable_downstreaming/sys/compat/freebsd32/freebsd32_sysent.c 2015-01-14 21:42:13.000000000 -0700 @@ -3,7 +3,7 @@ * * DO NOT EDIT-- this file is automatically generated. * $FreeBSD$ - * created from FreeBSD: stable/10/sys/compat/freebsd32/syscalls.master 276955 2015-01-11 07:02:03Z dchagin + * created from FreeBSD */ #include "opt_compat.h" @@ -616,4 +616,8 @@ { AS(freebsd32_procctl_args), (sy_call_t *)freebsd32_procctl, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 544 = freebsd32_procctl */ #endif { AS(freebsd32_ppoll_args), (sy_call_t *)freebsd32_ppoll, AUE_POLL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 545 = freebsd32_ppoll */ + { AS(security_descriptor_get_fd_args), (sy_call_t *)sys_security_descriptor_get_fd, AUE_SECURITY_DESCRIPTOR_GET_FD, NULL, 0, 0, 0, SY_THR_STATIC }, /* 546 = security_descriptor_get_fd */ + { AS(security_descriptor_set_fd_args), (sy_call_t *)sys_security_descriptor_set_fd, AUE_SECURITY_DESCRIPTOR_SET_FD, NULL, 0, 0, 0, SY_THR_STATIC }, /* 547 = security_descriptor_set_fd */ + { AS(security_descriptor_get_file_args), (sy_call_t *)sys_security_descriptor_get_file, AUE_SECURITY_DESCRIPTOR_GET_FILE, NULL, 0, 0, 0, SY_THR_STATIC }, /* 548 = security_descriptor_get_file */ + { AS(security_descriptor_set_file_args), (sy_call_t *)sys_security_descriptor_set_file, AUE_SECURITY_DESCRIPTOR_SET_FILE, NULL, 0, 0, 0, SY_THR_STATIC }, /* 549 = security_descriptor_set_file */ }; --- //depot/vendor/FreeBSD/stable/10/sys/compat/freebsd32/freebsd32_systrace_args.c 2015-01-11 07:04:18.000000000 -0700 +++ //SpectraBSD/stable_downstreaming/sys/compat/freebsd32/freebsd32_systrace_args.c 2015-01-14 21:42:13.000000000 -0700 @@ -3323,6 +3323,48 @@ *n_args = 4; break; } + /* security_descriptor_get_fd */ + case 546: { + struct security_descriptor_get_fd_args *p = params; + iarg[0] = p->fd; /* int */ + iarg[1] = p->security_info; /* int */ + uarg[2] = (intptr_t) p->sd; /* struct security_descriptor_serialized * */ + uarg[3] = p->sd_buf_size; /* size_t */ + uarg[4] = (intptr_t) p->sd_size; /* size_t * */ + *n_args = 5; + break; + } + /* security_descriptor_set_fd */ + case 547: { + struct security_descriptor_set_fd_args *p = params; + iarg[0] = p->fd; /* int */ + iarg[1] = p->security_info; /* int */ + uarg[2] = (intptr_t) p->sd; /* struct security_descriptor_serialized * */ + uarg[3] = p->sd_size; /* size_t */ + *n_args = 4; + break; + } + /* security_descriptor_get_file */ + case 548: { + struct security_descriptor_get_file_args *p = params; + uarg[0] = (intptr_t) p->path; /* const char * */ + iarg[1] = p->security_info; /* int */ + uarg[2] = (intptr_t) p->sd; /* struct security_descriptor_serialized * */ + uarg[3] = p->sd_buf_size; /* size_t */ + uarg[4] = (intptr_t) p->sd_size; /* size_t * */ + *n_args = 5; + break; + } + /* security_descriptor_set_file */ + case 549: { + struct security_descriptor_set_file_args *p = params; + uarg[0] = (intptr_t) p->path; /* const char * */ + iarg[1] = p->security_info; /* int */ + uarg[2] = (intptr_t) p->sd; /* struct security_descriptor_serialized * */ + uarg[3] = p->sd_size; /* size_t */ + *n_args = 4; + break; + } default: *n_args = 0; break; @@ -8907,6 +8949,88 @@ break; }; break; + /* security_descriptor_get_fd */ + case 546: + switch(ndx) { + case 0: + p = "int"; + break; + case 1: + p = "int"; + break; + case 2: + p = "struct security_descriptor_serialized *"; + break; + case 3: + p = "size_t"; + break; + case 4: + p = "size_t *"; + break; + default: + break; + }; + break; + /* security_descriptor_set_fd */ + case 547: + switch(ndx) { + case 0: + p = "int"; + break; + case 1: + p = "int"; + break; + case 2: + p = "struct security_descriptor_serialized *"; + break; + case 3: + p = "size_t"; + break; + default: + break; + }; + break; + /* security_descriptor_get_file */ + case 548: + switch(ndx) { + case 0: + p = "const char *"; + break; + case 1: + p = "int"; + break; + case 2: + p = "struct security_descriptor_serialized *"; + break; + case 3: + p = "size_t"; + break; + case 4: + p = "size_t *"; + break; + default: + break; + }; + break; + /* security_descriptor_set_file */ + case 549: + switch(ndx) { + case 0: + p = "const char *"; + break; + case 1: + p = "int"; + break; + case 2: + p = "struct security_descriptor_serialized *"; + break; + case 3: + p = "size_t"; + break; + default: + break; + }; + break; default: break; }; @@ -10795,6 +10919,26 @@ if (ndx == 0 || ndx == 1) p = "int"; break; + /* security_descriptor_get_fd */ + case 546: + if (ndx == 0 || ndx == 1) + p = "int"; + break; + /* security_descriptor_set_fd */ + case 547: + if (ndx == 0 || ndx == 1) + p = "int"; + break; + /* security_descriptor_get_file */ + case 548: + if (ndx == 0 || ndx == 1) + p = "int"; + break; + /* security_descriptor_set_file */ + case 549: + if (ndx == 0 || ndx == 1) + p = "int"; + break; default: break; }; --- //depot/vendor/FreeBSD/stable/10/sys/compat/freebsd32/syscalls.master 2015-01-11 07:02:03.000000000 -0700 +++ //SpectraBSD/stable_downstreaming/sys/compat/freebsd32/syscalls.master 2015-01-14 20:59:00.000000000 -0700 @@ -1069,3 +1069,25 @@ 545 AUE_POLL STD { int freebsd32_ppoll(struct pollfd *fds, \ u_int nfds, const struct timespec32 *ts, \ const sigset_t *set); } +546 AUE_SECURITY_DESCRIPTOR_GET_FD NOPROTO { \ + int security_descriptor_get_fd(int fd, \ + int security_info, \ + struct security_descriptor_serialized *sd, \ + size_t sd_buf_size, size_t *sd_size); } +547 AUE_SECURITY_DESCRIPTOR_SET_FD NOPROTO { \ + int security_descriptor_set_fd(int fd, \ + int security_info, \ + struct security_descriptor_serialized *sd, \ + size_t sd_size); } +548 AUE_SECURITY_DESCRIPTOR_GET_FILE NOPROTO { \ + int security_descriptor_get_file( \ + const char *path, \ + int security_info, \ + struct security_descriptor_serialized *sd, \ + size_t sd_buf_size, size_t *sd_size); } +549 AUE_SECURITY_DESCRIPTOR_SET_FILE NOPROTO { \ + int security_descriptor_set_file( \ + const char *path, \ + int security_info, \ + struct security_descriptor_serialized *sd, \ + size_t sd_size); } --- //depot/vendor/FreeBSD/stable/10/sys/conf/files 2015-01-05 03:27:09.000000000 -0700 +++ //SpectraBSD/stable_downstreaming/sys/conf/files 2015-01-14 20:59:00.000000000 -0700 @@ -2988,6 +3724,8 @@ kern/subr_rtc.c standard kern/subr_sbuf.c standard kern/subr_scanf.c standard +kern/subr_sd.c standard +kern/subr_sid.c standard kern/subr_sglist.c standard kern/subr_sleepqueue.c standard kern/subr_smp.c standard @@ -3044,6 +3782,7 @@ kern/vfs_lookup.c standard kern/vfs_mount.c standard kern/vfs_mountroot.c standard +kern/vfs_sd.c standard kern/vfs_subr.c standard kern/vfs_syscalls.c standard kern/vfs_vnops.c standard --- //depot/vendor/FreeBSD/stable/10/sys/kern/init_sysent.c 2015-01-11 07:04:18.000000000 -0700 +++ //SpectraBSD/stable_downstreaming/sys/kern/init_sysent.c 2015-01-14 20:59:00.000000000 -0700 @@ -580,4 +580,8 @@ { AS(aio_mlock_args), (sy_call_t *)lkmressys, AUE_NULL, NULL, 0, 0, 0, SY_THR_ABSENT }, /* 543 = aio_mlock */ { AS(procctl_args), (sy_call_t *)sys_procctl, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 544 = procctl */ { AS(ppoll_args), (sy_call_t *)sys_ppoll, AUE_POLL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 545 = ppoll */ + { AS(security_descriptor_get_fd_args), (sy_call_t *)sys_security_descriptor_get_fd, AUE_SECURITY_DESCRIPTOR_GET_FD, NULL, 0, 0, 0, SY_THR_STATIC }, /* 546 = security_descriptor_get_fd */ + { AS(security_descriptor_set_fd_args), (sy_call_t *)sys_security_descriptor_set_fd, AUE_SECURITY_DESCRIPTOR_SET_FD, NULL, 0, 0, 0, SY_THR_STATIC }, /* 547 = security_descriptor_set_fd */ + { AS(security_descriptor_get_file_args), (sy_call_t *)sys_security_descriptor_get_file, AUE_SECURITY_DESCRIPTOR_GET_FILE, NULL, 0, 0, 0, SY_THR_STATIC }, /* 548 = security_descriptor_get_file */ + { AS(security_descriptor_set_file_args), (sy_call_t *)sys_security_descriptor_set_file, AUE_SECURITY_DESCRIPTOR_SET_FILE, NULL, 0, 0, 0, SY_THR_STATIC }, /* 549 = security_descriptor_set_file */ }; --- //depot/vendor/FreeBSD/stable/10/sys/kern/syscalls.c 2015-01-11 07:04:18.000000000 -0700 +++ //SpectraBSD/stable_downstreaming/sys/kern/syscalls.c 2015-01-14 20:59:00.000000000 -0700 @@ -553,4 +553,8 @@ "aio_mlock", /* 543 = aio_mlock */ "procctl", /* 544 = procctl */ "ppoll", /* 545 = ppoll */ + "security_descriptor_get_fd", /* 546 = security_descriptor_get_fd */ + "security_descriptor_set_fd", /* 547 = security_descriptor_set_fd */ + "security_descriptor_get_file", /* 548 = security_descriptor_get_file */ + "security_descriptor_set_file", /* 549 = security_descriptor_set_file */ }; --- //depot/vendor/FreeBSD/stable/10/sys/kern/syscalls.master 2015-01-11 07:02:03.000000000 -0700 +++ //SpectraBSD/stable_downstreaming/sys/kern/syscalls.master 2015-01-14 20:59:00.000000000 -0700 @@ -983,5 +983,27 @@ 545 AUE_POLL STD { int ppoll(struct pollfd *fds, u_int nfds, \ const struct timespec *ts, \ const sigset_t *set); } +546 AUE_SECURITY_DESCRIPTOR_GET_FD STD { \ + int security_descriptor_get_fd(int fd, \ + int security_info, \ + struct security_descriptor_serialized *sd, \ + size_t sd_buf_size, size_t *sd_size); } +547 AUE_SECURITY_DESCRIPTOR_SET_FD STD { \ + int security_descriptor_set_fd(int fd, \ + int security_info, \ + struct security_descriptor_serialized *sd, \ + size_t sd_size); } +548 AUE_SECURITY_DESCRIPTOR_GET_FILE STD { \ + int security_descriptor_get_file( \ + const char *path, \ + int security_info, \ + struct security_descriptor_serialized *sd, \ + size_t sd_buf_size, size_t *sd_size); } +549 AUE_SECURITY_DESCRIPTOR_SET_FILE STD { \ + int security_descriptor_set_file( \ + const char *path, \ + int security_info, \ + struct security_descriptor_serialized *sd, \ + size_t sd_size); } ; Please copy any additions and changes to the following compatability tables: ; sys/compat/freebsd32/syscalls.master --- //depot/vendor/FreeBSD/stable/10/sys/kern/systrace_args.c 2015-01-11 07:04:18.000000000 -0700 +++ //SpectraBSD/stable_downstreaming/sys/kern/systrace_args.c 2015-01-14 20:59:00.000000000 -0700 @@ -3396,6 +3396,48 @@ *n_args = 4; break; } + /* security_descriptor_get_fd */ + case 546: { + struct security_descriptor_get_fd_args *p = params; + iarg[0] = p->fd; /* int */ + iarg[1] = p->security_info; /* int */ + uarg[2] = (intptr_t) p->sd; /* struct security_descriptor_serialized * */ + uarg[3] = p->sd_buf_size; /* size_t */ + uarg[4] = (intptr_t) p->sd_size; /* size_t * */ + *n_args = 5; + break; + } + /* security_descriptor_set_fd */ + case 547: { + struct security_descriptor_set_fd_args *p = params; + iarg[0] = p->fd; /* int */ + iarg[1] = p->security_info; /* int */ + uarg[2] = (intptr_t) p->sd; /* struct security_descriptor_serialized * */ + uarg[3] = p->sd_size; /* size_t */ + *n_args = 4; + break; + } + /* security_descriptor_get_file */ + case 548: { + struct security_descriptor_get_file_args *p = params; + uarg[0] = (intptr_t) p->path; /* const char * */ + iarg[1] = p->security_info; /* int */ + uarg[2] = (intptr_t) p->sd; /* struct security_descriptor_serialized * */ + uarg[3] = p->sd_buf_size; /* size_t */ + uarg[4] = (intptr_t) p->sd_size; /* size_t * */ + *n_args = 5; + break; + } + /* security_descriptor_set_file */ + case 549: { + struct security_descriptor_set_file_args *p = params; + uarg[0] = (intptr_t) p->path; /* const char * */ + iarg[1] = p->security_info; /* int */ + uarg[2] = (intptr_t) p->sd; /* struct security_descriptor_serialized * */ + uarg[3] = p->sd_size; /* size_t */ + *n_args = 4; + break; + } default: *n_args = 0; break; @@ -9053,6 +9095,88 @@ break; }; break; + /* security_descriptor_get_fd */ + case 546: + switch(ndx) { + case 0: + p = "int"; + break; + case 1: + p = "int"; + break; + case 2: + p = "struct security_descriptor_serialized *"; + break; + case 3: + p = "size_t"; + break; + case 4: + p = "size_t *"; + break; + default: + break; + }; + break; + /* security_descriptor_set_fd */ + case 547: + switch(ndx) { + case 0: + p = "int"; + break; + case 1: + p = "int"; + break; + case 2: + p = "struct security_descriptor_serialized *"; + break; + case 3: + p = "size_t"; + break; + default: + break; + }; + break; + /* security_descriptor_get_file */ + case 548: + switch(ndx) { + case 0: + p = "const char *"; + break; + case 1: + p = "int"; + break; + case 2: + p = "struct security_descriptor_serialized *"; + break; + case 3: + p = "size_t"; + break; + case 4: + p = "size_t *"; + break; + default: + break; + }; + break; + /* security_descriptor_set_file */ + case 549: + switch(ndx) { + case 0: + p = "const char *"; + break; + case 1: + p = "int"; + break; + case 2: + p = "struct security_descriptor_serialized *"; + break; + case 3: + p = "size_t"; + break; + default: + break; + }; + break; default: break; }; @@ -11006,6 +11130,26 @@ if (ndx == 0 || ndx == 1) p = "int"; break; + /* security_descriptor_get_fd */ + case 546: + if (ndx == 0 || ndx == 1) + p = "int"; + break; + /* security_descriptor_set_fd */ + case 547: + if (ndx == 0 || ndx == 1) + p = "int"; + break; + /* security_descriptor_get_file */ + case 548: + if (ndx == 0 || ndx == 1) + p = "int"; + break; + /* security_descriptor_set_file */ + case 549: + if (ndx == 0 || ndx == 1) + p = "int"; + break; default: break; }; --- //depot/vendor/FreeBSD/stable/10/sys/kern/vnode_if.src 2013-12-13 06:12:21.000000000 -0700 +++ //SpectraBSD/stable_downstreaming/sys/kern/vnode_if.src 2014-12-12 20:42:32.000000000 -0700 @@ -690,6 +690,26 @@ IN int inc; }; +%% getsd vp L L L + +vop_getsd { + IN struct vnode *vp; + IN int security_info; + OUT struct security_descriptor **sdp; + IN struct ucred *cred; + IN struct thread *td; +}; + +%% setsd vp E E E + +vop_setsd { + IN struct vnode *vp; + IN int security_info; + IN struct security_descriptor *sd; + IN struct ucred *cred; + IN struct thread *td; +}; + # The VOPs below are spares at the end of the table to allow new VOPs to be # added in stable branches without breaking the KBI. New VOPs in HEAD should # be added above these spares. When merging a new VOP to a stable branch, @@ -706,11 +726,3 @@ vop_spare3 { IN struct vnode *vp; }; - -vop_spare4 { - IN struct vnode *vp; -}; - -vop_spare5 { - IN struct vnode *vp; -}; --- //depot/vendor/FreeBSD/stable/10/sys/security/mac/mac_framework.h 2013-10-10 17:56:30.000000000 -0600 +++ //SpectraBSD/stable_downstreaming/sys/security/mac/mac_framework.h 2014-12-12 20:42:32.000000000 -0700 @@ -74,6 +74,7 @@ struct msg; struct msqid_kernel; struct proc; +struct security_descriptor; struct semid_kernel; struct shmfd; struct shmid_kernel; @@ -391,6 +392,8 @@ acl_type_t type); int mac_vnode_check_getextattr(struct ucred *cred, struct vnode *vp, int attrnamespace, const char *name); +int mac_vnode_check_getsd(struct ucred *cred, struct vnode *vp, + int secinfo); int mac_vnode_check_link(struct ucred *cred, struct vnode *dvp, struct vnode *vp, struct componentname *cnp); int mac_vnode_check_listextattr(struct ucred *cred, struct vnode *vp, @@ -424,6 +427,8 @@ mode_t mode); int mac_vnode_check_setowner(struct ucred *cred, struct vnode *vp, uid_t uid, gid_t gid); +int mac_vnode_check_setsd(struct ucred *cred, struct vnode *vp, + int secinfo, struct security_descriptor *sd); int mac_vnode_check_setutimes(struct ucred *cred, struct vnode *vp, struct timespec atime, struct timespec mtime); int mac_vnode_check_stat(struct ucred *active_cred, --- //depot/vendor/FreeBSD/stable/10/sys/security/mac/mac_policy.h 2013-10-10 17:56:30.000000000 -0600 +++ //SpectraBSD/stable_downstreaming/sys/security/mac/mac_policy.h 2014-12-12 20:42:32.000000000 -0700 @@ -88,6 +88,7 @@ struct pipepair; struct proc; struct sbuf; +struct security_descriptor; struct semid_kernel; struct shmfd; struct shmid_kernel; @@ -578,6 +579,9 @@ typedef int (*mpo_vnode_check_getextattr_t)(struct ucred *cred, struct vnode *vp, struct label *vplabel, int attrnamespace, const char *name); +typedef int (*mpo_vnode_check_getsd_t)(struct ucred *cred, + struct vnode *vp, struct label *vplabel, + int secinfo); typedef int (*mpo_vnode_check_link_t)(struct ucred *cred, struct vnode *dvp, struct label *dvplabel, struct vnode *vp, struct label *vplabel, @@ -634,6 +638,9 @@ typedef int (*mpo_vnode_check_setowner_t)(struct ucred *cred, struct vnode *vp, struct label *vplabel, uid_t uid, gid_t gid); +typedef int (*mpo_vnode_check_setsd_t)(struct ucred *cred, + struct vnode *vp, struct label *vplabel, int secinfo, + struct security_descriptor *sd); typedef int (*mpo_vnode_check_setutimes_t)(struct ucred *cred, struct vnode *vp, struct label *vplabel, struct timespec atime, struct timespec mtime); @@ -932,6 +939,7 @@ mpo_vnode_check_exec_t mpo_vnode_check_exec; mpo_vnode_check_getacl_t mpo_vnode_check_getacl; mpo_vnode_check_getextattr_t mpo_vnode_check_getextattr; + mpo_vnode_check_getsd_t mpo_vnode_check_getsd; 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; @@ -952,6 +960,7 @@ mpo_vnode_check_setflags_t mpo_vnode_check_setflags; mpo_vnode_check_setmode_t mpo_vnode_check_setmode; mpo_vnode_check_setowner_t mpo_vnode_check_setowner; + mpo_vnode_check_setsd_t mpo_vnode_check_setsd; mpo_vnode_check_setutimes_t mpo_vnode_check_setutimes; mpo_vnode_check_stat_t mpo_vnode_check_stat; mpo_vnode_check_unlink_t mpo_vnode_check_unlink; --- //depot/vendor/FreeBSD/stable/10/sys/security/mac/mac_vfs.c 2013-10-10 17:56:30.000000000 -0600 +++ //SpectraBSD/stable_downstreaming/sys/security/mac/mac_vfs.c 2014-12-12 20:42:32.000000000 -0700 @@ -524,6 +524,22 @@ return (error); } +MAC_CHECK_PROBE_DEFINE3(vnode_check_getsd, "struct ucred *", + "struct vnode *", "int"); + +int +mac_vnode_check_getsd(struct ucred *cred, struct vnode *vp, int secinfo) +{ + int error; + + ASSERT_VOP_LOCKED(vp, "mac_vnode_check_getsd"); + + MAC_POLICY_CHECK(vnode_check_getsd, cred, vp, vp->v_label, secinfo); + MAC_CHECK_PROBE3(vnode_check_getsd, error, cred, vp, secinfo); + + return (error); +} + MAC_CHECK_PROBE_DEFINE4(vnode_check_link, "struct ucred *", "struct vnode *", "struct vnode *", "struct componentname *"); @@ -867,6 +883,23 @@ return (error); } +MAC_CHECK_PROBE_DEFINE4(vnode_check_setsd, "struct ucred *", + "struct vnode *", "int", "struct security_descriptor *"); + +int +mac_vnode_check_setsd(struct ucred *cred, struct vnode *vp, int secinfo, + struct security_descriptor *sd) +{ + int error; + + ASSERT_VOP_LOCKED(vp, "mac_vnode_check_setsd"); + + MAC_POLICY_CHECK(vnode_check_setsd, cred, vp, vp->v_label, secinfo, sd); + MAC_CHECK_PROBE4(vnode_check_setsd, error, cred, vp, secinfo, sd); + + return (error); +} + MAC_CHECK_PROBE_DEFINE4(vnode_check_setutimes, "struct ucred *", "struct vnode *", "struct timespec *", "struct timespec *"); --- //depot/vendor/FreeBSD/stable/10/sys/sys/acl.h 2013-10-10 17:56:30.000000000 -0600 +++ //SpectraBSD/stable_downstreaming/sys/sys/acl.h 2014-12-12 20:42:32.000000000 -0700 @@ -249,11 +249,12 @@ #define ACL_ENTRY_INHERIT_ONLY 0x0008 #define ACL_ENTRY_SUCCESSFUL_ACCESS 0x0010 #define ACL_ENTRY_FAILED_ACCESS 0x0020 +#define ACL_ENTRY_INHERITED 0x0040 #define ACL_FLAGS_BITS (ACL_ENTRY_FILE_INHERIT | \ ACL_ENTRY_DIRECTORY_INHERIT | ACL_ENTRY_NO_PROPAGATE_INHERIT | \ ACL_ENTRY_INHERIT_ONLY | ACL_ENTRY_SUCCESSFUL_ACCESS | \ - ACL_ENTRY_FAILED_ACCESS) + ACL_ENTRY_FAILED_ACCESS | ACL_ENTRY_INHERITED) /* * Undefined value in ae_id field. ae_id should be set to this value --- //depot/vendor/FreeBSD/stable/10/sys/sys/capability.h 2014-10-14 21:19:23.000000000 -0600 +++ //SpectraBSD/stable_downstreaming/sys/sys/capability.h 2014-12-12 21:06:48.000000000 -0700 @@ -269,11 +269,15 @@ #define CAP_KQUEUE (CAP_KQUEUE_EVENT | CAP_KQUEUE_CHANGE) +/* Security Descriptors */ +#define CAP_SD_GET CAPRIGHT(1, 0x0000000000200000ULL) +#define CAP_SD_SET CAPRIGHT(1, 0x0000000000400000ULL) + /* All used bits for index 1. */ -#define CAP_ALL1 CAPRIGHT(1, 0x00000000001FFFFFULL) +#define CAP_ALL1 CAPRIGHT(1, 0x00000000007FFFFFULL) /* Available bits for index 1. */ -#define CAP_UNUSED1_22 CAPRIGHT(1, 0x0000000000200000ULL) +#define CAP_UNUSED1_24 CAPRIGHT(1, 0x0000000000800000ULL) /* ... */ #define CAP_UNUSED1_57 CAPRIGHT(1, 0x0100000000000000ULL) --- //depot/vendor/FreeBSD/stable/10/sys/sys/syscall.h 2015-01-11 07:04:18.000000000 -0700 +++ //SpectraBSD/stable_downstreaming/sys/sys/syscall.h 2015-01-14 20:59:00.000000000 -0700 @@ -465,4 +465,8 @@ #define SYS_aio_mlock 543 #define SYS_procctl 544 #define SYS_ppoll 545 -#define SYS_MAXSYSCALL 546 +#define SYS_security_descriptor_get_fd 546 +#define SYS_security_descriptor_set_fd 547 +#define SYS_security_descriptor_get_file 548 +#define SYS_security_descriptor_set_file 549 +#define SYS_MAXSYSCALL 550 --- //depot/vendor/FreeBSD/stable/10/sys/sys/syscall.mk 2015-01-11 07:04:18.000000000 -0700 +++ //SpectraBSD/stable_downstreaming/sys/sys/syscall.mk 2015-01-14 20:59:00.000000000 -0700 @@ -412,4 +412,8 @@ pipe2.o \ aio_mlock.o \ procctl.o \ - ppoll.o + ppoll.o \ + security_descriptor_get_fd.o \ + security_descriptor_set_fd.o \ + security_descriptor_get_file.o \ + security_descriptor_set_file.o --- //depot/vendor/FreeBSD/stable/10/sys/sys/sysproto.h 2015-01-11 07:04:18.000000000 -0700 +++ //SpectraBSD/stable_downstreaming/sys/sys/sysproto.h 2015-01-15 17:38:28.000000000 -0700 @@ -1825,6 +1825,32 @@ char ts_l_[PADL_(const struct timespec *)]; const struct timespec * ts; char ts_r_[PADR_(const struct timespec *)]; char set_l_[PADL_(const sigset_t *)]; const sigset_t * set; char set_r_[PADR_(const sigset_t *)]; }; +struct security_descriptor_get_fd_args { + char fd_l_[PADL_(int)]; int fd; char fd_r_[PADR_(int)]; + char security_info_l_[PADL_(int)]; int security_info; char security_info_r_[PADR_(int)]; + char sd_l_[PADL_(struct security_descriptor_serialized *)]; struct security_descriptor_serialized * sd; char sd_r_[PADR_(struct security_descriptor_serialized *)]; + char sd_buf_size_l_[PADL_(size_t)]; size_t sd_buf_size; char sd_buf_size_r_[PADR_(size_t)]; + char sd_size_l_[PADL_(size_t *)]; size_t * sd_size; char sd_size_r_[PADR_(size_t *)]; +}; +struct security_descriptor_set_fd_args { + char fd_l_[PADL_(int)]; int fd; char fd_r_[PADR_(int)]; + char security_info_l_[PADL_(int)]; int security_info; char security_info_r_[PADR_(int)]; + char sd_l_[PADL_(struct security_descriptor_serialized *)]; struct security_descriptor_serialized * sd; char sd_r_[PADR_(struct security_descriptor_serialized *)]; + char sd_size_l_[PADL_(size_t)]; size_t sd_size; char sd_size_r_[PADR_(size_t)]; +}; +struct security_descriptor_get_file_args { + char path_l_[PADL_(const char *)]; const char * path; char path_r_[PADR_(const char *)]; + char security_info_l_[PADL_(int)]; int security_info; char security_info_r_[PADR_(int)]; + char sd_l_[PADL_(struct security_descriptor_serialized *)]; struct security_descriptor_serialized * sd; char sd_r_[PADR_(struct security_descriptor_serialized *)]; + char sd_buf_size_l_[PADL_(size_t)]; size_t sd_buf_size; char sd_buf_size_r_[PADR_(size_t)]; + char sd_size_l_[PADL_(size_t *)]; size_t * sd_size; char sd_size_r_[PADR_(size_t *)]; +}; +struct security_descriptor_set_file_args { + char path_l_[PADL_(const char *)]; const char * path; char path_r_[PADR_(const char *)]; + char security_info_l_[PADL_(int)]; int security_info; char security_info_r_[PADR_(int)]; + char sd_l_[PADL_(struct security_descriptor_serialized *)]; struct security_descriptor_serialized * sd; char sd_r_[PADR_(struct security_descriptor_serialized *)]; + char sd_size_l_[PADL_(size_t)]; size_t sd_size; char sd_size_r_[PADR_(size_t)]; +}; int nosys(struct thread *, struct nosys_args *); void sys_sys_exit(struct thread *, struct sys_exit_args *); int sys_fork(struct thread *, struct fork_args *); @@ -2219,6 +2245,10 @@ int sys_aio_mlock(struct thread *, struct aio_mlock_args *); int sys_procctl(struct thread *, struct procctl_args *); int sys_ppoll(struct thread *, struct ppoll_args *); +int sys_security_descriptor_get_fd(struct thread *, struct security_descriptor_get_fd_args *); +int sys_security_descriptor_set_fd(struct thread *, struct security_descriptor_set_fd_args *); +int sys_security_descriptor_get_file(struct thread *, struct security_descriptor_get_file_args *); +int sys_security_descriptor_set_file(struct thread *, struct security_descriptor_set_file_args *); #ifdef COMPAT_43 @@ -2927,6 +2957,10 @@ #define SYS_AUE_aio_mlock AUE_NULL #define SYS_AUE_procctl AUE_NULL #define SYS_AUE_ppoll AUE_POLL +#define SYS_AUE_security_descriptor_get_fd AUE_SECURITY_DESCRIPTOR_GET_FD +#define SYS_AUE_security_descriptor_set_fd AUE_SECURITY_DESCRIPTOR_SET_FD +#define SYS_AUE_security_descriptor_get_file AUE_SECURITY_DESCRIPTOR_GET_FILE +#define SYS_AUE_security_descriptor_set_file AUE_SECURITY_DESCRIPTOR_SET_FILE #undef PAD_ #undef PADL_