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.rs b/keystore2/src/database.rs
index 34e0c59..aacaa92 100644
--- a/keystore2/src/database.rs
+++ b/keystore2/src/database.rs
@@ -2429,7 +2429,7 @@
         tx.execute("DELETE FROM persistent.keyparameter WHERE keyentryid = ?;", params![key_id])
             .context("Trying to delete keyparameters.")?;
         tx.execute("DELETE FROM persistent.grant WHERE keyentryid = ?;", params![key_id])
-            .context("Trying to delete grants.")?;
+            .context("Trying to delete grants to other apps.")?;
         // The associated blobentry rows are not immediately deleted when the owning keyentry is
         // removed, because a KeyMint `deleteKey()` invocation is needed (specifically for the
         // `KEY_BLOB`).  That should not be done from within the database transaction.  Also, calls
@@ -2444,6 +2444,19 @@
         Ok(updated != 0)
     }
 
+    fn delete_received_grants(tx: &Transaction, user_id: u32) -> Result<bool> {
+        let updated = tx
+            .execute(
+                &format!("DELETE FROM persistent.grant WHERE cast ( (grantee/{AID_USER_OFFSET}) as int) = ?;"),
+                params![user_id],
+            )
+            .context(format!(
+                "Trying to delete grants received by user ID {:?} from other apps.",
+                user_id
+            ))?;
+        Ok(updated != 0)
+    }
+
     /// Marks the given key as unreferenced and removes all of the grants to this key.
     /// Returns Ok(true) if a key was marked unreferenced as a hint for the garbage collector.
     pub fn unbind_key(
@@ -2573,6 +2586,11 @@
         let _wp = wd::watch("KeystoreDB::unbind_keys_for_user");
 
         self.with_transaction(Immediate("TX_unbind_keys_for_user"), |tx| {
+            Self::delete_received_grants(tx, user_id).context(format!(
+                "In unbind_keys_for_user. Failed to delete received grants for user ID {:?}.",
+                user_id
+            ))?;
+
             let mut stmt = tx
                 .prepare(&format!(
                     "SELECT id from persistent.keyentry
@@ -2618,7 +2636,7 @@
             let mut notify_gc = false;
             for key_id in key_ids {
                 notify_gc = Self::mark_unreferenced(tx, key_id)
-                    .context("In unbind_keys_for_user.")?
+                    .context("In unbind_keys_for_user. Failed to mark key id as unreferenced.")?
                     || notify_gc;
             }
             Ok(()).do_gc(notify_gc)
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)
 }