Branch data Line data Source code
1 : : /*
2 : : * AppArmor security module
3 : : *
4 : : * This file contains AppArmor ipc mediation
5 : : *
6 : : * Copyright (C) 1998-2008 Novell/SUSE
7 : : * Copyright 2009-2010 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/context.h"
21 : : #include "include/policy.h"
22 : : #include "include/ipc.h"
23 : :
24 : : /* call back to audit ptrace fields */
25 : 0 : static void audit_cb(struct audit_buffer *ab, void *va)
26 : : {
27 : : struct common_audit_data *sa = va;
28 : 0 : audit_log_format(ab, " target=");
29 : 0 : audit_log_untrustedstring(ab, sa->aad->target);
30 : 0 : }
31 : :
32 : : /**
33 : : * aa_audit_ptrace - do auditing for ptrace
34 : : * @profile: profile being enforced (NOT NULL)
35 : : * @target: profile being traced (NOT NULL)
36 : : * @error: error condition
37 : : *
38 : : * Returns: %0 or error code
39 : : */
40 : 0 : static int aa_audit_ptrace(struct aa_profile *profile,
41 : : struct aa_profile *target, int error)
42 : : {
43 : : struct common_audit_data sa;
44 : 0 : struct apparmor_audit_data aad = {0,};
45 : 0 : sa.type = LSM_AUDIT_DATA_NONE;
46 : 0 : sa.aad = &aad;
47 : 0 : aad.op = OP_PTRACE;
48 : 0 : aad.target = target;
49 : 0 : aad.error = error;
50 : :
51 : 0 : return aa_audit(AUDIT_APPARMOR_AUTO, profile, GFP_ATOMIC, &sa,
52 : : audit_cb);
53 : : }
54 : :
55 : : /**
56 : : * aa_may_ptrace - test if tracer task can trace the tracee
57 : : * @tracer: profile of the task doing the tracing (NOT NULL)
58 : : * @tracee: task to be traced
59 : : * @mode: whether PTRACE_MODE_READ || PTRACE_MODE_ATTACH
60 : : *
61 : : * Returns: %0 else error code if permission denied or error
62 : : */
63 : 0 : int aa_may_ptrace(struct aa_profile *tracer, struct aa_profile *tracee,
64 : : unsigned int mode)
65 : : {
66 : : /* TODO: currently only based on capability, not extended ptrace
67 : : * rules,
68 : : * Test mode for PTRACE_MODE_READ || PTRACE_MODE_ATTACH
69 : : */
70 : :
71 [ # # ][ # # ]: 0 : if (unconfined(tracer) || tracer == tracee)
[ # # ][ # # ]
72 : : return 0;
73 : : /* log this capability request */
74 : 0 : return aa_capable(tracer, CAP_SYS_PTRACE, 1);
75 : : }
76 : :
77 : : /**
78 : : * aa_ptrace - do ptrace permission check and auditing
79 : : * @tracer: task doing the tracing (NOT NULL)
80 : : * @tracee: task being traced (NOT NULL)
81 : : * @mode: ptrace mode either PTRACE_MODE_READ || PTRACE_MODE_ATTACH
82 : : *
83 : : * Returns: %0 else error code if permission denied or error
84 : : */
85 : 0 : int aa_ptrace(struct task_struct *tracer, struct task_struct *tracee,
86 : : unsigned int mode)
87 : : {
88 : : /*
89 : : * tracer can ptrace tracee when
90 : : * - tracer is unconfined ||
91 : : * - tracer is in complain mode
92 : : * - tracer has rules allowing it to trace tracee currently this is:
93 : : * - confined by the same profile ||
94 : : * - tracer profile has CAP_SYS_PTRACE
95 : : */
96 : :
97 : 89860 : struct aa_profile *tracer_p = aa_get_task_profile(tracer);
98 : : int error = 0;
99 : :
100 [ - + ]: 89860 : if (!unconfined(tracer_p)) {
101 : 0 : struct aa_profile *tracee_p = aa_get_task_profile(tracee);
102 : :
103 : : error = aa_may_ptrace(tracer_p, tracee_p, mode);
104 : 0 : error = aa_audit_ptrace(tracer_p, tracee_p, error);
105 : :
106 : : aa_put_profile(tracee_p);
107 : : }
108 : : aa_put_profile(tracer_p);
109 : :
110 : 89860 : return error;
111 : : }
|