mirror of
https://gitlab.com/cryptsetup/cryptsetup.git
synced 2025-12-05 16:00:05 +01:00
Fix partial reads from TTY (interactive terminal).
Some stable kernels started to return buffer from terminal in partial buffers of maximal size 64 bytes. This breaks all passphrases longer than 64 characters entered through interactive input (for all crypto formats). (The problem is probably fixed in more recent kernels, but the read() call can always return a partial read here.) This patch also fixes wrong password limit, the last character of passphrase of maximal size was never handled. Now the maximal passphrase length is really 512 characters. Fixes: #627.
This commit is contained in:
@@ -102,18 +102,41 @@ static int tools_check_password(const char *password)
|
||||
}
|
||||
|
||||
/* Password reading helpers */
|
||||
|
||||
static ssize_t read_tty_eol(int fd, char *pass, size_t maxlen)
|
||||
{
|
||||
bool eol = false;
|
||||
size_t read_size = 0;
|
||||
ssize_t r;
|
||||
|
||||
do {
|
||||
r = read(fd, pass, maxlen - read_size);
|
||||
if ((r == -1 && errno != EINTR) || quit)
|
||||
return -1;
|
||||
if (r >= 0) {
|
||||
if (!r || pass[r-1] == '\n')
|
||||
eol = true;
|
||||
read_size += (size_t)r;
|
||||
pass = pass + r;
|
||||
}
|
||||
} while (!eol && read_size != maxlen);
|
||||
|
||||
return (ssize_t)read_size;
|
||||
}
|
||||
|
||||
/* The pass buffer is zeroed and has trailing \0 already " */
|
||||
static int untimed_read(int fd, char *pass, size_t maxlen)
|
||||
{
|
||||
ssize_t i;
|
||||
|
||||
i = read(fd, pass, maxlen);
|
||||
i = read_tty_eol(fd, pass, maxlen);
|
||||
if (i > 0) {
|
||||
pass[i-1] = '\0';
|
||||
if (pass[i-1] == '\n')
|
||||
pass[i-1] = '\0';
|
||||
i = 0;
|
||||
} else if (i == 0) { /* EOF */
|
||||
*pass = 0;
|
||||
} else if (i == 0) /* empty input */
|
||||
i = -1;
|
||||
}
|
||||
|
||||
return i;
|
||||
}
|
||||
|
||||
@@ -200,10 +223,9 @@ static int crypt_get_key_tty(const char *prompt,
|
||||
log_err(_("Error reading passphrase from terminal."));
|
||||
goto out_err;
|
||||
}
|
||||
pass[key_size_max] = '\0';
|
||||
|
||||
if (verify) {
|
||||
pass_verify = crypt_safe_alloc(key_size_max);
|
||||
pass_verify = crypt_safe_alloc(key_size_max + 1);
|
||||
if (!pass_verify) {
|
||||
log_err(_("Out of memory while reading passphrase."));
|
||||
r = -ENOMEM;
|
||||
|
||||
@@ -1023,5 +1023,41 @@ EOF
|
||||
[ $? -eq 0 ] || fail "Expect script failed."
|
||||
$CRYPTSETUP remove $DEV_NAME || fail
|
||||
|
||||
prepare "[40] Long passphrase from TTY." wipe
|
||||
EXPECT_DEV=$(losetup $LOOPDEV | sed -e "s/.*(\(.*\))/\1/")
|
||||
|
||||
# Password of maximal length 512 characters
|
||||
LONG_PWD=\
|
||||
"0123456789abcdef0123456789ABCDEF0123456789abcdef0123456789ABCDEF"\
|
||||
"Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do "\
|
||||
"eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut e"\
|
||||
"nim ad minim veniam, quis nostrud exercitation ullamco laboris n"\
|
||||
"isi ut aliquip ex ea commodo consequat. Duis aute irure dolor in"\
|
||||
" reprehenderit in voluptate velit esse cillum dolore eu fugiat n"\
|
||||
"ulla pariatur. Excepteur sint occaecat cupidatat non proident, s"\
|
||||
"unt in culpa qui officia deserunt mollit anim id est laborum.DEF"
|
||||
|
||||
echo -n "$LONG_PWD" >$KEYE
|
||||
|
||||
expect_run - >/dev/null <<EOF
|
||||
proc abort {} { send_error "Timeout. "; exit 2 }
|
||||
set timeout 10
|
||||
eval spawn $CRYPTSETUP_RAW luksFormat --type luks1 $FAST_PBKDF_OPT -v $LOOPDEV
|
||||
expect timeout abort "Are you sure? (Type 'yes' in capital letters):"
|
||||
send "YES\n"
|
||||
expect timeout abort "Enter passphrase for $EXPECT_DEV:"
|
||||
sleep 0.1
|
||||
send "$LONG_PWD\n"
|
||||
expect timeout abort "Verify passphrase:"
|
||||
sleep 0.1
|
||||
send "$LONG_PWD\n"
|
||||
expect timeout abort "Command successful."
|
||||
expect timeout abort eof
|
||||
eval spawn $CRYPTSETUP_RAW luksOpen -v $LOOPDEV --test-passphrase --key-file $KEYE
|
||||
expect timeout abort "Command successful."
|
||||
expect timeout abort eof
|
||||
EOF
|
||||
[ $? -eq 0 ] || fail "Expect script failed."
|
||||
|
||||
remove_mapping
|
||||
exit 0
|
||||
|
||||
Reference in New Issue
Block a user