ipc.c 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234
  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. #include <linux/gfp.h>
  15. #include <linux/ptrace.h>
  16. #include "include/audit.h"
  17. #include "include/capability.h"
  18. #include "include/context.h"
  19. #include "include/policy.h"
  20. #include "include/ipc.h"
  21. #include "include/sig_names.h"
  22. /**
  23. * audit_ptrace_mask - convert mask to permission string
  24. * @buffer: buffer to write string to (NOT NULL)
  25. * @mask: permission mask to convert
  26. */
  27. static void audit_ptrace_mask(struct audit_buffer *ab, u32 mask)
  28. {
  29. switch (mask) {
  30. case MAY_READ:
  31. audit_log_string(ab, "read");
  32. break;
  33. case MAY_WRITE:
  34. audit_log_string(ab, "trace");
  35. break;
  36. case AA_MAY_BE_READ:
  37. audit_log_string(ab, "readby");
  38. break;
  39. case AA_MAY_BE_TRACED:
  40. audit_log_string(ab, "tracedby");
  41. break;
  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. if (aad(sa)->request & AA_PTRACE_PERM_MASK) {
  49. audit_log_format(ab, " requested_mask=");
  50. audit_ptrace_mask(ab, aad(sa)->request);
  51. if (aad(sa)->denied & AA_PTRACE_PERM_MASK) {
  52. audit_log_format(ab, " denied_mask=");
  53. audit_ptrace_mask(ab, 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. /* assumes check for PROFILE_MEDIATES is already done */
  61. /* TODO: conditionals */
  62. static int profile_ptrace_perm(struct aa_profile *profile,
  63. struct aa_label *peer, u32 request,
  64. struct common_audit_data *sa)
  65. {
  66. struct aa_perms perms = { };
  67. aad(sa)->peer = peer;
  68. aa_profile_match_label(profile, peer, AA_CLASS_PTRACE, request,
  69. &perms);
  70. aa_apply_modes_to_perms(profile, &perms);
  71. return aa_check_perms(profile, &perms, request, sa, audit_ptrace_cb);
  72. }
  73. static int profile_tracee_perm(struct aa_profile *tracee,
  74. struct aa_label *tracer, u32 request,
  75. struct common_audit_data *sa)
  76. {
  77. if (profile_unconfined(tracee) || unconfined(tracer) ||
  78. !PROFILE_MEDIATES(tracee, AA_CLASS_PTRACE))
  79. return 0;
  80. return profile_ptrace_perm(tracee, tracer, request, sa);
  81. }
  82. static int profile_tracer_perm(struct aa_profile *tracer,
  83. struct aa_label *tracee, u32 request,
  84. struct common_audit_data *sa)
  85. {
  86. if (profile_unconfined(tracer))
  87. return 0;
  88. if (PROFILE_MEDIATES(tracer, AA_CLASS_PTRACE))
  89. return profile_ptrace_perm(tracer, tracee, request, sa);
  90. /* profile uses the old style capability check for ptrace */
  91. if (&tracer->label == tracee)
  92. return 0;
  93. aad(sa)->label = &tracer->label;
  94. aad(sa)->peer = tracee;
  95. aad(sa)->request = 0;
  96. aad(sa)->error = aa_capable(&tracer->label, CAP_SYS_PTRACE, 1);
  97. return aa_audit(AUDIT_APPARMOR_AUTO, tracer, sa, audit_ptrace_cb);
  98. }
  99. /**
  100. * aa_may_ptrace - test if tracer task can trace the tracee
  101. * @tracer: label of the task doing the tracing (NOT NULL)
  102. * @tracee: task label to be traced
  103. * @request: permission request
  104. *
  105. * Returns: %0 else error code if permission denied or error
  106. */
  107. int aa_may_ptrace(struct aa_label *tracer, struct aa_label *tracee,
  108. u32 request)
  109. {
  110. struct aa_profile *profile;
  111. u32 xrequest = request << PTRACE_PERM_SHIFT;
  112. DEFINE_AUDIT_DATA(sa, LSM_AUDIT_DATA_NONE, OP_PTRACE);
  113. return xcheck_labels(tracer, tracee, profile,
  114. profile_tracer_perm(profile, tracee, request, &sa),
  115. profile_tracee_perm(profile, tracer, xrequest, &sa));
  116. }
  117. static inline int map_signal_num(int sig)
  118. {
  119. if (sig > SIGRTMAX)
  120. return SIGUNKNOWN;
  121. else if (sig >= SIGRTMIN)
  122. return sig - SIGRTMIN + 128; /* rt sigs mapped to 128 */
  123. else if (sig < MAXMAPPED_SIG)
  124. return sig_map[sig];
  125. return SIGUNKNOWN;
  126. }
  127. /**
  128. * audit_file_mask - convert mask to permission string
  129. * @buffer: buffer to write string to (NOT NULL)
  130. * @mask: permission mask to convert
  131. */
  132. static void audit_signal_mask(struct audit_buffer *ab, u32 mask)
  133. {
  134. if (mask & MAY_READ)
  135. audit_log_string(ab, "receive");
  136. if (mask & MAY_WRITE)
  137. audit_log_string(ab, "send");
  138. }
  139. /**
  140. * audit_cb - call back for signal specific audit fields
  141. * @ab: audit_buffer (NOT NULL)
  142. * @va: audit struct to audit values of (NOT NULL)
  143. */
  144. static void audit_signal_cb(struct audit_buffer *ab, void *va)
  145. {
  146. struct common_audit_data *sa = va;
  147. if (aad(sa)->request & AA_SIGNAL_PERM_MASK) {
  148. audit_log_format(ab, " requested_mask=");
  149. audit_signal_mask(ab, aad(sa)->request);
  150. if (aad(sa)->denied & AA_SIGNAL_PERM_MASK) {
  151. audit_log_format(ab, " denied_mask=");
  152. audit_signal_mask(ab, aad(sa)->denied);
  153. }
  154. }
  155. if (aad(sa)->signal < MAXMAPPED_SIGNAME)
  156. audit_log_format(ab, " signal=%s", sig_names[aad(sa)->signal]);
  157. else
  158. audit_log_format(ab, " signal=rtmin+%d",
  159. aad(sa)->signal - 128);
  160. audit_log_format(ab, " peer=");
  161. aa_label_xaudit(ab, labels_ns(aad(sa)->label), aad(sa)->peer,
  162. FLAGS_NONE, GFP_ATOMIC);
  163. }
  164. /* TODO: update to handle compound name&name2, conditionals */
  165. static void profile_match_signal(struct aa_profile *profile, const char *label,
  166. int signal, struct aa_perms *perms)
  167. {
  168. unsigned int state;
  169. /* TODO: secondary cache check <profile, profile, perm> */
  170. state = aa_dfa_next(profile->policy.dfa,
  171. profile->policy.start[AA_CLASS_SIGNAL],
  172. signal);
  173. state = aa_dfa_match(profile->policy.dfa, state, label);
  174. aa_compute_perms(profile->policy.dfa, state, perms);
  175. }
  176. static int profile_signal_perm(struct aa_profile *profile,
  177. struct aa_profile *peer, u32 request,
  178. struct common_audit_data *sa)
  179. {
  180. struct aa_perms perms;
  181. if (profile_unconfined(profile) ||
  182. !PROFILE_MEDIATES(profile, AA_CLASS_SIGNAL))
  183. return 0;
  184. aad(sa)->peer = &peer->label;
  185. profile_match_signal(profile, peer->base.hname, aad(sa)->signal,
  186. &perms);
  187. aa_apply_modes_to_perms(profile, &perms);
  188. return aa_check_perms(profile, &perms, request, sa, audit_signal_cb);
  189. }
  190. static int aa_signal_cross_perm(struct aa_profile *sender,
  191. struct aa_profile *target,
  192. struct common_audit_data *sa)
  193. {
  194. return xcheck(profile_signal_perm(sender, target, MAY_WRITE, sa),
  195. profile_signal_perm(target, sender, MAY_READ, sa));
  196. }
  197. int aa_may_signal(struct aa_label *sender, struct aa_label *target, int sig)
  198. {
  199. DEFINE_AUDIT_DATA(sa, LSM_AUDIT_DATA_NONE, OP_SIGNAL);
  200. aad(&sa)->signal = map_signal_num(sig);
  201. return xcheck_labels_profiles(sender, target, aa_signal_cross_perm,
  202. &sa);
  203. }