Exemplo n.º 1
0
/* audit interface for capability */
void kse_cap_audit(struct task_struct *tsk,
			int cap, int result)
{
	int sclass, request;
	struct common_audit_data ad;

	if (kse_noyaudit == 1 && result == 0)
		return;

	COMMON_AUDIT_DATA_INIT(&ad, CAP);
	ad.tsk = tsk;
	ad.u.cap = cap;
	request = CAP_TO_MASK(cap);
	switch (CAP_TO_INDEX(cap)) {
	case 0:
		sclass = SECCLASS_CAPABILITY;
		break;
	case 1:
		sclass = SECCLASS_CAPABILITY2;
		break;
	default:
		printk(KERN_ERR
		       "KUXSE:  out of range capability %d\n", cap);
		BUG();
	}

	//kse_audit(task_cred_xxx(tsk, security), NULL, NULL, 0, sclass,
			//request, result, &ad);
	kse_audit(tsk->security, NULL, NULL, 0, sclass, request, result, &ad);
}
Exemplo n.º 2
0
/**
 * aa_info_message - log a none profile related status message
 * @str: message to log
 */
void aa_info_message(const char *str)
{
	if (audit_enabled) {
		struct common_audit_data sa;
		COMMON_AUDIT_DATA_INIT(&sa, NONE);
		sa.aad.info = str;
		aa_audit_msg(AUDIT_APPARMOR_STATUS, &sa, NULL);
	}
	printk(KERN_INFO "AppArmor: %s\n", str);
}
Exemplo n.º 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);
}
Exemplo n.º 4
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);
}
Exemplo n.º 5
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, uid_t ouid, const char *info, int error)
{
	int type = AUDIT_APPARMOR_AUTO;
	struct common_audit_data sa;
	COMMON_AUDIT_DATA_INIT(&sa, NONE);
	sa.aad.op = op,
	sa.aad.fs.request = request;
	sa.aad.name = name;
	sa.aad.fs.target = target;
	sa.aad.fs.ouid = ouid;
	sa.aad.info = info;
	sa.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);
}
Exemplo n.º 6
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);
}
Exemplo n.º 7
0
Arquivo: hooks.c Projeto: vicvinc/Bsec
/* 
 * task_inode_perm: check permission when task operate on inode
 * tsk1: source task
 * inode: target inode
 * perm: permission to be checked
 * return value:
 *  0: granted
 * -1: denied
 * */
int task_inode_perm(struct task_struct *tsk1, struct inode *inode,
				struct dentry *dentry, int perm)
{
	struct task_security_struct *tsp1;
	struct inode_security_struct *iss;
	struct common_audit_data ad;
	int ret;
	int request = 0;

	if (kse_enabled == 0)
		return 0;

	tsp1 = (struct task_security_struct *)task_cred_xxx(tsk1, security);
	iss = inode->i_security;

	COMMON_AUDIT_DATA_INIT(&ad, FS);
	ad.u.fs.path.dentry = dentry;
	ad.u.fs.inode = inode;

	switch (perm) {
	case DIR__ADD_NAME:
		ret = kse_may_write(tsp1, NULL, iss, 1);
		break;
	case DIR__REMOVE_NAME:
		ret = kse_may_write(tsp1, NULL, iss, 1);
		break;
	case FILE__CREATE:
		ret = kse_may_write(tsp1, NULL, iss, 1);
		break;
	case FILE__LINK:
		ret = kse_may_write(tsp1, NULL, iss, 1);
		break;
	case FILE__UNLINK:
		ret = kse_may_write(tsp1, NULL, iss, 1);
		break;
	case FILE__READ:
		ret = kse_may_read(tsp1, NULL, iss, 1);
		break;
	case FILE__WRITE:
		ret = kse_may_write(tsp1, NULL, iss, 1);
		break;
	case FILE__APPEND:
		ret = kse_may_write(tsp1, NULL, iss, 1);
		break;
	case FILE__GETATTR:
		ret = kse_may_read(tsp1, NULL, iss, 1);
		break;
	case FILE__SETATTR:
		ret = kse_may_write(tsp1, NULL, iss, 1);
		break;
	case FILE__EXECUTE:
		ret = kse_may_read(tsp1, NULL, iss, 1);
		break;
	default:
		ret = -1;
		break;
	}
	request |= perm;

	if (kse_noyaudit == 1 && ret == 0)
		return ret;

	kse_audit(tsp1, NULL, iss, 1, SECCLASS_FILE, request, ret, &ad);
	return ret;
}
Exemplo n.º 8
0
Arquivo: hooks.c Projeto: vicvinc/Bsec
/* 
 * task_task_perm: check permission when task operate on task
 * tsk1: source task
 * tsk2: target task
 * perm: permission to be checked
 * return value:
 *  0: granted
 * -1: denied
 * */
int task_task_perm(struct task_struct *tsk1,
				struct task_struct *tsk2, int perm)
{
	struct task_security_struct *tsp1;
	struct task_security_struct *tsp2;
	struct common_audit_data ad;
	int ret;
	int request = 0;

	if (kse_enabled == 0)
		return 0;
	if (tsk1 == NULL || tsk2 == NULL)
		return -1;

	tsp1 = (struct task_security_struct *)task_cred_xxx(tsk1, security);
	tsp2 = (struct task_security_struct *)task_cred_xxx(tsk2, security);

	if (tsp1 == NULL || tsp2 == NULL)
		return -1;

	COMMON_AUDIT_DATA_INIT(&ad, TASK);

	switch (perm) {
	case PROCESS__GETPGID:
		ret = kse_may_read(tsp1, tsp2, NULL, 0);
		break;
	case PROCESS__SETPGID:
		ret = kse_may_write(tsp1, tsp2, NULL, 0);
		break;
	case PROCESS__GETSESSION:
		ret = kse_may_read(tsp1, tsp2, NULL, 0);
		break;
	case PROCESS__GETATTR:
		ret = kse_may_read(tsp1, tsp2, NULL, 0);
		break;
	case PROCESS__GETSCHED:
		ret = kse_may_read(tsp1, tsp2, NULL, 0);
		break;
	case PROCESS__SETSCHED:
		ret = kse_may_write(tsp1, tsp2, NULL, 0);
		break;
	case PROCESS__SETRLIMIT:
		ret = kse_may_write(tsp1, tsp2, NULL, 0);
		break;
	case PROCESS__SIGNAL:
		ret = kse_may_write(tsp1, tsp2, NULL, 0);
		break;
	case PROCESS__SIGCHLD:
		ret = kse_may_write(tsp1, tsp2, NULL, 0);
		break;
	default:
		ret = -1;
		break;
	}
	request = perm;

	if (kse_noyaudit == 1 && ret == 0)
		return ret;

	kse_audit(tsp1, tsp2, NULL, 0, SECCLASS_PROCESS, request, ret, &ad);
	return ret;
}