You've already forked linux-apfs
mirror of
https://github.com/linux-apfs/linux-apfs.git
synced 2026-05-01 15:00:59 -07:00
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/ebiederm/user-namespace
Pull user namespace and namespace infrastructure changes from Eric W Biederman: "This set of changes starts with a few small enhnacements to the user namespace. reboot support, allowing more arbitrary mappings, and support for mounting devpts, ramfs, tmpfs, and mqueuefs as just the user namespace root. I do my best to document that if you care about limiting your unprivileged users that when you have the user namespace support enabled you will need to enable memory control groups. There is a minor bug fix to prevent overflowing the stack if someone creates way too many user namespaces. The bulk of the changes are a continuation of the kuid/kgid push down work through the filesystems. These changes make using uids and gids typesafe which ensures that these filesystems are safe to use when multiple user namespaces are in use. The filesystems converted for 3.9 are ceph, 9p, afs, ocfs2, gfs2, ncpfs, nfs, nfsd, and cifs. The changes for these filesystems were a little more involved so I split the changes into smaller hopefully obviously correct changes. XFS is the only filesystem that remains. I was hoping I could get that in this release so that user namespace support would be enabled with an allyesconfig or an allmodconfig but it looks like the xfs changes need another couple of days before it they are ready." * 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/ebiederm/user-namespace: (93 commits) cifs: Enable building with user namespaces enabled. cifs: Convert struct cifs_ses to use a kuid_t and a kgid_t cifs: Convert struct cifs_sb_info to use kuids and kgids cifs: Modify struct smb_vol to use kuids and kgids cifs: Convert struct cifsFileInfo to use a kuid cifs: Convert struct cifs_fattr to use kuid and kgids cifs: Convert struct tcon_link to use a kuid. cifs: Modify struct cifs_unix_set_info_args to hold a kuid_t and a kgid_t cifs: Convert from a kuid before printing current_fsuid cifs: Use kuids and kgids SID to uid/gid mapping cifs: Pass GLOBAL_ROOT_UID and GLOBAL_ROOT_GID to keyring_alloc cifs: Use BUILD_BUG_ON to validate uids and gids are the same size cifs: Override unmappable incoming uids and gids nfsd: Enable building with user namespaces enabled. nfsd: Properly compare and initialize kuids and kgids nfsd: Store ex_anon_uid and ex_anon_gid as kuids and kgids nfsd: Modify nfsd4_cb_sec to use kuids and kgids nfsd: Handle kuids and kgids in the nfs4acl to posix_acl conversion nfsd: Convert nfsxdr to use kuids and kgids nfsd: Convert nfs3xdr to use kuids and kgids ...
This commit is contained in:
@@ -0,0 +1,14 @@
|
||||
There are a lot of kinds of objects in the kernel that don't have
|
||||
individual limits or that have limits that are ineffective when a set
|
||||
of processes is allowed to switch user ids. With user namespaces
|
||||
enabled in a kernel for people who don't trust their users or their
|
||||
users programs to play nice this problems becomes more acute.
|
||||
|
||||
Therefore it is recommended that memory control groups be enabled in
|
||||
kernels that enable user namespaces, and it is further recommended
|
||||
that userspace configure memory control groups to limit how much
|
||||
memory user's they don't trust to play nice can use.
|
||||
|
||||
Memory control groups can be configured by installing the libcgroup
|
||||
package present on most distros editing /etc/cgrules.conf,
|
||||
/etc/cgconfig.conf and setting up libpam-cgroup.
|
||||
+9
-8
@@ -74,19 +74,20 @@ int v9fs_fid_add(struct dentry *dentry, struct p9_fid *fid)
|
||||
*
|
||||
*/
|
||||
|
||||
static struct p9_fid *v9fs_fid_find(struct dentry *dentry, u32 uid, int any)
|
||||
static struct p9_fid *v9fs_fid_find(struct dentry *dentry, kuid_t uid, int any)
|
||||
{
|
||||
struct v9fs_dentry *dent;
|
||||
struct p9_fid *fid, *ret;
|
||||
|
||||
p9_debug(P9_DEBUG_VFS, " dentry: %s (%p) uid %d any %d\n",
|
||||
dentry->d_name.name, dentry, uid, any);
|
||||
dentry->d_name.name, dentry, from_kuid(&init_user_ns, uid),
|
||||
any);
|
||||
dent = (struct v9fs_dentry *) dentry->d_fsdata;
|
||||
ret = NULL;
|
||||
if (dent) {
|
||||
spin_lock(&dent->lock);
|
||||
list_for_each_entry(fid, &dent->fidlist, dlist) {
|
||||
if (any || fid->uid == uid) {
|
||||
if (any || uid_eq(fid->uid, uid)) {
|
||||
ret = fid;
|
||||
break;
|
||||
}
|
||||
@@ -126,7 +127,7 @@ err_out:
|
||||
}
|
||||
|
||||
static struct p9_fid *v9fs_fid_lookup_with_uid(struct dentry *dentry,
|
||||
uid_t uid, int any)
|
||||
kuid_t uid, int any)
|
||||
{
|
||||
struct dentry *ds;
|
||||
char **wnames, *uname;
|
||||
@@ -233,7 +234,7 @@ err_out:
|
||||
|
||||
struct p9_fid *v9fs_fid_lookup(struct dentry *dentry)
|
||||
{
|
||||
uid_t uid;
|
||||
kuid_t uid;
|
||||
int any, access;
|
||||
struct v9fs_session_info *v9ses;
|
||||
|
||||
@@ -253,7 +254,7 @@ struct p9_fid *v9fs_fid_lookup(struct dentry *dentry)
|
||||
break;
|
||||
|
||||
default:
|
||||
uid = ~0;
|
||||
uid = INVALID_UID;
|
||||
any = 0;
|
||||
break;
|
||||
}
|
||||
@@ -272,7 +273,7 @@ struct p9_fid *v9fs_fid_clone(struct dentry *dentry)
|
||||
return ret;
|
||||
}
|
||||
|
||||
static struct p9_fid *v9fs_fid_clone_with_uid(struct dentry *dentry, uid_t uid)
|
||||
static struct p9_fid *v9fs_fid_clone_with_uid(struct dentry *dentry, kuid_t uid)
|
||||
{
|
||||
struct p9_fid *fid, *ret;
|
||||
|
||||
@@ -289,7 +290,7 @@ struct p9_fid *v9fs_writeback_fid(struct dentry *dentry)
|
||||
int err;
|
||||
struct p9_fid *fid;
|
||||
|
||||
fid = v9fs_fid_clone_with_uid(dentry, 0);
|
||||
fid = v9fs_fid_clone_with_uid(dentry, GLOBAL_ROOT_UID);
|
||||
if (IS_ERR(fid))
|
||||
goto error_out;
|
||||
/*
|
||||
|
||||
+27
-7
@@ -161,7 +161,13 @@ static int v9fs_parse_options(struct v9fs_session_info *v9ses, char *opts)
|
||||
ret = r;
|
||||
continue;
|
||||
}
|
||||
v9ses->dfltuid = option;
|
||||
v9ses->dfltuid = make_kuid(current_user_ns(), option);
|
||||
if (!uid_valid(v9ses->dfltuid)) {
|
||||
p9_debug(P9_DEBUG_ERROR,
|
||||
"uid field, but not a uid?\n");
|
||||
ret = -EINVAL;
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
case Opt_dfltgid:
|
||||
r = match_int(&args[0], &option);
|
||||
@@ -171,7 +177,13 @@ static int v9fs_parse_options(struct v9fs_session_info *v9ses, char *opts)
|
||||
ret = r;
|
||||
continue;
|
||||
}
|
||||
v9ses->dfltgid = option;
|
||||
v9ses->dfltgid = make_kgid(current_user_ns(), option);
|
||||
if (!gid_valid(v9ses->dfltgid)) {
|
||||
p9_debug(P9_DEBUG_ERROR,
|
||||
"gid field, but not a gid?\n");
|
||||
ret = -EINVAL;
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
case Opt_afid:
|
||||
r = match_int(&args[0], &option);
|
||||
@@ -248,8 +260,9 @@ static int v9fs_parse_options(struct v9fs_session_info *v9ses, char *opts)
|
||||
else if (strcmp(s, "client") == 0) {
|
||||
v9ses->flags |= V9FS_ACCESS_CLIENT;
|
||||
} else {
|
||||
uid_t uid;
|
||||
v9ses->flags |= V9FS_ACCESS_SINGLE;
|
||||
v9ses->uid = simple_strtoul(s, &e, 10);
|
||||
uid = simple_strtoul(s, &e, 10);
|
||||
if (*e != '\0') {
|
||||
ret = -EINVAL;
|
||||
pr_info("Unknown access argument %s\n",
|
||||
@@ -257,6 +270,13 @@ static int v9fs_parse_options(struct v9fs_session_info *v9ses, char *opts)
|
||||
kfree(s);
|
||||
goto free_and_return;
|
||||
}
|
||||
v9ses->uid = make_kuid(current_user_ns(), uid);
|
||||
if (!uid_valid(v9ses->uid)) {
|
||||
ret = -EINVAL;
|
||||
pr_info("Uknown uid %s\n", s);
|
||||
kfree(s);
|
||||
goto free_and_return;
|
||||
}
|
||||
}
|
||||
|
||||
kfree(s);
|
||||
@@ -319,7 +339,7 @@ struct p9_fid *v9fs_session_init(struct v9fs_session_info *v9ses,
|
||||
list_add(&v9ses->slist, &v9fs_sessionlist);
|
||||
spin_unlock(&v9fs_sessionlist_lock);
|
||||
|
||||
v9ses->uid = ~0;
|
||||
v9ses->uid = INVALID_UID;
|
||||
v9ses->dfltuid = V9FS_DEFUID;
|
||||
v9ses->dfltgid = V9FS_DEFGID;
|
||||
|
||||
@@ -364,7 +384,7 @@ struct p9_fid *v9fs_session_init(struct v9fs_session_info *v9ses,
|
||||
|
||||
v9ses->flags &= ~V9FS_ACCESS_MASK;
|
||||
v9ses->flags |= V9FS_ACCESS_ANY;
|
||||
v9ses->uid = ~0;
|
||||
v9ses->uid = INVALID_UID;
|
||||
}
|
||||
if (!v9fs_proto_dotl(v9ses) ||
|
||||
!((v9ses->flags & V9FS_ACCESS_MASK) == V9FS_ACCESS_CLIENT)) {
|
||||
@@ -375,7 +395,7 @@ struct p9_fid *v9fs_session_init(struct v9fs_session_info *v9ses,
|
||||
v9ses->flags &= ~V9FS_ACL_MASK;
|
||||
}
|
||||
|
||||
fid = p9_client_attach(v9ses->clnt, NULL, v9ses->uname, ~0,
|
||||
fid = p9_client_attach(v9ses->clnt, NULL, v9ses->uname, INVALID_UID,
|
||||
v9ses->aname);
|
||||
if (IS_ERR(fid)) {
|
||||
retval = PTR_ERR(fid);
|
||||
@@ -387,7 +407,7 @@ struct p9_fid *v9fs_session_init(struct v9fs_session_info *v9ses,
|
||||
if ((v9ses->flags & V9FS_ACCESS_MASK) == V9FS_ACCESS_SINGLE)
|
||||
fid->uid = v9ses->uid;
|
||||
else
|
||||
fid->uid = ~0;
|
||||
fid->uid = INVALID_UID;
|
||||
|
||||
#ifdef CONFIG_9P_FSCACHE
|
||||
/* register the session for caching */
|
||||
|
||||
+5
-5
@@ -109,9 +109,9 @@ struct v9fs_session_info {
|
||||
char *uname; /* user name to mount as */
|
||||
char *aname; /* name of remote hierarchy being mounted */
|
||||
unsigned int maxdata; /* max data for client interface */
|
||||
unsigned int dfltuid; /* default uid/muid for legacy support */
|
||||
unsigned int dfltgid; /* default gid for legacy support */
|
||||
u32 uid; /* if ACCESS_SINGLE, the uid that has access */
|
||||
kuid_t dfltuid; /* default uid/muid for legacy support */
|
||||
kgid_t dfltgid; /* default gid for legacy support */
|
||||
kuid_t uid; /* if ACCESS_SINGLE, the uid that has access */
|
||||
struct p9_client *clnt; /* 9p client */
|
||||
struct list_head slist; /* list of sessions registered with v9fs */
|
||||
struct backing_dev_info bdi;
|
||||
@@ -165,8 +165,8 @@ extern struct inode *v9fs_inode_from_fid_dotl(struct v9fs_session_info *v9ses,
|
||||
#define V9FS_PORT 564
|
||||
#define V9FS_DEFUSER "nobody"
|
||||
#define V9FS_DEFANAME ""
|
||||
#define V9FS_DEFUID (-2)
|
||||
#define V9FS_DEFGID (-2)
|
||||
#define V9FS_DEFUID KUIDT_INIT(-2)
|
||||
#define V9FS_DEFGID KGIDT_INIT(-2)
|
||||
|
||||
static inline struct v9fs_session_info *v9fs_inode2v9ses(struct inode *inode)
|
||||
{
|
||||
|
||||
+3
-3
@@ -225,9 +225,9 @@ v9fs_blank_wstat(struct p9_wstat *wstat)
|
||||
wstat->uid = NULL;
|
||||
wstat->gid = NULL;
|
||||
wstat->muid = NULL;
|
||||
wstat->n_uid = ~0;
|
||||
wstat->n_gid = ~0;
|
||||
wstat->n_muid = ~0;
|
||||
wstat->n_uid = INVALID_UID;
|
||||
wstat->n_gid = INVALID_GID;
|
||||
wstat->n_muid = INVALID_UID;
|
||||
wstat->extension = NULL;
|
||||
}
|
||||
|
||||
|
||||
@@ -57,7 +57,7 @@ v9fs_vfs_mknod_dotl(struct inode *dir, struct dentry *dentry, umode_t omode,
|
||||
* group of the new file system object.
|
||||
*/
|
||||
|
||||
static gid_t v9fs_get_fsgid_for_create(struct inode *dir_inode)
|
||||
static kgid_t v9fs_get_fsgid_for_create(struct inode *dir_inode)
|
||||
{
|
||||
BUG_ON(dir_inode == NULL);
|
||||
|
||||
@@ -245,7 +245,7 @@ v9fs_vfs_atomic_open_dotl(struct inode *dir, struct dentry *dentry,
|
||||
int *opened)
|
||||
{
|
||||
int err = 0;
|
||||
gid_t gid;
|
||||
kgid_t gid;
|
||||
umode_t mode;
|
||||
char *name = NULL;
|
||||
struct p9_qid qid;
|
||||
@@ -396,7 +396,7 @@ static int v9fs_vfs_mkdir_dotl(struct inode *dir,
|
||||
int err;
|
||||
struct v9fs_session_info *v9ses;
|
||||
struct p9_fid *fid = NULL, *dfid = NULL;
|
||||
gid_t gid;
|
||||
kgid_t gid;
|
||||
char *name;
|
||||
umode_t mode;
|
||||
struct inode *inode;
|
||||
@@ -697,7 +697,7 @@ v9fs_vfs_symlink_dotl(struct inode *dir, struct dentry *dentry,
|
||||
const char *symname)
|
||||
{
|
||||
int err;
|
||||
gid_t gid;
|
||||
kgid_t gid;
|
||||
char *name;
|
||||
struct p9_qid qid;
|
||||
struct inode *inode;
|
||||
@@ -837,7 +837,7 @@ v9fs_vfs_mknod_dotl(struct inode *dir, struct dentry *dentry, umode_t omode,
|
||||
dev_t rdev)
|
||||
{
|
||||
int err;
|
||||
gid_t gid;
|
||||
kgid_t gid;
|
||||
char *name;
|
||||
umode_t mode;
|
||||
struct v9fs_session_info *v9ses;
|
||||
|
||||
+2
-9
@@ -119,8 +119,8 @@ struct afs_file_status {
|
||||
u64 size; /* file size */
|
||||
afs_dataversion_t data_version; /* current data version */
|
||||
u32 author; /* author ID */
|
||||
u32 owner; /* owner ID */
|
||||
u32 group; /* group ID */
|
||||
kuid_t owner; /* owner ID */
|
||||
kgid_t group; /* group ID */
|
||||
afs_access_t caller_access; /* access rights for authenticated caller */
|
||||
afs_access_t anon_access; /* access rights for unauthenticated caller */
|
||||
umode_t mode; /* UNIX mode */
|
||||
@@ -133,13 +133,6 @@ struct afs_file_status {
|
||||
/*
|
||||
* AFS file status change request
|
||||
*/
|
||||
struct afs_store_status {
|
||||
u32 mask; /* which bits of the struct are set */
|
||||
u32 mtime_client; /* last time client changed data */
|
||||
u32 owner; /* owner ID */
|
||||
u32 group; /* group ID */
|
||||
umode_t mode; /* UNIX mode */
|
||||
};
|
||||
|
||||
#define AFS_SET_MTIME 0x01 /* set the mtime */
|
||||
#define AFS_SET_OWNER 0x02 /* set the owner ID */
|
||||
|
||||
+10
-4
@@ -42,6 +42,8 @@ static void xdr_decode_AFSFetchStatus(const __be32 **_bp,
|
||||
umode_t mode;
|
||||
u64 data_version, size;
|
||||
u32 changed = 0; /* becomes non-zero if ctime-type changes seen */
|
||||
kuid_t owner;
|
||||
kgid_t group;
|
||||
|
||||
#define EXTRACT(DST) \
|
||||
do { \
|
||||
@@ -56,7 +58,9 @@ static void xdr_decode_AFSFetchStatus(const __be32 **_bp,
|
||||
size = ntohl(*bp++);
|
||||
data_version = ntohl(*bp++);
|
||||
EXTRACT(status->author);
|
||||
EXTRACT(status->owner);
|
||||
owner = make_kuid(&init_user_ns, ntohl(*bp++));
|
||||
changed |= !uid_eq(owner, status->owner);
|
||||
status->owner = owner;
|
||||
EXTRACT(status->caller_access); /* call ticket dependent */
|
||||
EXTRACT(status->anon_access);
|
||||
EXTRACT(status->mode);
|
||||
@@ -65,7 +69,9 @@ static void xdr_decode_AFSFetchStatus(const __be32 **_bp,
|
||||
bp++; /* seg size */
|
||||
status->mtime_client = ntohl(*bp++);
|
||||
status->mtime_server = ntohl(*bp++);
|
||||
EXTRACT(status->group);
|
||||
group = make_kgid(&init_user_ns, ntohl(*bp++));
|
||||
changed |= !gid_eq(group, status->group);
|
||||
status->group = group;
|
||||
bp++; /* sync counter */
|
||||
data_version |= (u64) ntohl(*bp++) << 32;
|
||||
EXTRACT(status->lock_count);
|
||||
@@ -181,12 +187,12 @@ static void xdr_encode_AFS_StoreStatus(__be32 **_bp, struct iattr *attr)
|
||||
|
||||
if (attr->ia_valid & ATTR_UID) {
|
||||
mask |= AFS_SET_OWNER;
|
||||
owner = attr->ia_uid;
|
||||
owner = from_kuid(&init_user_ns, attr->ia_uid);
|
||||
}
|
||||
|
||||
if (attr->ia_valid & ATTR_GID) {
|
||||
mask |= AFS_SET_GROUP;
|
||||
group = attr->ia_gid;
|
||||
group = from_kgid(&init_user_ns, attr->ia_gid);
|
||||
}
|
||||
|
||||
if (attr->ia_valid & ATTR_MODE) {
|
||||
|
||||
+3
-3
@@ -69,7 +69,7 @@ static int afs_inode_map_status(struct afs_vnode *vnode, struct key *key)
|
||||
|
||||
set_nlink(inode, vnode->status.nlink);
|
||||
inode->i_uid = vnode->status.owner;
|
||||
inode->i_gid = 0;
|
||||
inode->i_gid = GLOBAL_ROOT_GID;
|
||||
inode->i_size = vnode->status.size;
|
||||
inode->i_ctime.tv_sec = vnode->status.mtime_server;
|
||||
inode->i_ctime.tv_nsec = 0;
|
||||
@@ -175,8 +175,8 @@ struct inode *afs_iget_autocell(struct inode *dir, const char *dev_name,
|
||||
inode->i_mode = S_IFDIR | S_IRUGO | S_IXUGO;
|
||||
inode->i_op = &afs_autocell_inode_operations;
|
||||
set_nlink(inode, 2);
|
||||
inode->i_uid = 0;
|
||||
inode->i_gid = 0;
|
||||
inode->i_uid = GLOBAL_ROOT_UID;
|
||||
inode->i_gid = GLOBAL_ROOT_GID;
|
||||
inode->i_ctime.tv_sec = get_seconds();
|
||||
inode->i_ctime.tv_nsec = 0;
|
||||
inode->i_atime = inode->i_mtime = inode->i_ctime;
|
||||
|
||||
@@ -24,6 +24,8 @@
|
||||
#include <linux/parser.h>
|
||||
#include <linux/statfs.h>
|
||||
#include <linux/sched.h>
|
||||
#include <linux/nsproxy.h>
|
||||
#include <net/net_namespace.h>
|
||||
#include "internal.h"
|
||||
|
||||
#define AFS_FS_MAGIC 0x6B414653 /* 'kAFS' */
|
||||
@@ -363,6 +365,10 @@ static struct dentry *afs_mount(struct file_system_type *fs_type,
|
||||
|
||||
memset(¶ms, 0, sizeof(params));
|
||||
|
||||
ret = -EINVAL;
|
||||
if (current->nsproxy->net_ns != &init_net)
|
||||
goto error;
|
||||
|
||||
/* parse the options and device name */
|
||||
if (options) {
|
||||
ret = afs_parse_options(¶ms, options, &dev_name);
|
||||
|
||||
+9
-8
@@ -930,7 +930,7 @@ static int send_cap_msg(struct ceph_mds_session *session,
|
||||
u64 size, u64 max_size,
|
||||
struct timespec *mtime, struct timespec *atime,
|
||||
u64 time_warp_seq,
|
||||
uid_t uid, gid_t gid, umode_t mode,
|
||||
kuid_t uid, kgid_t gid, umode_t mode,
|
||||
u64 xattr_version,
|
||||
struct ceph_buffer *xattrs_buf,
|
||||
u64 follows)
|
||||
@@ -974,8 +974,8 @@ static int send_cap_msg(struct ceph_mds_session *session,
|
||||
ceph_encode_timespec(&fc->atime, atime);
|
||||
fc->time_warp_seq = cpu_to_le32(time_warp_seq);
|
||||
|
||||
fc->uid = cpu_to_le32(uid);
|
||||
fc->gid = cpu_to_le32(gid);
|
||||
fc->uid = cpu_to_le32(from_kuid(&init_user_ns, uid));
|
||||
fc->gid = cpu_to_le32(from_kgid(&init_user_ns, gid));
|
||||
fc->mode = cpu_to_le32(mode);
|
||||
|
||||
fc->xattr_version = cpu_to_le64(xattr_version);
|
||||
@@ -1081,8 +1081,8 @@ static int __send_cap(struct ceph_mds_client *mdsc, struct ceph_cap *cap,
|
||||
struct timespec mtime, atime;
|
||||
int wake = 0;
|
||||
umode_t mode;
|
||||
uid_t uid;
|
||||
gid_t gid;
|
||||
kuid_t uid;
|
||||
kgid_t gid;
|
||||
struct ceph_mds_session *session;
|
||||
u64 xattr_version = 0;
|
||||
struct ceph_buffer *xattr_blob = NULL;
|
||||
@@ -2359,10 +2359,11 @@ static void handle_cap_grant(struct inode *inode, struct ceph_mds_caps *grant,
|
||||
|
||||
if ((issued & CEPH_CAP_AUTH_EXCL) == 0) {
|
||||
inode->i_mode = le32_to_cpu(grant->mode);
|
||||
inode->i_uid = le32_to_cpu(grant->uid);
|
||||
inode->i_gid = le32_to_cpu(grant->gid);
|
||||
inode->i_uid = make_kuid(&init_user_ns, le32_to_cpu(grant->uid));
|
||||
inode->i_gid = make_kgid(&init_user_ns, le32_to_cpu(grant->gid));
|
||||
dout("%p mode 0%o uid.gid %d.%d\n", inode, inode->i_mode,
|
||||
inode->i_uid, inode->i_gid);
|
||||
from_kuid(&init_user_ns, inode->i_uid),
|
||||
from_kgid(&init_user_ns, inode->i_gid));
|
||||
}
|
||||
|
||||
if ((issued & CEPH_CAP_LINK_EXCL) == 0)
|
||||
|
||||
+14
-9
@@ -612,10 +612,11 @@ static int fill_inode(struct inode *inode,
|
||||
|
||||
if ((issued & CEPH_CAP_AUTH_EXCL) == 0) {
|
||||
inode->i_mode = le32_to_cpu(info->mode);
|
||||
inode->i_uid = le32_to_cpu(info->uid);
|
||||
inode->i_gid = le32_to_cpu(info->gid);
|
||||
inode->i_uid = make_kuid(&init_user_ns, le32_to_cpu(info->uid));
|
||||
inode->i_gid = make_kgid(&init_user_ns, le32_to_cpu(info->gid));
|
||||
dout("%p mode 0%o uid.gid %d.%d\n", inode, inode->i_mode,
|
||||
inode->i_uid, inode->i_gid);
|
||||
from_kuid(&init_user_ns, inode->i_uid),
|
||||
from_kgid(&init_user_ns, inode->i_gid));
|
||||
}
|
||||
|
||||
if ((issued & CEPH_CAP_LINK_EXCL) == 0)
|
||||
@@ -1565,26 +1566,30 @@ int ceph_setattr(struct dentry *dentry, struct iattr *attr)
|
||||
|
||||
if (ia_valid & ATTR_UID) {
|
||||
dout("setattr %p uid %d -> %d\n", inode,
|
||||
inode->i_uid, attr->ia_uid);
|
||||
from_kuid(&init_user_ns, inode->i_uid),
|
||||
from_kuid(&init_user_ns, attr->ia_uid));
|
||||
if (issued & CEPH_CAP_AUTH_EXCL) {
|
||||
inode->i_uid = attr->ia_uid;
|
||||
dirtied |= CEPH_CAP_AUTH_EXCL;
|
||||
} else if ((issued & CEPH_CAP_AUTH_SHARED) == 0 ||
|
||||
attr->ia_uid != inode->i_uid) {
|
||||
req->r_args.setattr.uid = cpu_to_le32(attr->ia_uid);
|
||||
!uid_eq(attr->ia_uid, inode->i_uid)) {
|
||||
req->r_args.setattr.uid = cpu_to_le32(
|
||||
from_kuid(&init_user_ns, attr->ia_uid));
|
||||
mask |= CEPH_SETATTR_UID;
|
||||
release |= CEPH_CAP_AUTH_SHARED;
|
||||
}
|
||||
}
|
||||
if (ia_valid & ATTR_GID) {
|
||||
dout("setattr %p gid %d -> %d\n", inode,
|
||||
inode->i_gid, attr->ia_gid);
|
||||
from_kgid(&init_user_ns, inode->i_gid),
|
||||
from_kgid(&init_user_ns, attr->ia_gid));
|
||||
if (issued & CEPH_CAP_AUTH_EXCL) {
|
||||
inode->i_gid = attr->ia_gid;
|
||||
dirtied |= CEPH_CAP_AUTH_EXCL;
|
||||
} else if ((issued & CEPH_CAP_AUTH_SHARED) == 0 ||
|
||||
attr->ia_gid != inode->i_gid) {
|
||||
req->r_args.setattr.gid = cpu_to_le32(attr->ia_gid);
|
||||
!gid_eq(attr->ia_gid, inode->i_gid)) {
|
||||
req->r_args.setattr.gid = cpu_to_le32(
|
||||
from_kgid(&init_user_ns, attr->ia_gid));
|
||||
mask |= CEPH_SETATTR_GID;
|
||||
release |= CEPH_CAP_AUTH_SHARED;
|
||||
}
|
||||
|
||||
@@ -1658,8 +1658,8 @@ static struct ceph_msg *create_request_message(struct ceph_mds_client *mdsc,
|
||||
|
||||
head->mdsmap_epoch = cpu_to_le32(mdsc->mdsmap->m_epoch);
|
||||
head->op = cpu_to_le32(req->r_op);
|
||||
head->caller_uid = cpu_to_le32(req->r_uid);
|
||||
head->caller_gid = cpu_to_le32(req->r_gid);
|
||||
head->caller_uid = cpu_to_le32(from_kuid(&init_user_ns, req->r_uid));
|
||||
head->caller_gid = cpu_to_le32(from_kgid(&init_user_ns, req->r_gid));
|
||||
head->args = req->r_args;
|
||||
|
||||
ceph_encode_filepath(&p, end, ino1, path1);
|
||||
|
||||
@@ -184,8 +184,8 @@ struct ceph_mds_request {
|
||||
|
||||
union ceph_mds_request_args r_args;
|
||||
int r_fmode; /* file mode, if expecting cap */
|
||||
uid_t r_uid;
|
||||
gid_t r_gid;
|
||||
kuid_t r_uid;
|
||||
kgid_t r_gid;
|
||||
|
||||
/* for choosing which mds to send this request to */
|
||||
int r_direct_mode;
|
||||
|
||||
+2
-2
@@ -138,8 +138,8 @@ struct ceph_cap_snap {
|
||||
struct ceph_snap_context *context;
|
||||
|
||||
umode_t mode;
|
||||
uid_t uid;
|
||||
gid_t gid;
|
||||
kuid_t uid;
|
||||
kgid_t gid;
|
||||
|
||||
struct ceph_buffer *xattr_blob;
|
||||
u64 xattr_version;
|
||||
|
||||
@@ -55,10 +55,10 @@ struct cifs_sb_info {
|
||||
unsigned int wsize;
|
||||
unsigned long actimeo; /* attribute cache timeout (jiffies) */
|
||||
atomic_t active;
|
||||
uid_t mnt_uid;
|
||||
gid_t mnt_gid;
|
||||
uid_t mnt_backupuid;
|
||||
gid_t mnt_backupgid;
|
||||
kuid_t mnt_uid;
|
||||
kgid_t mnt_gid;
|
||||
kuid_t mnt_backupuid;
|
||||
kgid_t mnt_backupgid;
|
||||
umode_t mnt_file_mode;
|
||||
umode_t mnt_dir_mode;
|
||||
unsigned int mnt_cifs_flags;
|
||||
|
||||
@@ -149,10 +149,12 @@ cifs_get_spnego_key(struct cifs_ses *sesInfo)
|
||||
goto out;
|
||||
|
||||
dp = description + strlen(description);
|
||||
sprintf(dp, ";uid=0x%x", sesInfo->linux_uid);
|
||||
sprintf(dp, ";uid=0x%x",
|
||||
from_kuid_munged(&init_user_ns, sesInfo->linux_uid));
|
||||
|
||||
dp = description + strlen(description);
|
||||
sprintf(dp, ";creduid=0x%x", sesInfo->cred_uid);
|
||||
sprintf(dp, ";creduid=0x%x",
|
||||
from_kuid_munged(&init_user_ns, sesInfo->cred_uid));
|
||||
|
||||
if (sesInfo->user_name) {
|
||||
dp = description + strlen(description);
|
||||
|
||||
+32
-15
@@ -266,8 +266,8 @@ sid_to_id(struct cifs_sb_info *cifs_sb, struct cifs_sid *psid,
|
||||
struct key *sidkey;
|
||||
char *sidstr;
|
||||
const struct cred *saved_cred;
|
||||
uid_t fuid = cifs_sb->mnt_uid;
|
||||
gid_t fgid = cifs_sb->mnt_gid;
|
||||
kuid_t fuid = cifs_sb->mnt_uid;
|
||||
kgid_t fgid = cifs_sb->mnt_gid;
|
||||
|
||||
/*
|
||||
* If we have too many subauthorities, then something is really wrong.
|
||||
@@ -297,6 +297,7 @@ sid_to_id(struct cifs_sb_info *cifs_sb, struct cifs_sid *psid,
|
||||
* probably a safe assumption but might be better to check based on
|
||||
* sidtype.
|
||||
*/
|
||||
BUILD_BUG_ON(sizeof(uid_t) != sizeof(gid_t));
|
||||
if (sidkey->datalen != sizeof(uid_t)) {
|
||||
rc = -EIO;
|
||||
cFYI(1, "%s: Downcall contained malformed key "
|
||||
@@ -305,10 +306,21 @@ sid_to_id(struct cifs_sb_info *cifs_sb, struct cifs_sid *psid,
|
||||
goto out_key_put;
|
||||
}
|
||||
|
||||
if (sidtype == SIDOWNER)
|
||||
memcpy(&fuid, &sidkey->payload.value, sizeof(uid_t));
|
||||
else
|
||||
memcpy(&fgid, &sidkey->payload.value, sizeof(gid_t));
|
||||
if (sidtype == SIDOWNER) {
|
||||
kuid_t uid;
|
||||
uid_t id;
|
||||
memcpy(&id, &sidkey->payload.value, sizeof(uid_t));
|
||||
uid = make_kuid(&init_user_ns, id);
|
||||
if (uid_valid(uid))
|
||||
fuid = uid;
|
||||
} else {
|
||||
kgid_t gid;
|
||||
gid_t id;
|
||||
memcpy(&id, &sidkey->payload.value, sizeof(gid_t));
|
||||
gid = make_kgid(&init_user_ns, id);
|
||||
if (gid_valid(gid))
|
||||
fgid = gid;
|
||||
}
|
||||
|
||||
out_key_put:
|
||||
key_put(sidkey);
|
||||
@@ -346,7 +358,8 @@ init_cifs_idmap(void)
|
||||
if (!cred)
|
||||
return -ENOMEM;
|
||||
|
||||
keyring = keyring_alloc(".cifs_idmap", 0, 0, cred,
|
||||
keyring = keyring_alloc(".cifs_idmap",
|
||||
GLOBAL_ROOT_UID, GLOBAL_ROOT_GID, cred,
|
||||
(KEY_POS_ALL & ~KEY_POS_SETATTR) |
|
||||
KEY_USR_VIEW | KEY_USR_READ,
|
||||
KEY_ALLOC_NOT_IN_QUOTA, NULL);
|
||||
@@ -774,7 +787,7 @@ static int parse_sec_desc(struct cifs_sb_info *cifs_sb,
|
||||
|
||||
/* Convert permission bits from mode to equivalent CIFS ACL */
|
||||
static int build_sec_desc(struct cifs_ntsd *pntsd, struct cifs_ntsd *pnntsd,
|
||||
__u32 secdesclen, __u64 nmode, uid_t uid, gid_t gid, int *aclflag)
|
||||
__u32 secdesclen, __u64 nmode, kuid_t uid, kgid_t gid, int *aclflag)
|
||||
{
|
||||
int rc = 0;
|
||||
__u32 dacloffset;
|
||||
@@ -806,17 +819,19 @@ static int build_sec_desc(struct cifs_ntsd *pntsd, struct cifs_ntsd *pnntsd,
|
||||
*aclflag = CIFS_ACL_DACL;
|
||||
} else {
|
||||
memcpy(pnntsd, pntsd, secdesclen);
|
||||
if (uid != NO_CHANGE_32) { /* chown */
|
||||
if (uid_valid(uid)) { /* chown */
|
||||
uid_t id;
|
||||
owner_sid_ptr = (struct cifs_sid *)((char *)pnntsd +
|
||||
le32_to_cpu(pnntsd->osidoffset));
|
||||
nowner_sid_ptr = kmalloc(sizeof(struct cifs_sid),
|
||||
GFP_KERNEL);
|
||||
if (!nowner_sid_ptr)
|
||||
return -ENOMEM;
|
||||
rc = id_to_sid(uid, SIDOWNER, nowner_sid_ptr);
|
||||
id = from_kuid(&init_user_ns, uid);
|
||||
rc = id_to_sid(id, SIDOWNER, nowner_sid_ptr);
|
||||
if (rc) {
|
||||
cFYI(1, "%s: Mapping error %d for owner id %d",
|
||||
__func__, rc, uid);
|
||||
__func__, rc, id);
|
||||
kfree(nowner_sid_ptr);
|
||||
return rc;
|
||||
}
|
||||
@@ -824,17 +839,19 @@ static int build_sec_desc(struct cifs_ntsd *pntsd, struct cifs_ntsd *pnntsd,
|
||||
kfree(nowner_sid_ptr);
|
||||
*aclflag = CIFS_ACL_OWNER;
|
||||
}
|
||||
if (gid != NO_CHANGE_32) { /* chgrp */
|
||||
if (gid_valid(gid)) { /* chgrp */
|
||||
gid_t id;
|
||||
group_sid_ptr = (struct cifs_sid *)((char *)pnntsd +
|
||||
le32_to_cpu(pnntsd->gsidoffset));
|
||||
ngroup_sid_ptr = kmalloc(sizeof(struct cifs_sid),
|
||||
GFP_KERNEL);
|
||||
if (!ngroup_sid_ptr)
|
||||
return -ENOMEM;
|
||||
rc = id_to_sid(gid, SIDGROUP, ngroup_sid_ptr);
|
||||
id = from_kgid(&init_user_ns, gid);
|
||||
rc = id_to_sid(id, SIDGROUP, ngroup_sid_ptr);
|
||||
if (rc) {
|
||||
cFYI(1, "%s: Mapping error %d for group id %d",
|
||||
__func__, rc, gid);
|
||||
__func__, rc, id);
|
||||
kfree(ngroup_sid_ptr);
|
||||
return rc;
|
||||
}
|
||||
@@ -1002,7 +1019,7 @@ cifs_acl_to_fattr(struct cifs_sb_info *cifs_sb, struct cifs_fattr *fattr,
|
||||
/* Convert mode bits to an ACL so we can update the ACL on the server */
|
||||
int
|
||||
id_mode_to_cifs_acl(struct inode *inode, const char *path, __u64 nmode,
|
||||
uid_t uid, gid_t gid)
|
||||
kuid_t uid, kgid_t gid)
|
||||
{
|
||||
int rc = 0;
|
||||
int aclflag = CIFS_ACL_DACL; /* default flag to set */
|
||||
|
||||
+10
-4
@@ -375,13 +375,15 @@ cifs_show_options(struct seq_file *s, struct dentry *root)
|
||||
(int)(srcaddr->sa_family));
|
||||
}
|
||||
|
||||
seq_printf(s, ",uid=%u", cifs_sb->mnt_uid);
|
||||
seq_printf(s, ",uid=%u",
|
||||
from_kuid_munged(&init_user_ns, cifs_sb->mnt_uid));
|
||||
if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_OVERR_UID)
|
||||
seq_printf(s, ",forceuid");
|
||||
else
|
||||
seq_printf(s, ",noforceuid");
|
||||
|
||||
seq_printf(s, ",gid=%u", cifs_sb->mnt_gid);
|
||||
seq_printf(s, ",gid=%u",
|
||||
from_kgid_munged(&init_user_ns, cifs_sb->mnt_gid));
|
||||
if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_OVERR_GID)
|
||||
seq_printf(s, ",forcegid");
|
||||
else
|
||||
@@ -436,9 +438,13 @@ cifs_show_options(struct seq_file *s, struct dentry *root)
|
||||
if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_PERM)
|
||||
seq_printf(s, ",noperm");
|
||||
if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_BACKUPUID)
|
||||
seq_printf(s, ",backupuid=%u", cifs_sb->mnt_backupuid);
|
||||
seq_printf(s, ",backupuid=%u",
|
||||
from_kuid_munged(&init_user_ns,
|
||||
cifs_sb->mnt_backupuid));
|
||||
if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_BACKUPGID)
|
||||
seq_printf(s, ",backupgid=%u", cifs_sb->mnt_backupgid);
|
||||
seq_printf(s, ",backupgid=%u",
|
||||
from_kgid_munged(&init_user_ns,
|
||||
cifs_sb->mnt_backupgid));
|
||||
|
||||
seq_printf(s, ",rsize=%u", cifs_sb->rsize);
|
||||
seq_printf(s, ",wsize=%u", cifs_sb->wsize);
|
||||
|
||||
+11
-11
@@ -400,11 +400,11 @@ struct smb_vol {
|
||||
char *iocharset; /* local code page for mapping to and from Unicode */
|
||||
char source_rfc1001_name[RFC1001_NAME_LEN_WITH_NULL]; /* clnt nb name */
|
||||
char target_rfc1001_name[RFC1001_NAME_LEN_WITH_NULL]; /* srvr nb name */
|
||||
uid_t cred_uid;
|
||||
uid_t linux_uid;
|
||||
gid_t linux_gid;
|
||||
uid_t backupuid;
|
||||
gid_t backupgid;
|
||||
kuid_t cred_uid;
|
||||
kuid_t linux_uid;
|
||||
kgid_t linux_gid;
|
||||
kuid_t backupuid;
|
||||
kgid_t backupgid;
|
||||
umode_t file_mode;
|
||||
umode_t dir_mode;
|
||||
unsigned secFlg;
|
||||
@@ -703,8 +703,8 @@ struct cifs_ses {
|
||||
char *serverNOS; /* name of network operating system of server */
|
||||
char *serverDomain; /* security realm of server */
|
||||
__u64 Suid; /* remote smb uid */
|
||||
uid_t linux_uid; /* overriding owner of files on the mount */
|
||||
uid_t cred_uid; /* owner of credentials */
|
||||
kuid_t linux_uid; /* overriding owner of files on the mount */
|
||||
kuid_t cred_uid; /* owner of credentials */
|
||||
unsigned int capabilities;
|
||||
char serverName[SERVER_NAME_LEN_WITH_NULL * 2]; /* BB make bigger for
|
||||
TCP names - will ipv6 and sctp addresses fit? */
|
||||
@@ -838,7 +838,7 @@ struct cifs_tcon {
|
||||
*/
|
||||
struct tcon_link {
|
||||
struct rb_node tl_rbnode;
|
||||
uid_t tl_uid;
|
||||
kuid_t tl_uid;
|
||||
unsigned long tl_flags;
|
||||
#define TCON_LINK_MASTER 0
|
||||
#define TCON_LINK_PENDING 1
|
||||
@@ -931,7 +931,7 @@ struct cifsFileInfo {
|
||||
struct list_head tlist; /* pointer to next fid owned by tcon */
|
||||
struct list_head flist; /* next fid (file instance) for this inode */
|
||||
struct cifs_fid_locks *llist; /* brlocks held by this fid */
|
||||
unsigned int uid; /* allows finding which FileInfo structure */
|
||||
kuid_t uid; /* allows finding which FileInfo structure */
|
||||
__u32 pid; /* process id who opened file */
|
||||
struct cifs_fid fid; /* file id from remote */
|
||||
/* BB add lock scope info here if needed */ ;
|
||||
@@ -1245,8 +1245,8 @@ struct cifs_fattr {
|
||||
u64 cf_eof;
|
||||
u64 cf_bytes;
|
||||
u64 cf_createtime;
|
||||
uid_t cf_uid;
|
||||
gid_t cf_gid;
|
||||
kuid_t cf_uid;
|
||||
kgid_t cf_gid;
|
||||
umode_t cf_mode;
|
||||
dev_t cf_rdev;
|
||||
unsigned int cf_nlink;
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user