To: vim_dev@googlegroups.com Subject: Patch 9.0.1669 Fcc: outbox From: Bram Moolenaar Mime-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ------------ Patch 9.0.1669 Problem: Crash syncing swapfile in new buffer when using sodium crypt. (James McCoy) Solution: Add checks for sodium encryption. (Christian Brabandt, closes #12591, closes #12585) Files: src/crypt.c, src/proto/crypt.pro, src/memline.c, src/optionstr.c, src/testdir/test_crypt.vim *** ../vim-9.0.1668/src/crypt.c 2023-05-27 18:02:50.188062442 +0100 --- src/crypt.c 2023-06-27 18:04:46.150672593 +0100 *************** *** 1267,1272 **** --- 1267,1279 ---- } # if defined(FEAT_SODIUM) || defined(PROTO) + void + crypt_sodium_lock_key(char_u *key) + { + if (sodium_init() >= 0) + sodium_mlock(key, STRLEN(key)); + } + int crypt_sodium_munlock(void *const addr, const size_t len) { *** ../vim-9.0.1668/src/proto/crypt.pro 2023-05-27 18:02:50.188062442 +0100 --- src/proto/crypt.pro 2023-06-27 17:59:37.762828206 +0100 *************** *** 26,31 **** --- 26,32 ---- void crypt_check_current_method(void); char_u *crypt_get_key(int store, int twice); void crypt_append_msg(buf_T *buf); + void crypt_sodium_lock_key(char_u *key); int crypt_sodium_munlock(void *const addr, const size_t len); void crypt_sodium_randombytes_buf(void *const buf, const size_t size); int crypt_sodium_init(void); *** ../vim-9.0.1668/src/memline.c 2023-06-26 18:48:05.343295466 +0100 --- src/memline.c 2023-06-27 18:41:14.683651172 +0100 *************** *** 425,430 **** --- 425,448 ---- #if defined(FEAT_CRYPT) || defined(PROTO) /* + * Swapfile encryption is not supported by XChaCha20. If this crypt method is + * used then disable the swapfile, to avoid plain text being written to disk, + * and return TRUE. + * Otherwise return FALSE. + */ + static int + crypt_may_close_swapfile(buf_T *buf, char_u *key, int method) + { + if (crypt_method_is_sodium(method) && *key != NUL) + { + mf_close_file(buf, TRUE); + buf->b_p_swf = FALSE; + return TRUE; + } + return FALSE; + } + + /* * Prepare encryption for "buf" for the current key and method. */ static void *************** *** 440,450 **** // Generate a seed and store it in the memfile. sha2_seed(buf->b_ml.ml_mfp->mf_seed, MF_SEED_LEN, NULL, 0); } ! #ifdef FEAT_SODIUM else if (crypt_method_is_sodium(method_nr)) ! crypt_sodium_randombytes_buf(buf->b_ml.ml_mfp->mf_seed, ! MF_SEED_LEN); ! #endif } /* --- 458,467 ---- // Generate a seed and store it in the memfile. sha2_seed(buf->b_ml.ml_mfp->mf_seed, MF_SEED_LEN, NULL, 0); } ! # ifdef FEAT_SODIUM else if (crypt_method_is_sodium(method_nr)) ! crypt_sodium_randombytes_buf(buf->b_ml.ml_mfp->mf_seed, MF_SEED_LEN); ! # endif } /* *************** *** 501,516 **** return; // no memfile yet, nothing to do old_method = crypt_method_nr_from_name(old_cm); ! // Swapfile encryption is not supported by XChaCha20, therefore disable the ! // swapfile to avoid plain text being written to disk. ! if (crypt_method_is_sodium(crypt_get_method_nr(buf)) ! && *buf->b_p_key != NUL) ! { ! // close the swapfile ! mf_close_file(buf, TRUE); ! buf->b_p_swf = FALSE; return; ! } // First make sure the swapfile is in a consistent state, using the old // key and method. --- 518,527 ---- return; // no memfile yet, nothing to do old_method = crypt_method_nr_from_name(old_cm); ! #ifdef FEAT_CRYPT ! if (crypt_may_close_swapfile(buf, buf->b_p_key, crypt_get_method_nr(buf))) return; ! #endif // First make sure the swapfile is in a consistent state, using the old // key and method. *************** *** 2494,2499 **** --- 2505,2516 ---- || buf->b_ml.ml_mfp->mf_fd < 0) continue; // no file + #ifdef FEAT_CRYPT + if (crypt_may_close_swapfile(buf, buf->b_p_key, + crypt_get_method_nr(buf))) + continue; + #endif + ml_flush_line(buf); // flush buffered line // flush locked block (void)ml_find_line(buf, (linenr_T)0, ML_FLUSH); *************** *** 2551,2556 **** --- 2568,2577 ---- emsg(_(e_cannot_preserve_there_is_no_swap_file)); return; } + #ifdef FEAT_CRYPT + if (crypt_may_close_swapfile(buf, buf->b_p_key, crypt_get_method_nr(buf))) + return; + #endif // We only want to stop when interrupted here, not when interrupted // before. *************** *** 5571,5576 **** --- 5592,5600 ---- if (*key == NUL) return NULL; + if (crypt_may_close_swapfile(buf, key, method_nr)) + return NULL; + if (method_nr == CRYPT_M_ZIP) { // For PKzip: Append the offset to the key, so that we use a different *** ../vim-9.0.1668/src/optionstr.c 2023-05-31 17:12:07.888535653 +0100 --- src/optionstr.c 2023-06-27 18:47:54.791198972 +0100 *************** *** 1174,1179 **** --- 1174,1183 ---- *curbuf->b_p_cm == NUL ? p_cm : curbuf->b_p_cm); changed_internal(); } + # ifdef FEAT_SODIUM + if (crypt_method_is_sodium(crypt_get_method_nr(curbuf))) + crypt_sodium_lock_key(args->os_newval.string); + # endif return NULL; } *** ../vim-9.0.1668/src/testdir/test_crypt.vim 2023-05-27 18:02:50.192062438 +0100 --- src/testdir/test_crypt.vim 2023-06-27 18:54:25.317284072 +0100 *************** *** 105,111 **** exe buf .. 'bwipe!' call assert_true(filereadable('Xfoo')) ! let buf = RunVimInTerminal('--cmd "set ch=3 cm=xchacha20v2 key=foo" Xfoo', #{rows: 10}) call g:TermWait(buf, g:RunningWithValgrind() ? 1000 : 50) call StopVimInTerminal(buf) --- 105,111 ---- exe buf .. 'bwipe!' call assert_true(filereadable('Xfoo')) ! let buf = RunVimInTerminal('--cmd "set ch=3 cm=xchacha20v2 key=foo" Xfoo', #{wait_for_ruler: 0, rows: 10}) call g:TermWait(buf, g:RunningWithValgrind() ? 1000 : 50) call StopVimInTerminal(buf) *************** *** 392,395 **** --- 392,415 ---- call delete('Xtest1.txt') endfunc + func Test_crypt_set_key_segfault() + CheckFeature sodium + + defer delete('Xtest2.txt') + new Xtest2.txt + call setline(1, 'nothing') + set cryptmethod=xchacha20 + set key=foobar + w + new Xtest3 + put ='other content' + setl modified + sil! preserve + bwipe! + + set cryptmethod& + set key= + bwipe! + endfunc + " vim: shiftwidth=2 sts=2 expandtab *** ../vim-9.0.1668/src/version.c 2023-06-26 22:05:33.291658094 +0100 --- src/version.c 2023-06-27 18:54:53.513136357 +0100 *************** *** 697,698 **** --- 697,700 ---- { /* Add new patch number below this line */ + /**/ + 1669, /**/ -- If you're sending someone Styrofoam, what do you pack it in? /// Bram Moolenaar -- Bram@Moolenaar.net -- http://www.Moolenaar.net \\\ /// \\\ \\\ sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ /// \\\ help me help AIDS victims -- http://ICCF-Holland.org ///