xref: /aosp_15_r20/system/security/keystore2/src/permission/tests.rs (revision e1997b9af69e3155ead6e072d106a0077849ffba)
1 // Copyright 2020, The Android Open Source Project
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 //     http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 
15 //! Access control tests.
16 
17 use super::*;
18 use crate::key_perm_set;
19 use anyhow::anyhow;
20 use anyhow::Result;
21 use keystore2_selinux::*;
22 
23 const ALL_PERMS: KeyPermSet = key_perm_set![
24     KeyPerm::ManageBlob,
25     KeyPerm::Delete,
26     KeyPerm::UseDevId,
27     KeyPerm::ReqForcedOp,
28     KeyPerm::GenUniqueId,
29     KeyPerm::Grant,
30     KeyPerm::GetInfo,
31     KeyPerm::Rebind,
32     KeyPerm::Update,
33     KeyPerm::Use,
34     KeyPerm::ConvertStorageKeyToEphemeral,
35 ];
36 
37 const SYSTEM_SERVER_PERMISSIONS_NO_GRANT: KeyPermSet = key_perm_set![
38     KeyPerm::Delete,
39     KeyPerm::UseDevId,
40     // No KeyPerm::Grant
41     KeyPerm::GetInfo,
42     KeyPerm::Rebind,
43     KeyPerm::Update,
44     KeyPerm::Use,
45 ];
46 
47 const NOT_GRANT_PERMS: KeyPermSet = key_perm_set![
48     KeyPerm::ManageBlob,
49     KeyPerm::Delete,
50     KeyPerm::UseDevId,
51     KeyPerm::ReqForcedOp,
52     KeyPerm::GenUniqueId,
53     // No KeyPerm::Grant
54     KeyPerm::GetInfo,
55     KeyPerm::Rebind,
56     KeyPerm::Update,
57     KeyPerm::Use,
58     KeyPerm::ConvertStorageKeyToEphemeral,
59 ];
60 
61 const UNPRIV_PERMS: KeyPermSet = key_perm_set![
62     KeyPerm::Delete,
63     KeyPerm::GetInfo,
64     KeyPerm::Rebind,
65     KeyPerm::Update,
66     KeyPerm::Use,
67 ];
68 
69 /// The su_key namespace as defined in su.te and keystore_key_contexts of the
70 /// SePolicy (system/sepolicy).
71 const SU_KEY_NAMESPACE: i32 = 0;
72 /// The shell_key namespace as defined in shell.te and keystore_key_contexts of the
73 /// SePolicy (system/sepolicy).
74 const SHELL_KEY_NAMESPACE: i32 = 1;
75 
test_getcon() -> Result<Context>76 pub fn test_getcon() -> Result<Context> {
77     Context::new("u:object_r:keystore:s0")
78 }
79 
80 // This macro evaluates the given expression and checks that
81 // a) evaluated to Result::Err() and that
82 // b) the wrapped error is selinux::Error::perm() (permission denied).
83 // We use a macro here because a function would mask which invocation caused the failure.
84 //
85 // TODO b/164121720 Replace this macro with a function when `track_caller` is available.
86 macro_rules! assert_perm_failed {
87     ($test_function:expr) => {
88         let result = $test_function;
89         assert!(result.is_err(), "Permission check should have failed.");
90         assert_eq!(
91             Some(&selinux::Error::perm()),
92             result.err().unwrap().root_cause().downcast_ref::<selinux::Error>()
93         );
94     };
95 }
96 
check_context() -> Result<(selinux::Context, i32, bool)>97 fn check_context() -> Result<(selinux::Context, i32, bool)> {
98     // Calling the non mocked selinux::getcon here intended.
99     let context = selinux::getcon()?;
100     match context.to_str().unwrap() {
101         "u:r:su:s0" => Ok((context, SU_KEY_NAMESPACE, true)),
102         "u:r:shell:s0" => Ok((context, SHELL_KEY_NAMESPACE, false)),
103         c => Err(anyhow!(format!(
104             "This test must be run as \"su\" or \"shell\". Current context: \"{}\"",
105             c
106         ))),
107     }
108 }
109 
110 #[test]
check_keystore_permission_test() -> Result<()>111 fn check_keystore_permission_test() -> Result<()> {
112     let system_server_ctx = Context::new("u:r:system_server:s0")?;
113     assert!(check_keystore_permission(&system_server_ctx, KeystorePerm::AddAuth).is_ok());
114     assert!(check_keystore_permission(&system_server_ctx, KeystorePerm::ClearNs).is_ok());
115     assert!(check_keystore_permission(&system_server_ctx, KeystorePerm::Lock).is_ok());
116     assert!(check_keystore_permission(&system_server_ctx, KeystorePerm::Reset).is_ok());
117     assert!(check_keystore_permission(&system_server_ctx, KeystorePerm::Unlock).is_ok());
118     assert!(check_keystore_permission(&system_server_ctx, KeystorePerm::ChangeUser).is_ok());
119     assert!(check_keystore_permission(&system_server_ctx, KeystorePerm::ChangePassword).is_ok());
120     assert!(check_keystore_permission(&system_server_ctx, KeystorePerm::ClearUID).is_ok());
121     let shell_ctx = Context::new("u:r:shell:s0")?;
122     assert_perm_failed!(check_keystore_permission(&shell_ctx, KeystorePerm::AddAuth));
123     assert_perm_failed!(check_keystore_permission(&shell_ctx, KeystorePerm::ClearNs));
124     assert_perm_failed!(check_keystore_permission(&shell_ctx, KeystorePerm::List));
125     assert_perm_failed!(check_keystore_permission(&shell_ctx, KeystorePerm::Lock));
126     assert_perm_failed!(check_keystore_permission(&shell_ctx, KeystorePerm::Reset));
127     assert_perm_failed!(check_keystore_permission(&shell_ctx, KeystorePerm::Unlock));
128     assert_perm_failed!(check_keystore_permission(&shell_ctx, KeystorePerm::ChangeUser));
129     assert_perm_failed!(check_keystore_permission(&shell_ctx, KeystorePerm::ChangePassword));
130     assert_perm_failed!(check_keystore_permission(&shell_ctx, KeystorePerm::ClearUID));
131     Ok(())
132 }
133 
134 #[test]
check_grant_permission_app() -> Result<()>135 fn check_grant_permission_app() -> Result<()> {
136     let system_server_ctx = Context::new("u:r:system_server:s0")?;
137     let key = KeyDescriptor { domain: Domain::APP, nspace: 0, alias: None, blob: None };
138     check_grant_permission(0, &system_server_ctx, SYSTEM_SERVER_PERMISSIONS_NO_GRANT, &key)
139         .expect("Grant permission check failed.");
140 
141     // attempts to grant the grant permission must always fail even when privileged.
142     assert_perm_failed!(check_grant_permission(0, &system_server_ctx, KeyPerm::Grant.into(), &key));
143     Ok(())
144 }
145 
146 #[test]
check_grant_permission_selinux() -> Result<()>147 fn check_grant_permission_selinux() -> Result<()> {
148     let (sctx, namespace, is_su) = check_context()?;
149     let key = KeyDescriptor {
150         domain: Domain::SELINUX,
151         nspace: namespace as i64,
152         alias: None,
153         blob: None,
154     };
155     if is_su {
156         assert!(check_grant_permission(0, &sctx, NOT_GRANT_PERMS, &key).is_ok());
157         // attempts to grant the grant permission must always fail even when privileged.
158         assert_perm_failed!(check_grant_permission(0, &sctx, KeyPerm::Grant.into(), &key));
159     } else {
160         // unprivileged grant attempts always fail. shell does not have the grant permission.
161         assert_perm_failed!(check_grant_permission(0, &sctx, UNPRIV_PERMS, &key));
162     }
163     Ok(())
164 }
165 
166 #[test]
check_key_permission_domain_grant() -> Result<()>167 fn check_key_permission_domain_grant() -> Result<()> {
168     let key = KeyDescriptor { domain: Domain::GRANT, nspace: 0, alias: None, blob: None };
169 
170     assert_perm_failed!(check_key_permission(
171         0,
172         &selinux::Context::new("ignored").unwrap(),
173         KeyPerm::Grant,
174         &key,
175         &Some(UNPRIV_PERMS)
176     ));
177 
178     check_key_permission(
179         0,
180         &selinux::Context::new("ignored").unwrap(),
181         KeyPerm::Use,
182         &key,
183         &Some(ALL_PERMS),
184     )
185 }
186 
187 #[test]
check_key_permission_domain_app() -> Result<()>188 fn check_key_permission_domain_app() -> Result<()> {
189     let system_server_ctx = Context::new("u:r:system_server:s0")?;
190     let shell_ctx = Context::new("u:r:shell:s0")?;
191     let gmscore_app = Context::new("u:r:gmscore_app:s0")?;
192 
193     let key = KeyDescriptor { domain: Domain::APP, nspace: 0, alias: None, blob: None };
194 
195     assert!(check_key_permission(0, &system_server_ctx, KeyPerm::Use, &key, &None).is_ok());
196     assert!(check_key_permission(0, &system_server_ctx, KeyPerm::Delete, &key, &None).is_ok());
197     assert!(check_key_permission(0, &system_server_ctx, KeyPerm::GetInfo, &key, &None).is_ok());
198     assert!(check_key_permission(0, &system_server_ctx, KeyPerm::Rebind, &key, &None).is_ok());
199     assert!(check_key_permission(0, &system_server_ctx, KeyPerm::Update, &key, &None).is_ok());
200     assert!(check_key_permission(0, &system_server_ctx, KeyPerm::Grant, &key, &None).is_ok());
201     assert!(check_key_permission(0, &system_server_ctx, KeyPerm::UseDevId, &key, &None).is_ok());
202     assert!(check_key_permission(0, &gmscore_app, KeyPerm::GenUniqueId, &key, &None).is_ok());
203 
204     assert!(check_key_permission(0, &shell_ctx, KeyPerm::Use, &key, &None).is_ok());
205     assert!(check_key_permission(0, &shell_ctx, KeyPerm::Delete, &key, &None).is_ok());
206     assert!(check_key_permission(0, &shell_ctx, KeyPerm::GetInfo, &key, &None).is_ok());
207     assert!(check_key_permission(0, &shell_ctx, KeyPerm::Rebind, &key, &None).is_ok());
208     assert!(check_key_permission(0, &shell_ctx, KeyPerm::Update, &key, &None).is_ok());
209     assert_perm_failed!(check_key_permission(0, &shell_ctx, KeyPerm::ReqForcedOp, &key, &None));
210     assert_perm_failed!(check_key_permission(0, &shell_ctx, KeyPerm::ManageBlob, &key, &None));
211     assert_perm_failed!(check_key_permission(0, &shell_ctx, KeyPerm::UseDevId, &key, &None));
212     assert_perm_failed!(check_key_permission(0, &shell_ctx, KeyPerm::GenUniqueId, &key, &None));
213 
214     // Also make sure that the permission fails if the caller is not the owner.
215     assert_perm_failed!(check_key_permission(
216         1, // the owner is 0
217         &system_server_ctx,
218         KeyPerm::Use,
219         &key,
220         &None
221     ));
222     // Unless there was a grant.
223     assert!(check_key_permission(
224         1,
225         &system_server_ctx,
226         KeyPerm::Use,
227         &key,
228         &Some(key_perm_set![KeyPerm::Use])
229     )
230     .is_ok());
231     // But fail if the grant did not cover the requested permission.
232     assert_perm_failed!(check_key_permission(
233         1,
234         &system_server_ctx,
235         KeyPerm::Use,
236         &key,
237         &Some(key_perm_set![KeyPerm::GetInfo])
238     ));
239 
240     Ok(())
241 }
242 
243 #[test]
check_key_permission_domain_selinux() -> Result<()>244 fn check_key_permission_domain_selinux() -> Result<()> {
245     let (sctx, namespace, is_su) = check_context()?;
246     let key = KeyDescriptor {
247         domain: Domain::SELINUX,
248         nspace: namespace as i64,
249         alias: None,
250         blob: None,
251     };
252 
253     assert!(check_key_permission(0, &sctx, KeyPerm::Use, &key, &None).is_ok());
254     assert!(check_key_permission(0, &sctx, KeyPerm::Delete, &key, &None).is_ok());
255     assert!(check_key_permission(0, &sctx, KeyPerm::GetInfo, &key, &None).is_ok());
256     assert!(check_key_permission(0, &sctx, KeyPerm::Rebind, &key, &None).is_ok());
257     assert!(check_key_permission(0, &sctx, KeyPerm::Update, &key, &None).is_ok());
258 
259     if is_su {
260         assert!(check_key_permission(0, &sctx, KeyPerm::Grant, &key, &None).is_ok());
261         assert!(check_key_permission(0, &sctx, KeyPerm::ManageBlob, &key, &None).is_ok());
262         assert!(check_key_permission(0, &sctx, KeyPerm::UseDevId, &key, &None).is_ok());
263         assert!(check_key_permission(0, &sctx, KeyPerm::GenUniqueId, &key, &None).is_ok());
264         assert!(check_key_permission(0, &sctx, KeyPerm::ReqForcedOp, &key, &None).is_ok());
265     } else {
266         assert_perm_failed!(check_key_permission(0, &sctx, KeyPerm::Grant, &key, &None));
267         assert_perm_failed!(check_key_permission(0, &sctx, KeyPerm::ReqForcedOp, &key, &None));
268         assert_perm_failed!(check_key_permission(0, &sctx, KeyPerm::ManageBlob, &key, &None));
269         assert_perm_failed!(check_key_permission(0, &sctx, KeyPerm::UseDevId, &key, &None));
270         assert_perm_failed!(check_key_permission(0, &sctx, KeyPerm::GenUniqueId, &key, &None));
271     }
272     Ok(())
273 }
274 
275 #[test]
check_key_permission_domain_blob() -> Result<()>276 fn check_key_permission_domain_blob() -> Result<()> {
277     let (sctx, namespace, is_su) = check_context()?;
278     let key =
279         KeyDescriptor { domain: Domain::BLOB, nspace: namespace as i64, alias: None, blob: None };
280 
281     if is_su {
282         check_key_permission(0, &sctx, KeyPerm::Use, &key, &None)
283     } else {
284         assert_perm_failed!(check_key_permission(0, &sctx, KeyPerm::Use, &key, &None));
285         Ok(())
286     }
287 }
288 
289 #[test]
check_key_permission_domain_key_id() -> Result<()>290 fn check_key_permission_domain_key_id() -> Result<()> {
291     let key = KeyDescriptor { domain: Domain::KEY_ID, nspace: 0, alias: None, blob: None };
292 
293     assert_eq!(
294         Some(&KsError::sys()),
295         check_key_permission(
296             0,
297             &selinux::Context::new("ignored").unwrap(),
298             KeyPerm::Use,
299             &key,
300             &None
301         )
302         .err()
303         .unwrap()
304         .root_cause()
305         .downcast_ref::<KsError>()
306     );
307     Ok(())
308 }
309 
310 #[test]
key_perm_set_all_test()311 fn key_perm_set_all_test() {
312     let v = key_perm_set![
313         KeyPerm::ManageBlob,
314         KeyPerm::Delete,
315         KeyPerm::UseDevId,
316         KeyPerm::ReqForcedOp,
317         KeyPerm::GenUniqueId,
318         KeyPerm::Grant,
319         KeyPerm::GetInfo,
320         KeyPerm::Rebind,
321         KeyPerm::Update,
322         KeyPerm::Use // Test if the macro accepts missing comma at the end of the list.
323     ];
324     let mut i = v.into_iter();
325     assert_eq!(i.next().unwrap().name(), "delete");
326     assert_eq!(i.next().unwrap().name(), "gen_unique_id");
327     assert_eq!(i.next().unwrap().name(), "get_info");
328     assert_eq!(i.next().unwrap().name(), "grant");
329     assert_eq!(i.next().unwrap().name(), "manage_blob");
330     assert_eq!(i.next().unwrap().name(), "rebind");
331     assert_eq!(i.next().unwrap().name(), "req_forced_op");
332     assert_eq!(i.next().unwrap().name(), "update");
333     assert_eq!(i.next().unwrap().name(), "use");
334     assert_eq!(i.next().unwrap().name(), "use_dev_id");
335     assert_eq!(None, i.next());
336 }
337 #[test]
key_perm_set_sparse_test()338 fn key_perm_set_sparse_test() {
339     let v = key_perm_set![
340         KeyPerm::ManageBlob,
341         KeyPerm::ReqForcedOp,
342         KeyPerm::GenUniqueId,
343         KeyPerm::Update,
344         KeyPerm::Use, // Test if macro accepts the comma at the end of the list.
345     ];
346     let mut i = v.into_iter();
347     assert_eq!(i.next().unwrap().name(), "gen_unique_id");
348     assert_eq!(i.next().unwrap().name(), "manage_blob");
349     assert_eq!(i.next().unwrap().name(), "req_forced_op");
350     assert_eq!(i.next().unwrap().name(), "update");
351     assert_eq!(i.next().unwrap().name(), "use");
352     assert_eq!(None, i.next());
353 }
354 #[test]
key_perm_set_empty_test()355 fn key_perm_set_empty_test() {
356     let v = key_perm_set![];
357     let mut i = v.into_iter();
358     assert_eq!(None, i.next());
359 }
360 #[test]
key_perm_set_include_subset_test()361 fn key_perm_set_include_subset_test() {
362     let v1 = key_perm_set![
363         KeyPerm::ManageBlob,
364         KeyPerm::Delete,
365         KeyPerm::UseDevId,
366         KeyPerm::ReqForcedOp,
367         KeyPerm::GenUniqueId,
368         KeyPerm::Grant,
369         KeyPerm::GetInfo,
370         KeyPerm::Rebind,
371         KeyPerm::Update,
372         KeyPerm::Use,
373     ];
374     let v2 = key_perm_set![
375         KeyPerm::ManageBlob,
376         KeyPerm::Delete,
377         KeyPerm::Rebind,
378         KeyPerm::Update,
379         KeyPerm::Use,
380     ];
381     assert!(v1.includes(v2));
382     assert!(!v2.includes(v1));
383 }
384 #[test]
key_perm_set_include_equal_test()385 fn key_perm_set_include_equal_test() {
386     let v1 = key_perm_set![
387         KeyPerm::ManageBlob,
388         KeyPerm::Delete,
389         KeyPerm::Rebind,
390         KeyPerm::Update,
391         KeyPerm::Use,
392     ];
393     let v2 = key_perm_set![
394         KeyPerm::ManageBlob,
395         KeyPerm::Delete,
396         KeyPerm::Rebind,
397         KeyPerm::Update,
398         KeyPerm::Use,
399     ];
400     assert!(v1.includes(v2));
401     assert!(v2.includes(v1));
402 }
403 #[test]
key_perm_set_include_overlap_test()404 fn key_perm_set_include_overlap_test() {
405     let v1 = key_perm_set![
406         KeyPerm::ManageBlob,
407         KeyPerm::Delete,
408         KeyPerm::Grant, // only in v1
409         KeyPerm::Rebind,
410         KeyPerm::Update,
411         KeyPerm::Use,
412     ];
413     let v2 = key_perm_set![
414         KeyPerm::ManageBlob,
415         KeyPerm::Delete,
416         KeyPerm::ReqForcedOp, // only in v2
417         KeyPerm::Rebind,
418         KeyPerm::Update,
419         KeyPerm::Use,
420     ];
421     assert!(!v1.includes(v2));
422     assert!(!v2.includes(v1));
423 }
424 #[test]
key_perm_set_include_no_overlap_test()425 fn key_perm_set_include_no_overlap_test() {
426     let v1 = key_perm_set![KeyPerm::ManageBlob, KeyPerm::Delete, KeyPerm::Grant,];
427     let v2 = key_perm_set![KeyPerm::ReqForcedOp, KeyPerm::Rebind, KeyPerm::Update, KeyPerm::Use,];
428     assert!(!v1.includes(v2));
429     assert!(!v2.includes(v1));
430 }
431