Duplicate all dynamically allocated memory passed
keyslot context during initialization and make it
self contained.
Before current patch all pointers passed in keyslot
context initialization routines have to remain valid
for the duration of the keyslot context. Otherwise
memory violation could occur.
This patch fixes the issue in backward compatible
way so that we do not have to change API for all
keyslot contexts. As of now all dynamically allocated
memory can be freed right after keyslot context
initialization.
For each 1 MiB of data en/decrypted, 'cryptsetup benchmark' is setting
up a new AF_ALG socket, which involves 4 system calls and is included in
the data en/decryption time. With high-speed ciphers (e.g. VAES
optimized AES-XTS) this can measure well over 10000 AF_ALG socket setups
per second. This is not representative of dm-crypt, which only
allocates a cipher when the dm-crypt device is created.
Therefore, allocate the AF_ALG socket once, before doing the benchmark.
On AMD Ryzen 9 9950X this increases the 'cryptsetup benchmark' result of
AES-256-XTS slightly, from 14000 MiB/s to 14600 MiB/s.
Note that an in-kernel benchmark of the crypto API with the same block
size (65536 bytes) gives 34100 MiB/s, so AF_ALG still takes more time
than the en/decryption itself -- this cannot easily be addressed though.
Signed-off-by: Eric Biggers <ebiggers@google.com>
We use common libcryptsetup-token.sym version script that contain
all symbols, but some of them are optional.
As clang linker treats missing symbols as errors, the linker
phase for ssh token fails as optional cryptsetup_token_buffer_free
is not defined.
(Most of distros has this option still disabled, though).
As the sym file is also example for token authors, removing symbols
there is not an option. For clang, we can use --undefined-version option,
but it is not supported by other linkers, so it requires non-trivial
checks for usable LDFLAGS (for both autoconf and meson).
Instead, fix it by simply defining the symbol in ssh token, which
duplicates the internal libcryptsetup functionality.
Fixes: #830
Hard abort is justified here. The online reencryption on
data devices that do not support O_DIRECT io flag is
dangerous and leads to data corruption. This should be
impossible to hit due to a patch that handles it
in initialization phase. Better safe than sorry.
Verify the data device supports O_DIRECT io flag in
the initialization phase. Online reencryption is not
safe unless we can read and write the data in direct
mode.
Currently, direct-io is disabled if underlying device is suspended.
This was an unfortunate change, as it is part of data corruption
problem in online reenryption.
Let's relax the test to assume that suspended device
(suspended => must be a device-mapper device) supports direct-io.
The read test is still needed as some network based devices
misbehaves if opened with direct-io flag.
The ssize_t must be defined in the range [-1, SSIZE_MAX].
The return value is overwritten to -EINVAL later anyway,
return -1 here to be on the safe side.
Fixes: #900
This patch allows dm_status_suspended() to report if device
is suspended or not also for unknown target types from
libcryptsetup perspective (e.g.: dm-cache).
Consider device is suspended only if dm_status_suspended return code
is true.
This function returned -EEXIST for dm devices with target types unknown
to libcryptsetup (for example dm-cache) and turned off O_DIRECT flag
for devices unexpectedly.
Turned out ignoring direct-io was a problem after all :).
Fixes: 0f51b5bacb (Do not run sector read check on suspended device.)
Parsing --debug output with quiet flag can produce SIGPIPE output
if running with valgrind wrapper, just workaround it with another
grep as used elsewhere.
The option allows data device to be used in multiple
DM table mappings and exclusive access is not checked
anymore in-before device activation.
It also allows correct concurrent verity device activation.
With --shared option if multiple processes compete for same DM
verity name using same underlying data device we can now guarantee
one process succeeds and all other fails with -EEXIST.
CRYPT_ACTIVATE_SHARED flag was silently ignored
while activating dm-verity devices by libcryptsetup.
This was a bug.
DM verity shared activation is generaly safe (single mapped data device
in multiple DM verity tables) since all verity devices are
read only.
The CRYPT_ACTIVATE_SHARED flag also fixes a race condition
when multiple processes compete for the same DM device name
(all dm-verity) while using same backing data device.
The exclusive open check in-before verity activation could
fail DM table load for a process that otherwise successfully acquired
DM device name (succeed in creating the DM device). This could (in some
cases) result in all processes competening for the DM verity device
to fail and none would activate the DM verity device.
Exclusive flag is defined only when creating a file,
for opening existing file it is undefinded operation.
Remove it from crypt_loop_attach as it was wrong since
the initial commit.
Due to internal retry-overengineering in libdevmapper, some dm-ioctl
failures can disappear. One such case is when there is a device
creation race and DM device is created but reload fails.
this can heppen because some block device used in table mapping is
already claimed (it needs exclusive access for bdev_open in kernel).
The kernel ioctl properly returns EBUSY, this errno is lost
in libdevmapper (dm_task_get_errno returns 0).
While this should be solved by libdevampper, we need some reliable
way on older systems to properly report "busy" error instead of
overloaded "invalid" error.
With modified reproducer (see check_concurrent in very compat test),
this situation can happen quite often.
This patch modifies dm_create_device to return ENODEV only if
dm-ioctl also reports no device (ENXIO); following dm status reports ENODEV
and also some referenced device is no longer accesible through stat().
In all other cases we return EBUSY. Command line translates EBUSY and EEXIST
to the same return vaules, for API users it now returns EBUSY instead
of generic EINVAL.
IOW, if device activation returns EEXIST or EBUSY, device-mapper
cannot create the device because it already exits (EEXIST) or some referenced
device is claimed by other subystem (EBUSY) and mapping table cannot be created.
There is no need to unlock keyslot if the provided name
has wrong format. Let's check for length and '/' in name early.
Note that other commands could accept path to the device
as libdevmapper translate it to the name (status /dev/mapper/xxx).
Add early check only to activate commands.
It still can fail later because of mangled characters.
Fixes: #893
Mbed-TLS is a tiny TLS implementation designed for embedded environment which
can greatly reduce the disk space requirement compared to OpenSSL. While we
already have crypto_kernel for this purpose and Mbed-TLS lacking hash/cipher
support can cause reduced functionality, there're situations where AF_ALG is
not available but we're fine with limited scenarios like LUKS2 only.
Use read/write buffer functions to avoid partial operation.
This also fixed leaked fd warning. Also fix error path
for context failure - if initialize_context() fails,
rc->log_fd is closed in context destructor, no need to close
it in open_log/parse_log.
Another fixed bug is in parse_log, where immediatelly after
creation we have to seek to the beginning of the file first.