@@ -79,14 +79,16 @@ static void file_audit_cb(struct audit_buffer *ab, void *va)
79
79
}
80
80
}
81
81
82
+ // ??? differentiate between
83
+ // cached - allow : no audit == 1
84
+ // cached - deny : no audit < 0
85
+ // cached - complain : no audit
86
+ // cached - partial : audit missing part : as miss
87
+ // not cached = 0
82
88
static int check_cache (struct aa_profile * profile ,
83
- struct apparmor_audit_data * ad ,
84
- struct aa_perms * perms )
89
+ struct apparmor_audit_data * ad )
85
90
{
86
- struct aa_audit_node * node = NULL ;
87
91
struct aa_audit_node * hit ;
88
- bool cache_response ;
89
- int err ;
90
92
91
93
AA_BUG (!profile );
92
94
ad -> subj_label = & profile -> label ; // normally set in aa_audit
@@ -116,34 +118,48 @@ static int check_cache(struct aa_profile *profile,
116
118
/* continue to do prompt */
117
119
} else {
118
120
AA_DEBUG (DEBUG_UPCALL , "cache hit" );
119
- ad -> error = 0 ;
120
121
aa_put_audit_node (hit );
121
- /* do audit */
122
- return 0 ;
122
+ /* don't audit: if its in the cache already audited */
123
+ return 1 ;
123
124
}
124
125
aa_put_audit_node (hit );
125
126
hit = NULL ;
126
127
} else {
127
128
AA_DEBUG (DEBUG_UPCALL , "cache miss" );
128
129
}
130
+
131
+ return 0 ;
132
+ }
133
+
134
+ // error - immediate return
135
+ // - debug message do audit
136
+ // caching is handled on listener task side
137
+ static int check_user (struct aa_profile * profile ,
138
+ struct apparmor_audit_data * ad ,
139
+ struct aa_perms * perms )
140
+ {
141
+ struct aa_audit_node * node = NULL ;
142
+ int err ;
143
+
129
144
/* assume we are going to dispatch */
130
145
node = aa_dup_audit_data (ad , GFP_KERNEL );
131
146
if (!node ) {
132
147
AA_DEBUG (DEBUG_UPCALL ,
133
148
"notifcation failed to duplicate with error -ENOMEM\n" );
134
149
/* do audit */
135
- return 0 ;
150
+ return - ENOMEM ;
136
151
}
137
152
138
153
get_task_struct (current );
139
154
node -> data .subjtsk = current ;
140
155
node -> data .type = AUDIT_APPARMOR_USER ;
141
156
node -> data .request = ad -> request ;
142
157
node -> data .denied = ad -> request & ~perms -> allow ;
143
- err = aa_do_notification (APPARMOR_NOTIF_OP , node , & cache_response );
158
+ err = aa_do_notification (APPARMOR_NOTIF_OP , node );
144
159
put_task_struct (node -> data .subjtsk );
145
160
146
161
if (err ) {
162
+ // do we want to do something special with -ERESTARTSYS
147
163
AA_DEBUG (DEBUG_UPCALL , "notifcation failed with error %d\n" ,
148
164
ad -> error );
149
165
goto return_to_audit ;
@@ -154,33 +170,9 @@ static int check_cache(struct aa_profile *profile,
154
170
ad -> denied = node -> data .denied ;
155
171
ad -> error = node -> data .error ;
156
172
157
- if (cache_response ) {
158
- /* TODO: shouldn't add until after auditing it, or at
159
- * least having a refcount. Fix once removing entry is
160
- * allowed
161
- */
162
- AA_DEBUG (DEBUG_UPCALL , "inserting cache entry requ 0x%x denied 0x%x" ,
163
- node -> data .request , node -> data .denied );
164
- hit = aa_audit_cache_insert (& profile -> learning_cache ,
165
- node );
166
- AA_DEBUG (DEBUG_UPCALL , "cache insert %s: name %s node %s\n" ,
167
- hit != node ? "lost race" : "" ,
168
- hit -> data .name , node -> data .name );
169
- if (hit != node ) {
170
- AA_DEBUG (DEBUG_UPCALL , "updating existing cache entry" );
171
- aa_audit_cache_update_ent (& profile -> learning_cache ,
172
- hit , & node -> data );
173
- aa_put_audit_node (hit );
174
- } else {
175
-
176
- AA_DEBUG (DEBUG_UPCALL , "inserted into cache" );
177
- }
178
- /* now to audit */
179
- } /* cache_response */
180
-
181
173
return_to_audit :
182
174
aa_put_audit_node (node );
183
- return 0 ;
175
+ return err ;
184
176
}
185
177
186
178
/**
@@ -220,14 +212,33 @@ int aa_audit_file(const struct cred *subj_cred,
220
212
ad .common .u .tsk = NULL ;
221
213
ad .subjtsk = NULL ;
222
214
223
- if (unlikely (ad .error ) && ((prompt && USER_MODE (profile )) ||
224
- ((request & perms -> prompt ) &&
225
- ((request & (perms -> prompt |
226
- perms -> allow )) == request )))) {
227
- err = check_cache (profile , & ad , perms );
228
- if (err )
229
- /* only happens if already cached */
230
- return err ;
215
+ ad .denied = denied_perms (perms , ad .request );
216
+
217
+ if (unlikely (ad .error )) {
218
+ u32 implicit_deny ;
219
+
220
+ /* learning cache - not audit dedup yet */
221
+ err = check_cache (profile , & ad );
222
+ if (err != 0 )
223
+ /* cached */
224
+ return ad .error ;
225
+
226
+ implicit_deny = (ad .request & ~perms -> allow ) & ~perms -> deny ;
227
+ if (USER_MODE (profile ))
228
+ perms -> prompt = ALL_PERMS_MASK ;
229
+
230
+ /* don't prompt
231
+ * - if explicit deny
232
+ * - if implicit_deny is not entirely covered by prompt
233
+ * as no point asking user to just deny it anyway.
234
+ */
235
+ if (prompt && !(request & perms -> deny ) &&
236
+ (perms -> prompt & implicit_deny ) == implicit_deny ) {
237
+ err = check_user (profile , & ad , perms );
238
+ if (err == - ERESTARTSYS )
239
+ /* are there other errors we should bail on */
240
+ return err ;
241
+ }
231
242
}
232
243
233
244
if (likely (!ad .error )) {
@@ -260,7 +271,6 @@ int aa_audit_file(const struct cred *subj_cred,
260
271
return ad .error ;
261
272
}
262
273
263
- ad .denied = ad .request & ~perms -> allow ;
264
274
err = aa_audit (type , profile , & ad , file_audit_cb );
265
275
return err ;
266
276
}
0 commit comments