Uploaded image for project: 'WiredTiger'
  1. WiredTiger
  2. WT-3312

encryption btree configuration test

    • Type: Icon: Bug Bug
    • Resolution: Fixed
    • Priority: Icon: Minor - P4 Minor - P4
    • WT2.9.3, 3.5.9
    • Affects Version/s: None
    • Component/s: None
    • None
    • Storage 2017-05-29

      sue.loverso asked:

      In the case when we're evicting pages to the LAS file are we obeying encryption? Clearly it would be bad to save pages in the clear in the LAS file for encrypted tables. While we cannot encrypt the LAS pages with each table's individual encryptor, the LAS table should be using the connection encryptor for that data. I cannot tell what cfg would end up in bt_handle.c:__btree_conf on the creation of the LAS file. At line 429, it would have to make sure the cval.len == 0 (i.e. it is given the empty string for encryption=(name=)) or add another piece to explicitly check for the LAS.

      It's a good question. Here's the interesting code from __btree_conf:

          420 /*
          421  * We do not use __wt_config_gets_none here because "none"
          422  * and the empty string have different meanings.  The
          423  * empty string means inherit the system encryption setting
          424  * and "none" means this table is in the clear even if the
          425  * database is encrypted.  If this is the metadata handle
          426  * always inherit from the connection.
          427  */
          428 WT_RET(__wt_config_gets(session, cfg, "encryption.name", &cval));
          429 if (WT_IS_METADATA(btree->dhandle) || cval.len == 0)
          430         btree->kencryptor = conn->kencryptor;
          431 else if (WT_STRING_MATCH("none", cval.str, cval.len))
          432         btree->kencryptor = NULL;
          433 else {
          434         WT_RET(__wt_config_gets_none(
          435             session, cfg, "encryption.keyid", &keyid));
          436         WT_RET(__wt_config_gets(session, cfg, "encryption", &enc));
          437         if (enc.len != 0)
          438                 WT_RET(__wt_strndup(session, enc.str, enc.len,
          439                     &enc_cfg[0]));
          440         ret = __wt_encryptor_config(session, &cval, &keyid,
          441             (WT_CONFIG_ARG *)enc_cfg, &btree->kencryptor);
          442         __wt_free(session, enc_cfg[0]);
          443         WT_RET(ret);
          444 }
      

      And here's the interesting stack:

      (gdb) where
      #0  __btree_conf (session=0x807042000, ckpt=0x7fffffffc050)
          at src/btree/bt_handle.c:430
      #1  0x0000000803abd396 in __wt_btree_open (session=0x807042000, op_cfg=0x0)
          at src/btree/bt_handle.c:117
      #2  0x0000000803b16a79 in __wt_conn_btree_open (session=0x807042000, cfg=0x0, 
          flags=8) at src/conn/conn_dhandle.c:352
      #3  0x0000000803be1eac in __wt_session_get_btree (session=0x807042000, 
          uri=0x803c08f40 "file:WiredTigerLAS.wt", checkpoint=0x0, cfg=0x0, flags=8)
          at src/session/session_dhandle.c:541
      #4  0x0000000803bc1437 in __create_file (session=0x807042000, 
          uri=0x803c08f40 "file:WiredTigerLAS.wt", exclusive=false, 
          config=0x803c0b543 "key_format=IuQQu,value_format=QIu")
          at src/schema/schema_create.c:119
      #5  0x0000000803bc0597 in __wt_schema_create (session=0x807042000, 
          uri=0x803c08f40 "file:WiredTigerLAS.wt", 
          config=0x803c0b543 "key_format=IuQQu,value_format=QIu")
          at src/schema/schema_create.c:683
      #6  0x0000000803bd3c74 in __wt_session_create (session=0x807042000, 
          uri=0x803c08f40 "file:WiredTigerLAS.wt", 
          config=0x803c0b543 "key_format=IuQQu,value_format=QIu")
          at src/session/session_api.c:518
      #7  0x0000000803b01954 in __wt_las_create (session=0x807042000)
          at src/cache/cache_las.c:89
      #8  0x0000000803b1da93 in __wt_connection_workers (session=0x807042000, 
          cfg=0x7fffffffc440) at src/conn/conn_open.c:255
      #9  0x0000000803b0a45c in wiredtiger_open (home=0x8006be48c ".", 
          event_handler=0x803a637b8, 
          config=0x806e014dc "create,error_prefix=\"test_encrypt01.test_encrypt01.test_encrypt(file.nop.none)\",encryption=(name=nop),,extensions=[\"/usr/home/bostic/wt.develop/ext/encryptors/nop/.libs/libwiredtiger_nop.so\"]", 
          wt_connp=0x7fffffffc618) at src/conn/conn_api.c:2457
      

      In short, we open the LAS file as part of wiredtiger_open(), we don't find "encryption.name" in the config, and so we inherit the conn->kencryptor value at line 430, which has already been set by wiredtiger_open().

      So, I think the right thing happens, but it's not explicitly happening. What if wiredtiger_open() doesn't set up encryption first? (Well, that can't happen, and I can't imagine it ever happening, that would be difficult to envision.)

      I'm a little confused by why we're doing a check against WT_IS_METADATA(btree->dhandle), it seems to me that is an unnecessary test because encryption.name won't be set, that is, testing cval.len == 0 should be sufficient in both cases.

      In summary, I'm asking why we don't do something like:

      diff --git a/src/btree/bt_handle.c b/src/btree/bt_handle.c
      index 687a77aaa..7ddfeac95 100644
      --- a/src/btree/bt_handle.c
      +++ b/src/btree/bt_handle.c
      @@ -418,15 +418,14 @@ __btree_conf(WT_SESSION_IMPL *session, WT_CKPT *ckpt)
              WT_RET(__wt_compressor_config(session, &cval, &btree->compressor));
       
              /*
      -        * We do not use __wt_config_gets_none here because "none"
      -        * and the empty string have different meanings.  The
      -        * empty string means inherit the system encryption setting
      -        * and "none" means this table is in the clear even if the
      -        * database is encrypted.  If this is the metadata handle
      +        * We do not use __wt_config_gets_none here because "none" and the empty
      +        * string have different meanings.  The empty string means inherit the
      +        * system encryption setting and "none" means this table is in the clear
      +        * even if the database is encrypted. If the encryption name is not set,
               * always inherit from the connection.
               */
              WT_RET(__wt_config_gets(session, cfg, "encryption.name", &cval));
      -       if (WT_IS_METADATA(btree->dhandle) || cval.len == 0)
      +       if (cval.len == 0)
                      btree->kencryptor = conn->kencryptor;
              else if (WT_STRING_MATCH("none", cval.str, cval.len))
                      btree->kencryptor = NULL;
      

            Assignee:
            keith.bostic@mongodb.com Keith Bostic (Inactive)
            Reporter:
            keith.bostic@mongodb.com Keith Bostic (Inactive)
            Votes:
            0 Vote for this issue
            Watchers:
            1 Start watching this issue

              Created:
              Updated:
              Resolved: