Skip to content

Commit

Permalink
FreeBSD: Fix UNIX permissions checking
Browse files Browse the repository at this point in the history
Reviewed-by: Ryan Moeller <ryan@iXsystems.com>
Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov>
Signed-off-by: Matt Macy <mmacy@FreeBSD.org>
Closes #10727
  • Loading branch information
mattmacy committed Aug 18, 2020
1 parent 5e7eaf8 commit 716b53d
Show file tree
Hide file tree
Showing 7 changed files with 174 additions and 99 deletions.
97 changes: 97 additions & 0 deletions include/os/freebsd/spl/sys/idmap.h
@@ -0,0 +1,97 @@
/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
* Copyright 2010 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/

#ifndef _SYS_IDMAP_H
#define _SYS_IDMAP_H


/* Idmap status codes */
#define IDMAP_SUCCESS 0
#define IDMAP_NEXT 1
#define IDMAP_ERR_OTHER -10000
#define IDMAP_ERR_INTERNAL -9999
#define IDMAP_ERR_MEMORY -9998
#define IDMAP_ERR_NORESULT -9997
#define IDMAP_ERR_NOTUSER -9996
#define IDMAP_ERR_NOTGROUP -9995
#define IDMAP_ERR_NOTSUPPORTED -9994
#define IDMAP_ERR_W2U_NAMERULE -9993
#define IDMAP_ERR_U2W_NAMERULE -9992
#define IDMAP_ERR_CACHE -9991
#define IDMAP_ERR_DB -9990
#define IDMAP_ERR_ARG -9989
#define IDMAP_ERR_SID -9988
#define IDMAP_ERR_IDTYPE -9987
#define IDMAP_ERR_RPC_HANDLE -9986
#define IDMAP_ERR_RPC -9985
#define IDMAP_ERR_CLIENT_HANDLE -9984
#define IDMAP_ERR_BUSY -9983
#define IDMAP_ERR_PERMISSION_DENIED -9982
#define IDMAP_ERR_NOMAPPING -9981
#define IDMAP_ERR_NEW_ID_ALLOC_REQD -9980
#define IDMAP_ERR_DOMAIN -9979
#define IDMAP_ERR_SECURITY -9978
#define IDMAP_ERR_NOTFOUND -9977
#define IDMAP_ERR_DOMAIN_NOTFOUND -9976
#define IDMAP_ERR_UPDATE_NOTALLOWED -9975
#define IDMAP_ERR_CFG -9974
#define IDMAP_ERR_CFG_CHANGE -9973
#define IDMAP_ERR_NOTMAPPED_WELLKNOWN -9972
#define IDMAP_ERR_RETRIABLE_NET_ERR -9971
#define IDMAP_ERR_W2U_NAMERULE_CONFLICT -9970
#define IDMAP_ERR_U2W_NAMERULE_CONFLICT -9969
#define IDMAP_ERR_BAD_UTF8 -9968
#define IDMAP_ERR_NONE_GENERATED -9967
#define IDMAP_ERR_PROP_UNKNOWN -9966
#define IDMAP_ERR_NS_LDAP_OP_FAILED -9965
#define IDMAP_ERR_NS_LDAP_PARTIAL -9964
#define IDMAP_ERR_NS_LDAP_CFG -9963
#define IDMAP_ERR_NS_LDAP_BAD_WINNAME -9962
#define IDMAP_ERR_NO_ACTIVEDIRECTORY -9961

/* Reserved GIDs for some well-known SIDs */
#define IDMAP_WK_LOCAL_SYSTEM_GID 2147483648U /* 0x80000000 */
#define IDMAP_WK_CREATOR_GROUP_GID 2147483649U
#define IDMAP_WK__MAX_GID 2147483649U

/* Reserved UIDs for some well-known SIDs */
#define IDMAP_WK_CREATOR_OWNER_UID 2147483648U
#define IDMAP_WK__MAX_UID 2147483648U

/* Reserved SIDs */
#define IDMAP_WK_CREATOR_SID_AUTHORITY "S-1-3"

/*
* Max door RPC size for ID mapping (can't be too large relative to the
* default user-land thread stack size, since clnt_door_call()
* alloca()s). See libidmap:idmap_init().
*/
#define IDMAP_MAX_DOOR_RPC (256 * 1024)

#define IDMAP_SENTINEL_PID UINT32_MAX
#define IDMAP_ID_IS_EPHEMERAL(pid) \
(((pid) > INT32_MAX) && ((pid) != IDMAP_SENTINEL_PID))

#endif /* _SYS_IDMAP_H */
41 changes: 41 additions & 0 deletions include/os/freebsd/spl/sys/kidmap.h
@@ -0,0 +1,41 @@
/*
* 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_ */
2 changes: 2 additions & 0 deletions include/os/freebsd/spl/sys/sid.h
Expand Up @@ -28,6 +28,8 @@

#ifndef _OPENSOLARIS_SYS_SID_H_
#define _OPENSOLARIS_SYS_SID_H_
#include <sys/idmap.h>
#include <sys/kidmap.h>

typedef struct ksiddomain {
char *kd_name; /* Domain part of SID */
Expand Down
7 changes: 3 additions & 4 deletions module/Makefile.bsd
Expand Up @@ -27,9 +27,9 @@ CFLAGS+= -I${INCDIR}/os/freebsd/spl
CFLAGS+= -I${INCDIR}/os/freebsd/zfs
CFLAGS+= -include ${INCDIR}/os/freebsd/spl/sys/ccompile.h

CFLAGS+= -D__KERNEL__ -DFREEBSD_NAMECACHE -DBUILDING_ZFS -D__BSD_VISIBLE=1
CFLAGS+= -DHAVE_UIO_ZEROCOPY -DWITHOUT_NETDUMP -D__KERNEL -D_SYS_CONDVAR_H_
CFLAGS+= -D_SYS_VMEM_H_ -DKDTRACE_HOOKS -DSMP
CFLAGS+= -D__KERNEL__ -DFREEBSD_NAMECACHE -DBUILDING_ZFS -D__BSD_VISIBLE=1 \
-DHAVE_UIO_ZEROCOPY -DWITHOUT_NETDUMP -D__KERNEL -D_SYS_CONDVAR_H_ \
-D_SYS_VMEM_H_ -DKDTRACE_HOOKS -DSMP -DHAVE_KSID

.if ${MACHINE_ARCH} == "amd64"
CFLAGS+= -DHAVE_AVX2 -DHAVE_AVX -D__x86_64 -DHAVE_SSE2 -DHAVE_AVX512F -DHAVE_SSSE3
Expand Down Expand Up @@ -276,7 +276,6 @@ SRCS+= abd.c \
zfs_file_os.c \
zfs_fm.c \
zfs_fuid.c \
zfs_fuid_os.c \
zfs_ioctl.c \
zfs_onexit.c \
zfs_quota.c \
Expand Down
34 changes: 0 additions & 34 deletions module/os/freebsd/zfs/zfs_acl.c
Expand Up @@ -2305,10 +2305,7 @@ zfs_zaccess_append(znode_t *zp, uint32_t *working_mode, boolean_t *check_privs,
int
zfs_fastaccesschk_execute(znode_t *zdp, cred_t *cr)
{
boolean_t owner = B_FALSE;
boolean_t groupmbr = B_FALSE;
boolean_t is_attr;
uid_t uid = crgetuid(cr);

if (zdp->z_pflags & ZFS_AV_QUARANTINED)
return (1);
Expand All @@ -2321,37 +2318,6 @@ zfs_fastaccesschk_execute(znode_t *zdp, cred_t *cr)
if (zdp->z_pflags & ZFS_NO_EXECS_DENIED)
return (0);

mutex_enter(&zdp->z_acl_lock);
if (FUID_INDEX(zdp->z_uid) != 0 || FUID_INDEX(zdp->z_gid) != 0) {
goto out_slow;
}

if (uid == zdp->z_uid) {
owner = B_TRUE;
if (zdp->z_mode & S_IXUSR) {
goto out;
} else {
goto out_slow;
}
}
if (groupmember(zdp->z_gid, cr)) {
groupmbr = B_TRUE;
if (zdp->z_mode & S_IXGRP) {
goto out;
} else {
goto out_slow;
}
}
if (!owner && !groupmbr) {
if (zdp->z_mode & S_IXOTH) {
goto out;
}
}
out:
mutex_exit(&zdp->z_acl_lock);
return (0);
out_slow:
mutex_exit(&zdp->z_acl_lock);
return (1);
}

Expand Down
51 changes: 0 additions & 51 deletions module/os/freebsd/zfs/zfs_fuid_os.c

This file was deleted.

41 changes: 31 additions & 10 deletions module/zfs/zfs_fuid.c
Expand Up @@ -387,11 +387,34 @@ zfs_fuid_map_ids(znode_t *zp, cred_t *cr, uid_t *uidp, uid_t *gidp)
cr, ZFS_GROUP);
}

#ifdef __FreeBSD__
uid_t
zfs_fuid_map_id(zfsvfs_t *zfsvfs, uint64_t fuid,
cred_t *cr, zfs_fuid_type_t type)
{
uint32_t index = FUID_INDEX(fuid);

if (index == 0)
return (fuid);

return (UID_NOBODY);
}
#elif defined(__linux__)
uid_t
zfs_fuid_map_id(zfsvfs_t *zfsvfs, uint64_t fuid,
cred_t *cr, zfs_fuid_type_t type)
{
/*
* The Linux port only supports POSIX IDs, use the passed id.
*/
return (fuid);
}

#else
uid_t
zfs_fuid_map_id(zfsvfs_t *zfsvfs, uint64_t fuid,
cred_t *cr, zfs_fuid_type_t type)
{
#ifdef HAVE_KSID
uint32_t index = FUID_INDEX(fuid);
const char *domain;
uid_t id;
Expand All @@ -410,13 +433,8 @@ zfs_fuid_map_id(zfsvfs_t *zfsvfs, uint64_t fuid,
FUID_RID(fuid), &id);
}
return (id);
#else
/*
* The Linux port only supports POSIX IDs, use the passed id.
*/
return (fuid);
#endif /* HAVE_KSID */
}
#endif

/*
* Add a FUID node to the list of fuid's being created for this
Expand Down Expand Up @@ -559,9 +577,9 @@ zfs_fuid_create(zfsvfs_t *zfsvfs, uint64_t id, cred_t *cr,
const char *domain;
char *kdomain;
uint32_t fuid_idx = FUID_INDEX(id);
uint32_t rid;
uint32_t rid = 0;
idmap_stat status;
uint64_t idx = 0;
uint64_t idx = UID_NOBODY;
zfs_fuid_t *zfuid = NULL;
zfs_fuid_info_t *fuidp = NULL;

Expand Down Expand Up @@ -711,9 +729,11 @@ boolean_t
zfs_groupmember(zfsvfs_t *zfsvfs, uint64_t id, cred_t *cr)
{
#ifdef HAVE_KSID
uid_t gid;

#ifdef illumos
ksid_t *ksid = crgetsid(cr, KSID_GROUP);
ksidlist_t *ksidlist = crgetsidlist(cr);
uid_t gid;

if (ksid && ksidlist) {
int i;
Expand Down Expand Up @@ -746,6 +766,7 @@ zfs_groupmember(zfsvfs_t *zfsvfs, uint64_t id, cred_t *cr)
}
}
}
#endif /* illumos */

/*
* Not found in ksidlist, check posix groups
Expand Down

0 comments on commit 716b53d

Please sign in to comment.