Example #1
0
/*
 * Check for LL_SBI_FILE_SECCTX before calling.
 */
int ll_dentry_init_security(struct dentry *dentry, int mode, struct qstr *name,
			    const char **secctx_name, void **secctx,
			    __u32 *secctx_size)
{
#ifdef HAVE_SECURITY_DENTRY_INIT_SECURITY
	int rc;

	/* security_dentry_init_security() is strange. Like
	 * security_inode_init_security() it may return a context (provided a
	 * Linux security module is enabled) but unlike
	 * security_inode_init_security() it does not return to us the name of
	 * the extended attribute to store the context under (for example
	 * "security.selinux"). So we only call it when we think we know what
	 * the name of the extended attribute will be. This is OK-ish since
	 * SELinux is the only module that implements
	 * security_dentry_init_security(). Note that the NFS client code just
	 * calls it and assumes that if anything is returned then it must come
	 * from SELinux. */

	if (!selinux_is_enabled())
		return 0;

	rc = security_dentry_init_security(dentry, mode, name, secctx,
					   secctx_size);
	if (rc < 0)
		return rc;

	*secctx_name = XATTR_NAME_SELINUX;
#endif /* HAVE_SECURITY_DENTRY_INIT_SECURITY */

	return 0;
}
Example #2
0
/**
 * Get security context xattr name used by policy.
 *
 * \retval >= 0     length of xattr name
 * \retval < 0      failure to get security context xattr name
 */
int
ll_listsecurity(struct inode *inode, char *secctx_name, size_t secctx_name_size)
{
	int rc;

	if (!selinux_is_enabled())
		return 0;

#ifdef HAVE_SECURITY_INODE_LISTSECURITY
	rc = security_inode_listsecurity(inode, secctx_name, secctx_name_size);
	if (rc >= secctx_name_size)
		rc = -ERANGE;
	else if (rc >= 0)
		secctx_name[rc] = '\0';
	return rc;
#else /* !HAVE_SECURITY_INODE_LISTSECURITY */
	rc = sizeof(XATTR_NAME_SELINUX);
	if (secctx_name && rc < secctx_name_size) {
		memcpy(secctx_name, XATTR_NAME_SELINUX, rc);
		secctx_name[rc] = '\0';
	} else {
		rc = -ERANGE;
	}
	return rc;
#endif /* HAVE_SECURITY_INODE_LISTSECURITY */
}
Example #3
0
/**
 * Initializes security context
 *
 * Get security context of @inode in @dir,
 * and put it in 'security.xxx' xattr of @dentry.
 *
 * \retval 0        success, or SELinux is disabled
 * \retval -ENOMEM  if no memory could be allocated for xattr name
 * \retval < 0      failure to get security context or set xattr
 */
int
ll_inode_init_security(struct dentry *dentry, struct inode *inode,
		       struct inode *dir)
{
	char *full_name;
	void *value;
	char *name;
	size_t len;
	int err;

	if (!selinux_is_enabled())
		return 0;

	err = ll_security_inode_init_security(inode, dir, &name, &value, &len,
					      NULL, dentry);
	if (err != 0) {
		if (err == -EOPNOTSUPP)
			return 0;
		return err;
	}

	full_name = kasprintf(GFP_KERNEL, "%s%s", XATTR_SECURITY_PREFIX, name);
	if (!full_name)
		GOTO(out_free, err = -ENOMEM);

	err = __vfs_setxattr(dentry, inode, full_name, value, len,
			     XATTR_CREATE);
	kfree(full_name);
out_free:
	kfree(name);
	kfree(value);

	return err;
}
Example #4
0
/**
 * Initializes security context
 *
 * Get security context of @inode in @dir,
 * and put it in 'security.xxx' xattr of @dentry.
 *
 * \retval 0        success, or SELinux is disabled
 * \retval -ENOMEM  if no memory could be allocated for xattr name
 * \retval < 0      failure to get security context or set xattr
 */
int
ll_inode_init_security(struct dentry *dentry, struct inode *inode,
		       struct inode *dir)
{
	if (!selinux_is_enabled())
		return 0;

	return ll_security_inode_init_security(inode, dir, NULL, NULL, 0,
					       &ll_initxattrs, dentry);
}
Example #5
0
static int __init selinux_mod_init(void)
{

	selinux_is_enabled_t selinux_is_enabled = (selinux_is_enabled_t)kallsyms_lookup_name("selinux_is_enabled");

	printk(KERN_INFO "[%s] module loaded\n", __this_module.name);

	if(!selinux_is_enabled)
	{
		printk(KERN_INFO "[%s] Failed to find selinux_is_enabled\n", __this_module.name);
		return 1;
	}

	status_enabled = selinux_is_enabled();
	printk(KERN_INFO "[%s] old selinux_enabled: %lu\n", __this_module.name,  status_enabled);

	selinux_enabled = (unsigned long*)kallsyms_lookup_name("selinux_enabled");
	if(!selinux_enabled)
	{
		printk(KERN_INFO "[%s] Failed to find selinux_enabled address\n", __this_module.name);
		return 1;

	}

	*selinux_enabled = 0U;
	printk(KERN_INFO "[%s] current selinux_enabled: %u\n", __this_module.name,  selinux_is_enabled());

	selinux_enforcing = (unsigned long*)kallsyms_lookup_name("selinux_enforcing");
	if(!selinux_enforcing )
	{
		printk(KERN_INFO "[%s] Failed to find selinux_enforcing address\n", __this_module.name);
		return 1;
	}

	status_enforcing = *selinux_enforcing;
	printk(KERN_INFO "[%s] old selinux_enforcing: %lu\n", __this_module.name, status_enforcing);

	*selinux_enforcing = 0U;
	printk(KERN_INFO "[%s] current selinux_enforcing: %lu\n", __this_module.name, *selinux_enforcing);

	return 0;
}
Example #6
0
File: xattr.c Project: IDM350/linux
static
int ll_getxattr_common(struct inode *inode, const char *name,
		       void *buffer, size_t size, __u64 valid)
{
	struct ll_sb_info *sbi = ll_i2sbi(inode);
	struct ptlrpc_request *req = NULL;
	struct mdt_body *body;
	int xattr_type, rc;
	void *xdata;
	struct obd_capa *oc;
	struct rmtacl_ctl_entry *rce = NULL;

	CDEBUG(D_VFSTRACE, "VFS Op:inode=%lu/%u(%p)\n",
	       inode->i_ino, inode->i_generation, inode);

	/* listxattr have slightly different behavior from of ext3:
	 * without 'user_xattr' ext3 will list all xattr names but
	 * filtered out "^user..*"; we list them all for simplicity.
	 */
	if (!name) {
		xattr_type = XATTR_OTHER_T;
		goto do_getxattr;
	}

	xattr_type = get_xattr_type(name);
	rc = xattr_type_filter(sbi, xattr_type);
	if (rc)
		return rc;

	/* b15587: ignore security.capability xattr for now */
	if ((xattr_type == XATTR_SECURITY_T &&
	    strcmp(name, "security.capability") == 0))
		return -ENODATA;

	/* LU-549:  Disable security.selinux when selinux is disabled */
	if (xattr_type == XATTR_SECURITY_T && !selinux_is_enabled() &&
	    strcmp(name, "security.selinux") == 0)
		return -EOPNOTSUPP;

#ifdef CONFIG_FS_POSIX_ACL
	if (sbi->ll_flags & LL_SBI_RMT_CLIENT &&
	    (xattr_type == XATTR_ACL_ACCESS_T ||
	    xattr_type == XATTR_ACL_DEFAULT_T)) {
		rce = rct_search(&sbi->ll_rct, current_pid());
		if (rce == NULL ||
		    (rce->rce_ops != RMT_LSETFACL &&
		    rce->rce_ops != RMT_LGETFACL &&
		    rce->rce_ops != RMT_RSETFACL &&
		    rce->rce_ops != RMT_RGETFACL))
			return -EOPNOTSUPP;
	}

	/* posix acl is under protection of LOOKUP lock. when calling to this,
	 * we just have path resolution to the target inode, so we have great
	 * chance that cached ACL is uptodate.
	 */
	if (xattr_type == XATTR_ACL_ACCESS_T &&
	    !(sbi->ll_flags & LL_SBI_RMT_CLIENT)) {
		struct ll_inode_info *lli = ll_i2info(inode);
		struct posix_acl *acl;

		spin_lock(&lli->lli_lock);
		acl = posix_acl_dup(lli->lli_posix_acl);
		spin_unlock(&lli->lli_lock);

		if (!acl)
			return -ENODATA;

		rc = posix_acl_to_xattr(&init_user_ns, acl, buffer, size);
		posix_acl_release(acl);
		return rc;
	}
	if (xattr_type == XATTR_ACL_DEFAULT_T && !S_ISDIR(inode->i_mode))
		return -ENODATA;
#endif

do_getxattr:
	if (sbi->ll_xattr_cache_enabled && (rce == NULL ||
					    rce->rce_ops == RMT_LGETFACL ||
					    rce->rce_ops == RMT_LSETFACL)) {
		rc = ll_xattr_cache_get(inode, name, buffer, size, valid);
		if (rc < 0)
			GOTO(out_xattr, rc);
	} else {
		oc = ll_mdscapa_get(inode);
		rc = md_getxattr(sbi->ll_md_exp, ll_inode2fid(inode), oc,
				valid | (rce ? rce_ops2valid(rce->rce_ops) : 0),
				name, NULL, 0, size, 0, &req);
		capa_put(oc);

		if (rc < 0)
			GOTO(out_xattr, rc);

		body = req_capsule_server_get(&req->rq_pill, &RMF_MDT_BODY);
		LASSERT(body);

		/* only detect the xattr size */
		if (size == 0)
			GOTO(out, rc = body->eadatasize);

		if (size < body->eadatasize) {
			CERROR("server bug: replied size %u > %u\n",
				body->eadatasize, (int)size);
			GOTO(out, rc = -ERANGE);
		}

		if (body->eadatasize == 0)
			GOTO(out, rc = -ENODATA);

		/* do not need swab xattr data */
		xdata = req_capsule_server_sized_get(&req->rq_pill, &RMF_EADATA,
							body->eadatasize);
		if (!xdata)
			GOTO(out, rc = -EFAULT);

		memcpy(buffer, xdata, body->eadatasize);
		rc = body->eadatasize;
	}

#ifdef CONFIG_FS_POSIX_ACL
	if (rce && rce->rce_ops == RMT_LSETFACL) {
		ext_acl_xattr_header *acl;

		acl = lustre_posix_acl_xattr_2ext(
					(posix_acl_xattr_header *)buffer, rc);
		if (IS_ERR(acl))
			GOTO(out, rc = PTR_ERR(acl));

		rc = ee_add(&sbi->ll_et, current_pid(), ll_inode2fid(inode),
			    xattr_type, acl);
		if (unlikely(rc < 0)) {
			lustre_ext_acl_xattr_free(acl);
			GOTO(out, rc);
		}
	}
#endif

out_xattr:
	if (rc == -EOPNOTSUPP && xattr_type == XATTR_USER_T) {
		LCONSOLE_INFO(
			"%s: disabling user_xattr feature because it is not supported on the server: rc = %d\n",
			ll_get_fsname(inode->i_sb, NULL, 0), rc);
		sbi->ll_flags &= ~LL_SBI_USER_XATTR;
	}
out:
	ptlrpc_req_finished(req);
	return rc;
}
Example #7
0
File: xattr.c Project: IDM350/linux
static
int ll_setxattr_common(struct inode *inode, const char *name,
		       const void *value, size_t size,
		       int flags, __u64 valid)
{
	struct ll_sb_info *sbi = ll_i2sbi(inode);
	struct ptlrpc_request *req = NULL;
	int xattr_type, rc;
	struct obd_capa *oc;
	struct rmtacl_ctl_entry *rce = NULL;
#ifdef CONFIG_FS_POSIX_ACL
	posix_acl_xattr_header *new_value = NULL;
	ext_acl_xattr_header *acl = NULL;
#endif
	const char *pv = value;

	xattr_type = get_xattr_type(name);
	rc = xattr_type_filter(sbi, xattr_type);
	if (rc)
		return rc;

	/* b10667: ignore lustre special xattr for now */
	if ((xattr_type == XATTR_TRUSTED_T && strcmp(name, "trusted.lov") == 0) ||
	    (xattr_type == XATTR_LUSTRE_T && strcmp(name, "lustre.lov") == 0))
		return 0;

	/* b15587: ignore security.capability xattr for now */
	if ((xattr_type == XATTR_SECURITY_T &&
	    strcmp(name, "security.capability") == 0))
		return 0;

	/* LU-549:  Disable security.selinux when selinux is disabled */
	if (xattr_type == XATTR_SECURITY_T && !selinux_is_enabled() &&
	    strcmp(name, "security.selinux") == 0)
		return -EOPNOTSUPP;

#ifdef CONFIG_FS_POSIX_ACL
	if (sbi->ll_flags & LL_SBI_RMT_CLIENT &&
	    (xattr_type == XATTR_ACL_ACCESS_T ||
	    xattr_type == XATTR_ACL_DEFAULT_T)) {
		rce = rct_search(&sbi->ll_rct, current_pid());
		if (rce == NULL ||
		    (rce->rce_ops != RMT_LSETFACL &&
		    rce->rce_ops != RMT_RSETFACL))
			return -EOPNOTSUPP;

		if (rce->rce_ops == RMT_LSETFACL) {
			struct eacl_entry *ee;

			ee = et_search_del(&sbi->ll_et, current_pid(),
					   ll_inode2fid(inode), xattr_type);
			LASSERT(ee != NULL);
			if (valid & OBD_MD_FLXATTR) {
				acl = lustre_acl_xattr_merge2ext(
						(posix_acl_xattr_header *)value,
						size, ee->ee_acl);
				if (IS_ERR(acl)) {
					ee_free(ee);
					return PTR_ERR(acl);
				}
				size =  CFS_ACL_XATTR_SIZE(\
						le32_to_cpu(acl->a_count), \
						ext_acl_xattr);
				pv = (const char *)acl;
			}
			ee_free(ee);
		} else if (rce->rce_ops == RMT_RSETFACL) {
			size = lustre_posix_acl_xattr_filter(
						(posix_acl_xattr_header *)value,
						size, &new_value);
			if (unlikely(size < 0))
				return size;

			pv = (const char *)new_value;
		} else
			return -EOPNOTSUPP;

		valid |= rce_ops2valid(rce->rce_ops);
	}
#endif
	if (sbi->ll_xattr_cache_enabled &&
	    (rce == NULL || rce->rce_ops == RMT_LSETFACL)) {
		rc = ll_xattr_cache_update(inode, name, pv, size, valid, flags);
	} else {
		oc = ll_mdscapa_get(inode);
		rc = md_setxattr(sbi->ll_md_exp, ll_inode2fid(inode), oc,
				valid, name, pv, size, 0, flags,
				ll_i2suppgid(inode), &req);
		capa_put(oc);
	}

#ifdef CONFIG_FS_POSIX_ACL
	if (new_value != NULL)
		lustre_posix_acl_xattr_free(new_value, size);
	if (acl != NULL)
		lustre_ext_acl_xattr_free(acl);
#endif
	if (rc) {
		if (rc == -EOPNOTSUPP && xattr_type == XATTR_USER_T) {
			LCONSOLE_INFO("Disabling user_xattr feature because "
				      "it is not supported on the server\n");
			sbi->ll_flags &= ~LL_SBI_USER_XATTR;
		}
		return rc;
	}

	ptlrpc_req_finished(req);
	return 0;
}