zfsonfreebsd / ZoF

ZFS on FreeBSD - the official out of tree OpenZFS implementation for FreeBSD
https://freebsd.org
Other
100 stars 8 forks source link

Cannot import a pool created by zol. #145

Closed philmb3487 closed 4 years ago

philmb3487 commented 4 years ago

When I try to import an encrypted pool created from zol, I get an error when it comes time to mount. The error is simply, Input/output error. The versions do not matter, I have tried everything from the current code to the old one, and also on the zol side, from stable releases to git head.

I am not sure how to get more debugging information on this, I tried dbgmsg facility and it works, but nothing outputs on zfs mount.

output is like this

> [root@blah] /# zfs mount pool
> cannot mount 'pool': Input/output error

Scrubbing the pool works.

ghost commented 4 years ago

Confirmed this is an issue. As for debugging, dmesg is an easy one to check, and dtrace to watch for the set-error probe can help you get a stack trace of where the error could be from.

mattmacy commented 4 years ago

I've tracked it down to a local_mac mismatch:


int
spa_do_crypt_objset_mac_abd(boolean_t generate, spa_t *spa, uint64_t dsobj,
    abd_t *abd, uint_t datalen, boolean_t byteswap)
{
    int ret;
    dsl_crypto_key_t *dck = NULL;
    void *buf = abd_borrow_buf_copy(abd, datalen);
    objset_phys_t *osp = buf;
    uint8_t portable_mac[ZIO_OBJSET_MAC_LEN];
    uint8_t local_mac[ZIO_OBJSET_MAC_LEN];

    /* look up the key from the spa's keystore */
    ret = spa_keystore_lookup_key(spa, dsobj, FTAG, &dck);
    if (ret != 0) {
        printf("key lookup fail\n");
        goto error;
    }
    /* calculate both HMACs */
    ret = zio_crypt_do_objset_hmacs(&dck->dck_key, buf, datalen,
        byteswap, portable_mac, local_mac);
    if (ret != 0) {
        printf("bad hmacs\n");
        goto error;
    }
    spa_keystore_dsl_key_rele(spa, dck, FTAG);

    /* if we are generating encode the HMACs in the objset_phys_t */
    if (generate) {
        bcopy(portable_mac, osp->os_portable_mac, ZIO_OBJSET_MAC_LEN);
        bcopy(local_mac, osp->os_local_mac, ZIO_OBJSET_MAC_LEN);
        abd_return_buf_copy(abd, buf, datalen);
        return (0);
    }

    if (bcmp(portable_mac, osp->os_portable_mac, ZIO_OBJSET_MAC_LEN) != 0 ||
        bcmp(local_mac, osp->os_local_mac, ZIO_OBJSET_MAC_LEN) != 0) {
        printf("portable_mac\t%32D\n", portable_mac, ":");
        printf("os_portable_mac\t%32D\n", osp->os_portable_mac, ":");

        printf("local_mac\t%32D\n", local_mac, ":");
        printf("os_local_mac\t%32D\n", osp->os_local_mac, ":");
        abd_return_buf(abd, buf, datalen);
        printf("mac mismatch\n");
        return (SET_ERROR(ECKSUM));
    }

    abd_return_buf(abd, buf, datalen);

    return (0);

error:
    if (dck != NULL)
        spa_keystore_dsl_key_rele(spa, dck, FTAG);
    abd_return_buf(abd, buf, datalen);
    return SET_ERROR(ret);
}

generates:

portable_mac    e0:35:cb:c0:2a:bb:63:54:63:bb:26:74:dd:35:8e:65:6a:b5:87:02:c3:57:be:28:5d:d4:30:d6:75:f1:73:30
os_portable_mac e0:35:cb:c0:2a:bb:63:54:63:bb:26:74:dd:35:8e:65:6a:b5:87:02:c3:57:be:28:5d:d4:30:d6:75:f1:73:30
local_mac       c0:3b:97:9b:66:46:86:0a:b4:80:b9:d0:55:60:e0:44:a3:25:05:54:2c:c7:47:e8:a7:60:60:42:79:c4:10:ac
os_local_mac    63:b5:b5:08:8f:1e:26:94:7f:00:d7:2b:2a:84:73:9b:66:56:b1:40:7e:c3:a4:fc:e4:88:d9:a7:81:72:d0:34
mac mismatch
mattmacy commented 4 years ago

Fixed in 6bdb485e3887f8aa3698d90209affaa026abbdaf