Beispiel #1
0
Datei: net.c Projekt: SelfImp/m75
/**
 * audit_net - audit network access
 * @profile: profile being enforced  (NOT NULL)
 * @op: operation being checked
 * @family: network family
 * @type:   network type
 * @protocol: network protocol
 * @sk: socket auditing is being applied to
 * @error: error code for failure else 0
 *
 * Returns: %0 or sa->error else other errorcode on failure
 */
static int audit_net(struct aa_profile *profile, int op, u16 family, int type,
		     int protocol, struct sock *sk, int error)
{
	int audit_type = AUDIT_APPARMOR_AUTO;
	DEFINE_AUDIT_NET(sa, op, sk, family, type, protocol);
	aad(&sa)->error = error;

	if (likely(!aad(&sa)->error)) {
		u16 audit_mask = profile->net.audit[sa.u.net->family];
		if (likely((AUDIT_MODE(profile) != AUDIT_ALL) &&
			   !(1 << aad(&sa)->net.type & audit_mask)))
			return 0;
		audit_type = AUDIT_APPARMOR_AUDIT;
	} else {
		u16 quiet_mask = profile->net.quiet[sa.u.net->family];
		u16 kill_mask = 0;
		u16 denied = (1 << aad(&sa)->net.type);

		if (denied & kill_mask)
			audit_type = AUDIT_APPARMOR_KILL;

		if ((denied & quiet_mask) &&
		    AUDIT_MODE(profile) != AUDIT_NOQUIET &&
		    AUDIT_MODE(profile) != AUDIT_ALL)
		  return COMPLAIN_MODE(profile) ? 0 : aad(&sa)->error;
	}

	return aa_audit(audit_type, profile, &sa, audit_net_cb);
}
Beispiel #2
0
/**
 * audit_resource - audit setting resource limit
 * @profile: profile being enforced  (NOT NULL)
 * @resoure: rlimit being auditing
 * @value: value being set
 * @error: error value
 *
 * Returns: 0 or sa->error else other error code on failure
 */
static int audit_resource(struct aa_profile *profile, unsigned int resource,
			  unsigned long value, int error)
{
	DEFINE_AUDIT_DATA(sa, LSM_AUDIT_DATA_NONE, OP_SETRLIMIT);

	aad(&sa)->rlim.rlim = resource;
	aad(&sa)->rlim.max = value;
	aad(&sa)->error = error;
	return aa_audit(AUDIT_APPARMOR_AUTO, profile, &sa, audit_cb);
}
Beispiel #3
0
/**
 * aa_audit_ptrace - do auditing for ptrace
 * @profile: profile being enforced  (NOT NULL)
 * @target: profile being traced (NOT NULL)
 * @error: error condition
 *
 * Returns: %0 or error code
 */
static int aa_audit_ptrace(struct aa_profile *profile,
                           struct aa_profile *target, int error)
{
    struct common_audit_data sa;
    COMMON_AUDIT_DATA_INIT(&sa, NONE);
    sa.aad.op = OP_PTRACE;
    sa.aad.target = target;
    sa.aad.error = error;

    return aa_audit(AUDIT_APPARMOR_AUTO, profile, GFP_ATOMIC, &sa,
                    audit_cb);
}
Beispiel #4
0
/**
 * aa_audit_file - handle the auditing of file operations
 * @profile: the profile being enforced  (NOT NULL)
 * @perms: the permissions computed for the request (NOT NULL)
 * @op: operation being mediated
 * @request: permissions requested
 * @name: name of object being mediated (MAYBE NULL)
 * @target: name of target (MAYBE NULL)
 * @tlabel: target label (MAY BE NULL)
 * @ouid: object uid
 * @info: extra information message (MAYBE NULL)
 * @error: 0 if operation allowed else failure error code
 *
 * Returns: %0 or error on failure
 */
int aa_audit_file(struct aa_profile *profile, struct aa_perms *perms,
		  const char *op, u32 request, const char *name,
		  const char *target, struct aa_label *tlabel,
		  kuid_t ouid, const char *info, int error)
{
	int type = AUDIT_APPARMOR_AUTO;
	DEFINE_AUDIT_DATA(sa, LSM_AUDIT_DATA_TASK, op);

	sa.u.tsk = NULL;
	aad(&sa)->request = request;
	aad(&sa)->name = name;
	aad(&sa)->fs.target = target;
	aad(&sa)->peer = tlabel;
	aad(&sa)->fs.ouid = ouid;
	aad(&sa)->info = info;
	aad(&sa)->error = error;
	sa.u.tsk = NULL;

	if (likely(!aad(&sa)->error)) {
		u32 mask = perms->audit;

		if (unlikely(AUDIT_MODE(profile) == AUDIT_ALL))
			mask = 0xffff;

		/* mask off perms that are not being force audited */
		aad(&sa)->request &= mask;

		if (likely(!aad(&sa)->request))
			return 0;
		type = AUDIT_APPARMOR_AUDIT;
	} else {
		/* only report permissions that were denied */
		aad(&sa)->request = aad(&sa)->request & ~perms->allow;
		AA_BUG(!aad(&sa)->request);

		if (aad(&sa)->request & perms->kill)
			type = AUDIT_APPARMOR_KILL;

		/* quiet known rejects, assumes quiet and kill do not overlap */
		if ((aad(&sa)->request & perms->quiet) &&
		    AUDIT_MODE(profile) != AUDIT_NOQUIET &&
		    AUDIT_MODE(profile) != AUDIT_ALL)
			aad(&sa)->request &= ~perms->quiet;

		if (!aad(&sa)->request)
			return aad(&sa)->error;
	}

	aad(&sa)->denied = aad(&sa)->request & ~perms->allow;
	return aa_audit(type, profile, &sa, file_audit_cb);
}
Beispiel #5
0
/**
 * audit_mount - handle the auditing of mount operations
 * @profile: the profile being enforced  (NOT NULL)
 * @op: operation being mediated (NOT NULL)
 * @name: name of object being mediated (MAYBE NULL)
 * @src_name: src_name of object being mediated (MAYBE_NULL)
 * @type: type of filesystem (MAYBE_NULL)
 * @trans: name of trans (MAYBE NULL)
 * @flags: filesystem independent mount flags
 * @data: filesystem mount flags
 * @request: permissions requested
 * @perms: the permissions computed for the request (NOT NULL)
 * @info: extra information message (MAYBE NULL)
 * @error: 0 if operation allowed else failure error code
 *
 * Returns: %0 or error on failure
 */
static int audit_mount(struct aa_profile *profile, const char *op,
		       const char *name, const char *src_name,
		       const char *type, const char *trans,
		       unsigned long flags, const void *data, u32 request,
		       struct aa_perms *perms, const char *info, int error)
{
	int audit_type = AUDIT_APPARMOR_AUTO;
	DEFINE_AUDIT_DATA(sa, LSM_AUDIT_DATA_NONE, op);

	if (likely(!error)) {
		u32 mask = perms->audit;

		if (unlikely(AUDIT_MODE(profile) == AUDIT_ALL))
			mask = 0xffff;

		/* mask off perms that are not being force audited */
		request &= mask;

		if (likely(!request))
			return 0;
		audit_type = AUDIT_APPARMOR_AUDIT;
	} else {
		/* only report permissions that were denied */
		request = request & ~perms->allow;

		if (request & perms->kill)
			audit_type = AUDIT_APPARMOR_KILL;

		/* quiet known rejects, assumes quiet and kill do not overlap */
		if ((request & perms->quiet) &&
		    AUDIT_MODE(profile) != AUDIT_NOQUIET &&
		    AUDIT_MODE(profile) != AUDIT_ALL)
			request &= ~perms->quiet;

		if (!request)
			return error;
	}

	aad(&sa)->name = name;
	aad(&sa)->mnt.src_name = src_name;
	aad(&sa)->mnt.type = type;
	aad(&sa)->mnt.trans = trans;
	aad(&sa)->mnt.flags = flags;
	if (data && (perms->audit & AA_AUDIT_DATA))
		aad(&sa)->mnt.data = data;
	aad(&sa)->info = info;
	aad(&sa)->error = error;

	return aa_audit(audit_type, profile, &sa, audit_cb);
}
Beispiel #6
0
int aa_audit_file(struct aa_profile *profile, struct file_perms *perms,
		  gfp_t gfp, int op, u32 request, const char *name,
		  const char *target, uid_t ouid, const char *info, int error)
{
	int type = AUDIT_APPARMOR_AUTO;
	struct common_audit_data sa;
	struct apparmor_audit_data aad = {0,};
	COMMON_AUDIT_DATA_INIT(&sa, NONE);
	sa.aad = &aad;
	aad.op = op,
	aad.fs.request = request;
	aad.name = name;
	aad.fs.target = target;
	aad.fs.ouid = ouid;
	aad.info = info;
	aad.error = error;

	if (likely(!sa.aad->error)) {
		u32 mask = perms->audit;

		if (unlikely(AUDIT_MODE(profile) == AUDIT_ALL))
			mask = 0xffff;

		/*                                                 */
		sa.aad->fs.request &= mask;

		if (likely(!sa.aad->fs.request))
			return 0;
		type = AUDIT_APPARMOR_AUDIT;
	} else {
		/*                                          */
		sa.aad->fs.request = sa.aad->fs.request & ~perms->allow;

		if (sa.aad->fs.request & perms->kill)
			type = AUDIT_APPARMOR_KILL;

		/*                                                            */
		if ((sa.aad->fs.request & perms->quiet) &&
		    AUDIT_MODE(profile) != AUDIT_NOQUIET &&
		    AUDIT_MODE(profile) != AUDIT_ALL)
			sa.aad->fs.request &= ~perms->quiet;

		if (!sa.aad->fs.request)
			return COMPLAIN_MODE(profile) ? 0 : sa.aad->error;
	}

	sa.aad->fs.denied = sa.aad->fs.request & ~perms->allow;
	return aa_audit(type, profile, gfp, &sa, file_audit_cb);
}
Beispiel #7
0
/**
 * aa_audit_file - handle the auditing of file operations
 * @profile: the profile being enforced  (NOT NULL)
 * @perms: the permissions computed for the request (NOT NULL)
 * @gfp: allocation flags
 * @op: operation being mediated
 * @request: permissions requested
 * @name: name of object being mediated (MAYBE NULL)
 * @target: name of target (MAYBE NULL)
 * @ouid: object uid
 * @info: extra information message (MAYBE NULL)
 * @error: 0 if operation allowed else failure error code
 *
 * Returns: %0 or error on failure
 */
int aa_audit_file(struct aa_profile *profile, struct file_perms *perms,
		  gfp_t gfp, int op, u32 request, const char *name,
		  const char *target, kuid_t ouid, const char *info, int error)
{
	int type = AUDIT_APPARMOR_AUTO;
	struct common_audit_data sa;
	struct apparmor_audit_data aad = {0,};
	sa.type = LSM_AUDIT_DATA_NONE;
	sa.aad = &aad;
	aad.op = op,
	aad.fs.request = request;
	aad.name = name;
	aad.fs.target = target;
	aad.fs.ouid = ouid;
	aad.info = info;
	aad.error = error;

	if (likely(!sa.aad->error)) {
		u32 mask = perms->audit;

		if (unlikely(AUDIT_MODE(profile) == AUDIT_ALL))
			mask = 0xffff;

		/* mask off perms that are not being force audited */
		sa.aad->fs.request &= mask;

		if (likely(!sa.aad->fs.request))
			return 0;
		type = AUDIT_APPARMOR_AUDIT;
	} else {
		/* only report permissions that were denied */
		sa.aad->fs.request = sa.aad->fs.request & ~perms->allow;

		if (sa.aad->fs.request & perms->kill)
			type = AUDIT_APPARMOR_KILL;

		/* quiet known rejects, assumes quiet and kill do not overlap */
		if ((sa.aad->fs.request & perms->quiet) &&
		    AUDIT_MODE(profile) != AUDIT_NOQUIET &&
		    AUDIT_MODE(profile) != AUDIT_ALL)
			sa.aad->fs.request &= ~perms->quiet;

		if (!sa.aad->fs.request)
			return COMPLAIN_MODE(profile) ? 0 : sa.aad->error;
	}

	sa.aad->fs.denied = sa.aad->fs.request & ~perms->allow;
	return aa_audit(type, profile, gfp, &sa, file_audit_cb);
}
Beispiel #8
0
/**
 * audit_resource - audit setting resource limit
 * @profile: profile being enforced  (NOT NULL)
 * @resoure: rlimit being auditing
 * @value: value being set
 * @error: error value
 *
 * Returns: 0 or sa->error else other error code on failure
 */
static int audit_resource(struct aa_profile *profile, unsigned int resource,
			  unsigned long value, int error)
{
	struct common_audit_data sa;
	struct apparmor_audit_data aad = {0,};

	sa.type = LSM_AUDIT_DATA_NONE;
	sa.aad = &aad;
	aad.op = OP_SETRLIMIT,
	aad.rlim.rlim = resource;
	aad.rlim.max = value;
	aad.error = error;
	return aa_audit(AUDIT_APPARMOR_AUTO, profile, GFP_KERNEL, &sa,
			audit_cb);
}
Beispiel #9
0
/**
 * audit_caps - audit a capability
 * @profile: profile confining task (NOT NULL)
 * @task: task capability test was performed against (NOT NULL)
 * @cap: capability tested
 * @error: error code returned by test
 *
 * Do auditing of capability and handle, audit/complain/kill modes switching
 * and duplicate message elimination.
 *
 * Returns: 0 or sa->error on success,  error code on failure
 */
static int audit_caps(struct aa_profile *profile, struct task_struct *task,
		      int cap, int error)
{
	struct audit_cache *ent;
	int type = AUDIT_APPARMOR_AUTO;
	struct common_audit_data sa;
	struct apparmor_audit_data aad = {0,};
	COMMON_AUDIT_DATA_INIT(&sa, CAP);
	sa.aad = &aad;
	sa.tsk = task;
	sa.u.cap = cap;
	sa.aad->op = OP_CAPABLE;
	sa.aad->error = error;

	if (likely(!error)) {
		/* test if auditing is being forced */
		if (likely((AUDIT_MODE(profile) != AUDIT_ALL) &&
			   !cap_raised(profile->caps.audit, cap)))
			return 0;
		type = AUDIT_APPARMOR_AUDIT;
	} else if (KILL_MODE(profile) ||
		   cap_raised(profile->caps.kill, cap)) {
		type = AUDIT_APPARMOR_KILL;
	} else if (cap_raised(profile->caps.quiet, cap) &&
		   AUDIT_MODE(profile) != AUDIT_NOQUIET &&
		   AUDIT_MODE(profile) != AUDIT_ALL) {
		/* quiet auditing */
		return error;
	}

	/* Do simple duplicate message elimination */
	ent = &get_cpu_var(audit_cache);
	if (profile == ent->profile && cap_raised(ent->caps, cap)) {
		put_cpu_var(audit_cache);
		if (COMPLAIN_MODE(profile))
			return complain_error(error);
		return error;
	} else {
		aa_put_profile(ent->profile);
		ent->profile = aa_get_profile(profile);
		cap_raise(ent->caps, cap);
	}
	put_cpu_var(audit_cache);

	return aa_audit(type, profile, GFP_ATOMIC, &sa, audit_cb);
}
Beispiel #10
0
/**
 * audit_net - audit network access
 * @profile: profile being enforced  (NOT NULL)
 * @op: operation being checked
 * @family: network family
 * @type:   network type
 * @protocol: network protocol
 * @sk: socket auditing is being applied to
 * @error: error code for failure else 0
 *
 * Returns: %0 or sa->error else other errorcode on failure
 */
static int audit_net(struct aa_profile *profile, int op, u16 family, int type,
		     int protocol, struct sock *sk, int error)
{
	int audit_type = AUDIT_APPARMOR_AUTO;
	struct common_audit_data sa;
	struct apparmor_audit_data aad = { };
	struct lsm_network_audit net = { };
	if (sk) {
		sa.type = LSM_AUDIT_DATA_NET;
	} else {
		sa.type = LSM_AUDIT_DATA_NONE;
	}
	/* todo fill in socket addr info */
	sa.aad = &aad;
	sa.u.net = &net;
	sa.aad->op = op,
	sa.u.net->family = family;
	sa.u.net->sk = sk;
	sa.aad->net.type = type;
	sa.aad->net.protocol = protocol;
	sa.aad->error = error;

	if (likely(!sa.aad->error)) {
		u16 audit_mask = profile->net.audit[sa.u.net->family];
		if (likely((AUDIT_MODE(profile) != AUDIT_ALL) &&
			   !(1 << sa.aad->net.type & audit_mask)))
			return 0;
		audit_type = AUDIT_APPARMOR_AUDIT;
	} else {
		u16 quiet_mask = profile->net.quiet[sa.u.net->family];
		u16 kill_mask = 0;
		u16 denied = (1 << sa.aad->net.type) & ~quiet_mask;

		if (denied & kill_mask)
			audit_type = AUDIT_APPARMOR_KILL;

		if ((denied & quiet_mask) &&
		    AUDIT_MODE(profile) != AUDIT_NOQUIET &&
		    AUDIT_MODE(profile) != AUDIT_ALL)
			return COMPLAIN_MODE(profile) ? 0 : sa.aad->error;
	}

	return aa_audit(audit_type, profile, GFP_KERNEL, &sa, audit_cb);
}
Beispiel #11
0
Datei: ipc.c Projekt: SelfImp/m75
static int cross_ptrace_perm(struct aa_profile *tracer,
			     struct aa_profile *tracee, u32 request,
			     struct common_audit_data *sa)
{
	if (PROFILE_MEDIATES(tracer, AA_CLASS_PTRACE))
		return xcheck(profile_ptrace_perm(tracer, tracee, request, sa),
			      profile_ptrace_perm(tracee, tracer,
						  request << PTRACE_PERM_SHIFT,
						  sa));
	/* policy uses the old style capability check for ptrace */
	if (profile_unconfined(tracer) || tracer == tracee)
		return 0;

	aad(sa)->label = &tracer->label;
	aad(sa)->target = tracee->base.hname;
	aad(sa)->request = 0;
	aad(sa)->error = aa_capable(&tracer->label, CAP_SYS_PTRACE, 1);
	return aa_audit(AUDIT_APPARMOR_AUTO, tracer, sa, audit_ptrace_cb);
}
Beispiel #12
0
/**
 * audit_caps - audit a capability
 * @sa: audit data
 * @profile: profile being tested for confinement (NOT NULL)
 * @cap: capability tested
 * @error: error code returned by test
 *
 * Do auditing of capability and handle, audit/complain/kill modes switching
 * and duplicate message elimination.
 *
 * Returns: 0 or sa->error on success,  error code on failure
 */
static int audit_caps(struct common_audit_data *sa, struct aa_profile *profile,
		      int cap, int error)
{
	struct audit_cache *ent;
	int type = AUDIT_APPARMOR_AUTO;

	aad(sa)->error = error;

	if (likely(!error)) {
		/* test if auditing is being forced */
		if (likely((AUDIT_MODE(profile) != AUDIT_ALL) &&
			   !cap_raised(profile->caps.audit, cap)))
			return 0;
		type = AUDIT_APPARMOR_AUDIT;
	} else if (KILL_MODE(profile) ||
		   cap_raised(profile->caps.kill, cap)) {
		type = AUDIT_APPARMOR_KILL;
	} else if (cap_raised(profile->caps.quiet, cap) &&
		   AUDIT_MODE(profile) != AUDIT_NOQUIET &&
		   AUDIT_MODE(profile) != AUDIT_ALL) {
		/* quiet auditing */
		return error;
	}

	/* Do simple duplicate message elimination */
	ent = &get_cpu_var(audit_cache);
	if (profile == ent->profile && cap_raised(ent->caps, cap)) {
		put_cpu_var(audit_cache);
		if (COMPLAIN_MODE(profile))
			return complain_error(error);
		return error;
	} else {
		aa_put_profile(ent->profile);
		ent->profile = aa_get_profile(profile);
		cap_raise(ent->caps, cap);
	}
	put_cpu_var(audit_cache);

	return aa_audit(type, profile, sa, audit_cb);
}
Beispiel #13
0
static int profile_tracer_perm(struct aa_profile *tracer,
			       struct aa_label *tracee, u32 request,
			       struct common_audit_data *sa)
{
	if (profile_unconfined(tracer))
		return 0;

	if (PROFILE_MEDIATES(tracer, AA_CLASS_PTRACE))
		return profile_ptrace_perm(tracer, tracee, request, sa);

	/* profile uses the old style capability check for ptrace */
	if (&tracer->label == tracee)
		return 0;

	aad(sa)->label = &tracer->label;
	aad(sa)->peer = tracee;
	aad(sa)->request = 0;
	aad(sa)->error = aa_capable(&tracer->label, CAP_SYS_PTRACE,
				    CAP_OPT_NONE);

	return aa_audit(AUDIT_APPARMOR_AUTO, tracer, sa, audit_ptrace_cb);
}