Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit c948390f authored by Gregoire Pichon's avatar Gregoire Pichon Committed by Greg Kroah-Hartman
Browse files

staging: lustre: llite: fix inconsistencies of root squash feature



Root squash exhibits inconsistent behaviour on a client when
enabled. If a file is not cached on the client, then root will get
a permission denied error when accessing the file. When
the file has recently been accessed by a regular user and is
still in cache, root will be able to access the file without error
because the permission check is only done by the client that
isn't aware of root squash.

While the only real security benefit from root squash is to deny
clients access to files owned by root itself, it also makes sense
to treat file access on the client in a consistent manner
regardless of whether the file is in cache or not.

This patch adds root squash settings to llite so that client is able
to apply root squashing when it is relevant.

Configuration of MDT root squash settings will automatically be
applied to llite config log as well.

Update cfs_str2num_check() routine by removing any modification
of the specified string parameter. Since string can come from ls_str
field of a lstr structure, this avoids inconsistent ls_len field.

Signed-off-by: default avatarGregoire Pichon <gregoire.pichon@bull.net>
Intel-bug-id: https://jira.hpdd.intel.com/browse/LU-1778
Reviewed-on: http://review.whamcloud.com/5700


Reviewed-by: default avatarAndreas Dilger <andreas.dilger@intel.com>
Reviewed-by: default avatarNiu Yawei <yawei.niu@intel.com>
Reviewed-by: default avatarOleg Drokin <oleg.drokin@intel.com>
Signed-off-by: default avatarJames Simmons <jsimmons@infradead.org>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent d097d67b
Loading
Loading
Loading
Loading
+0 −2
Original line number Diff line number Diff line
@@ -229,8 +229,6 @@ cfs_str2num_check(char *str, int nob, unsigned *num,
	char *endp, cache;
	int rc;

	str = cfs_trimwhite(str);

	/**
	 * kstrouint can only handle strings composed
	 * of only numbers. We need to scan the string
+6 −0
Original line number Diff line number Diff line
@@ -681,6 +681,12 @@ static struct lustre_attr lustre_attr_##name = __ATTR(name, mode, show, store)

extern const struct sysfs_ops lustre_sysfs_ops;

struct root_squash_info;
int lprocfs_wr_root_squash(const char *buffer, unsigned long count,
			   struct root_squash_info *squash, char *name);
int lprocfs_wr_nosquash_nids(const char *buffer, unsigned long count,
			     struct root_squash_info *squash, char *name);

/* all quota proc functions */
int lprocfs_quota_rd_bunit(char *page, char **start,
			   loff_t off, int count,
+9 −0
Original line number Diff line number Diff line
@@ -1759,4 +1759,13 @@ extern spinlock_t obd_types_lock;
/* prng.c */
#define ll_generate_random_uuid(uuid_out) cfs_get_random_bytes(uuid_out, sizeof(class_uuid_t))

/* root squash info */
struct rw_semaphore;
struct root_squash_info {
	uid_t			rsi_uid;
	gid_t			rsi_gid;
	struct list_head	rsi_nosquash_nids;
	struct rw_semaphore	rsi_sem;
};

#endif /* __LINUX_OBD_CLASS_H */
+44 −0
Original line number Diff line number Diff line
@@ -41,6 +41,7 @@
#include "../include/lustre_lite.h"
#include <linux/pagemap.h>
#include <linux/file.h>
#include <linux/sched.h>
#include <linux/mount.h>
#include "llite_internal.h"
#include "../include/lustre/ll_fiemap.h"
@@ -3289,6 +3290,12 @@ struct posix_acl *ll_get_acl(struct inode *inode, int type)

int ll_inode_permission(struct inode *inode, int mask)
{
	struct ll_sb_info *sbi;
	struct root_squash_info *squash;
	const struct cred *old_cred = NULL;
	struct cred *cred = NULL;
	bool squash_id = false;
	cfs_cap_t cap;
	int rc = 0;

	if (mask & MAY_NOT_BLOCK)
@@ -3308,9 +3315,46 @@ int ll_inode_permission(struct inode *inode, int mask)
	CDEBUG(D_VFSTRACE, "VFS Op:inode="DFID"(%p), inode mode %x mask %o\n",
	       PFID(ll_inode2fid(inode)), inode, inode->i_mode, mask);

	/* squash fsuid/fsgid if needed */
	sbi = ll_i2sbi(inode);
	squash = &sbi->ll_squash;
	if (unlikely(squash->rsi_uid &&
		     uid_eq(current_fsuid(), GLOBAL_ROOT_UID) &&
		     !(sbi->ll_flags & LL_SBI_NOROOTSQUASH))) {
		squash_id = true;
	}

	if (squash_id) {
		CDEBUG(D_OTHER, "squash creds (%d:%d)=>(%d:%d)\n",
		       __kuid_val(current_fsuid()), __kgid_val(current_fsgid()),
		       squash->rsi_uid, squash->rsi_gid);

		/*
		 * update current process's credentials
		 * and FS capability
		 */
		cred = prepare_creds();
		if (!cred)
			return -ENOMEM;

		cred->fsuid = make_kuid(&init_user_ns, squash->rsi_uid);
		cred->fsgid = make_kgid(&init_user_ns, squash->rsi_gid);
		for (cap = 0; cap < sizeof(cfs_cap_t) * 8; cap++) {
			if ((1 << cap) & CFS_CAP_FS_MASK)
				cap_lower(cred->cap_effective, cap);
		}
		old_cred = override_creds(cred);
	}

	ll_stats_ops_tally(ll_i2sbi(inode), LPROC_LL_INODE_PERM, 1);
	rc = generic_permission(inode, mask);

	/* restore current process's credentials and FS capability */
	if (squash_id) {
		revert_creds(old_cred);
		put_cred(cred);
	}

	return rc;
}

+6 −0
Original line number Diff line number Diff line
@@ -412,6 +412,7 @@ enum stats_track_type {
#define LL_SBI_LAYOUT_LOCK    0x20000 /* layout lock support */
#define LL_SBI_USER_FID2PATH  0x40000 /* allow fid2path by unprivileged users */
#define LL_SBI_XATTR_CACHE    0x80000 /* support for xattr cache */
#define LL_SBI_NOROOTSQUASH	0x100000 /* do not apply root squash */

#define LL_SBI_FLAGS {	\
	"nolck",	\
@@ -434,6 +435,7 @@ enum stats_track_type {
	"layout",	\
	"user_fid2path",\
	"xattr",	\
	"norootsquash",	\
}

struct ll_sb_info {
@@ -500,6 +502,9 @@ struct ll_sb_info {
	dev_t			  ll_sdev_orig; /* save s_dev before assign for
						 * clustered nfs
						 */
	/* root squash */
	struct root_squash_info	  ll_squash;

	__kernel_fsid_t		  ll_fsid;
	struct kobject		 ll_kobj; /* sysfs object */
	struct super_block	*ll_sb; /* struct super_block (for sysfs code)*/
@@ -798,6 +803,7 @@ struct md_op_data *ll_prep_md_op_data(struct md_op_data *op_data,
void ll_finish_md_op_data(struct md_op_data *op_data);
int ll_get_obd_name(struct inode *inode, unsigned int cmd, unsigned long arg);
char *ll_get_fsname(struct super_block *sb, char *buf, int buflen);
void ll_compute_rootsquash_state(struct ll_sb_info *sbi);
void ll_open_cleanup(struct super_block *sb, struct ptlrpc_request *open_req);

/* llite/llite_nfs.c */
Loading