1 // SPDX-License-Identifier: GPL-2.0-only
3 * AppArmor security module
5 * This file contains AppArmor ipc mediation
7 * Copyright (C) 1998-2008 Novell/SUSE
8 * Copyright 2009-2017 Canonical Ltd.
11 #include <linux/gfp.h>
12 #include <linux/ptrace.h>
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"
22 * audit_ptrace_mask - convert mask to permission string
23 * @mask: permission mask to convert
25 * Returns: pointer to static string
27 static const char *audit_ptrace_mask(u32 mask
)
36 case AA_MAY_BE_TRACED
:
42 /* call back to audit ptrace fields */
43 static void audit_ptrace_cb(struct audit_buffer
*ab
, void *va
)
45 struct common_audit_data
*sa
= va
;
47 if (aad(sa
)->request
& AA_PTRACE_PERM_MASK
) {
48 audit_log_format(ab
, " requested_mask=\"%s\"",
49 audit_ptrace_mask(aad(sa
)->request
));
51 if (aad(sa
)->denied
& AA_PTRACE_PERM_MASK
) {
52 audit_log_format(ab
, " denied_mask=\"%s\"",
53 audit_ptrace_mask(aad(sa
)->denied
));
56 audit_log_format(ab
, " peer=");
57 aa_label_xaudit(ab
, labels_ns(aad(sa
)->label
), aad(sa
)->peer
,
58 FLAGS_NONE
, GFP_ATOMIC
);
61 /* assumes check for PROFILE_MEDIATES is already done */
62 /* TODO: conditionals */
63 static int profile_ptrace_perm(struct aa_profile
*profile
,
64 struct aa_label
*peer
, u32 request
,
65 struct common_audit_data
*sa
)
67 struct aa_perms perms
= { };
70 aa_profile_match_label(profile
, peer
, AA_CLASS_PTRACE
, request
,
72 aa_apply_modes_to_perms(profile
, &perms
);
73 return aa_check_perms(profile
, &perms
, request
, sa
, audit_ptrace_cb
);
76 static int profile_tracee_perm(struct aa_profile
*tracee
,
77 struct aa_label
*tracer
, u32 request
,
78 struct common_audit_data
*sa
)
80 if (profile_unconfined(tracee
) || unconfined(tracer
) ||
81 !PROFILE_MEDIATES(tracee
, AA_CLASS_PTRACE
))
84 return profile_ptrace_perm(tracee
, tracer
, request
, sa
);
87 static int profile_tracer_perm(struct aa_profile
*tracer
,
88 struct aa_label
*tracee
, u32 request
,
89 struct common_audit_data
*sa
)
91 if (profile_unconfined(tracer
))
94 if (PROFILE_MEDIATES(tracer
, AA_CLASS_PTRACE
))
95 return profile_ptrace_perm(tracer
, tracee
, request
, sa
);
97 /* profile uses the old style capability check for ptrace */
98 if (&tracer
->label
== tracee
)
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
,
107 return aa_audit(AUDIT_APPARMOR_AUTO
, tracer
, sa
, audit_ptrace_cb
);
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
116 * Returns: %0 else error code if permission denied or error
118 int aa_may_ptrace(struct aa_label
*tracer
, struct aa_label
*tracee
,
121 struct aa_profile
*profile
;
122 u32 xrequest
= request
<< PTRACE_PERM_SHIFT
;
123 DEFINE_AUDIT_DATA(sa
, LSM_AUDIT_DATA_NONE
, OP_PTRACE
);
125 return xcheck_labels(tracer
, tracee
, profile
,
126 profile_tracer_perm(profile
, tracee
, request
, &sa
),
127 profile_tracee_perm(profile
, tracer
, xrequest
, &sa
));
131 static inline int map_signal_num(int sig
)
135 else if (sig
>= SIGRTMIN
)
136 return sig
- SIGRTMIN
+ SIGRT_BASE
;
137 else if (sig
< MAXMAPPED_SIG
)
143 * audit_signal_mask - convert mask to permission string
144 * @mask: permission mask to convert
146 * Returns: pointer to static string
148 static const char *audit_signal_mask(u32 mask
)
152 if (mask
& MAY_WRITE
)
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)
162 static void audit_signal_cb(struct audit_buffer
*ab
, void *va
)
164 struct common_audit_data
*sa
= va
;
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
));
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
]);
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
);
187 static int profile_signal_perm(struct aa_profile
*profile
,
188 struct aa_label
*peer
, u32 request
,
189 struct common_audit_data
*sa
)
191 struct aa_perms perms
;
194 if (profile_unconfined(profile
) ||
195 !PROFILE_MEDIATES(profile
, AA_CLASS_SIGNAL
))
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
],
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
);
208 int aa_may_signal(struct aa_label
*sender
, struct aa_label
*target
, int sig
)
210 struct aa_profile
*profile
;
211 DEFINE_AUDIT_DATA(sa
, LSM_AUDIT_DATA_NONE
, OP_SIGNAL
);
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
));