root/security/apparmor/ipc.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. audit_ptrace_mask
  2. audit_ptrace_cb
  3. profile_ptrace_perm
  4. profile_tracee_perm
  5. profile_tracer_perm
  6. aa_may_ptrace
  7. map_signal_num
  8. audit_signal_mask
  9. audit_signal_cb
  10. profile_signal_perm
  11. aa_may_signal

   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  * @buffer: buffer to write string to (NOT NULL)
  24  * @mask: permission mask to convert
  25  */
  26 static void audit_ptrace_mask(struct audit_buffer *ab, u32 mask)
  27 {
  28         switch (mask) {
  29         case MAY_READ:
  30                 audit_log_string(ab, "read");
  31                 break;
  32         case MAY_WRITE:
  33                 audit_log_string(ab, "trace");
  34                 break;
  35         case AA_MAY_BE_READ:
  36                 audit_log_string(ab, "readby");
  37                 break;
  38         case AA_MAY_BE_TRACED:
  39                 audit_log_string(ab, "tracedby");
  40                 break;
  41         }
  42 }
  43 
  44 /* call back to audit ptrace fields */
  45 static void audit_ptrace_cb(struct audit_buffer *ab, void *va)
  46 {
  47         struct common_audit_data *sa = va;
  48 
  49         if (aad(sa)->request & AA_PTRACE_PERM_MASK) {
  50                 audit_log_format(ab, " requested_mask=");
  51                 audit_ptrace_mask(ab, aad(sa)->request);
  52 
  53                 if (aad(sa)->denied & AA_PTRACE_PERM_MASK) {
  54                         audit_log_format(ab, " denied_mask=");
  55                         audit_ptrace_mask(ab, aad(sa)->denied);
  56                 }
  57         }
  58         audit_log_format(ab, " peer=");
  59         aa_label_xaudit(ab, labels_ns(aad(sa)->label), aad(sa)->peer,
  60                         FLAGS_NONE, GFP_ATOMIC);
  61 }
  62 
  63 /* assumes check for PROFILE_MEDIATES is already done */
  64 /* TODO: conditionals */
  65 static int profile_ptrace_perm(struct aa_profile *profile,
  66                              struct aa_label *peer, u32 request,
  67                              struct common_audit_data *sa)
  68 {
  69         struct aa_perms perms = { };
  70 
  71         aad(sa)->peer = peer;
  72         aa_profile_match_label(profile, peer, AA_CLASS_PTRACE, request,
  73                                &perms);
  74         aa_apply_modes_to_perms(profile, &perms);
  75         return aa_check_perms(profile, &perms, request, sa, audit_ptrace_cb);
  76 }
  77 
  78 static int profile_tracee_perm(struct aa_profile *tracee,
  79                                struct aa_label *tracer, u32 request,
  80                                struct common_audit_data *sa)
  81 {
  82         if (profile_unconfined(tracee) || unconfined(tracer) ||
  83             !PROFILE_MEDIATES(tracee, AA_CLASS_PTRACE))
  84                 return 0;
  85 
  86         return profile_ptrace_perm(tracee, tracer, request, sa);
  87 }
  88 
  89 static int profile_tracer_perm(struct aa_profile *tracer,
  90                                struct aa_label *tracee, u32 request,
  91                                struct common_audit_data *sa)
  92 {
  93         if (profile_unconfined(tracer))
  94                 return 0;
  95 
  96         if (PROFILE_MEDIATES(tracer, AA_CLASS_PTRACE))
  97                 return profile_ptrace_perm(tracer, tracee, request, sa);
  98 
  99         /* profile uses the old style capability check for ptrace */
 100         if (&tracer->label == tracee)
 101                 return 0;
 102 
 103         aad(sa)->label = &tracer->label;
 104         aad(sa)->peer = tracee;
 105         aad(sa)->request = 0;
 106         aad(sa)->error = aa_capable(&tracer->label, CAP_SYS_PTRACE,
 107                                     CAP_OPT_NONE);
 108 
 109         return aa_audit(AUDIT_APPARMOR_AUTO, tracer, sa, audit_ptrace_cb);
 110 }
 111 
 112 /**
 113  * aa_may_ptrace - test if tracer task can trace the tracee
 114  * @tracer: label of the task doing the tracing  (NOT NULL)
 115  * @tracee: task label to be traced
 116  * @request: permission request
 117  *
 118  * Returns: %0 else error code if permission denied or error
 119  */
 120 int aa_may_ptrace(struct aa_label *tracer, struct aa_label *tracee,
 121                   u32 request)
 122 {
 123         struct aa_profile *profile;
 124         u32 xrequest = request << PTRACE_PERM_SHIFT;
 125         DEFINE_AUDIT_DATA(sa, LSM_AUDIT_DATA_NONE, OP_PTRACE);
 126 
 127         return xcheck_labels(tracer, tracee, profile,
 128                         profile_tracer_perm(profile, tracee, request, &sa),
 129                         profile_tracee_perm(profile, tracer, xrequest, &sa));
 130 }
 131 
 132 
 133 static inline int map_signal_num(int sig)
 134 {
 135         if (sig > SIGRTMAX)
 136                 return SIGUNKNOWN;
 137         else if (sig >= SIGRTMIN)
 138                 return sig - SIGRTMIN + SIGRT_BASE;
 139         else if (sig < MAXMAPPED_SIG)
 140                 return sig_map[sig];
 141         return SIGUNKNOWN;
 142 }
 143 
 144 /**
 145  * audit_file_mask - convert mask to permission string
 146  * @buffer: buffer to write string to (NOT NULL)
 147  * @mask: permission mask to convert
 148  */
 149 static void audit_signal_mask(struct audit_buffer *ab, u32 mask)
 150 {
 151         if (mask & MAY_READ)
 152                 audit_log_string(ab, "receive");
 153         if (mask & MAY_WRITE)
 154                 audit_log_string(ab, "send");
 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  */
 162 static 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=");
 168                 audit_signal_mask(ab, aad(sa)->request);
 169                 if (aad(sa)->denied & AA_SIGNAL_PERM_MASK) {
 170                         audit_log_format(ab, " denied_mask=");
 171                         audit_signal_mask(ab, 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 
 187 static 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 
 208 int 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 }

/* [<][>][^][v][top][bottom][index][help] */