mirror of
https://github.com/vim/vim.git
synced 2025-07-26 11:04:33 -04:00
patch 9.0.1669: Crash syncing swapfile in new buffer when using sodium crypt
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)
This commit is contained in:
parent
0256d76a33
commit
19e6c4fd2d
@ -1267,6 +1267,13 @@ crypt_sodium_buffer_decode(
|
|||||||
}
|
}
|
||||||
|
|
||||||
# if defined(FEAT_SODIUM) || defined(PROTO)
|
# if defined(FEAT_SODIUM) || defined(PROTO)
|
||||||
|
void
|
||||||
|
crypt_sodium_lock_key(char_u *key)
|
||||||
|
{
|
||||||
|
if (sodium_init() >= 0)
|
||||||
|
sodium_mlock(key, STRLEN(key));
|
||||||
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
crypt_sodium_munlock(void *const addr, const size_t len)
|
crypt_sodium_munlock(void *const addr, const size_t len)
|
||||||
{
|
{
|
||||||
|
@ -424,6 +424,24 @@ error:
|
|||||||
}
|
}
|
||||||
|
|
||||||
#if defined(FEAT_CRYPT) || defined(PROTO)
|
#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.
|
* Prepare encryption for "buf" for the current key and method.
|
||||||
*/
|
*/
|
||||||
@ -440,11 +458,10 @@ ml_set_mfp_crypt(buf_T *buf)
|
|||||||
// Generate a seed and store it in the memfile.
|
// Generate a seed and store it in the memfile.
|
||||||
sha2_seed(buf->b_ml.ml_mfp->mf_seed, MF_SEED_LEN, NULL, 0);
|
sha2_seed(buf->b_ml.ml_mfp->mf_seed, MF_SEED_LEN, NULL, 0);
|
||||||
}
|
}
|
||||||
#ifdef FEAT_SODIUM
|
# ifdef FEAT_SODIUM
|
||||||
else if (crypt_method_is_sodium(method_nr))
|
else if (crypt_method_is_sodium(method_nr))
|
||||||
crypt_sodium_randombytes_buf(buf->b_ml.ml_mfp->mf_seed,
|
crypt_sodium_randombytes_buf(buf->b_ml.ml_mfp->mf_seed, MF_SEED_LEN);
|
||||||
MF_SEED_LEN);
|
# endif
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -501,16 +518,10 @@ ml_set_crypt_key(
|
|||||||
return; // no memfile yet, nothing to do
|
return; // no memfile yet, nothing to do
|
||||||
old_method = crypt_method_nr_from_name(old_cm);
|
old_method = crypt_method_nr_from_name(old_cm);
|
||||||
|
|
||||||
// Swapfile encryption is not supported by XChaCha20, therefore disable the
|
#ifdef FEAT_CRYPT
|
||||||
// swapfile to avoid plain text being written to disk.
|
if (crypt_may_close_swapfile(buf, buf->b_p_key, crypt_get_method_nr(buf)))
|
||||||
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;
|
return;
|
||||||
}
|
#endif
|
||||||
|
|
||||||
// First make sure the swapfile is in a consistent state, using the old
|
// First make sure the swapfile is in a consistent state, using the old
|
||||||
// key and method.
|
// key and method.
|
||||||
@ -2494,6 +2505,12 @@ ml_sync_all(int check_file, int check_char)
|
|||||||
|| buf->b_ml.ml_mfp->mf_fd < 0)
|
|| buf->b_ml.ml_mfp->mf_fd < 0)
|
||||||
continue; // no file
|
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
|
ml_flush_line(buf); // flush buffered line
|
||||||
// flush locked block
|
// flush locked block
|
||||||
(void)ml_find_line(buf, (linenr_T)0, ML_FLUSH);
|
(void)ml_find_line(buf, (linenr_T)0, ML_FLUSH);
|
||||||
@ -2551,6 +2568,10 @@ ml_preserve(buf_T *buf, int message)
|
|||||||
emsg(_(e_cannot_preserve_there_is_no_swap_file));
|
emsg(_(e_cannot_preserve_there_is_no_swap_file));
|
||||||
return;
|
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
|
// We only want to stop when interrupted here, not when interrupted
|
||||||
// before.
|
// before.
|
||||||
@ -5571,6 +5592,9 @@ ml_crypt_prepare(memfile_T *mfp, off_T offset, int reading)
|
|||||||
if (*key == NUL)
|
if (*key == NUL)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
|
if (crypt_may_close_swapfile(buf, key, method_nr))
|
||||||
|
return NULL;
|
||||||
|
|
||||||
if (method_nr == CRYPT_M_ZIP)
|
if (method_nr == CRYPT_M_ZIP)
|
||||||
{
|
{
|
||||||
// For PKzip: Append the offset to the key, so that we use a different
|
// For PKzip: Append the offset to the key, so that we use a different
|
||||||
|
@ -1174,6 +1174,10 @@ did_set_cryptkey(optset_T *args)
|
|||||||
*curbuf->b_p_cm == NUL ? p_cm : curbuf->b_p_cm);
|
*curbuf->b_p_cm == NUL ? p_cm : curbuf->b_p_cm);
|
||||||
changed_internal();
|
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;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
@ -26,6 +26,7 @@ void crypt_check_swapfile_curbuf(void);
|
|||||||
void crypt_check_current_method(void);
|
void crypt_check_current_method(void);
|
||||||
char_u *crypt_get_key(int store, int twice);
|
char_u *crypt_get_key(int store, int twice);
|
||||||
void crypt_append_msg(buf_T *buf);
|
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);
|
int crypt_sodium_munlock(void *const addr, const size_t len);
|
||||||
void crypt_sodium_randombytes_buf(void *const buf, const size_t size);
|
void crypt_sodium_randombytes_buf(void *const buf, const size_t size);
|
||||||
int crypt_sodium_init(void);
|
int crypt_sodium_init(void);
|
||||||
|
@ -105,7 +105,7 @@ func Test_crypt_sodium_v2_startup()
|
|||||||
exe buf .. 'bwipe!'
|
exe buf .. 'bwipe!'
|
||||||
call assert_true(filereadable('Xfoo'))
|
call assert_true(filereadable('Xfoo'))
|
||||||
|
|
||||||
let buf = RunVimInTerminal('--cmd "set ch=3 cm=xchacha20v2 key=foo" Xfoo', #{rows: 10})
|
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 g:TermWait(buf, g:RunningWithValgrind() ? 1000 : 50)
|
||||||
call StopVimInTerminal(buf)
|
call StopVimInTerminal(buf)
|
||||||
|
|
||||||
@ -392,4 +392,24 @@ func Test_crypt_set_key_changes_buffer()
|
|||||||
call delete('Xtest1.txt')
|
call delete('Xtest1.txt')
|
||||||
endfunc
|
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: shiftwidth=2 sts=2 expandtab
|
||||||
|
@ -695,6 +695,8 @@ static char *(features[]) =
|
|||||||
|
|
||||||
static int included_patches[] =
|
static int included_patches[] =
|
||||||
{ /* Add new patch number below this line */
|
{ /* Add new patch number below this line */
|
||||||
|
/**/
|
||||||
|
1669,
|
||||||
/**/
|
/**/
|
||||||
1668,
|
1668,
|
||||||
/**/
|
/**/
|
||||||
|
Loading…
x
Reference in New Issue
Block a user