* This function ensures that, when doing a decrypting read of a block, * we make sure we have decrypted the dnode associated with it. We must do * this so that we ensure we are fully authenticating the checksum-of-MACs * tree from the root of the objset down to this block. Indirect blocks are * always verified against their secure checksum-of-MACs assuming that the * dnode containing them is
| 1387 | * decrypt / authenticate them when we need to read an encrypted bonus buffer. |
| 1388 | */ |
| 1389 | static int |
| 1390 | dbuf_read_verify_dnode_crypt(dmu_buf_impl_t *db, uint32_t flags) |
| 1391 | { |
| 1392 | int err = 0; |
| 1393 | objset_t *os = db->db_objset; |
| 1394 | arc_buf_t *dnode_abuf; |
| 1395 | dnode_t *dn; |
| 1396 | zbookmark_phys_t zb; |
| 1397 | |
| 1398 | ASSERT(MUTEX_HELD(&db->db_mtx)); |
| 1399 | |
| 1400 | if (!os->os_encrypted || os->os_raw_receive || |
| 1401 | (flags & DB_RF_NO_DECRYPT) != 0) |
| 1402 | return (0); |
| 1403 | |
| 1404 | DB_DNODE_ENTER(db); |
| 1405 | dn = DB_DNODE(db); |
| 1406 | dnode_abuf = (dn->dn_dbuf != NULL) ? dn->dn_dbuf->db_buf : NULL; |
| 1407 | |
| 1408 | if (dnode_abuf == NULL || !arc_is_encrypted(dnode_abuf)) { |
| 1409 | DB_DNODE_EXIT(db); |
| 1410 | return (0); |
| 1411 | } |
| 1412 | |
| 1413 | SET_BOOKMARK(&zb, dmu_objset_id(os), |
| 1414 | DMU_META_DNODE_OBJECT, 0, dn->dn_dbuf->db_blkid); |
| 1415 | err = arc_untransform(dnode_abuf, os->os_spa, &zb, B_TRUE); |
| 1416 | |
| 1417 | /* |
| 1418 | * An error code of EACCES tells us that the key is still not |
| 1419 | * available. This is ok if we are only reading authenticated |
| 1420 | * (and therefore non-encrypted) blocks. |
| 1421 | */ |
| 1422 | if (err == EACCES && ((db->db_blkid != DMU_BONUS_BLKID && |
| 1423 | !DMU_OT_IS_ENCRYPTED(dn->dn_type)) || |
| 1424 | (db->db_blkid == DMU_BONUS_BLKID && |
| 1425 | !DMU_OT_IS_ENCRYPTED(dn->dn_bonustype)))) |
| 1426 | err = 0; |
| 1427 | |
| 1428 | DB_DNODE_EXIT(db); |
| 1429 | |
| 1430 | return (err); |
| 1431 | } |
| 1432 | |
| 1433 | /* |
| 1434 | * Drops db_mtx and the parent lock specified by dblt and tag before |
no test coverage detected