Delete grants to a user ID when it is removed.
Currently, if there is a grant to user ID 1 for app ID A and then user
ID 1 is removed and a new user is created with user ID 1, that new user
will inherit the grant for app ID A, which would give it access to a
key it shouldn't have access to.
Bug: 372415590
Test: atest keystore2_test
Change-Id: Id19bc31968df9c54ac5fb100f3bf471441eb989c
diff --git a/keystore2/src/database/tests.rs b/keystore2/src/database/tests.rs
index 4ada694..7482a1c 100644
--- a/keystore2/src/database/tests.rs
+++ b/keystore2/src/database/tests.rs
@@ -2090,6 +2090,42 @@
Ok(())
}
+#[test]
+fn test_unbind_keys_for_user_removes_received_grants() -> Result<()> {
+ let mut db = new_test_db()?;
+ const USER_ID_1: u32 = 1;
+ const USER_ID_2: u32 = 2;
+ const APPLICATION_ID_1: u32 = 11;
+ const APPLICATION_ID_2: u32 = 22;
+ const UID_1_FOR_USER_ID_1: u32 = USER_ID_1 * AID_USER_OFFSET + APPLICATION_ID_1;
+ const UID_2_FOR_USER_ID_1: u32 = USER_ID_1 * AID_USER_OFFSET + APPLICATION_ID_2;
+ const UID_1_FOR_USER_ID_2: u32 = USER_ID_2 * AID_USER_OFFSET + APPLICATION_ID_1;
+
+ // Pretend two application IDs for user ID 1 were granted access to 1 key each and one
+ // application ID for user ID 2 was granted access to 1 key.
+ db.conn.execute(
+ &format!(
+ "INSERT INTO persistent.grant (id, grantee, keyentryid, access_vector)
+ VALUES (1, {UID_1_FOR_USER_ID_1}, 111, 222),
+ (2, {UID_1_FOR_USER_ID_2}, 333, 444),
+ (3, {UID_2_FOR_USER_ID_1}, 555, 666);"
+ ),
+ [],
+ )?;
+ db.unbind_keys_for_user(USER_ID_1)?;
+
+ let mut stmt = db.conn.prepare("SELECT id, grantee FROM persistent.grant")?;
+ let mut rows = stmt.query_map::<(i64, u32), _, _>([], |row| Ok((row.get(0)?, row.get(1)?)))?;
+
+ // The rows for the user ID 1 grantees (UID_1_FOR_USER_ID_1 and UID_2_FOR_USER_ID_1) should be
+ // deleted and the row for the user ID 2 grantee (UID_1_FOR_USER_ID_2) should be untouched.
+ let r = rows.next().unwrap().unwrap();
+ assert_eq!(r, (2, UID_1_FOR_USER_ID_2));
+ assert!(rows.next().is_none());
+
+ Ok(())
+}
+
fn app_key_exists(db: &mut KeystoreDB, nspace: i64, alias: &str) -> Result<bool> {
db.key_exists(Domain::APP, nspace, alias, KeyType::Client)
}