Beispiel #1
0
int aa_new_mount(struct aa_label *label, const char *dev_name,
		 const struct path *path, const char *type, unsigned long flags,
		 void *data)
{
	struct aa_profile *profile;
	char *buffer = NULL, *dev_buffer = NULL;
	bool binary = true;
	int error;
	int requires_dev = 0;
	struct path tmp_path, *dev_path = NULL;

	AA_BUG(!label);
	AA_BUG(!path);

	if (type) {
		struct file_system_type *fstype;

		fstype = get_fs_type(type);
		if (!fstype)
			return -ENODEV;
		binary = fstype->fs_flags & FS_BINARY_MOUNTDATA;
		requires_dev = fstype->fs_flags & FS_REQUIRES_DEV;
		put_filesystem(fstype);

		if (requires_dev) {
			if (!dev_name || !*dev_name)
				return -ENOENT;

			error = kern_path(dev_name, LOOKUP_FOLLOW, &tmp_path);
			if (error)
				return error;
			dev_path = &tmp_path;
		}
	}

	get_buffers(buffer, dev_buffer);
	if (dev_path) {
		error = fn_for_each_confined(label, profile,
			match_mnt(profile, path, buffer, dev_path, dev_buffer,
				  type, flags, data, binary));
	} else {
		error = fn_for_each_confined(label, profile,
			match_mnt_path_str(profile, path, buffer, dev_name,
					   type, flags, data, binary, NULL));
	}
	put_buffers(buffer, dev_buffer);
	if (dev_path)
		path_put(dev_path);

	return error;
}
Beispiel #2
0
int aa_move_mount(struct aa_label *label, const struct path *path,
		  const char *orig_name)
{
	struct aa_profile *profile;
	char *buffer = NULL, *old_buffer = NULL;
	struct path old_path;
	int error;

	AA_BUG(!label);
	AA_BUG(!path);

	if (!orig_name || !*orig_name)
		return -EINVAL;

	error = kern_path(orig_name, LOOKUP_FOLLOW, &old_path);
	if (error)
		return error;

	get_buffers(buffer, old_buffer);
	error = fn_for_each_confined(label, profile,
			match_mnt(profile, path, buffer, &old_path, old_buffer,
				  NULL, MS_MOVE, NULL, false));
	put_buffers(buffer, old_buffer);
	path_put(&old_path);

	return error;
}
Beispiel #3
0
int aa_bind_mount(struct aa_label *label, const struct path *path,
		  const char *dev_name, unsigned long flags)
{
	struct aa_profile *profile;
	char *buffer = NULL, *old_buffer = NULL;
	struct path old_path;
	int error;

	AA_BUG(!label);
	AA_BUG(!path);

	if (!dev_name || !*dev_name)
		return -EINVAL;

	flags &= MS_REC | MS_BIND;

	error = kern_path(dev_name, LOOKUP_FOLLOW|LOOKUP_AUTOMOUNT, &old_path);
	if (error)
		return error;

	get_buffers(buffer, old_buffer);
	error = fn_for_each_confined(label, profile,
			match_mnt(profile, path, buffer, &old_path, old_buffer,
				  NULL, flags, NULL, false));
	put_buffers(buffer, old_buffer);
	path_put(&old_path);

	return error;
}
Beispiel #4
0
Datei: net.c Projekt: SelfImp/m75
int aa_af_perm(struct aa_label *label, int op, u32 request, u16 family,
	       int type, int protocol, struct sock *sk)
{
	struct aa_profile *profile;

	return fn_for_each_confined(label, profile,
			aa_profile_af_perm(profile, op, family, type, protocol,
					   sk));
}
Beispiel #5
0
int apparmor_secmark_check(struct aa_label *label, char *op, u32 request,
			   u32 secid, struct sock *sk)
{
	struct aa_profile *profile;
	DEFINE_AUDIT_SK(sa, op, sk);

	return fn_for_each_confined(label, profile,
				    aa_secmark_perm(profile, request, secid,
						    &sa, sk));
}
Beispiel #6
0
int aa_af_perm(struct aa_label *label, const char *op, u32 request, u16 family,
	       int type, int protocol)
{
	struct aa_profile *profile;
	DEFINE_AUDIT_NET(sa, op, NULL, family, type, protocol);

	return fn_for_each_confined(label, profile,
			aa_profile_af_perm(profile, &sa, request, family,
					   type));
}
Beispiel #7
0
/**
 * aa_capable - test permission to use capability
 * @label: label being tested for capability (NOT NULL)
 * @cap: capability to be tested
 * @audit: whether an audit record should be generated
 *
 * Look up capability in profile capability set.
 *
 * Returns: 0 on success, or else an error code.
 */
int aa_capable(struct aa_label *label, int cap, int audit)
{
	struct aa_profile *profile;
	int error = 0;
	DEFINE_AUDIT_DATA(sa, LSM_AUDIT_DATA_CAP, OP_CAPABLE);
	sa.u.cap = cap;

	error = fn_for_each_confined(label, profile,
			profile_capable(profile, cap, audit ? &sa : NULL));

	return error;
}
Beispiel #8
0
/**
 * aa_capable - test permission to use capability
 * @label: label being tested for capability (NOT NULL)
 * @cap: capability to be tested
 * @opts: CAP_OPT_NOAUDIT bit determines whether audit record is generated
 *
 * Look up capability in profile capability set.
 *
 * Returns: 0 on success, or else an error code.
 */
int aa_capable(struct aa_label *label, int cap, unsigned int opts)
{
	struct aa_profile *profile;
	int error = 0;
	DEFINE_AUDIT_DATA(sa, LSM_AUDIT_DATA_CAP, OP_CAPABLE);

	sa.u.cap = cap;
	error = fn_for_each_confined(label, profile,
			profile_capable(profile, cap, opts, &sa));

	return error;
}
Beispiel #9
0
Datei: net.c Projekt: SelfImp/m75
static int aa_label_sk_perm(struct aa_label *label, int op, u32 request,
			    struct sock *sk)
{
	struct aa_profile *profile;

	AA_BUG(!label);
	AA_BUG(!sk);

	if (unconfined(label))
		return 0;

	return fn_for_each_confined(label, profile,
			aa_profile_af_perm(profile, op, sk->sk_family,
					   sk->sk_type, sk->sk_protocol,
					   sk));

}
Beispiel #10
0
static int aa_label_sk_perm(struct aa_label *label, const char *op, u32 request,
			    struct sock *sk)
{
	int error = 0;

	AA_BUG(!label);
	AA_BUG(!sk);

	if (!unconfined(label)) {
		struct aa_profile *profile;
		DEFINE_AUDIT_SK(sa, op, sk);

		error = fn_for_each_confined(label, profile,
			    aa_profile_af_sk_perm(profile, &sa, request, sk));
	}

	return error;
}
Beispiel #11
0
static int path_name(const char *op, struct aa_label *label,
		     const struct path *path, int flags, char *buffer,
		     const char **name, struct path_cond *cond, u32 request)
{
	struct aa_profile *profile;
	const char *info = NULL;
	int error;

	error = aa_path_name(path, flags, buffer, name, &info,
			     labels_profile(label)->disconnected);
	if (error) {
		fn_for_each_confined(label, profile,
			aa_audit_file(profile, &nullperms, op, request, *name,
				      NULL, NULL, cond->uid, info, error));
		return error;
	}

	return 0;
}
Beispiel #12
0
int aa_remount(struct aa_label *label, const struct path *path,
	       unsigned long flags, void *data)
{
	struct aa_profile *profile;
	char *buffer = NULL;
	bool binary;
	int error;

	AA_BUG(!label);
	AA_BUG(!path);

	binary = path->dentry->d_sb->s_type->fs_flags & FS_BINARY_MOUNTDATA;

	get_buffers(buffer);
	error = fn_for_each_confined(label, profile,
			match_mnt(profile, path, buffer, NULL, NULL, NULL,
				  flags, data, binary));
	put_buffers(buffer);

	return error;
}
Beispiel #13
0
int aa_mount_change_type(struct aa_label *label, const struct path *path,
			 unsigned long flags)
{
	struct aa_profile *profile;
	char *buffer = NULL;
	int error;

	AA_BUG(!label);
	AA_BUG(!path);

	/* These are the flags allowed by do_change_type() */
	flags &= (MS_REC | MS_SILENT | MS_SHARED | MS_PRIVATE | MS_SLAVE |
		  MS_UNBINDABLE);

	get_buffers(buffer);
	error = fn_for_each_confined(label, profile,
			match_mnt(profile, path, buffer, NULL, NULL, NULL,
				  flags, NULL, false));
	put_buffers(buffer);

	return error;
}
Beispiel #14
0
int aa_umount(struct aa_label *label, struct vfsmount *mnt, int flags)
{
	struct aa_profile *profile;
	char *buffer = NULL;
	int error;
	struct path path = { .mnt = mnt, .dentry = mnt->mnt_root };

	AA_BUG(!label);
	AA_BUG(!mnt);

	get_buffers(buffer);
	error = fn_for_each_confined(label, profile,
			profile_umount(profile, &path, buffer));
	put_buffers(buffer);

	return error;
}

/* helper fn for transition on pivotroot
 *
 * Returns: label for transition or ERR_PTR. Does not return NULL
 */
static struct aa_label *build_pivotroot(struct aa_profile *profile,
					const struct path *new_path,
					char *new_buffer,
					const struct path *old_path,
					char *old_buffer)
{
	const char *old_name, *new_name = NULL, *info = NULL;
	const char *trans_name = NULL;
	struct aa_perms perms = { };
	unsigned int state;
	int error;

	AA_BUG(!profile);
	AA_BUG(!new_path);
	AA_BUG(!old_path);

	if (profile_unconfined(profile) ||
	    !PROFILE_MEDIATES(profile, AA_CLASS_MOUNT))
		return aa_get_newest_label(&profile->label);

	error = aa_path_name(old_path, path_flags(profile, old_path),
			     old_buffer, &old_name, &info,
			     profile->disconnected);
	if (error)
		goto audit;
	error = aa_path_name(new_path, path_flags(profile, new_path),
			     new_buffer, &new_name, &info,
			     profile->disconnected);
	if (error)
		goto audit;

	error = -EACCES;
	state = aa_dfa_match(profile->policy.dfa,
			     profile->policy.start[AA_CLASS_MOUNT],
			     new_name);
	state = aa_dfa_null_transition(profile->policy.dfa, state);
	state = aa_dfa_match(profile->policy.dfa, state, old_name);
	perms = compute_mnt_perms(profile->policy.dfa, state);

	if (AA_MAY_PIVOTROOT & perms.allow)
		error = 0;

audit:
	error = audit_mount(profile, OP_PIVOTROOT, new_name, old_name,
			    NULL, trans_name, 0, NULL, AA_MAY_PIVOTROOT,
			    &perms, info, error);
	if (error)
		return ERR_PTR(error);

	return aa_get_newest_label(&profile->label);
}

int aa_pivotroot(struct aa_label *label, const struct path *old_path,
		 const struct path *new_path)
{
	struct aa_profile *profile;
	struct aa_label *target = NULL;
	char *old_buffer = NULL, *new_buffer = NULL, *info = NULL;
	int error;

	AA_BUG(!label);
	AA_BUG(!old_path);
	AA_BUG(!new_path);

	get_buffers(old_buffer, new_buffer);
	target = fn_label_build(label, profile, GFP_ATOMIC,
			build_pivotroot(profile, new_path, new_buffer,
					old_path, old_buffer));
	if (!target) {
		info = "label build failed";
		error = -ENOMEM;
		goto fail;
	} else if (!IS_ERR(target)) {
		error = aa_replace_current_label(target);
		if (error) {
			/* TODO: audit target */
			aa_put_label(target);
			goto out;
		}
	} else
		/* already audited error */
		error = PTR_ERR(target);
out:
	put_buffers(old_buffer, new_buffer);

	return error;

fail:
	/* TODO: add back in auditing of new_name and old_name */
	error = fn_for_each(label, profile,
			audit_mount(profile, OP_PIVOTROOT, NULL /*new_name */,
				    NULL /* old_name */,
				    NULL, NULL,
				    0, NULL, AA_MAY_PIVOTROOT, &nullperms, info,
				    error));
	goto out;
}