diff options
-rw-r--r-- | include/linux/lsm_audit.h | 54 | ||||
-rw-r--r-- | security/apparmor/audit.c | 38 | ||||
-rw-r--r-- | security/apparmor/capability.c | 6 | ||||
-rw-r--r-- | security/apparmor/file.c | 54 | ||||
-rw-r--r-- | security/apparmor/include/audit.h | 28 | ||||
-rw-r--r-- | security/apparmor/ipc.c | 10 | ||||
-rw-r--r-- | security/apparmor/lib.c | 4 | ||||
-rw-r--r-- | security/apparmor/lsm.c | 8 | ||||
-rw-r--r-- | security/apparmor/policy.c | 10 | ||||
-rw-r--r-- | security/apparmor/policy_unpack.c | 20 | ||||
-rw-r--r-- | security/apparmor/resource.c | 12 | ||||
-rw-r--r-- | security/selinux/avc.c | 34 | ||||
-rw-r--r-- | security/selinux/hooks.c | 71 | ||||
-rw-r--r-- | security/selinux/include/avc.h | 16 | ||||
-rw-r--r-- | security/smack/smack.h | 13 | ||||
-rw-r--r-- | security/smack/smack_access.c | 11 |
16 files changed, 242 insertions, 147 deletions
diff --git a/include/linux/lsm_audit.h b/include/linux/lsm_audit.h index eab507f2b1cb..6f4fb37aac88 100644 --- a/include/linux/lsm_audit.h +++ b/include/linux/lsm_audit.h | |||
@@ -72,61 +72,15 @@ struct common_audit_data { | |||
72 | /* this union contains LSM specific data */ | 72 | /* this union contains LSM specific data */ |
73 | union { | 73 | union { |
74 | #ifdef CONFIG_SECURITY_SMACK | 74 | #ifdef CONFIG_SECURITY_SMACK |
75 | /* SMACK data */ | 75 | struct smack_audit_data *smack_audit_data; |
76 | struct smack_audit_data { | ||
77 | const char *function; | ||
78 | char *subject; | ||
79 | char *object; | ||
80 | char *request; | ||
81 | int result; | ||
82 | } smack_audit_data; | ||
83 | #endif | 76 | #endif |
84 | #ifdef CONFIG_SECURITY_SELINUX | 77 | #ifdef CONFIG_SECURITY_SELINUX |
85 | /* SELinux data */ | 78 | struct selinux_audit_data *selinux_audit_data; |
86 | struct { | ||
87 | u32 ssid; | ||
88 | u32 tsid; | ||
89 | u16 tclass; | ||
90 | u32 requested; | ||
91 | u32 audited; | ||
92 | u32 denied; | ||
93 | /* | ||
94 | * auditdeny is a bit tricky and unintuitive. See the | ||
95 | * comments in avc.c for it's meaning and usage. | ||
96 | */ | ||
97 | u32 auditdeny; | ||
98 | struct av_decision *avd; | ||
99 | int result; | ||
100 | } selinux_audit_data; | ||
101 | #endif | 79 | #endif |
102 | #ifdef CONFIG_SECURITY_APPARMOR | 80 | #ifdef CONFIG_SECURITY_APPARMOR |
103 | struct { | 81 | struct apparmor_audit_data *apparmor_audit_data; |
104 | int error; | ||
105 | int op; | ||
106 | int type; | ||
107 | void *profile; | ||
108 | const char *name; | ||
109 | const char *info; | ||
110 | union { | ||
111 | void *target; | ||
112 | struct { | ||
113 | long pos; | ||
114 | void *target; | ||
115 | } iface; | ||
116 | struct { | ||
117 | int rlim; | ||
118 | unsigned long max; | ||
119 | } rlim; | ||
120 | struct { | ||
121 | const char *target; | ||
122 | u32 request; | ||
123 | u32 denied; | ||
124 | uid_t ouid; | ||
125 | } fs; | ||
126 | }; | ||
127 | } apparmor_audit_data; | ||
128 | #endif | 82 | #endif |
129 | }; | 83 | }; /* per LSM data pointer union */ |
130 | /* these callback will be implemented by a specific LSM */ | 84 | /* these callback will be implemented by a specific LSM */ |
131 | void (*lsm_pre_audit)(struct audit_buffer *, void *); | 85 | void (*lsm_pre_audit)(struct audit_buffer *, void *); |
132 | void (*lsm_post_audit)(struct audit_buffer *, void *); | 86 | void (*lsm_post_audit)(struct audit_buffer *, void *); |
diff --git a/security/apparmor/audit.c b/security/apparmor/audit.c index 5ff67776a5ad..23f7eb658d9c 100644 --- a/security/apparmor/audit.c +++ b/security/apparmor/audit.c | |||
@@ -115,23 +115,23 @@ static void audit_pre(struct audit_buffer *ab, void *ca) | |||
115 | 115 | ||
116 | if (aa_g_audit_header) { | 116 | if (aa_g_audit_header) { |
117 | audit_log_format(ab, "apparmor="); | 117 | audit_log_format(ab, "apparmor="); |
118 | audit_log_string(ab, aa_audit_type[sa->aad.type]); | 118 | audit_log_string(ab, aa_audit_type[sa->aad->type]); |
119 | } | 119 | } |
120 | 120 | ||
121 | if (sa->aad.op) { | 121 | if (sa->aad->op) { |
122 | audit_log_format(ab, " operation="); | 122 | audit_log_format(ab, " operation="); |
123 | audit_log_string(ab, op_table[sa->aad.op]); | 123 | audit_log_string(ab, op_table[sa->aad->op]); |
124 | } | 124 | } |
125 | 125 | ||
126 | if (sa->aad.info) { | 126 | if (sa->aad->info) { |
127 | audit_log_format(ab, " info="); | 127 | audit_log_format(ab, " info="); |
128 | audit_log_string(ab, sa->aad.info); | 128 | audit_log_string(ab, sa->aad->info); |
129 | if (sa->aad.error) | 129 | if (sa->aad->error) |
130 | audit_log_format(ab, " error=%d", sa->aad.error); | 130 | audit_log_format(ab, " error=%d", sa->aad->error); |
131 | } | 131 | } |
132 | 132 | ||
133 | if (sa->aad.profile) { | 133 | if (sa->aad->profile) { |
134 | struct aa_profile *profile = sa->aad.profile; | 134 | struct aa_profile *profile = sa->aad->profile; |
135 | pid_t pid; | 135 | pid_t pid; |
136 | rcu_read_lock(); | 136 | rcu_read_lock(); |
137 | pid = rcu_dereference(tsk->real_parent)->pid; | 137 | pid = rcu_dereference(tsk->real_parent)->pid; |
@@ -145,9 +145,9 @@ static void audit_pre(struct audit_buffer *ab, void *ca) | |||
145 | audit_log_untrustedstring(ab, profile->base.hname); | 145 | audit_log_untrustedstring(ab, profile->base.hname); |
146 | } | 146 | } |
147 | 147 | ||
148 | if (sa->aad.name) { | 148 | if (sa->aad->name) { |
149 | audit_log_format(ab, " name="); | 149 | audit_log_format(ab, " name="); |
150 | audit_log_untrustedstring(ab, sa->aad.name); | 150 | audit_log_untrustedstring(ab, sa->aad->name); |
151 | } | 151 | } |
152 | } | 152 | } |
153 | 153 | ||
@@ -159,7 +159,7 @@ static void audit_pre(struct audit_buffer *ab, void *ca) | |||
159 | void aa_audit_msg(int type, struct common_audit_data *sa, | 159 | void aa_audit_msg(int type, struct common_audit_data *sa, |
160 | void (*cb) (struct audit_buffer *, void *)) | 160 | void (*cb) (struct audit_buffer *, void *)) |
161 | { | 161 | { |
162 | sa->aad.type = type; | 162 | sa->aad->type = type; |
163 | sa->lsm_pre_audit = audit_pre; | 163 | sa->lsm_pre_audit = audit_pre; |
164 | sa->lsm_post_audit = cb; | 164 | sa->lsm_post_audit = cb; |
165 | common_lsm_audit(sa); | 165 | common_lsm_audit(sa); |
@@ -184,7 +184,7 @@ int aa_audit(int type, struct aa_profile *profile, gfp_t gfp, | |||
184 | BUG_ON(!profile); | 184 | BUG_ON(!profile); |
185 | 185 | ||
186 | if (type == AUDIT_APPARMOR_AUTO) { | 186 | if (type == AUDIT_APPARMOR_AUTO) { |
187 | if (likely(!sa->aad.error)) { | 187 | if (likely(!sa->aad->error)) { |
188 | if (AUDIT_MODE(profile) != AUDIT_ALL) | 188 | if (AUDIT_MODE(profile) != AUDIT_ALL) |
189 | return 0; | 189 | return 0; |
190 | type = AUDIT_APPARMOR_AUDIT; | 190 | type = AUDIT_APPARMOR_AUDIT; |
@@ -196,21 +196,21 @@ int aa_audit(int type, struct aa_profile *profile, gfp_t gfp, | |||
196 | if (AUDIT_MODE(profile) == AUDIT_QUIET || | 196 | if (AUDIT_MODE(profile) == AUDIT_QUIET || |
197 | (type == AUDIT_APPARMOR_DENIED && | 197 | (type == AUDIT_APPARMOR_DENIED && |
198 | AUDIT_MODE(profile) == AUDIT_QUIET)) | 198 | AUDIT_MODE(profile) == AUDIT_QUIET)) |
199 | return sa->aad.error; | 199 | return sa->aad->error; |
200 | 200 | ||
201 | if (KILL_MODE(profile) && type == AUDIT_APPARMOR_DENIED) | 201 | if (KILL_MODE(profile) && type == AUDIT_APPARMOR_DENIED) |
202 | type = AUDIT_APPARMOR_KILL; | 202 | type = AUDIT_APPARMOR_KILL; |
203 | 203 | ||
204 | if (!unconfined(profile)) | 204 | if (!unconfined(profile)) |
205 | sa->aad.profile = profile; | 205 | sa->aad->profile = profile; |
206 | 206 | ||
207 | aa_audit_msg(type, sa, cb); | 207 | aa_audit_msg(type, sa, cb); |
208 | 208 | ||
209 | if (sa->aad.type == AUDIT_APPARMOR_KILL) | 209 | if (sa->aad->type == AUDIT_APPARMOR_KILL) |
210 | (void)send_sig_info(SIGKILL, NULL, sa->tsk ? sa->tsk : current); | 210 | (void)send_sig_info(SIGKILL, NULL, sa->tsk ? sa->tsk : current); |
211 | 211 | ||
212 | if (sa->aad.type == AUDIT_APPARMOR_ALLOWED) | 212 | if (sa->aad->type == AUDIT_APPARMOR_ALLOWED) |
213 | return complain_error(sa->aad.error); | 213 | return complain_error(sa->aad->error); |
214 | 214 | ||
215 | return sa->aad.error; | 215 | return sa->aad->error; |
216 | } | 216 | } |
diff --git a/security/apparmor/capability.c b/security/apparmor/capability.c index 9982c48def4e..088dba3bf7dc 100644 --- a/security/apparmor/capability.c +++ b/security/apparmor/capability.c | |||
@@ -64,11 +64,13 @@ static int audit_caps(struct aa_profile *profile, struct task_struct *task, | |||
64 | struct audit_cache *ent; | 64 | struct audit_cache *ent; |
65 | int type = AUDIT_APPARMOR_AUTO; | 65 | int type = AUDIT_APPARMOR_AUTO; |
66 | struct common_audit_data sa; | 66 | struct common_audit_data sa; |
67 | struct apparmor_audit_data aad = {0,}; | ||
67 | COMMON_AUDIT_DATA_INIT(&sa, CAP); | 68 | COMMON_AUDIT_DATA_INIT(&sa, CAP); |
69 | sa.aad = &aad; | ||
68 | sa.tsk = task; | 70 | sa.tsk = task; |
69 | sa.u.cap = cap; | 71 | sa.u.cap = cap; |
70 | sa.aad.op = OP_CAPABLE; | 72 | sa.aad->op = OP_CAPABLE; |
71 | sa.aad.error = error; | 73 | sa.aad->error = error; |
72 | 74 | ||
73 | if (likely(!error)) { | 75 | if (likely(!error)) { |
74 | /* test if auditing is being forced */ | 76 | /* test if auditing is being forced */ |
diff --git a/security/apparmor/file.c b/security/apparmor/file.c index 5d176f2530c9..2f8fcba9ce4b 100644 --- a/security/apparmor/file.c +++ b/security/apparmor/file.c | |||
@@ -67,22 +67,22 @@ static void file_audit_cb(struct audit_buffer *ab, void *va) | |||
67 | struct common_audit_data *sa = va; | 67 | struct common_audit_data *sa = va; |
68 | uid_t fsuid = current_fsuid(); | 68 | uid_t fsuid = current_fsuid(); |
69 | 69 | ||
70 | if (sa->aad.fs.request & AA_AUDIT_FILE_MASK) { | 70 | if (sa->aad->fs.request & AA_AUDIT_FILE_MASK) { |
71 | audit_log_format(ab, " requested_mask="); | 71 | audit_log_format(ab, " requested_mask="); |
72 | audit_file_mask(ab, sa->aad.fs.request); | 72 | audit_file_mask(ab, sa->aad->fs.request); |
73 | } | 73 | } |
74 | if (sa->aad.fs.denied & AA_AUDIT_FILE_MASK) { | 74 | if (sa->aad->fs.denied & AA_AUDIT_FILE_MASK) { |
75 | audit_log_format(ab, " denied_mask="); | 75 | audit_log_format(ab, " denied_mask="); |
76 | audit_file_mask(ab, sa->aad.fs.denied); | 76 | audit_file_mask(ab, sa->aad->fs.denied); |
77 | } | 77 | } |
78 | if (sa->aad.fs.request & AA_AUDIT_FILE_MASK) { | 78 | if (sa->aad->fs.request & AA_AUDIT_FILE_MASK) { |
79 | audit_log_format(ab, " fsuid=%d", fsuid); | 79 | audit_log_format(ab, " fsuid=%d", fsuid); |
80 | audit_log_format(ab, " ouid=%d", sa->aad.fs.ouid); | 80 | audit_log_format(ab, " ouid=%d", sa->aad->fs.ouid); |
81 | } | 81 | } |
82 | 82 | ||
83 | if (sa->aad.fs.target) { | 83 | if (sa->aad->fs.target) { |
84 | audit_log_format(ab, " target="); | 84 | audit_log_format(ab, " target="); |
85 | audit_log_untrustedstring(ab, sa->aad.fs.target); | 85 | audit_log_untrustedstring(ab, sa->aad->fs.target); |
86 | } | 86 | } |
87 | } | 87 | } |
88 | 88 | ||
@@ -107,45 +107,47 @@ int aa_audit_file(struct aa_profile *profile, struct file_perms *perms, | |||
107 | { | 107 | { |
108 | int type = AUDIT_APPARMOR_AUTO; | 108 | int type = AUDIT_APPARMOR_AUTO; |
109 | struct common_audit_data sa; | 109 | struct common_audit_data sa; |
110 | struct apparmor_audit_data aad = {0,}; | ||
110 | COMMON_AUDIT_DATA_INIT(&sa, NONE); | 111 | COMMON_AUDIT_DATA_INIT(&sa, NONE); |
111 | sa.aad.op = op, | 112 | sa.aad = &aad; |
112 | sa.aad.fs.request = request; | 113 | aad.op = op, |
113 | sa.aad.name = name; | 114 | aad.fs.request = request; |
114 | sa.aad.fs.target = target; | 115 | aad.name = name; |
115 | sa.aad.fs.ouid = ouid; | 116 | aad.fs.target = target; |
116 | sa.aad.info = info; | 117 | aad.fs.ouid = ouid; |
117 | sa.aad.error = error; | 118 | aad.info = info; |
118 | 119 | aad.error = error; | |
119 | if (likely(!sa.aad.error)) { | 120 | |
121 | if (likely(!sa.aad->error)) { | ||
120 | u32 mask = perms->audit; | 122 | u32 mask = perms->audit; |
121 | 123 | ||
122 | if (unlikely(AUDIT_MODE(profile) == AUDIT_ALL)) | 124 | if (unlikely(AUDIT_MODE(profile) == AUDIT_ALL)) |
123 | mask = 0xffff; | 125 | mask = 0xffff; |
124 | 126 | ||
125 | /* mask off perms that are not being force audited */ | 127 | /* mask off perms that are not being force audited */ |
126 | sa.aad.fs.request &= mask; | 128 | sa.aad->fs.request &= mask; |
127 | 129 | ||
128 | if (likely(!sa.aad.fs.request)) | 130 | if (likely(!sa.aad->fs.request)) |
129 | return 0; | 131 | return 0; |
130 | type = AUDIT_APPARMOR_AUDIT; | 132 | type = AUDIT_APPARMOR_AUDIT; |
131 | } else { | 133 | } else { |
132 | /* only report permissions that were denied */ | 134 | /* only report permissions that were denied */ |
133 | sa.aad.fs.request = sa.aad.fs.request & ~perms->allow; | 135 | sa.aad->fs.request = sa.aad->fs.request & ~perms->allow; |
134 | 136 | ||
135 | if (sa.aad.fs.request & perms->kill) | 137 | if (sa.aad->fs.request & perms->kill) |
136 | type = AUDIT_APPARMOR_KILL; | 138 | type = AUDIT_APPARMOR_KILL; |
137 | 139 | ||
138 | /* quiet known rejects, assumes quiet and kill do not overlap */ | 140 | /* quiet known rejects, assumes quiet and kill do not overlap */ |
139 | if ((sa.aad.fs.request & perms->quiet) && | 141 | if ((sa.aad->fs.request & perms->quiet) && |
140 | AUDIT_MODE(profile) != AUDIT_NOQUIET && | 142 | AUDIT_MODE(profile) != AUDIT_NOQUIET && |
141 | AUDIT_MODE(profile) != AUDIT_ALL) | 143 | AUDIT_MODE(profile) != AUDIT_ALL) |
142 | sa.aad.fs.request &= ~perms->quiet; | 144 | sa.aad->fs.request &= ~perms->quiet; |
143 | 145 | ||
144 | if (!sa.aad.fs.request) | 146 | if (!sa.aad->fs.request) |
145 | return COMPLAIN_MODE(profile) ? 0 : sa.aad.error; | 147 | return COMPLAIN_MODE(profile) ? 0 : sa.aad->error; |
146 | } | 148 | } |
147 | 149 | ||
148 | sa.aad.fs.denied = sa.aad.fs.request & ~perms->allow; | 150 | sa.aad->fs.denied = sa.aad->fs.request & ~perms->allow; |
149 | return aa_audit(type, profile, gfp, &sa, file_audit_cb); | 151 | return aa_audit(type, profile, gfp, &sa, file_audit_cb); |
150 | } | 152 | } |
151 | 153 | ||
diff --git a/security/apparmor/include/audit.h b/security/apparmor/include/audit.h index 4ba78c203af1..3868b1e5d5ba 100644 --- a/security/apparmor/include/audit.h +++ b/security/apparmor/include/audit.h | |||
@@ -103,7 +103,33 @@ enum aa_ops { | |||
103 | }; | 103 | }; |
104 | 104 | ||
105 | 105 | ||
106 | /* define a short hand for apparmor_audit_data portion of common_audit_data */ | 106 | struct apparmor_audit_data { |
107 | int error; | ||
108 | int op; | ||
109 | int type; | ||
110 | void *profile; | ||
111 | const char *name; | ||
112 | const char *info; | ||
113 | union { | ||
114 | void *target; | ||
115 | struct { | ||
116 | long pos; | ||
117 | void *target; | ||
118 | } iface; | ||
119 | struct { | ||
120 | int rlim; | ||
121 | unsigned long max; | ||
122 | } rlim; | ||
123 | struct { | ||
124 | const char *target; | ||
125 | u32 request; | ||
126 | u32 denied; | ||
127 | uid_t ouid; | ||
128 | } fs; | ||
129 | }; | ||
130 | }; | ||
131 | |||
132 | /* define a short hand for apparmor_audit_data structure */ | ||
107 | #define aad apparmor_audit_data | 133 | #define aad apparmor_audit_data |
108 | 134 | ||
109 | void aa_audit_msg(int type, struct common_audit_data *sa, | 135 | void aa_audit_msg(int type, struct common_audit_data *sa, |
diff --git a/security/apparmor/ipc.c b/security/apparmor/ipc.c index 7ee05c6f3c64..c3da93a5150d 100644 --- a/security/apparmor/ipc.c +++ b/security/apparmor/ipc.c | |||
@@ -26,7 +26,7 @@ static void audit_cb(struct audit_buffer *ab, void *va) | |||
26 | { | 26 | { |
27 | struct common_audit_data *sa = va; | 27 | struct common_audit_data *sa = va; |
28 | audit_log_format(ab, " target="); | 28 | audit_log_format(ab, " target="); |
29 | audit_log_untrustedstring(ab, sa->aad.target); | 29 | audit_log_untrustedstring(ab, sa->aad->target); |
30 | } | 30 | } |
31 | 31 | ||
32 | /** | 32 | /** |
@@ -41,10 +41,12 @@ static int aa_audit_ptrace(struct aa_profile *profile, | |||
41 | struct aa_profile *target, int error) | 41 | struct aa_profile *target, int error) |
42 | { | 42 | { |
43 | struct common_audit_data sa; | 43 | struct common_audit_data sa; |
44 | struct apparmor_audit_data aad = {0,}; | ||
44 | COMMON_AUDIT_DATA_INIT(&sa, NONE); | 45 | COMMON_AUDIT_DATA_INIT(&sa, NONE); |
45 | sa.aad.op = OP_PTRACE; | 46 | sa.aad = &aad; |
46 | sa.aad.target = target; | 47 | aad.op = OP_PTRACE; |
47 | sa.aad.error = error; | 48 | aad.target = target; |
49 | aad.error = error; | ||
48 | 50 | ||
49 | return aa_audit(AUDIT_APPARMOR_AUTO, profile, GFP_ATOMIC, &sa, | 51 | return aa_audit(AUDIT_APPARMOR_AUTO, profile, GFP_ATOMIC, &sa, |
50 | audit_cb); | 52 | audit_cb); |
diff --git a/security/apparmor/lib.c b/security/apparmor/lib.c index 9516948041ad..e75829ba0ff9 100644 --- a/security/apparmor/lib.c +++ b/security/apparmor/lib.c | |||
@@ -65,8 +65,10 @@ void aa_info_message(const char *str) | |||
65 | { | 65 | { |
66 | if (audit_enabled) { | 66 | if (audit_enabled) { |
67 | struct common_audit_data sa; | 67 | struct common_audit_data sa; |
68 | struct apparmor_audit_data aad = {0,}; | ||
68 | COMMON_AUDIT_DATA_INIT(&sa, NONE); | 69 | COMMON_AUDIT_DATA_INIT(&sa, NONE); |
69 | sa.aad.info = str; | 70 | sa.aad = &aad; |
71 | aad.info = str; | ||
70 | aa_audit_msg(AUDIT_APPARMOR_STATUS, &sa, NULL); | 72 | aa_audit_msg(AUDIT_APPARMOR_STATUS, &sa, NULL); |
71 | } | 73 | } |
72 | printk(KERN_INFO "AppArmor: %s\n", str); | 74 | printk(KERN_INFO "AppArmor: %s\n", str); |
diff --git a/security/apparmor/lsm.c b/security/apparmor/lsm.c index 97ce8fae49b3..ad05d391974d 100644 --- a/security/apparmor/lsm.c +++ b/security/apparmor/lsm.c | |||
@@ -588,10 +588,12 @@ static int apparmor_setprocattr(struct task_struct *task, char *name, | |||
588 | error = aa_setprocattr_permipc(args); | 588 | error = aa_setprocattr_permipc(args); |
589 | } else { | 589 | } else { |
590 | struct common_audit_data sa; | 590 | struct common_audit_data sa; |
591 | struct apparmor_audit_data aad = {0,}; | ||
591 | COMMON_AUDIT_DATA_INIT(&sa, NONE); | 592 | COMMON_AUDIT_DATA_INIT(&sa, NONE); |
592 | sa.aad.op = OP_SETPROCATTR; | 593 | sa.aad = &aad; |
593 | sa.aad.info = name; | 594 | aad.op = OP_SETPROCATTR; |
594 | sa.aad.error = -EINVAL; | 595 | aad.info = name; |
596 | aad.error = -EINVAL; | ||
595 | return aa_audit(AUDIT_APPARMOR_DENIED, | 597 | return aa_audit(AUDIT_APPARMOR_DENIED, |
596 | __aa_current_profile(), GFP_KERNEL, | 598 | __aa_current_profile(), GFP_KERNEL, |
597 | &sa, NULL); | 599 | &sa, NULL); |
diff --git a/security/apparmor/policy.c b/security/apparmor/policy.c index 906414383022..f1f7506a464d 100644 --- a/security/apparmor/policy.c +++ b/security/apparmor/policy.c | |||
@@ -964,11 +964,13 @@ static int audit_policy(int op, gfp_t gfp, const char *name, const char *info, | |||
964 | int error) | 964 | int error) |
965 | { | 965 | { |
966 | struct common_audit_data sa; | 966 | struct common_audit_data sa; |
967 | struct apparmor_audit_data aad = {0,}; | ||
967 | COMMON_AUDIT_DATA_INIT(&sa, NONE); | 968 | COMMON_AUDIT_DATA_INIT(&sa, NONE); |
968 | sa.aad.op = op; | 969 | sa.aad = &aad; |
969 | sa.aad.name = name; | 970 | aad.op = op; |
970 | sa.aad.info = info; | 971 | aad.name = name; |
971 | sa.aad.error = error; | 972 | aad.info = info; |
973 | aad.error = error; | ||
972 | 974 | ||
973 | return aa_audit(AUDIT_APPARMOR_STATUS, __aa_current_profile(), gfp, | 975 | return aa_audit(AUDIT_APPARMOR_STATUS, __aa_current_profile(), gfp, |
974 | &sa, NULL); | 976 | &sa, NULL); |
diff --git a/security/apparmor/policy_unpack.c b/security/apparmor/policy_unpack.c index 25fd51edc8da..deab7c7e8dc0 100644 --- a/security/apparmor/policy_unpack.c +++ b/security/apparmor/policy_unpack.c | |||
@@ -70,13 +70,13 @@ struct aa_ext { | |||
70 | static void audit_cb(struct audit_buffer *ab, void *va) | 70 | static void audit_cb(struct audit_buffer *ab, void *va) |
71 | { | 71 | { |
72 | struct common_audit_data *sa = va; | 72 | struct common_audit_data *sa = va; |
73 | if (sa->aad.iface.target) { | 73 | if (sa->aad->iface.target) { |
74 | struct aa_profile *name = sa->aad.iface.target; | 74 | struct aa_profile *name = sa->aad->iface.target; |
75 | audit_log_format(ab, " name="); | 75 | audit_log_format(ab, " name="); |
76 | audit_log_untrustedstring(ab, name->base.hname); | 76 | audit_log_untrustedstring(ab, name->base.hname); |
77 | } | 77 | } |
78 | if (sa->aad.iface.pos) | 78 | if (sa->aad->iface.pos) |
79 | audit_log_format(ab, " offset=%ld", sa->aad.iface.pos); | 79 | audit_log_format(ab, " offset=%ld", sa->aad->iface.pos); |
80 | } | 80 | } |
81 | 81 | ||
82 | /** | 82 | /** |
@@ -94,13 +94,15 @@ static int audit_iface(struct aa_profile *new, const char *name, | |||
94 | { | 94 | { |
95 | struct aa_profile *profile = __aa_current_profile(); | 95 | struct aa_profile *profile = __aa_current_profile(); |
96 | struct common_audit_data sa; | 96 | struct common_audit_data sa; |
97 | struct apparmor_audit_data aad = {0,}; | ||
97 | COMMON_AUDIT_DATA_INIT(&sa, NONE); | 98 | COMMON_AUDIT_DATA_INIT(&sa, NONE); |
99 | sa.aad = &aad; | ||
98 | if (e) | 100 | if (e) |
99 | sa.aad.iface.pos = e->pos - e->start; | 101 | aad.iface.pos = e->pos - e->start; |
100 | sa.aad.iface.target = new; | 102 | aad.iface.target = new; |
101 | sa.aad.name = name; | 103 | aad.name = name; |
102 | sa.aad.info = info; | 104 | aad.info = info; |
103 | sa.aad.error = error; | 105 | aad.error = error; |
104 | 106 | ||
105 | return aa_audit(AUDIT_APPARMOR_STATUS, profile, GFP_KERNEL, &sa, | 107 | return aa_audit(AUDIT_APPARMOR_STATUS, profile, GFP_KERNEL, &sa, |
106 | audit_cb); | 108 | audit_cb); |
diff --git a/security/apparmor/resource.c b/security/apparmor/resource.c index 72c25a4f2cfd..2fe8613efe33 100644 --- a/security/apparmor/resource.c +++ b/security/apparmor/resource.c | |||
@@ -34,7 +34,7 @@ static void audit_cb(struct audit_buffer *ab, void *va) | |||
34 | struct common_audit_data *sa = va; | 34 | struct common_audit_data *sa = va; |
35 | 35 | ||
36 | audit_log_format(ab, " rlimit=%s value=%lu", | 36 | audit_log_format(ab, " rlimit=%s value=%lu", |
37 | rlim_names[sa->aad.rlim.rlim], sa->aad.rlim.max); | 37 | rlim_names[sa->aad->rlim.rlim], sa->aad->rlim.max); |
38 | } | 38 | } |
39 | 39 | ||
40 | /** | 40 | /** |
@@ -50,12 +50,14 @@ static int audit_resource(struct aa_profile *profile, unsigned int resource, | |||
50 | unsigned long value, int error) | 50 | unsigned long value, int error) |
51 | { | 51 | { |
52 | struct common_audit_data sa; | 52 | struct common_audit_data sa; |
53 | struct apparmor_audit_data aad = {0,}; | ||
53 | 54 | ||
54 | COMMON_AUDIT_DATA_INIT(&sa, NONE); | 55 | COMMON_AUDIT_DATA_INIT(&sa, NONE); |
55 | sa.aad.op = OP_SETRLIMIT, | 56 | sa.aad = &aad; |
56 | sa.aad.rlim.rlim = resource; | 57 | aad.op = OP_SETRLIMIT, |
57 | sa.aad.rlim.max = value; | 58 | aad.rlim.rlim = resource; |
58 | sa.aad.error = error; | 59 | aad.rlim.max = value; |
60 | aad.error = error; | ||
59 | return aa_audit(AUDIT_APPARMOR_AUTO, profile, GFP_KERNEL, &sa, | 61 | return aa_audit(AUDIT_APPARMOR_AUTO, profile, GFP_KERNEL, &sa, |
60 | audit_cb); | 62 | audit_cb); |
61 | } | 63 | } |
diff --git a/security/selinux/avc.c b/security/selinux/avc.c index 1a70fa26da72..00f3860c2370 100644 --- a/security/selinux/avc.c +++ b/security/selinux/avc.c | |||
@@ -436,9 +436,9 @@ static void avc_audit_pre_callback(struct audit_buffer *ab, void *a) | |||
436 | { | 436 | { |
437 | struct common_audit_data *ad = a; | 437 | struct common_audit_data *ad = a; |
438 | audit_log_format(ab, "avc: %s ", | 438 | audit_log_format(ab, "avc: %s ", |
439 | ad->selinux_audit_data.denied ? "denied" : "granted"); | 439 | ad->selinux_audit_data->denied ? "denied" : "granted"); |
440 | avc_dump_av(ab, ad->selinux_audit_data.tclass, | 440 | avc_dump_av(ab, ad->selinux_audit_data->tclass, |
441 | ad->selinux_audit_data.audited); | 441 | ad->selinux_audit_data->audited); |
442 | audit_log_format(ab, " for "); | 442 | audit_log_format(ab, " for "); |
443 | } | 443 | } |
444 | 444 | ||
@@ -452,9 +452,9 @@ static void avc_audit_post_callback(struct audit_buffer *ab, void *a) | |||
452 | { | 452 | { |
453 | struct common_audit_data *ad = a; | 453 | struct common_audit_data *ad = a; |
454 | audit_log_format(ab, " "); | 454 | audit_log_format(ab, " "); |
455 | avc_dump_query(ab, ad->selinux_audit_data.ssid, | 455 | avc_dump_query(ab, ad->selinux_audit_data->ssid, |
456 | ad->selinux_audit_data.tsid, | 456 | ad->selinux_audit_data->tsid, |
457 | ad->selinux_audit_data.tclass); | 457 | ad->selinux_audit_data->tclass); |
458 | } | 458 | } |
459 | 459 | ||
460 | /* This is the slow part of avc audit with big stack footprint */ | 460 | /* This is the slow part of avc audit with big stack footprint */ |
@@ -464,10 +464,12 @@ static noinline int slow_avc_audit(u32 ssid, u32 tsid, u16 tclass, | |||
464 | unsigned flags) | 464 | unsigned flags) |
465 | { | 465 | { |
466 | struct common_audit_data stack_data; | 466 | struct common_audit_data stack_data; |
467 | struct selinux_audit_data sad = {0,}; | ||
467 | 468 | ||
468 | if (!a) { | 469 | if (!a) { |
469 | a = &stack_data; | 470 | a = &stack_data; |
470 | COMMON_AUDIT_DATA_INIT(a, NONE); | 471 | COMMON_AUDIT_DATA_INIT(a, NONE); |
472 | a->selinux_audit_data = &sad; | ||
471 | } | 473 | } |
472 | 474 | ||
473 | /* | 475 | /* |
@@ -481,12 +483,12 @@ static noinline int slow_avc_audit(u32 ssid, u32 tsid, u16 tclass, | |||
481 | (flags & MAY_NOT_BLOCK)) | 483 | (flags & MAY_NOT_BLOCK)) |
482 | return -ECHILD; | 484 | return -ECHILD; |
483 | 485 | ||
484 | a->selinux_audit_data.tclass = tclass; | 486 | a->selinux_audit_data->tclass = tclass; |
485 | a->selinux_audit_data.requested = requested; | 487 | a->selinux_audit_data->requested = requested; |
486 | a->selinux_audit_data.ssid = ssid; | 488 | a->selinux_audit_data->ssid = ssid; |
487 | a->selinux_audit_data.tsid = tsid; | 489 | a->selinux_audit_data->tsid = tsid; |
488 | a->selinux_audit_data.audited = audited; | 490 | a->selinux_audit_data->audited = audited; |
489 | a->selinux_audit_data.denied = denied; | 491 | a->selinux_audit_data->denied = denied; |
490 | a->lsm_pre_audit = avc_audit_pre_callback; | 492 | a->lsm_pre_audit = avc_audit_pre_callback; |
491 | a->lsm_post_audit = avc_audit_post_callback; | 493 | a->lsm_post_audit = avc_audit_post_callback; |
492 | common_lsm_audit(a); | 494 | common_lsm_audit(a); |
@@ -523,7 +525,7 @@ inline int avc_audit(u32 ssid, u32 tsid, | |||
523 | if (unlikely(denied)) { | 525 | if (unlikely(denied)) { |
524 | audited = denied & avd->auditdeny; | 526 | audited = denied & avd->auditdeny; |
525 | /* | 527 | /* |
526 | * a->selinux_audit_data.auditdeny is TRICKY! Setting a bit in | 528 | * a->selinux_audit_data->auditdeny is TRICKY! Setting a bit in |
527 | * this field means that ANY denials should NOT be audited if | 529 | * this field means that ANY denials should NOT be audited if |
528 | * the policy contains an explicit dontaudit rule for that | 530 | * the policy contains an explicit dontaudit rule for that |
529 | * permission. Take notice that this is unrelated to the | 531 | * permission. Take notice that this is unrelated to the |
@@ -532,15 +534,15 @@ inline int avc_audit(u32 ssid, u32 tsid, | |||
532 | * | 534 | * |
533 | * denied == READ | 535 | * denied == READ |
534 | * avd.auditdeny & ACCESS == 0 (not set means explicit rule) | 536 | * avd.auditdeny & ACCESS == 0 (not set means explicit rule) |
535 | * selinux_audit_data.auditdeny & ACCESS == 1 | 537 | * selinux_audit_data->auditdeny & ACCESS == 1 |
536 | * | 538 | * |
537 | * We will NOT audit the denial even though the denied | 539 | * We will NOT audit the denial even though the denied |
538 | * permission was READ and the auditdeny checks were for | 540 | * permission was READ and the auditdeny checks were for |
539 | * ACCESS | 541 | * ACCESS |
540 | */ | 542 | */ |
541 | if (a && | 543 | if (a && |
542 | a->selinux_audit_data.auditdeny && | 544 | a->selinux_audit_data->auditdeny && |
543 | !(a->selinux_audit_data.auditdeny & avd->auditdeny)) | 545 | !(a->selinux_audit_data->auditdeny & avd->auditdeny)) |
544 | audited = 0; | 546 | audited = 0; |
545 | } else if (result) | 547 | } else if (result) |
546 | audited = denied = requested; | 548 | audited = denied = requested; |
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c index 28482f9e15b8..3861ce4b1007 100644 --- a/security/selinux/hooks.c +++ b/security/selinux/hooks.c | |||
@@ -1420,6 +1420,7 @@ static int cred_has_capability(const struct cred *cred, | |||
1420 | int cap, int audit) | 1420 | int cap, int audit) |
1421 | { | 1421 | { |
1422 | struct common_audit_data ad; | 1422 | struct common_audit_data ad; |
1423 | struct selinux_audit_data sad = {0,}; | ||
1423 | struct av_decision avd; | 1424 | struct av_decision avd; |
1424 | u16 sclass; | 1425 | u16 sclass; |
1425 | u32 sid = cred_sid(cred); | 1426 | u32 sid = cred_sid(cred); |
@@ -1427,6 +1428,7 @@ static int cred_has_capability(const struct cred *cred, | |||
1427 | int rc; | 1428 | int rc; |
1428 | 1429 | ||
1429 | COMMON_AUDIT_DATA_INIT(&ad, CAP); | 1430 | COMMON_AUDIT_DATA_INIT(&ad, CAP); |
1431 | ad.selinux_audit_data = &sad; | ||
1430 | ad.tsk = current; | 1432 | ad.tsk = current; |
1431 | ad.u.cap = cap; | 1433 | ad.u.cap = cap; |
1432 | 1434 | ||
@@ -1492,9 +1494,11 @@ static int inode_has_perm_noadp(const struct cred *cred, | |||
1492 | unsigned flags) | 1494 | unsigned flags) |
1493 | { | 1495 | { |
1494 | struct common_audit_data ad; | 1496 | struct common_audit_data ad; |
1497 | struct selinux_audit_data sad = {0,}; | ||
1495 | 1498 | ||
1496 | COMMON_AUDIT_DATA_INIT(&ad, INODE); | 1499 | COMMON_AUDIT_DATA_INIT(&ad, INODE); |
1497 | ad.u.inode = inode; | 1500 | ad.u.inode = inode; |
1501 | ad.selinux_audit_data = &sad; | ||
1498 | return inode_has_perm(cred, inode, perms, &ad, flags); | 1502 | return inode_has_perm(cred, inode, perms, &ad, flags); |
1499 | } | 1503 | } |
1500 | 1504 | ||
@@ -1507,9 +1511,11 @@ static inline int dentry_has_perm(const struct cred *cred, | |||
1507 | { | 1511 | { |
1508 | struct inode *inode = dentry->d_inode; | 1512 | struct inode *inode = dentry->d_inode; |
1509 | struct common_audit_data ad; | 1513 | struct common_audit_data ad; |
1514 | struct selinux_audit_data sad = {0,}; | ||
1510 | 1515 | ||
1511 | COMMON_AUDIT_DATA_INIT(&ad, DENTRY); | 1516 | COMMON_AUDIT_DATA_INIT(&ad, DENTRY); |
1512 | ad.u.dentry = dentry; | 1517 | ad.u.dentry = dentry; |
1518 | ad.selinux_audit_data = &sad; | ||
1513 | return inode_has_perm(cred, inode, av, &ad, 0); | 1519 | return inode_has_perm(cred, inode, av, &ad, 0); |
1514 | } | 1520 | } |
1515 | 1521 | ||
@@ -1522,9 +1528,11 @@ static inline int path_has_perm(const struct cred *cred, | |||
1522 | { | 1528 | { |
1523 | struct inode *inode = path->dentry->d_inode; | 1529 | struct inode *inode = path->dentry->d_inode; |
1524 | struct common_audit_data ad; | 1530 | struct common_audit_data ad; |
1531 | struct selinux_audit_data sad = {0,}; | ||
1525 | 1532 | ||
1526 | COMMON_AUDIT_DATA_INIT(&ad, PATH); | 1533 | COMMON_AUDIT_DATA_INIT(&ad, PATH); |
1527 | ad.u.path = *path; | 1534 | ad.u.path = *path; |
1535 | ad.selinux_audit_data = &sad; | ||
1528 | return inode_has_perm(cred, inode, av, &ad, 0); | 1536 | return inode_has_perm(cred, inode, av, &ad, 0); |
1529 | } | 1537 | } |
1530 | 1538 | ||
@@ -1543,11 +1551,13 @@ static int file_has_perm(const struct cred *cred, | |||
1543 | struct file_security_struct *fsec = file->f_security; | 1551 | struct file_security_struct *fsec = file->f_security; |
1544 | struct inode *inode = file->f_path.dentry->d_inode; | 1552 | struct inode *inode = file->f_path.dentry->d_inode; |
1545 | struct common_audit_data ad; | 1553 | struct common_audit_data ad; |
1554 | struct selinux_audit_data sad = {0,}; | ||
1546 | u32 sid = cred_sid(cred); | 1555 | u32 sid = cred_sid(cred); |
1547 | int rc; | 1556 | int rc; |
1548 | 1557 | ||
1549 | COMMON_AUDIT_DATA_INIT(&ad, PATH); | 1558 | COMMON_AUDIT_DATA_INIT(&ad, PATH); |
1550 | ad.u.path = file->f_path; | 1559 | ad.u.path = file->f_path; |
1560 | ad.selinux_audit_data = &sad; | ||
1551 | 1561 | ||
1552 | if (sid != fsec->sid) { | 1562 | if (sid != fsec->sid) { |
1553 | rc = avc_has_perm(sid, fsec->sid, | 1563 | rc = avc_has_perm(sid, fsec->sid, |
@@ -1577,6 +1587,7 @@ static int may_create(struct inode *dir, | |||
1577 | struct superblock_security_struct *sbsec; | 1587 | struct superblock_security_struct *sbsec; |
1578 | u32 sid, newsid; | 1588 | u32 sid, newsid; |
1579 | struct common_audit_data ad; | 1589 | struct common_audit_data ad; |
1590 | struct selinux_audit_data sad = {0,}; | ||
1580 | int rc; | 1591 | int rc; |
1581 | 1592 | ||
1582 | dsec = dir->i_security; | 1593 | dsec = dir->i_security; |
@@ -1587,6 +1598,7 @@ static int may_create(struct inode *dir, | |||
1587 | 1598 | ||
1588 | COMMON_AUDIT_DATA_INIT(&ad, DENTRY); | 1599 | COMMON_AUDIT_DATA_INIT(&ad, DENTRY); |
1589 | ad.u.dentry = dentry; | 1600 | ad.u.dentry = dentry; |
1601 | ad.selinux_audit_data = &sad; | ||
1590 | 1602 | ||
1591 | rc = avc_has_perm(sid, dsec->sid, SECCLASS_DIR, | 1603 | rc = avc_has_perm(sid, dsec->sid, SECCLASS_DIR, |
1592 | DIR__ADD_NAME | DIR__SEARCH, | 1604 | DIR__ADD_NAME | DIR__SEARCH, |
@@ -1631,6 +1643,7 @@ static int may_link(struct inode *dir, | |||
1631 | { | 1643 | { |
1632 | struct inode_security_struct *dsec, *isec; | 1644 | struct inode_security_struct *dsec, *isec; |
1633 | struct common_audit_data ad; | 1645 | struct common_audit_data ad; |
1646 | struct selinux_audit_data sad = {0,}; | ||
1634 | u32 sid = current_sid(); | 1647 | u32 sid = current_sid(); |
1635 | u32 av; | 1648 | u32 av; |
1636 | int rc; | 1649 | int rc; |
@@ -1640,6 +1653,7 @@ static int may_link(struct inode *dir, | |||
1640 | 1653 | ||
1641 | COMMON_AUDIT_DATA_INIT(&ad, DENTRY); | 1654 | COMMON_AUDIT_DATA_INIT(&ad, DENTRY); |
1642 | ad.u.dentry = dentry; | 1655 | ad.u.dentry = dentry; |
1656 | ad.selinux_audit_data = &sad; | ||
1643 | 1657 | ||
1644 | av = DIR__SEARCH; | 1658 | av = DIR__SEARCH; |
1645 | av |= (kind ? DIR__REMOVE_NAME : DIR__ADD_NAME); | 1659 | av |= (kind ? DIR__REMOVE_NAME : DIR__ADD_NAME); |
@@ -1674,6 +1688,7 @@ static inline int may_rename(struct inode *old_dir, | |||
1674 | { | 1688 | { |
1675 | struct inode_security_struct *old_dsec, *new_dsec, *old_isec, *new_isec; | 1689 | struct inode_security_struct *old_dsec, *new_dsec, *old_isec, *new_isec; |
1676 | struct common_audit_data ad; | 1690 | struct common_audit_data ad; |
1691 | struct selinux_audit_data sad = {0,}; | ||
1677 | u32 sid = current_sid(); | 1692 | u32 sid = current_sid(); |
1678 | u32 av; | 1693 | u32 av; |
1679 | int old_is_dir, new_is_dir; | 1694 | int old_is_dir, new_is_dir; |
@@ -1685,6 +1700,7 @@ static inline int may_rename(struct inode *old_dir, | |||
1685 | new_dsec = new_dir->i_security; | 1700 | new_dsec = new_dir->i_security; |
1686 | 1701 | ||
1687 | COMMON_AUDIT_DATA_INIT(&ad, DENTRY); | 1702 | COMMON_AUDIT_DATA_INIT(&ad, DENTRY); |
1703 | ad.selinux_audit_data = &sad; | ||
1688 | 1704 | ||
1689 | ad.u.dentry = old_dentry; | 1705 | ad.u.dentry = old_dentry; |
1690 | rc = avc_has_perm(sid, old_dsec->sid, SECCLASS_DIR, | 1706 | rc = avc_has_perm(sid, old_dsec->sid, SECCLASS_DIR, |
@@ -1970,6 +1986,7 @@ static int selinux_bprm_set_creds(struct linux_binprm *bprm) | |||
1970 | struct task_security_struct *new_tsec; | 1986 | struct task_security_struct *new_tsec; |
1971 | struct inode_security_struct *isec; | 1987 | struct inode_security_struct *isec; |
1972 | struct common_audit_data ad; | 1988 | struct common_audit_data ad; |
1989 | struct selinux_audit_data sad = {0,}; | ||
1973 | struct inode *inode = bprm->file->f_path.dentry->d_inode; | 1990 | struct inode *inode = bprm->file->f_path.dentry->d_inode; |
1974 | int rc; | 1991 | int rc; |
1975 | 1992 | ||
@@ -2009,6 +2026,7 @@ static int selinux_bprm_set_creds(struct linux_binprm *bprm) | |||
2009 | } | 2026 | } |
2010 | 2027 | ||
2011 | COMMON_AUDIT_DATA_INIT(&ad, PATH); | 2028 | COMMON_AUDIT_DATA_INIT(&ad, PATH); |
2029 | ad.selinux_audit_data = &sad; | ||
2012 | ad.u.path = bprm->file->f_path; | 2030 | ad.u.path = bprm->file->f_path; |
2013 | 2031 | ||
2014 | if (bprm->file->f_path.mnt->mnt_flags & MNT_NOSUID) | 2032 | if (bprm->file->f_path.mnt->mnt_flags & MNT_NOSUID) |
@@ -2098,6 +2116,7 @@ static inline void flush_unauthorized_files(const struct cred *cred, | |||
2098 | struct files_struct *files) | 2116 | struct files_struct *files) |
2099 | { | 2117 | { |
2100 | struct common_audit_data ad; | 2118 | struct common_audit_data ad; |
2119 | struct selinux_audit_data sad = {0,}; | ||
2101 | struct file *file, *devnull = NULL; | 2120 | struct file *file, *devnull = NULL; |
2102 | struct tty_struct *tty; | 2121 | struct tty_struct *tty; |
2103 | struct fdtable *fdt; | 2122 | struct fdtable *fdt; |
@@ -2135,6 +2154,7 @@ static inline void flush_unauthorized_files(const struct cred *cred, | |||
2135 | /* Revalidate access to inherited open files. */ | 2154 | /* Revalidate access to inherited open files. */ |
2136 | 2155 | ||
2137 | COMMON_AUDIT_DATA_INIT(&ad, INODE); | 2156 | COMMON_AUDIT_DATA_INIT(&ad, INODE); |
2157 | ad.selinux_audit_data = &sad; | ||
2138 | 2158 | ||
2139 | spin_lock(&files->file_lock); | 2159 | spin_lock(&files->file_lock); |
2140 | for (;;) { | 2160 | for (;;) { |
@@ -2472,6 +2492,7 @@ static int selinux_sb_kern_mount(struct super_block *sb, int flags, void *data) | |||
2472 | { | 2492 | { |
2473 | const struct cred *cred = current_cred(); | 2493 | const struct cred *cred = current_cred(); |
2474 | struct common_audit_data ad; | 2494 | struct common_audit_data ad; |
2495 | struct selinux_audit_data sad = {0,}; | ||
2475 | int rc; | 2496 | int rc; |
2476 | 2497 | ||
2477 | rc = superblock_doinit(sb, data); | 2498 | rc = superblock_doinit(sb, data); |
@@ -2483,6 +2504,7 @@ static int selinux_sb_kern_mount(struct super_block *sb, int flags, void *data) | |||
2483 | return 0; | 2504 | return 0; |
2484 | 2505 | ||
2485 | COMMON_AUDIT_DATA_INIT(&ad, DENTRY); | 2506 | COMMON_AUDIT_DATA_INIT(&ad, DENTRY); |
2507 | ad.selinux_audit_data = &sad; | ||
2486 | ad.u.dentry = sb->s_root; | 2508 | ad.u.dentry = sb->s_root; |
2487 | return superblock_has_perm(cred, sb, FILESYSTEM__MOUNT, &ad); | 2509 | return superblock_has_perm(cred, sb, FILESYSTEM__MOUNT, &ad); |
2488 | } | 2510 | } |
@@ -2491,8 +2513,10 @@ static int selinux_sb_statfs(struct dentry *dentry) | |||
2491 | { | 2513 | { |
2492 | const struct cred *cred = current_cred(); | 2514 | const struct cred *cred = current_cred(); |
2493 | struct common_audit_data ad; | 2515 | struct common_audit_data ad; |
2516 | struct selinux_audit_data sad = {0,}; | ||
2494 | 2517 | ||
2495 | COMMON_AUDIT_DATA_INIT(&ad, DENTRY); | 2518 | COMMON_AUDIT_DATA_INIT(&ad, DENTRY); |
2519 | ad.selinux_audit_data = &sad; | ||
2496 | ad.u.dentry = dentry->d_sb->s_root; | 2520 | ad.u.dentry = dentry->d_sb->s_root; |
2497 | return superblock_has_perm(cred, dentry->d_sb, FILESYSTEM__GETATTR, &ad); | 2521 | return superblock_has_perm(cred, dentry->d_sb, FILESYSTEM__GETATTR, &ad); |
2498 | } | 2522 | } |
@@ -2656,6 +2680,7 @@ static int selinux_inode_permission(struct inode *inode, int mask) | |||
2656 | { | 2680 | { |
2657 | const struct cred *cred = current_cred(); | 2681 | const struct cred *cred = current_cred(); |
2658 | struct common_audit_data ad; | 2682 | struct common_audit_data ad; |
2683 | struct selinux_audit_data sad = {0,}; | ||
2659 | u32 perms; | 2684 | u32 perms; |
2660 | bool from_access; | 2685 | bool from_access; |
2661 | unsigned flags = mask & MAY_NOT_BLOCK; | 2686 | unsigned flags = mask & MAY_NOT_BLOCK; |
@@ -2668,10 +2693,11 @@ static int selinux_inode_permission(struct inode *inode, int mask) | |||
2668 | return 0; | 2693 | return 0; |
2669 | 2694 | ||
2670 | COMMON_AUDIT_DATA_INIT(&ad, INODE); | 2695 | COMMON_AUDIT_DATA_INIT(&ad, INODE); |
2696 | ad.selinux_audit_data = &sad; | ||
2671 | ad.u.inode = inode; | 2697 | ad.u.inode = inode; |
2672 | 2698 | ||
2673 | if (from_access) | 2699 | if (from_access) |
2674 | ad.selinux_audit_data.auditdeny |= FILE__AUDIT_ACCESS; | 2700 | ad.selinux_audit_data->auditdeny |= FILE__AUDIT_ACCESS; |
2675 | 2701 | ||
2676 | perms = file_mask_to_av(inode->i_mode, mask); | 2702 | perms = file_mask_to_av(inode->i_mode, mask); |
2677 | 2703 | ||
@@ -2737,6 +2763,7 @@ static int selinux_inode_setxattr(struct dentry *dentry, const char *name, | |||
2737 | struct inode_security_struct *isec = inode->i_security; | 2763 | struct inode_security_struct *isec = inode->i_security; |
2738 | struct superblock_security_struct *sbsec; | 2764 | struct superblock_security_struct *sbsec; |
2739 | struct common_audit_data ad; | 2765 | struct common_audit_data ad; |
2766 | struct selinux_audit_data sad = {0,}; | ||
2740 | u32 newsid, sid = current_sid(); | 2767 | u32 newsid, sid = current_sid(); |
2741 | int rc = 0; | 2768 | int rc = 0; |
2742 | 2769 | ||
@@ -2751,6 +2778,7 @@ static int selinux_inode_setxattr(struct dentry *dentry, const char *name, | |||
2751 | return -EPERM; | 2778 | return -EPERM; |
2752 | 2779 | ||
2753 | COMMON_AUDIT_DATA_INIT(&ad, DENTRY); | 2780 | COMMON_AUDIT_DATA_INIT(&ad, DENTRY); |
2781 | ad.selinux_audit_data = &sad; | ||
2754 | ad.u.dentry = dentry; | 2782 | ad.u.dentry = dentry; |
2755 | 2783 | ||
2756 | rc = avc_has_perm(sid, isec->sid, isec->sclass, | 2784 | rc = avc_has_perm(sid, isec->sid, isec->sclass, |
@@ -3345,10 +3373,12 @@ static int selinux_kernel_module_request(char *kmod_name) | |||
3345 | { | 3373 | { |
3346 | u32 sid; | 3374 | u32 sid; |
3347 | struct common_audit_data ad; | 3375 | struct common_audit_data ad; |
3376 | struct selinux_audit_data sad = {0,}; | ||
3348 | 3377 | ||
3349 | sid = task_sid(current); | 3378 | sid = task_sid(current); |
3350 | 3379 | ||
3351 | COMMON_AUDIT_DATA_INIT(&ad, KMOD); | 3380 | COMMON_AUDIT_DATA_INIT(&ad, KMOD); |
3381 | ad.selinux_audit_data = &sad; | ||
3352 | ad.u.kmod_name = kmod_name; | 3382 | ad.u.kmod_name = kmod_name; |
3353 | 3383 | ||
3354 | return avc_has_perm(sid, SECINITSID_KERNEL, SECCLASS_SYSTEM, | 3384 | return avc_has_perm(sid, SECINITSID_KERNEL, SECCLASS_SYSTEM, |
@@ -3721,12 +3751,14 @@ static int sock_has_perm(struct task_struct *task, struct sock *sk, u32 perms) | |||
3721 | { | 3751 | { |
3722 | struct sk_security_struct *sksec = sk->sk_security; | 3752 | struct sk_security_struct *sksec = sk->sk_security; |
3723 | struct common_audit_data ad; | 3753 | struct common_audit_data ad; |
3754 | struct selinux_audit_data sad = {0,}; | ||
3724 | u32 tsid = task_sid(task); | 3755 | u32 tsid = task_sid(task); |
3725 | 3756 | ||
3726 | if (sksec->sid == SECINITSID_KERNEL) | 3757 | if (sksec->sid == SECINITSID_KERNEL) |
3727 | return 0; | 3758 | return 0; |
3728 | 3759 | ||
3729 | COMMON_AUDIT_DATA_INIT(&ad, NET); | 3760 | COMMON_AUDIT_DATA_INIT(&ad, NET); |
3761 | ad.selinux_audit_data = &sad; | ||
3730 | ad.u.net.sk = sk; | 3762 | ad.u.net.sk = sk; |
3731 | 3763 | ||
3732 | return avc_has_perm(tsid, sksec->sid, sksec->sclass, perms, &ad); | 3764 | return avc_has_perm(tsid, sksec->sid, sksec->sclass, perms, &ad); |
@@ -3805,6 +3837,7 @@ static int selinux_socket_bind(struct socket *sock, struct sockaddr *address, in | |||
3805 | char *addrp; | 3837 | char *addrp; |
3806 | struct sk_security_struct *sksec = sk->sk_security; | 3838 | struct sk_security_struct *sksec = sk->sk_security; |
3807 | struct common_audit_data ad; | 3839 | struct common_audit_data ad; |
3840 | struct selinux_audit_data sad = {0,}; | ||
3808 | struct sockaddr_in *addr4 = NULL; | 3841 | struct sockaddr_in *addr4 = NULL; |
3809 | struct sockaddr_in6 *addr6 = NULL; | 3842 | struct sockaddr_in6 *addr6 = NULL; |
3810 | unsigned short snum; | 3843 | unsigned short snum; |
@@ -3831,6 +3864,7 @@ static int selinux_socket_bind(struct socket *sock, struct sockaddr *address, in | |||
3831 | if (err) | 3864 | if (err) |
3832 | goto out; | 3865 | goto out; |
3833 | COMMON_AUDIT_DATA_INIT(&ad, NET); | 3866 | COMMON_AUDIT_DATA_INIT(&ad, NET); |
3867 | ad.selinux_audit_data = &sad; | ||
3834 | ad.u.net.sport = htons(snum); | 3868 | ad.u.net.sport = htons(snum); |
3835 | ad.u.net.family = family; | 3869 | ad.u.net.family = family; |
3836 | err = avc_has_perm(sksec->sid, sid, | 3870 | err = avc_has_perm(sksec->sid, sid, |
@@ -3864,6 +3898,7 @@ static int selinux_socket_bind(struct socket *sock, struct sockaddr *address, in | |||
3864 | goto out; | 3898 | goto out; |
3865 | 3899 | ||
3866 | COMMON_AUDIT_DATA_INIT(&ad, NET); | 3900 | COMMON_AUDIT_DATA_INIT(&ad, NET); |
3901 | ad.selinux_audit_data = &sad; | ||
3867 | ad.u.net.sport = htons(snum); | 3902 | ad.u.net.sport = htons(snum); |
3868 | ad.u.net.family = family; | 3903 | ad.u.net.family = family; |
3869 | 3904 | ||
@@ -3897,6 +3932,7 @@ static int selinux_socket_connect(struct socket *sock, struct sockaddr *address, | |||
3897 | if (sksec->sclass == SECCLASS_TCP_SOCKET || | 3932 | if (sksec->sclass == SECCLASS_TCP_SOCKET || |
3898 | sksec->sclass == SECCLASS_DCCP_SOCKET) { | 3933 | sksec->sclass == SECCLASS_DCCP_SOCKET) { |
3899 | struct common_audit_data ad; | 3934 | struct common_audit_data ad; |
3935 | struct selinux_audit_data sad = {0,}; | ||
3900 | struct sockaddr_in *addr4 = NULL; | 3936 | struct sockaddr_in *addr4 = NULL; |
3901 | struct sockaddr_in6 *addr6 = NULL; | 3937 | struct sockaddr_in6 *addr6 = NULL; |
3902 | unsigned short snum; | 3938 | unsigned short snum; |
@@ -3922,6 +3958,7 @@ static int selinux_socket_connect(struct socket *sock, struct sockaddr *address, | |||
3922 | TCP_SOCKET__NAME_CONNECT : DCCP_SOCKET__NAME_CONNECT; | 3958 | TCP_SOCKET__NAME_CONNECT : DCCP_SOCKET__NAME_CONNECT; |
3923 | 3959 | ||
3924 | COMMON_AUDIT_DATA_INIT(&ad, NET); | 3960 | COMMON_AUDIT_DATA_INIT(&ad, NET); |
3961 | ad.selinux_audit_data = &sad; | ||
3925 | ad.u.net.dport = htons(snum); | 3962 | ad.u.net.dport = htons(snum); |
3926 | ad.u.net.family = sk->sk_family; | 3963 | ad.u.net.family = sk->sk_family; |
3927 | err = avc_has_perm(sksec->sid, sid, sksec->sclass, perm, &ad); | 3964 | err = avc_has_perm(sksec->sid, sid, sksec->sclass, perm, &ad); |
@@ -4012,9 +4049,11 @@ static int selinux_socket_unix_stream_connect(struct sock *sock, | |||
4012 | struct sk_security_struct *sksec_other = other->sk_security; | 4049 | struct sk_security_struct *sksec_other = other->sk_security; |
4013 | struct sk_security_struct *sksec_new = newsk->sk_security; | 4050 | struct sk_security_struct *sksec_new = newsk->sk_security; |
4014 | struct common_audit_data ad; | 4051 | struct common_audit_data ad; |
4052 | struct selinux_audit_data sad = {0,}; | ||
4015 | int err; | 4053 | int err; |
4016 | 4054 | ||
4017 | COMMON_AUDIT_DATA_INIT(&ad, NET); | 4055 | COMMON_AUDIT_DATA_INIT(&ad, NET); |
4056 | ad.selinux_audit_data = &sad; | ||
4018 | ad.u.net.sk = other; | 4057 | ad.u.net.sk = other; |
4019 | 4058 | ||
4020 | err = avc_has_perm(sksec_sock->sid, sksec_other->sid, | 4059 | err = avc_has_perm(sksec_sock->sid, sksec_other->sid, |
@@ -4042,8 +4081,10 @@ static int selinux_socket_unix_may_send(struct socket *sock, | |||
4042 | struct sk_security_struct *ssec = sock->sk->sk_security; | 4081 | struct sk_security_struct *ssec = sock->sk->sk_security; |
4043 | struct sk_security_struct *osec = other->sk->sk_security; | 4082 | struct sk_security_struct *osec = other->sk->sk_security; |
4044 | struct common_audit_data ad; | 4083 | struct common_audit_data ad; |
4084 | struct selinux_audit_data sad = {0,}; | ||
4045 | 4085 | ||
4046 | COMMON_AUDIT_DATA_INIT(&ad, NET); | 4086 | COMMON_AUDIT_DATA_INIT(&ad, NET); |
4087 | ad.selinux_audit_data = &sad; | ||
4047 | ad.u.net.sk = other->sk; | 4088 | ad.u.net.sk = other->sk; |
4048 | 4089 | ||
4049 | return avc_has_perm(ssec->sid, osec->sid, osec->sclass, SOCKET__SENDTO, | 4090 | return avc_has_perm(ssec->sid, osec->sid, osec->sclass, SOCKET__SENDTO, |
@@ -4080,9 +4121,11 @@ static int selinux_sock_rcv_skb_compat(struct sock *sk, struct sk_buff *skb, | |||
4080 | struct sk_security_struct *sksec = sk->sk_security; | 4121 | struct sk_security_struct *sksec = sk->sk_security; |
4081 | u32 sk_sid = sksec->sid; | 4122 | u32 sk_sid = sksec->sid; |
4082 | struct common_audit_data ad; | 4123 | struct common_audit_data ad; |
4124 | struct selinux_audit_data sad = {0,}; | ||
4083 | char *addrp; | 4125 | char *addrp; |
4084 | 4126 | ||
4085 | COMMON_AUDIT_DATA_INIT(&ad, NET); | 4127 | COMMON_AUDIT_DATA_INIT(&ad, NET); |
4128 | ad.selinux_audit_data = &sad; | ||
4086 | ad.u.net.netif = skb->skb_iif; | 4129 | ad.u.net.netif = skb->skb_iif; |
4087 | ad.u.net.family = family; | 4130 | ad.u.net.family = family; |
4088 | err = selinux_parse_skb(skb, &ad, &addrp, 1, NULL); | 4131 | err = selinux_parse_skb(skb, &ad, &addrp, 1, NULL); |
@@ -4111,6 +4154,7 @@ static int selinux_socket_sock_rcv_skb(struct sock *sk, struct sk_buff *skb) | |||
4111 | u16 family = sk->sk_family; | 4154 | u16 family = sk->sk_family; |
4112 | u32 sk_sid = sksec->sid; | 4155 | u32 sk_sid = sksec->sid; |
4113 | struct common_audit_data ad; | 4156 | struct common_audit_data ad; |
4157 | struct selinux_audit_data sad = {0,}; | ||
4114 | char *addrp; | 4158 | char *addrp; |
4115 | u8 secmark_active; | 4159 | u8 secmark_active; |
4116 | u8 peerlbl_active; | 4160 | u8 peerlbl_active; |
@@ -4135,6 +4179,7 @@ static int selinux_socket_sock_rcv_skb(struct sock *sk, struct sk_buff *skb) | |||
4135 | return 0; | 4179 | return 0; |
4136 | 4180 | ||
4137 | COMMON_AUDIT_DATA_INIT(&ad, NET); | 4181 | COMMON_AUDIT_DATA_INIT(&ad, NET); |
4182 | ad.selinux_audit_data = &sad; | ||
4138 | ad.u.net.netif = skb->skb_iif; | 4183 | ad.u.net.netif = skb->skb_iif; |
4139 | ad.u.net.family = family; | 4184 | ad.u.net.family = family; |
4140 | err = selinux_parse_skb(skb, &ad, &addrp, 1, NULL); | 4185 | err = selinux_parse_skb(skb, &ad, &addrp, 1, NULL); |
@@ -4471,6 +4516,7 @@ static unsigned int selinux_ip_forward(struct sk_buff *skb, int ifindex, | |||
4471 | char *addrp; | 4516 | char *addrp; |
4472 | u32 peer_sid; | 4517 | u32 peer_sid; |
4473 | struct common_audit_data ad; | 4518 | struct common_audit_data ad; |
4519 | struct selinux_audit_data sad = {0,}; | ||
4474 | u8 secmark_active; | 4520 | u8 secmark_active; |
4475 | u8 netlbl_active; | 4521 | u8 netlbl_active; |
4476 | u8 peerlbl_active; | 4522 | u8 peerlbl_active; |
@@ -4488,6 +4534,7 @@ static unsigned int selinux_ip_forward(struct sk_buff *skb, int ifindex, | |||
4488 | return NF_DROP; | 4534 | return NF_DROP; |
4489 | 4535 | ||
4490 | COMMON_AUDIT_DATA_INIT(&ad, NET); | 4536 | COMMON_AUDIT_DATA_INIT(&ad, NET); |
4537 | ad.selinux_audit_data = &sad; | ||
4491 | ad.u.net.netif = ifindex; | 4538 | ad.u.net.netif = ifindex; |
4492 | ad.u.net.family = family; | 4539 | ad.u.net.family = family; |
4493 | if (selinux_parse_skb(skb, &ad, &addrp, 1, NULL) != 0) | 4540 | if (selinux_parse_skb(skb, &ad, &addrp, 1, NULL) != 0) |
@@ -4576,6 +4623,7 @@ static unsigned int selinux_ip_postroute_compat(struct sk_buff *skb, | |||
4576 | struct sock *sk = skb->sk; | 4623 | struct sock *sk = skb->sk; |
4577 | struct sk_security_struct *sksec; | 4624 | struct sk_security_struct *sksec; |
4578 | struct common_audit_data ad; | 4625 | struct common_audit_data ad; |
4626 | struct selinux_audit_data sad = {0,}; | ||
4579 | char *addrp; | 4627 | char *addrp; |
4580 | u8 proto; | 4628 | u8 proto; |
4581 | 4629 | ||
@@ -4584,6 +4632,7 @@ static unsigned int selinux_ip_postroute_compat(struct sk_buff *skb, | |||
4584 | sksec = sk->sk_security; | 4632 | sksec = sk->sk_security; |
4585 | 4633 | ||
4586 | COMMON_AUDIT_DATA_INIT(&ad, NET); | 4634 | COMMON_AUDIT_DATA_INIT(&ad, NET); |
4635 | ad.selinux_audit_data = &sad; | ||
4587 | ad.u.net.netif = ifindex; | 4636 | ad.u.net.netif = ifindex; |
4588 | ad.u.net.family = family; | 4637 | ad.u.net.family = family; |
4589 | if (selinux_parse_skb(skb, &ad, &addrp, 0, &proto)) | 4638 | if (selinux_parse_skb(skb, &ad, &addrp, 0, &proto)) |
@@ -4607,6 +4656,7 @@ static unsigned int selinux_ip_postroute(struct sk_buff *skb, int ifindex, | |||
4607 | u32 peer_sid; | 4656 | u32 peer_sid; |
4608 | struct sock *sk; | 4657 | struct sock *sk; |
4609 | struct common_audit_data ad; | 4658 | struct common_audit_data ad; |
4659 | struct selinux_audit_data sad = {0,}; | ||
4610 | char *addrp; | 4660 | char *addrp; |
4611 | u8 secmark_active; | 4661 | u8 secmark_active; |
4612 | u8 peerlbl_active; | 4662 | u8 peerlbl_active; |
@@ -4653,6 +4703,7 @@ static unsigned int selinux_ip_postroute(struct sk_buff *skb, int ifindex, | |||
4653 | } | 4703 | } |
4654 | 4704 | ||
4655 | COMMON_AUDIT_DATA_INIT(&ad, NET); | 4705 | COMMON_AUDIT_DATA_INIT(&ad, NET); |
4706 | ad.selinux_audit_data = &sad; | ||
4656 | ad.u.net.netif = ifindex; | 4707 | ad.u.net.netif = ifindex; |
4657 | ad.u.net.family = family; | 4708 | ad.u.net.family = family; |
4658 | if (selinux_parse_skb(skb, &ad, &addrp, 0, NULL)) | 4709 | if (selinux_parse_skb(skb, &ad, &addrp, 0, NULL)) |
@@ -4769,11 +4820,13 @@ static int ipc_has_perm(struct kern_ipc_perm *ipc_perms, | |||
4769 | { | 4820 | { |
4770 | struct ipc_security_struct *isec; | 4821 | struct ipc_security_struct *isec; |
4771 | struct common_audit_data ad; | 4822 | struct common_audit_data ad; |
4823 | struct selinux_audit_data sad = {0,}; | ||
4772 | u32 sid = current_sid(); | 4824 | u32 sid = current_sid(); |
4773 | 4825 | ||
4774 | isec = ipc_perms->security; | 4826 | isec = ipc_perms->security; |
4775 | 4827 | ||
4776 | COMMON_AUDIT_DATA_INIT(&ad, IPC); | 4828 | COMMON_AUDIT_DATA_INIT(&ad, IPC); |
4829 | ad.selinux_audit_data = &sad; | ||
4777 | ad.u.ipc_id = ipc_perms->key; | 4830 | ad.u.ipc_id = ipc_perms->key; |
4778 | 4831 | ||
4779 | return avc_has_perm(sid, isec->sid, isec->sclass, perms, &ad); | 4832 | return avc_has_perm(sid, isec->sid, isec->sclass, perms, &ad); |
@@ -4794,6 +4847,7 @@ static int selinux_msg_queue_alloc_security(struct msg_queue *msq) | |||
4794 | { | 4847 | { |
4795 | struct ipc_security_struct *isec; | 4848 | struct ipc_security_struct *isec; |
4796 | struct common_audit_data ad; | 4849 | struct common_audit_data ad; |
4850 | struct selinux_audit_data sad = {0,}; | ||
4797 | u32 sid = current_sid(); | 4851 | u32 sid = current_sid(); |
4798 | int rc; | 4852 | int rc; |
4799 | 4853 | ||
@@ -4804,6 +4858,7 @@ static int selinux_msg_queue_alloc_security(struct msg_queue *msq) | |||
4804 | isec = msq->q_perm.security; | 4858 | isec = msq->q_perm.security; |
4805 | 4859 | ||
4806 | COMMON_AUDIT_DATA_INIT(&ad, IPC); | 4860 | COMMON_AUDIT_DATA_INIT(&ad, IPC); |
4861 | ad.selinux_audit_data = &sad; | ||
4807 | ad.u.ipc_id = msq->q_perm.key; | 4862 | ad.u.ipc_id = msq->q_perm.key; |
4808 | 4863 | ||
4809 | rc = avc_has_perm(sid, isec->sid, SECCLASS_MSGQ, | 4864 | rc = avc_has_perm(sid, isec->sid, SECCLASS_MSGQ, |
@@ -4824,11 +4879,13 @@ static int selinux_msg_queue_associate(struct msg_queue *msq, int msqflg) | |||
4824 | { | 4879 | { |
4825 | struct ipc_security_struct *isec; | 4880 | struct ipc_security_struct *isec; |
4826 | struct common_audit_data ad; | 4881 | struct common_audit_data ad; |
4882 | struct selinux_audit_data sad = {0,}; | ||
4827 | u32 sid = current_sid(); | 4883 | u32 sid = current_sid(); |
4828 | 4884 | ||
4829 | isec = msq->q_perm.security; | 4885 | isec = msq->q_perm.security; |
4830 | 4886 | ||
4831 | COMMON_AUDIT_DATA_INIT(&ad, IPC); | 4887 | COMMON_AUDIT_DATA_INIT(&ad, IPC); |
4888 | ad.selinux_audit_data = &sad; | ||
4832 | ad.u.ipc_id = msq->q_perm.key; | 4889 | ad.u.ipc_id = msq->q_perm.key; |
4833 | 4890 | ||
4834 | return avc_has_perm(sid, isec->sid, SECCLASS_MSGQ, | 4891 | return avc_has_perm(sid, isec->sid, SECCLASS_MSGQ, |
@@ -4868,6 +4925,7 @@ static int selinux_msg_queue_msgsnd(struct msg_queue *msq, struct msg_msg *msg, | |||
4868 | struct ipc_security_struct *isec; | 4925 | struct ipc_security_struct *isec; |
4869 | struct msg_security_struct *msec; | 4926 | struct msg_security_struct *msec; |
4870 | struct common_audit_data ad; | 4927 | struct common_audit_data ad; |
4928 | struct selinux_audit_data sad = {0,}; | ||
4871 | u32 sid = current_sid(); | 4929 | u32 sid = current_sid(); |
4872 | int rc; | 4930 | int rc; |
4873 | 4931 | ||
@@ -4889,6 +4947,7 @@ static int selinux_msg_queue_msgsnd(struct msg_queue *msq, struct msg_msg *msg, | |||
4889 | } | 4947 | } |
4890 | 4948 | ||
4891 | COMMON_AUDIT_DATA_INIT(&ad, IPC); | 4949 | COMMON_AUDIT_DATA_INIT(&ad, IPC); |
4950 | ad.selinux_audit_data = &sad; | ||
4892 | ad.u.ipc_id = msq->q_perm.key; | 4951 | ad.u.ipc_id = msq->q_perm.key; |
4893 | 4952 | ||
4894 | /* Can this process write to the queue? */ | 4953 | /* Can this process write to the queue? */ |
@@ -4913,6 +4972,7 @@ static int selinux_msg_queue_msgrcv(struct msg_queue *msq, struct msg_msg *msg, | |||
4913 | struct ipc_security_struct *isec; | 4972 | struct ipc_security_struct *isec; |
4914 | struct msg_security_struct *msec; | 4973 | struct msg_security_struct *msec; |
4915 | struct common_audit_data ad; | 4974 | struct common_audit_data ad; |
4975 | struct selinux_audit_data sad = {0,}; | ||
4916 | u32 sid = task_sid(target); | 4976 | u32 sid = task_sid(target); |
4917 | int rc; | 4977 | int rc; |
4918 | 4978 | ||
@@ -4920,6 +4980,7 @@ static int selinux_msg_queue_msgrcv(struct msg_queue *msq, struct msg_msg *msg, | |||
4920 | msec = msg->security; | 4980 | msec = msg->security; |
4921 | 4981 | ||
4922 | COMMON_AUDIT_DATA_INIT(&ad, IPC); | 4982 | COMMON_AUDIT_DATA_INIT(&ad, IPC); |
4983 | ad.selinux_audit_data = &sad; | ||
4923 | ad.u.ipc_id = msq->q_perm.key; | 4984 | ad.u.ipc_id = msq->q_perm.key; |
4924 | 4985 | ||
4925 | rc = avc_has_perm(sid, isec->sid, | 4986 | rc = avc_has_perm(sid, isec->sid, |
@@ -4935,6 +4996,7 @@ static int selinux_shm_alloc_security(struct shmid_kernel *shp) | |||
4935 | { | 4996 | { |
4936 | struct ipc_security_struct *isec; | 4997 | struct ipc_security_struct *isec; |
4937 | struct common_audit_data ad; | 4998 | struct common_audit_data ad; |
4999 | struct selinux_audit_data sad = {0,}; | ||
4938 | u32 sid = current_sid(); | 5000 | u32 sid = current_sid(); |
4939 | int rc; | 5001 | int rc; |
4940 | 5002 | ||
@@ -4945,6 +5007,7 @@ static int selinux_shm_alloc_security(struct shmid_kernel *shp) | |||
4945 | isec = shp->shm_perm.security; | 5007 | isec = shp->shm_perm.security; |
4946 | 5008 | ||
4947 | COMMON_AUDIT_DATA_INIT(&ad, IPC); | 5009 | COMMON_AUDIT_DATA_INIT(&ad, IPC); |
5010 | ad.selinux_audit_data = &sad; | ||
4948 | ad.u.ipc_id = shp->shm_perm.key; | 5011 | ad.u.ipc_id = shp->shm_perm.key; |
4949 | 5012 | ||
4950 | rc = avc_has_perm(sid, isec->sid, SECCLASS_SHM, | 5013 | rc = avc_has_perm(sid, isec->sid, SECCLASS_SHM, |
@@ -4965,11 +5028,13 @@ static int selinux_shm_associate(struct shmid_kernel *shp, int shmflg) | |||
4965 | { | 5028 | { |
4966 | struct ipc_security_struct *isec; | 5029 | struct ipc_security_struct *isec; |
4967 | struct common_audit_data ad; | 5030 | struct common_audit_data ad; |
5031 | struct selinux_audit_data sad = {0,}; | ||
4968 | u32 sid = current_sid(); | 5032 | u32 sid = current_sid(); |
4969 | 5033 | ||
4970 | isec = shp->shm_perm.security; | 5034 | isec = shp->shm_perm.security; |
4971 | 5035 | ||
4972 | COMMON_AUDIT_DATA_INIT(&ad, IPC); | 5036 | COMMON_AUDIT_DATA_INIT(&ad, IPC); |
5037 | ad.selinux_audit_data = &sad; | ||
4973 | ad.u.ipc_id = shp->shm_perm.key; | 5038 | ad.u.ipc_id = shp->shm_perm.key; |
4974 | 5039 | ||
4975 | return avc_has_perm(sid, isec->sid, SECCLASS_SHM, | 5040 | return avc_has_perm(sid, isec->sid, SECCLASS_SHM, |
@@ -5027,6 +5092,7 @@ static int selinux_sem_alloc_security(struct sem_array *sma) | |||
5027 | { | 5092 | { |
5028 | struct ipc_security_struct *isec; | 5093 | struct ipc_security_struct *isec; |
5029 | struct common_audit_data ad; | 5094 | struct common_audit_data ad; |
5095 | struct selinux_audit_data sad = {0,}; | ||
5030 | u32 sid = current_sid(); | 5096 | u32 sid = current_sid(); |
5031 | int rc; | 5097 | int rc; |
5032 | 5098 | ||
@@ -5037,6 +5103,7 @@ static int selinux_sem_alloc_security(struct sem_array *sma) | |||
5037 | isec = sma->sem_perm.security; | 5103 | isec = sma->sem_perm.security; |
5038 | 5104 | ||
5039 | COMMON_AUDIT_DATA_INIT(&ad, IPC); | 5105 | COMMON_AUDIT_DATA_INIT(&ad, IPC); |
5106 | ad.selinux_audit_data = &sad; | ||
5040 | ad.u.ipc_id = sma->sem_perm.key; | 5107 | ad.u.ipc_id = sma->sem_perm.key; |
5041 | 5108 | ||
5042 | rc = avc_has_perm(sid, isec->sid, SECCLASS_SEM, | 5109 | rc = avc_has_perm(sid, isec->sid, SECCLASS_SEM, |
@@ -5057,11 +5124,13 @@ static int selinux_sem_associate(struct sem_array *sma, int semflg) | |||
5057 | { | 5124 | { |
5058 | struct ipc_security_struct *isec; | 5125 | struct ipc_security_struct *isec; |
5059 | struct common_audit_data ad; | 5126 | struct common_audit_data ad; |
5127 | struct selinux_audit_data sad = {0,}; | ||
5060 | u32 sid = current_sid(); | 5128 | u32 sid = current_sid(); |
5061 | 5129 | ||
5062 | isec = sma->sem_perm.security; | 5130 | isec = sma->sem_perm.security; |
5063 | 5131 | ||
5064 | COMMON_AUDIT_DATA_INIT(&ad, IPC); | 5132 | COMMON_AUDIT_DATA_INIT(&ad, IPC); |
5133 | ad.selinux_audit_data = &sad; | ||
5065 | ad.u.ipc_id = sma->sem_perm.key; | 5134 | ad.u.ipc_id = sma->sem_perm.key; |
5066 | 5135 | ||
5067 | return avc_has_perm(sid, isec->sid, SECCLASS_SEM, | 5136 | return avc_has_perm(sid, isec->sid, SECCLASS_SEM, |
diff --git a/security/selinux/include/avc.h b/security/selinux/include/avc.h index 005a91bcb200..fa13f17ce0ff 100644 --- a/security/selinux/include/avc.h +++ b/security/selinux/include/avc.h | |||
@@ -46,6 +46,22 @@ struct avc_cache_stats { | |||
46 | unsigned int frees; | 46 | unsigned int frees; |
47 | }; | 47 | }; |
48 | 48 | ||
49 | struct selinux_audit_data { | ||
50 | u32 ssid; | ||
51 | u32 tsid; | ||
52 | u16 tclass; | ||
53 | u32 requested; | ||
54 | u32 audited; | ||
55 | u32 denied; | ||
56 | /* | ||
57 | * auditdeny is a bit tricky and unintuitive. See the | ||
58 | * comments in avc.c for it's meaning and usage. | ||
59 | */ | ||
60 | u32 auditdeny; | ||
61 | struct av_decision *avd; | ||
62 | int result; | ||
63 | }; | ||
64 | |||
49 | /* | 65 | /* |
50 | * AVC operations | 66 | * AVC operations |
51 | */ | 67 | */ |
diff --git a/security/smack/smack.h b/security/smack/smack.h index 2ad00657b801..ccba3823d9ef 100644 --- a/security/smack/smack.h +++ b/security/smack/smack.h | |||
@@ -185,6 +185,15 @@ struct smack_known { | |||
185 | */ | 185 | */ |
186 | #define SMK_NUM_ACCESS_TYPE 5 | 186 | #define SMK_NUM_ACCESS_TYPE 5 |
187 | 187 | ||
188 | /* SMACK data */ | ||
189 | struct smack_audit_data { | ||
190 | const char *function; | ||
191 | char *subject; | ||
192 | char *object; | ||
193 | char *request; | ||
194 | int result; | ||
195 | }; | ||
196 | |||
188 | /* | 197 | /* |
189 | * Smack audit data; is empty if CONFIG_AUDIT not set | 198 | * Smack audit data; is empty if CONFIG_AUDIT not set |
190 | * to save some stack | 199 | * to save some stack |
@@ -192,6 +201,7 @@ struct smack_known { | |||
192 | struct smk_audit_info { | 201 | struct smk_audit_info { |
193 | #ifdef CONFIG_AUDIT | 202 | #ifdef CONFIG_AUDIT |
194 | struct common_audit_data a; | 203 | struct common_audit_data a; |
204 | struct smack_audit_data sad; | ||
195 | #endif | 205 | #endif |
196 | }; | 206 | }; |
197 | /* | 207 | /* |
@@ -311,7 +321,8 @@ static inline void smk_ad_init(struct smk_audit_info *a, const char *func, | |||
311 | { | 321 | { |
312 | memset(a, 0, sizeof(*a)); | 322 | memset(a, 0, sizeof(*a)); |
313 | a->a.type = type; | 323 | a->a.type = type; |
314 | a->a.smack_audit_data.function = func; | 324 | a->a.smack_audit_data = &a->sad; |
325 | a->a.smack_audit_data->function = func; | ||
315 | } | 326 | } |
316 | 327 | ||
317 | static inline void smk_ad_setfield_u_tsk(struct smk_audit_info *a, | 328 | static inline void smk_ad_setfield_u_tsk(struct smk_audit_info *a, |
diff --git a/security/smack/smack_access.c b/security/smack/smack_access.c index cc7cb6edba08..2af7fcc98a71 100644 --- a/security/smack/smack_access.c +++ b/security/smack/smack_access.c | |||
@@ -275,9 +275,9 @@ static inline void smack_str_from_perm(char *string, int access) | |||
275 | static void smack_log_callback(struct audit_buffer *ab, void *a) | 275 | static void smack_log_callback(struct audit_buffer *ab, void *a) |
276 | { | 276 | { |
277 | struct common_audit_data *ad = a; | 277 | struct common_audit_data *ad = a; |
278 | struct smack_audit_data *sad = &ad->smack_audit_data; | 278 | struct smack_audit_data *sad = ad->smack_audit_data; |
279 | audit_log_format(ab, "lsm=SMACK fn=%s action=%s", | 279 | audit_log_format(ab, "lsm=SMACK fn=%s action=%s", |
280 | ad->smack_audit_data.function, | 280 | ad->smack_audit_data->function, |
281 | sad->result ? "denied" : "granted"); | 281 | sad->result ? "denied" : "granted"); |
282 | audit_log_format(ab, " subject="); | 282 | audit_log_format(ab, " subject="); |
283 | audit_log_untrustedstring(ab, sad->subject); | 283 | audit_log_untrustedstring(ab, sad->subject); |
@@ -310,11 +310,12 @@ void smack_log(char *subject_label, char *object_label, int request, | |||
310 | if (result == 0 && (log_policy & SMACK_AUDIT_ACCEPT) == 0) | 310 | if (result == 0 && (log_policy & SMACK_AUDIT_ACCEPT) == 0) |
311 | return; | 311 | return; |
312 | 312 | ||
313 | if (a->smack_audit_data.function == NULL) | 313 | sad = a->smack_audit_data; |
314 | a->smack_audit_data.function = "unknown"; | 314 | |
315 | if (sad->function == NULL) | ||
316 | sad->function = "unknown"; | ||
315 | 317 | ||
316 | /* end preparing the audit data */ | 318 | /* end preparing the audit data */ |
317 | sad = &a->smack_audit_data; | ||
318 | smack_str_from_perm(request_buffer, request); | 319 | smack_str_from_perm(request_buffer, request); |
319 | sad->subject = subject_label; | 320 | sad->subject = subject_label; |
320 | sad->object = object_label; | 321 | sad->object = object_label; |