Linux Audio

Check our new training course

Loading...
v4.17
 
  1/*
  2 * AppArmor security module
  3 *
  4 * This file contains AppArmor ipc mediation
  5 *
  6 * Copyright (C) 1998-2008 Novell/SUSE
  7 * Copyright 2009-2017 Canonical Ltd.
  8 *
  9 * This program is free software; you can redistribute it and/or
 10 * modify it under the terms of the GNU General Public License as
 11 * published by the Free Software Foundation, version 2 of the
 12 * License.
 13 */
 14
 15#include <linux/gfp.h>
 16#include <linux/ptrace.h>
 17
 18#include "include/audit.h"
 19#include "include/capability.h"
 20#include "include/cred.h"
 21#include "include/policy.h"
 22#include "include/ipc.h"
 23#include "include/sig_names.h"
 24
 25/**
 26 * audit_ptrace_mask - convert mask to permission string
 27 * @buffer: buffer to write string to (NOT NULL)
 28 * @mask: permission mask to convert
 
 
 29 */
 30static void audit_ptrace_mask(struct audit_buffer *ab, u32 mask)
 31{
 32	switch (mask) {
 33	case MAY_READ:
 34		audit_log_string(ab, "read");
 35		break;
 36	case MAY_WRITE:
 37		audit_log_string(ab, "trace");
 38		break;
 39	case AA_MAY_BE_READ:
 40		audit_log_string(ab, "readby");
 41		break;
 42	case AA_MAY_BE_TRACED:
 43		audit_log_string(ab, "tracedby");
 44		break;
 45	}
 
 46}
 47
 48/* call back to audit ptrace fields */
 49static void audit_ptrace_cb(struct audit_buffer *ab, void *va)
 50{
 51	struct common_audit_data *sa = va;
 52
 53	if (aad(sa)->request & AA_PTRACE_PERM_MASK) {
 54		audit_log_format(ab, " requested_mask=");
 55		audit_ptrace_mask(ab, aad(sa)->request);
 56
 57		if (aad(sa)->denied & AA_PTRACE_PERM_MASK) {
 58			audit_log_format(ab, " denied_mask=");
 59			audit_ptrace_mask(ab, aad(sa)->denied);
 60		}
 61	}
 62	audit_log_format(ab, " peer=");
 63	aa_label_xaudit(ab, labels_ns(aad(sa)->label), aad(sa)->peer,
 64			FLAGS_NONE, GFP_ATOMIC);
 65}
 66
 67/* assumes check for PROFILE_MEDIATES is already done */
 68/* TODO: conditionals */
 69static int profile_ptrace_perm(struct aa_profile *profile,
 70			     struct aa_label *peer, u32 request,
 71			     struct common_audit_data *sa)
 72{
 73	struct aa_perms perms = { };
 74
 75	aad(sa)->peer = peer;
 76	aa_profile_match_label(profile, peer, AA_CLASS_PTRACE, request,
 77			       &perms);
 78	aa_apply_modes_to_perms(profile, &perms);
 79	return aa_check_perms(profile, &perms, request, sa, audit_ptrace_cb);
 80}
 81
 82static int profile_tracee_perm(struct aa_profile *tracee,
 83			       struct aa_label *tracer, u32 request,
 84			       struct common_audit_data *sa)
 85{
 86	if (profile_unconfined(tracee) || unconfined(tracer) ||
 87	    !PROFILE_MEDIATES(tracee, AA_CLASS_PTRACE))
 88		return 0;
 89
 90	return profile_ptrace_perm(tracee, tracer, request, sa);
 91}
 92
 93static int profile_tracer_perm(struct aa_profile *tracer,
 94			       struct aa_label *tracee, u32 request,
 95			       struct common_audit_data *sa)
 96{
 97	if (profile_unconfined(tracer))
 98		return 0;
 99
100	if (PROFILE_MEDIATES(tracer, AA_CLASS_PTRACE))
101		return profile_ptrace_perm(tracer, tracee, request, sa);
102
103	/* profile uses the old style capability check for ptrace */
104	if (&tracer->label == tracee)
105		return 0;
106
107	aad(sa)->label = &tracer->label;
108	aad(sa)->peer = tracee;
109	aad(sa)->request = 0;
110	aad(sa)->error = aa_capable(&tracer->label, CAP_SYS_PTRACE, 1);
 
111
112	return aa_audit(AUDIT_APPARMOR_AUTO, tracer, sa, audit_ptrace_cb);
113}
114
115/**
116 * aa_may_ptrace - test if tracer task can trace the tracee
117 * @tracer: label of the task doing the tracing  (NOT NULL)
118 * @tracee: task label to be traced
119 * @request: permission request
120 *
121 * Returns: %0 else error code if permission denied or error
122 */
123int aa_may_ptrace(struct aa_label *tracer, struct aa_label *tracee,
124		  u32 request)
125{
126	struct aa_profile *profile;
127	u32 xrequest = request << PTRACE_PERM_SHIFT;
128	DEFINE_AUDIT_DATA(sa, LSM_AUDIT_DATA_NONE, OP_PTRACE);
129
130	return xcheck_labels(tracer, tracee, profile,
131			profile_tracer_perm(profile, tracee, request, &sa),
132			profile_tracee_perm(profile, tracer, xrequest, &sa));
133}
134
135
136static inline int map_signal_num(int sig)
137{
138	if (sig > SIGRTMAX)
139		return SIGUNKNOWN;
140	else if (sig >= SIGRTMIN)
141		return sig - SIGRTMIN + SIGRT_BASE;
142	else if (sig < MAXMAPPED_SIG)
143		return sig_map[sig];
144	return SIGUNKNOWN;
145}
146
147/**
148 * audit_file_mask - convert mask to permission string
149 * @buffer: buffer to write string to (NOT NULL)
150 * @mask: permission mask to convert
 
 
151 */
152static void audit_signal_mask(struct audit_buffer *ab, u32 mask)
153{
154	if (mask & MAY_READ)
155		audit_log_string(ab, "receive");
156	if (mask & MAY_WRITE)
157		audit_log_string(ab, "send");
 
158}
159
160/**
161 * audit_cb - call back for signal specific audit fields
162 * @ab: audit_buffer  (NOT NULL)
163 * @va: audit struct to audit values of  (NOT NULL)
164 */
165static void audit_signal_cb(struct audit_buffer *ab, void *va)
166{
167	struct common_audit_data *sa = va;
168
169	if (aad(sa)->request & AA_SIGNAL_PERM_MASK) {
170		audit_log_format(ab, " requested_mask=");
171		audit_signal_mask(ab, aad(sa)->request);
172		if (aad(sa)->denied & AA_SIGNAL_PERM_MASK) {
173			audit_log_format(ab, " denied_mask=");
174			audit_signal_mask(ab, aad(sa)->denied);
175		}
176	}
177	if (aad(sa)->signal == SIGUNKNOWN)
178		audit_log_format(ab, "signal=unknown(%d)",
179				 aad(sa)->unmappedsig);
180	else if (aad(sa)->signal < MAXMAPPED_SIGNAME)
181		audit_log_format(ab, " signal=%s", sig_names[aad(sa)->signal]);
182	else
183		audit_log_format(ab, " signal=rtmin+%d",
184				 aad(sa)->signal - SIGRT_BASE);
185	audit_log_format(ab, " peer=");
186	aa_label_xaudit(ab, labels_ns(aad(sa)->label), aad(sa)->peer,
187			FLAGS_NONE, GFP_ATOMIC);
188}
189
190static int profile_signal_perm(struct aa_profile *profile,
191			       struct aa_label *peer, u32 request,
192			       struct common_audit_data *sa)
193{
194	struct aa_perms perms;
195	unsigned int state;
196
197	if (profile_unconfined(profile) ||
198	    !PROFILE_MEDIATES(profile, AA_CLASS_SIGNAL))
199		return 0;
200
201	aad(sa)->peer = peer;
202	/* TODO: secondary cache check <profile, profile, perm> */
203	state = aa_dfa_next(profile->policy.dfa,
204			    profile->policy.start[AA_CLASS_SIGNAL],
205			    aad(sa)->signal);
206	aa_label_match(profile, peer, state, false, request, &perms);
207	aa_apply_modes_to_perms(profile, &perms);
208	return aa_check_perms(profile, &perms, request, sa, audit_signal_cb);
209}
210
211int aa_may_signal(struct aa_label *sender, struct aa_label *target, int sig)
212{
213	struct aa_profile *profile;
214	DEFINE_AUDIT_DATA(sa, LSM_AUDIT_DATA_NONE, OP_SIGNAL);
215
216	aad(&sa)->signal = map_signal_num(sig);
217	aad(&sa)->unmappedsig = sig;
218	return xcheck_labels(sender, target, profile,
219			profile_signal_perm(profile, target, MAY_WRITE, &sa),
220			profile_signal_perm(profile, sender, MAY_READ, &sa));
221}
v5.9
  1// SPDX-License-Identifier: GPL-2.0-only
  2/*
  3 * AppArmor security module
  4 *
  5 * This file contains AppArmor ipc mediation
  6 *
  7 * Copyright (C) 1998-2008 Novell/SUSE
  8 * Copyright 2009-2017 Canonical Ltd.
 
 
 
 
 
  9 */
 10
 11#include <linux/gfp.h>
 12#include <linux/ptrace.h>
 13
 14#include "include/audit.h"
 15#include "include/capability.h"
 16#include "include/cred.h"
 17#include "include/policy.h"
 18#include "include/ipc.h"
 19#include "include/sig_names.h"
 20
 21/**
 22 * audit_ptrace_mask - convert mask to permission string
 
 23 * @mask: permission mask to convert
 24 *
 25 * Returns: pointer to static string
 26 */
 27static const char *audit_ptrace_mask(u32 mask)
 28{
 29	switch (mask) {
 30	case MAY_READ:
 31		return "read";
 
 32	case MAY_WRITE:
 33		return "trace";
 
 34	case AA_MAY_BE_READ:
 35		return "readby";
 
 36	case AA_MAY_BE_TRACED:
 37		return "tracedby";
 
 38	}
 39	return "";
 40}
 41
 42/* call back to audit ptrace fields */
 43static void audit_ptrace_cb(struct audit_buffer *ab, void *va)
 44{
 45	struct common_audit_data *sa = va;
 46
 47	if (aad(sa)->request & AA_PTRACE_PERM_MASK) {
 48		audit_log_format(ab, " requested_mask=\"%s\"",
 49				 audit_ptrace_mask(aad(sa)->request));
 50
 51		if (aad(sa)->denied & AA_PTRACE_PERM_MASK) {
 52			audit_log_format(ab, " denied_mask=\"%s\"",
 53					 audit_ptrace_mask(aad(sa)->denied));
 54		}
 55	}
 56	audit_log_format(ab, " peer=");
 57	aa_label_xaudit(ab, labels_ns(aad(sa)->label), aad(sa)->peer,
 58			FLAGS_NONE, GFP_ATOMIC);
 59}
 60
 61/* assumes check for PROFILE_MEDIATES is already done */
 62/* TODO: conditionals */
 63static int profile_ptrace_perm(struct aa_profile *profile,
 64			     struct aa_label *peer, u32 request,
 65			     struct common_audit_data *sa)
 66{
 67	struct aa_perms perms = { };
 68
 69	aad(sa)->peer = peer;
 70	aa_profile_match_label(profile, peer, AA_CLASS_PTRACE, request,
 71			       &perms);
 72	aa_apply_modes_to_perms(profile, &perms);
 73	return aa_check_perms(profile, &perms, request, sa, audit_ptrace_cb);
 74}
 75
 76static int profile_tracee_perm(struct aa_profile *tracee,
 77			       struct aa_label *tracer, u32 request,
 78			       struct common_audit_data *sa)
 79{
 80	if (profile_unconfined(tracee) || unconfined(tracer) ||
 81	    !PROFILE_MEDIATES(tracee, AA_CLASS_PTRACE))
 82		return 0;
 83
 84	return profile_ptrace_perm(tracee, tracer, request, sa);
 85}
 86
 87static int profile_tracer_perm(struct aa_profile *tracer,
 88			       struct aa_label *tracee, u32 request,
 89			       struct common_audit_data *sa)
 90{
 91	if (profile_unconfined(tracer))
 92		return 0;
 93
 94	if (PROFILE_MEDIATES(tracer, AA_CLASS_PTRACE))
 95		return profile_ptrace_perm(tracer, tracee, request, sa);
 96
 97	/* profile uses the old style capability check for ptrace */
 98	if (&tracer->label == tracee)
 99		return 0;
100
101	aad(sa)->label = &tracer->label;
102	aad(sa)->peer = tracee;
103	aad(sa)->request = 0;
104	aad(sa)->error = aa_capable(&tracer->label, CAP_SYS_PTRACE,
105				    CAP_OPT_NONE);
106
107	return aa_audit(AUDIT_APPARMOR_AUTO, tracer, sa, audit_ptrace_cb);
108}
109
110/**
111 * aa_may_ptrace - test if tracer task can trace the tracee
112 * @tracer: label of the task doing the tracing  (NOT NULL)
113 * @tracee: task label to be traced
114 * @request: permission request
115 *
116 * Returns: %0 else error code if permission denied or error
117 */
118int aa_may_ptrace(struct aa_label *tracer, struct aa_label *tracee,
119		  u32 request)
120{
121	struct aa_profile *profile;
122	u32 xrequest = request << PTRACE_PERM_SHIFT;
123	DEFINE_AUDIT_DATA(sa, LSM_AUDIT_DATA_NONE, OP_PTRACE);
124
125	return xcheck_labels(tracer, tracee, profile,
126			profile_tracer_perm(profile, tracee, request, &sa),
127			profile_tracee_perm(profile, tracer, xrequest, &sa));
128}
129
130
131static inline int map_signal_num(int sig)
132{
133	if (sig > SIGRTMAX)
134		return SIGUNKNOWN;
135	else if (sig >= SIGRTMIN)
136		return sig - SIGRTMIN + SIGRT_BASE;
137	else if (sig < MAXMAPPED_SIG)
138		return sig_map[sig];
139	return SIGUNKNOWN;
140}
141
142/**
143 * audit_signal_mask - convert mask to permission string
 
144 * @mask: permission mask to convert
145 *
146 * Returns: pointer to static string
147 */
148static const char *audit_signal_mask(u32 mask)
149{
150	if (mask & MAY_READ)
151		return "receive";
152	if (mask & MAY_WRITE)
153		return "send";
154	return "";
155}
156
157/**
158 * audit_cb - call back for signal specific audit fields
159 * @ab: audit_buffer  (NOT NULL)
160 * @va: audit struct to audit values of  (NOT NULL)
161 */
162static void audit_signal_cb(struct audit_buffer *ab, void *va)
163{
164	struct common_audit_data *sa = va;
165
166	if (aad(sa)->request & AA_SIGNAL_PERM_MASK) {
167		audit_log_format(ab, " requested_mask=\"%s\"",
168				 audit_signal_mask(aad(sa)->request));
169		if (aad(sa)->denied & AA_SIGNAL_PERM_MASK) {
170			audit_log_format(ab, " denied_mask=\"%s\"",
171					 audit_signal_mask(aad(sa)->denied));
172		}
173	}
174	if (aad(sa)->signal == SIGUNKNOWN)
175		audit_log_format(ab, "signal=unknown(%d)",
176				 aad(sa)->unmappedsig);
177	else if (aad(sa)->signal < MAXMAPPED_SIGNAME)
178		audit_log_format(ab, " signal=%s", sig_names[aad(sa)->signal]);
179	else
180		audit_log_format(ab, " signal=rtmin+%d",
181				 aad(sa)->signal - SIGRT_BASE);
182	audit_log_format(ab, " peer=");
183	aa_label_xaudit(ab, labels_ns(aad(sa)->label), aad(sa)->peer,
184			FLAGS_NONE, GFP_ATOMIC);
185}
186
187static int profile_signal_perm(struct aa_profile *profile,
188			       struct aa_label *peer, u32 request,
189			       struct common_audit_data *sa)
190{
191	struct aa_perms perms;
192	unsigned int state;
193
194	if (profile_unconfined(profile) ||
195	    !PROFILE_MEDIATES(profile, AA_CLASS_SIGNAL))
196		return 0;
197
198	aad(sa)->peer = peer;
199	/* TODO: secondary cache check <profile, profile, perm> */
200	state = aa_dfa_next(profile->policy.dfa,
201			    profile->policy.start[AA_CLASS_SIGNAL],
202			    aad(sa)->signal);
203	aa_label_match(profile, peer, state, false, request, &perms);
204	aa_apply_modes_to_perms(profile, &perms);
205	return aa_check_perms(profile, &perms, request, sa, audit_signal_cb);
206}
207
208int aa_may_signal(struct aa_label *sender, struct aa_label *target, int sig)
209{
210	struct aa_profile *profile;
211	DEFINE_AUDIT_DATA(sa, LSM_AUDIT_DATA_NONE, OP_SIGNAL);
212
213	aad(&sa)->signal = map_signal_num(sig);
214	aad(&sa)->unmappedsig = sig;
215	return xcheck_labels(sender, target, profile,
216			profile_signal_perm(profile, target, MAY_WRITE, &sa),
217			profile_signal_perm(profile, sender, MAY_READ, &sa));
218}