Fix ACL checks for NFS kernel server
This PR changes ZFS ACL checks to evaluate fsuid / fsgid rather than euid / egid to avoid accidentally granting elevated permissions to NFS clients. Reviewed-by: Serapheim Dimitropoulos <serapheim@delphix.com> Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov> Co-authored-by: Andrew Walker <awalker@ixsystems.com> Co-authored-by: Ryan Moeller <freqlabs@FreeBSD.org> Signed-off-by: Ryan Moeller <freqlabs@FreeBSD.org> Closes #13221
This commit is contained in:
parent
9e3619c535
commit
847d03060f
|
@ -22,7 +22,6 @@ KERNEL_H = \
|
||||||
inttypes.h \
|
inttypes.h \
|
||||||
isa_defs.h \
|
isa_defs.h \
|
||||||
kmem_cache.h \
|
kmem_cache.h \
|
||||||
kidmap.h \
|
|
||||||
kmem.h \
|
kmem.h \
|
||||||
kstat.h \
|
kstat.h \
|
||||||
list_impl.h \
|
list_impl.h \
|
||||||
|
|
|
@ -48,138 +48,20 @@ extern "C" {
|
||||||
typedef struct ucred cred_t;
|
typedef struct ucred cred_t;
|
||||||
|
|
||||||
#define CRED() curthread->td_ucred
|
#define CRED() curthread->td_ucred
|
||||||
|
|
||||||
|
/*
|
||||||
|
* kcred is used when you need all privileges.
|
||||||
|
*/
|
||||||
#define kcred (thread0.td_ucred)
|
#define kcred (thread0.td_ucred)
|
||||||
|
|
||||||
#define KUID_TO_SUID(x) (x)
|
#define KUID_TO_SUID(x) (x)
|
||||||
#define KGID_TO_SGID(x) (x)
|
#define KGID_TO_SGID(x) (x)
|
||||||
#define crgetuid(cred) ((cred)->cr_uid)
|
#define crgetuid(cr) ((cr)->cr_uid)
|
||||||
#define crgetruid(cred) ((cred)->cr_ruid)
|
#define crgetruid(cr) ((cr)->cr_ruid)
|
||||||
#define crgetgid(cred) ((cred)->cr_gid)
|
#define crgetgid(cr) ((cr)->cr_gid)
|
||||||
#define crgetgroups(cred) ((cred)->cr_groups)
|
#define crgetgroups(cr) ((cr)->cr_groups)
|
||||||
#define crgetngroups(cred) ((cred)->cr_ngroups)
|
#define crgetngroups(cr) ((cr)->cr_ngroups)
|
||||||
#define crgetsid(cred, i) (NULL)
|
#define crgetzoneid(cr) ((cr)->cr_prison->pr_id)
|
||||||
|
|
||||||
struct proc; /* cred.h is included in proc.h */
|
|
||||||
struct prcred;
|
|
||||||
struct ksid;
|
|
||||||
struct ksidlist;
|
|
||||||
struct credklpd;
|
|
||||||
struct credgrp;
|
|
||||||
|
|
||||||
struct auditinfo_addr; /* cred.h is included in audit.h */
|
|
||||||
|
|
||||||
extern int ngroups_max;
|
|
||||||
/*
|
|
||||||
* kcred is used when you need all privileges.
|
|
||||||
*/
|
|
||||||
|
|
||||||
extern void cred_init(void);
|
|
||||||
extern void crfree(cred_t *);
|
|
||||||
extern cred_t *cralloc(void); /* all but ref uninitialized */
|
|
||||||
extern cred_t *cralloc_ksid(void); /* cralloc() + ksid alloc'ed */
|
|
||||||
extern cred_t *crget(void); /* initialized */
|
|
||||||
extern void crcopy_to(cred_t *, cred_t *);
|
|
||||||
extern cred_t *crdup(cred_t *);
|
|
||||||
extern void crdup_to(cred_t *, cred_t *);
|
|
||||||
extern cred_t *crgetcred(void);
|
|
||||||
extern void crset(struct proc *, cred_t *);
|
|
||||||
extern void crset_zone_privall(cred_t *);
|
|
||||||
extern int supgroupmember(gid_t, const cred_t *);
|
|
||||||
extern int hasprocperm(const cred_t *, const cred_t *);
|
|
||||||
extern int prochasprocperm(struct proc *, struct proc *, const cred_t *);
|
|
||||||
extern int crcmp(const cred_t *, const cred_t *);
|
|
||||||
extern cred_t *zone_kcred(void);
|
|
||||||
|
|
||||||
extern gid_t crgetrgid(const cred_t *);
|
|
||||||
extern gid_t crgetsgid(const cred_t *);
|
|
||||||
|
|
||||||
#define crgetzoneid(cr) ((cr)->cr_prison->pr_id)
|
|
||||||
extern projid_t crgetprojid(const cred_t *);
|
|
||||||
|
|
||||||
extern cred_t *crgetmapped(const cred_t *);
|
|
||||||
|
|
||||||
|
|
||||||
extern const struct auditinfo_addr *crgetauinfo(const cred_t *);
|
|
||||||
extern struct auditinfo_addr *crgetauinfo_modifiable(cred_t *);
|
|
||||||
|
|
||||||
extern uint_t crgetref(const cred_t *);
|
|
||||||
|
|
||||||
extern const gid_t *crgetggroups(const struct credgrp *);
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Sets real, effective and/or saved uid/gid;
|
|
||||||
* -1 argument accepted as "no change".
|
|
||||||
*/
|
|
||||||
extern int crsetresuid(cred_t *, uid_t, uid_t, uid_t);
|
|
||||||
extern int crsetresgid(cred_t *, gid_t, gid_t, gid_t);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Sets real, effective and saved uids/gids all to the same
|
|
||||||
* values. Both values must be non-negative and <= MAXUID
|
|
||||||
*/
|
|
||||||
extern int crsetugid(cred_t *, uid_t, gid_t);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Functions to handle the supplemental group list.
|
|
||||||
*/
|
|
||||||
extern struct credgrp *crgrpcopyin(int, gid_t *);
|
|
||||||
extern void crgrprele(struct credgrp *);
|
|
||||||
extern void crsetcredgrp(cred_t *, struct credgrp *);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Private interface for setting zone association of credential.
|
|
||||||
*/
|
|
||||||
struct zone;
|
|
||||||
extern void crsetzone(cred_t *, struct zone *);
|
|
||||||
extern struct zone *crgetzone(const cred_t *);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Private interface for setting project id in credential.
|
|
||||||
*/
|
|
||||||
extern void crsetprojid(cred_t *, projid_t);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Private interface for nfs.
|
|
||||||
*/
|
|
||||||
extern cred_t *crnetadjust(cred_t *);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Private interface for procfs.
|
|
||||||
*/
|
|
||||||
extern void cred2prcred(const cred_t *, struct prcred *);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Private interfaces for Rampart Trusted Solaris.
|
|
||||||
*/
|
|
||||||
struct ts_label_s;
|
|
||||||
extern struct ts_label_s *crgetlabel(const cred_t *);
|
|
||||||
extern boolean_t crisremote(const cred_t *);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Private interfaces for ephemeral uids.
|
|
||||||
*/
|
|
||||||
#define VALID_UID(id, zn) \
|
|
||||||
((id) <= MAXUID || valid_ephemeral_uid((zn), (id)))
|
|
||||||
|
|
||||||
#define VALID_GID(id, zn) \
|
|
||||||
((id) <= MAXUID || valid_ephemeral_gid((zn), (id)))
|
|
||||||
|
|
||||||
extern boolean_t valid_ephemeral_uid(struct zone *, uid_t);
|
|
||||||
extern boolean_t valid_ephemeral_gid(struct zone *, gid_t);
|
|
||||||
|
|
||||||
extern int eph_uid_alloc(struct zone *, int, uid_t *, int);
|
|
||||||
extern int eph_gid_alloc(struct zone *, int, gid_t *, int);
|
|
||||||
|
|
||||||
extern void crsetsid(cred_t *, struct ksid *, int);
|
|
||||||
extern void crsetsidlist(cred_t *, struct ksidlist *);
|
|
||||||
|
|
||||||
extern struct ksidlist *crgetsidlist(const cred_t *);
|
|
||||||
|
|
||||||
extern int crsetpriv(cred_t *, ...);
|
|
||||||
|
|
||||||
extern struct credklpd *crgetcrklpd(const cred_t *);
|
|
||||||
extern void crsetcrklpd(cred_t *, struct credklpd *);
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,41 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (c) 2007 Pawel Jakub Dawidek <pjd@FreeBSD.org>
|
|
||||||
* All rights reserved.
|
|
||||||
*
|
|
||||||
* Redistribution and use in source and binary forms, with or without
|
|
||||||
* modification, are permitted provided that the following conditions
|
|
||||||
* are met:
|
|
||||||
* 1. Redistributions of source code must retain the above copyright
|
|
||||||
* notice, this list of conditions and the following disclaimer.
|
|
||||||
* 2. Redistributions in binary form must reproduce the above copyright
|
|
||||||
* notice, this list of conditions and the following disclaimer in the
|
|
||||||
* documentation and/or other materials provided with the distribution.
|
|
||||||
*
|
|
||||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND
|
|
||||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
||||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
|
||||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE
|
|
||||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
|
||||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
|
||||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
|
||||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
|
||||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
|
||||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
|
||||||
* SUCH DAMAGE.
|
|
||||||
*
|
|
||||||
* $FreeBSD$
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef _OPENSOLARIS_SYS_KIDMAP_H_
|
|
||||||
#define _OPENSOLARIS_SYS_KIDMAP_H_
|
|
||||||
|
|
||||||
#include <sys/idmap.h>
|
|
||||||
|
|
||||||
typedef int32_t idmap_stat;
|
|
||||||
typedef void idmap_get_handle_t;
|
|
||||||
|
|
||||||
#define kidmap_get_create() (NULL)
|
|
||||||
#define kidmap_get_destroy(hdl) do { } while (0)
|
|
||||||
#define kidmap_get_mappings(hdl) (NULL)
|
|
||||||
|
|
||||||
#endif /* _OPENSOLARIS_SYS_KIDMAP_H_ */
|
|
|
@ -29,7 +29,6 @@
|
||||||
#ifndef _OPENSOLARIS_SYS_SID_H_
|
#ifndef _OPENSOLARIS_SYS_SID_H_
|
||||||
#define _OPENSOLARIS_SYS_SID_H_
|
#define _OPENSOLARIS_SYS_SID_H_
|
||||||
#include <sys/idmap.h>
|
#include <sys/idmap.h>
|
||||||
#include <sys/kidmap.h>
|
|
||||||
|
|
||||||
typedef struct ksiddomain {
|
typedef struct ksiddomain {
|
||||||
char *kd_name; /* Domain part of SID */
|
char *kd_name; /* Domain part of SID */
|
||||||
|
@ -59,28 +58,4 @@ ksiddomain_rele(ksiddomain_t *kd)
|
||||||
kmem_free(kd, sizeof (*kd));
|
kmem_free(kd, sizeof (*kd));
|
||||||
}
|
}
|
||||||
|
|
||||||
static __inline uint_t
|
|
||||||
ksid_getid(ksid_t *ks)
|
|
||||||
{
|
|
||||||
|
|
||||||
panic("%s has been unexpectedly called", __func__);
|
|
||||||
}
|
|
||||||
|
|
||||||
static __inline const char *
|
|
||||||
ksid_getdomain(ksid_t *ks)
|
|
||||||
{
|
|
||||||
|
|
||||||
panic("%s has been unexpectedly called", __func__);
|
|
||||||
}
|
|
||||||
|
|
||||||
static __inline uint_t
|
|
||||||
ksid_getrid(ksid_t *ks)
|
|
||||||
{
|
|
||||||
|
|
||||||
panic("%s has been unexpectedly called", __func__);
|
|
||||||
}
|
|
||||||
|
|
||||||
#define kidmap_getsidbyuid(zone, uid, sid_prefix, rid) (1)
|
|
||||||
#define kidmap_getsidbygid(zone, gid, sid_prefix, rid) (1)
|
|
||||||
|
|
||||||
#endif /* _OPENSOLARIS_SYS_SID_H_ */
|
#endif /* _OPENSOLARIS_SYS_SID_H_ */
|
||||||
|
|
|
@ -49,12 +49,7 @@ extern void crhold(cred_t *cr);
|
||||||
extern void crfree(cred_t *cr);
|
extern void crfree(cred_t *cr);
|
||||||
extern uid_t crgetuid(const cred_t *cr);
|
extern uid_t crgetuid(const cred_t *cr);
|
||||||
extern uid_t crgetruid(const cred_t *cr);
|
extern uid_t crgetruid(const cred_t *cr);
|
||||||
extern uid_t crgetsuid(const cred_t *cr);
|
|
||||||
extern uid_t crgetfsuid(const cred_t *cr);
|
|
||||||
extern gid_t crgetgid(const cred_t *cr);
|
extern gid_t crgetgid(const cred_t *cr);
|
||||||
extern gid_t crgetrgid(const cred_t *cr);
|
|
||||||
extern gid_t crgetsgid(const cred_t *cr);
|
|
||||||
extern gid_t crgetfsgid(const cred_t *cr);
|
|
||||||
extern int crgetngroups(const cred_t *cr);
|
extern int crgetngroups(const cred_t *cr);
|
||||||
extern gid_t *crgetgroups(const cred_t *cr);
|
extern gid_t *crgetgroups(const cred_t *cr);
|
||||||
extern int groupmember(gid_t gid, const cred_t *cr);
|
extern int groupmember(gid_t gid, const cred_t *cr);
|
||||||
|
|
|
@ -32,7 +32,7 @@ CFLAGS+= -include ${INCDIR}/os/freebsd/spl/sys/ccompile.h
|
||||||
|
|
||||||
CFLAGS+= -D__KERNEL__ -DFREEBSD_NAMECACHE -DBUILDING_ZFS -D__BSD_VISIBLE=1 \
|
CFLAGS+= -D__KERNEL__ -DFREEBSD_NAMECACHE -DBUILDING_ZFS -D__BSD_VISIBLE=1 \
|
||||||
-DHAVE_UIO_ZEROCOPY -DWITHOUT_NETDUMP -D__KERNEL -D_SYS_CONDVAR_H_ \
|
-DHAVE_UIO_ZEROCOPY -DWITHOUT_NETDUMP -D__KERNEL -D_SYS_CONDVAR_H_ \
|
||||||
-D_SYS_VMEM_H_ -DKDTRACE_HOOKS -DSMP -DHAVE_KSID -DCOMPAT_FREEBSD11
|
-D_SYS_VMEM_H_ -DKDTRACE_HOOKS -DSMP -DCOMPAT_FREEBSD11
|
||||||
|
|
||||||
.if ${MACHINE_ARCH} == "amd64"
|
.if ${MACHINE_ARCH} == "amd64"
|
||||||
CFLAGS+= -DHAVE_AVX2 -DHAVE_AVX -D__x86_64 -DHAVE_SSE2 -DHAVE_AVX512F -DHAVE_SSSE3
|
CFLAGS+= -DHAVE_AVX2 -DHAVE_AVX -D__x86_64 -DHAVE_SSE2 -DHAVE_AVX512F -DHAVE_SSSE3
|
||||||
|
|
|
@ -1653,8 +1653,10 @@ zfs_acl_ids_create(znode_t *dzp, int flag, vattr_t *vap, cred_t *cr,
|
||||||
ZFS_GROUP, &acl_ids->z_fuidp);
|
ZFS_GROUP, &acl_ids->z_fuidp);
|
||||||
gid = vap->va_gid;
|
gid = vap->va_gid;
|
||||||
} else {
|
} else {
|
||||||
acl_ids->z_fuid = zfs_fuid_create_cred(zfsvfs, ZFS_OWNER,
|
uid_t id = crgetuid(cr);
|
||||||
cr, &acl_ids->z_fuidp);
|
if (IS_EPHEMERAL(id))
|
||||||
|
id = UID_NOBODY;
|
||||||
|
acl_ids->z_fuid = (uint64_t)id;
|
||||||
acl_ids->z_fgid = 0;
|
acl_ids->z_fgid = 0;
|
||||||
if (vap->va_mask & AT_GID) {
|
if (vap->va_mask & AT_GID) {
|
||||||
acl_ids->z_fgid = zfs_fuid_create(zfsvfs,
|
acl_ids->z_fgid = zfs_fuid_create(zfsvfs,
|
||||||
|
|
|
@ -1060,8 +1060,7 @@ zfs_create(znode_t *dzp, const char *name, vattr_t *vap, int excl, int mode,
|
||||||
objset_t *os;
|
objset_t *os;
|
||||||
dmu_tx_t *tx;
|
dmu_tx_t *tx;
|
||||||
int error;
|
int error;
|
||||||
ksid_t *ksid;
|
uid_t uid = crgetuid(cr);
|
||||||
uid_t uid;
|
|
||||||
gid_t gid = crgetgid(cr);
|
gid_t gid = crgetgid(cr);
|
||||||
uint64_t projid = ZFS_DEFAULT_PROJID;
|
uint64_t projid = ZFS_DEFAULT_PROJID;
|
||||||
zfs_acl_ids_t acl_ids;
|
zfs_acl_ids_t acl_ids;
|
||||||
|
@ -1075,13 +1074,6 @@ zfs_create(znode_t *dzp, const char *name, vattr_t *vap, int excl, int mode,
|
||||||
* If we have an ephemeral id, ACL, or XVATTR then
|
* If we have an ephemeral id, ACL, or XVATTR then
|
||||||
* make sure file system is at proper version
|
* make sure file system is at proper version
|
||||||
*/
|
*/
|
||||||
|
|
||||||
ksid = crgetsid(cr, KSID_OWNER);
|
|
||||||
if (ksid)
|
|
||||||
uid = ksid_getid(ksid);
|
|
||||||
else
|
|
||||||
uid = crgetuid(cr);
|
|
||||||
|
|
||||||
if (zfsvfs->z_use_fuids == B_FALSE &&
|
if (zfsvfs->z_use_fuids == B_FALSE &&
|
||||||
(vsecp || (vap->va_mask & AT_XVATTR) ||
|
(vsecp || (vap->va_mask & AT_XVATTR) ||
|
||||||
IS_EPHEMERAL(uid) || IS_EPHEMERAL(gid)))
|
IS_EPHEMERAL(uid) || IS_EPHEMERAL(gid)))
|
||||||
|
@ -1415,8 +1407,7 @@ zfs_mkdir(znode_t *dzp, const char *dirname, vattr_t *vap, znode_t **zpp,
|
||||||
uint64_t txtype;
|
uint64_t txtype;
|
||||||
dmu_tx_t *tx;
|
dmu_tx_t *tx;
|
||||||
int error;
|
int error;
|
||||||
ksid_t *ksid;
|
uid_t uid = crgetuid(cr);
|
||||||
uid_t uid;
|
|
||||||
gid_t gid = crgetgid(cr);
|
gid_t gid = crgetgid(cr);
|
||||||
zfs_acl_ids_t acl_ids;
|
zfs_acl_ids_t acl_ids;
|
||||||
boolean_t fuid_dirtied;
|
boolean_t fuid_dirtied;
|
||||||
|
@ -1427,12 +1418,6 @@ zfs_mkdir(znode_t *dzp, const char *dirname, vattr_t *vap, znode_t **zpp,
|
||||||
* If we have an ephemeral id, ACL, or XVATTR then
|
* If we have an ephemeral id, ACL, or XVATTR then
|
||||||
* make sure file system is at proper version
|
* make sure file system is at proper version
|
||||||
*/
|
*/
|
||||||
|
|
||||||
ksid = crgetsid(cr, KSID_OWNER);
|
|
||||||
if (ksid)
|
|
||||||
uid = ksid_getid(ksid);
|
|
||||||
else
|
|
||||||
uid = crgetuid(cr);
|
|
||||||
if (zfsvfs->z_use_fuids == B_FALSE &&
|
if (zfsvfs->z_use_fuids == B_FALSE &&
|
||||||
((vap->va_mask & AT_XVATTR) ||
|
((vap->va_mask & AT_XVATTR) ||
|
||||||
IS_EPHEMERAL(uid) || IS_EPHEMERAL(gid)))
|
IS_EPHEMERAL(uid) || IS_EPHEMERAL(gid)))
|
||||||
|
|
|
@ -128,7 +128,7 @@ groupmember(gid_t gid, const cred_t *cr)
|
||||||
uid_t
|
uid_t
|
||||||
crgetuid(const cred_t *cr)
|
crgetuid(const cred_t *cr)
|
||||||
{
|
{
|
||||||
return (KUID_TO_SUID(cr->euid));
|
return (KUID_TO_SUID(cr->fsuid));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Return the real user id */
|
/* Return the real user id */
|
||||||
|
@ -138,44 +138,9 @@ crgetruid(const cred_t *cr)
|
||||||
return (KUID_TO_SUID(cr->uid));
|
return (KUID_TO_SUID(cr->uid));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Return the saved user id */
|
|
||||||
uid_t
|
|
||||||
crgetsuid(const cred_t *cr)
|
|
||||||
{
|
|
||||||
return (KUID_TO_SUID(cr->suid));
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Return the filesystem user id */
|
|
||||||
uid_t
|
|
||||||
crgetfsuid(const cred_t *cr)
|
|
||||||
{
|
|
||||||
return (KUID_TO_SUID(cr->fsuid));
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Return the effective group id */
|
/* Return the effective group id */
|
||||||
gid_t
|
gid_t
|
||||||
crgetgid(const cred_t *cr)
|
crgetgid(const cred_t *cr)
|
||||||
{
|
|
||||||
return (KGID_TO_SGID(cr->egid));
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Return the real group id */
|
|
||||||
gid_t
|
|
||||||
crgetrgid(const cred_t *cr)
|
|
||||||
{
|
|
||||||
return (KGID_TO_SGID(cr->gid));
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Return the saved group id */
|
|
||||||
gid_t
|
|
||||||
crgetsgid(const cred_t *cr)
|
|
||||||
{
|
|
||||||
return (KGID_TO_SGID(cr->sgid));
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Return the filesystem group id */
|
|
||||||
gid_t
|
|
||||||
crgetfsgid(const cred_t *cr)
|
|
||||||
{
|
{
|
||||||
return (KGID_TO_SGID(cr->fsgid));
|
return (KGID_TO_SGID(cr->fsgid));
|
||||||
}
|
}
|
||||||
|
@ -184,12 +149,7 @@ EXPORT_SYMBOL(crhold);
|
||||||
EXPORT_SYMBOL(crfree);
|
EXPORT_SYMBOL(crfree);
|
||||||
EXPORT_SYMBOL(crgetuid);
|
EXPORT_SYMBOL(crgetuid);
|
||||||
EXPORT_SYMBOL(crgetruid);
|
EXPORT_SYMBOL(crgetruid);
|
||||||
EXPORT_SYMBOL(crgetsuid);
|
|
||||||
EXPORT_SYMBOL(crgetfsuid);
|
|
||||||
EXPORT_SYMBOL(crgetgid);
|
EXPORT_SYMBOL(crgetgid);
|
||||||
EXPORT_SYMBOL(crgetrgid);
|
|
||||||
EXPORT_SYMBOL(crgetsgid);
|
|
||||||
EXPORT_SYMBOL(crgetfsgid);
|
|
||||||
EXPORT_SYMBOL(crgetngroups);
|
EXPORT_SYMBOL(crgetngroups);
|
||||||
EXPORT_SYMBOL(crgetgroups);
|
EXPORT_SYMBOL(crgetgroups);
|
||||||
EXPORT_SYMBOL(groupmember);
|
EXPORT_SYMBOL(groupmember);
|
||||||
|
|
|
@ -121,7 +121,7 @@ secpolicy_vnode_access2(const cred_t *cr, struct inode *ip, uid_t owner,
|
||||||
int
|
int
|
||||||
secpolicy_vnode_any_access(const cred_t *cr, struct inode *ip, uid_t owner)
|
secpolicy_vnode_any_access(const cred_t *cr, struct inode *ip, uid_t owner)
|
||||||
{
|
{
|
||||||
if (crgetfsuid(cr) == owner)
|
if (crgetuid(cr) == owner)
|
||||||
return (0);
|
return (0);
|
||||||
|
|
||||||
if (zpl_inode_owner_or_capable(kcred->user_ns, ip))
|
if (zpl_inode_owner_or_capable(kcred->user_ns, ip))
|
||||||
|
@ -147,7 +147,7 @@ secpolicy_vnode_any_access(const cred_t *cr, struct inode *ip, uid_t owner)
|
||||||
int
|
int
|
||||||
secpolicy_vnode_chown(const cred_t *cr, uid_t owner)
|
secpolicy_vnode_chown(const cred_t *cr, uid_t owner)
|
||||||
{
|
{
|
||||||
if (crgetfsuid(cr) == owner)
|
if (crgetuid(cr) == owner)
|
||||||
return (0);
|
return (0);
|
||||||
|
|
||||||
#if defined(CONFIG_USER_NS)
|
#if defined(CONFIG_USER_NS)
|
||||||
|
@ -184,7 +184,7 @@ secpolicy_vnode_remove(const cred_t *cr)
|
||||||
int
|
int
|
||||||
secpolicy_vnode_setdac(const cred_t *cr, uid_t owner)
|
secpolicy_vnode_setdac(const cred_t *cr, uid_t owner)
|
||||||
{
|
{
|
||||||
if (crgetfsuid(cr) == owner)
|
if (crgetuid(cr) == owner)
|
||||||
return (0);
|
return (0);
|
||||||
|
|
||||||
#if defined(CONFIG_USER_NS)
|
#if defined(CONFIG_USER_NS)
|
||||||
|
@ -220,7 +220,7 @@ secpolicy_vnode_setids_setgids(const cred_t *cr, gid_t gid)
|
||||||
if (!kgid_has_mapping(cr->user_ns, SGID_TO_KGID(gid)))
|
if (!kgid_has_mapping(cr->user_ns, SGID_TO_KGID(gid)))
|
||||||
return (EPERM);
|
return (EPERM);
|
||||||
#endif
|
#endif
|
||||||
if (crgetfsgid(cr) != gid && !groupmember(gid, cr))
|
if (crgetgid(cr) != gid && !groupmember(gid, cr))
|
||||||
return (priv_policy_user(cr, CAP_FSETID, EPERM));
|
return (priv_policy_user(cr, CAP_FSETID, EPERM));
|
||||||
|
|
||||||
return (0);
|
return (0);
|
||||||
|
@ -286,7 +286,7 @@ secpolicy_setid_clear(vattr_t *vap, cred_t *cr)
|
||||||
static int
|
static int
|
||||||
secpolicy_vnode_setid_modify(const cred_t *cr, uid_t owner)
|
secpolicy_vnode_setid_modify(const cred_t *cr, uid_t owner)
|
||||||
{
|
{
|
||||||
if (crgetfsuid(cr) == owner)
|
if (crgetuid(cr) == owner)
|
||||||
return (0);
|
return (0);
|
||||||
|
|
||||||
#if defined(CONFIG_USER_NS)
|
#if defined(CONFIG_USER_NS)
|
||||||
|
|
|
@ -116,14 +116,14 @@ zpl_vap_init(vattr_t *vap, struct inode *dir, umode_t mode, cred_t *cr)
|
||||||
{
|
{
|
||||||
vap->va_mask = ATTR_MODE;
|
vap->va_mask = ATTR_MODE;
|
||||||
vap->va_mode = mode;
|
vap->va_mode = mode;
|
||||||
vap->va_uid = crgetfsuid(cr);
|
vap->va_uid = crgetuid(cr);
|
||||||
|
|
||||||
if (dir && dir->i_mode & S_ISGID) {
|
if (dir && dir->i_mode & S_ISGID) {
|
||||||
vap->va_gid = KGID_TO_SGID(dir->i_gid);
|
vap->va_gid = KGID_TO_SGID(dir->i_gid);
|
||||||
if (S_ISDIR(mode))
|
if (S_ISDIR(mode))
|
||||||
vap->va_mode |= S_ISGID;
|
vap->va_mode |= S_ISGID;
|
||||||
} else {
|
} else {
|
||||||
vap->va_gid = crgetfsgid(cr);
|
vap->va_gid = crgetgid(cr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -492,8 +492,8 @@ zpl_xattr_set_dir(struct inode *ip, const char *name, const void *value,
|
||||||
vap = kmem_zalloc(sizeof (vattr_t), KM_SLEEP);
|
vap = kmem_zalloc(sizeof (vattr_t), KM_SLEEP);
|
||||||
vap->va_mode = xattr_mode;
|
vap->va_mode = xattr_mode;
|
||||||
vap->va_mask = ATTR_MODE;
|
vap->va_mask = ATTR_MODE;
|
||||||
vap->va_uid = crgetfsuid(cr);
|
vap->va_uid = crgetuid(cr);
|
||||||
vap->va_gid = crgetfsgid(cr);
|
vap->va_gid = crgetgid(cr);
|
||||||
|
|
||||||
error = -zfs_create(dxzp, (char *)name, vap, 0, 0644, &xzp,
|
error = -zfs_create(dxzp, (char *)name, vap, 0, 0644, &xzp,
|
||||||
cr, 0, NULL);
|
cr, 0, NULL);
|
||||||
|
|
Loading…
Reference in New Issue