mirror of
https://gitlab.com/cryptsetup/cryptsetup.git
synced 2025-12-22 16:20:01 +01:00
cryptsetup-reencrypt: harden checks for hdr backups removal
There're various situations where hdr backups together with log file may get removed even when the hdr was already marked unusable. This patch fixes the most sever case already reported and generaly tries harder protecting the log file and both hdr backups.
This commit is contained in:
committed by
Milan Broz
parent
d7b127549c
commit
3e742452cd
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* cryptsetup-reencrypt - crypt utility for offline re-encryption
|
||||
*
|
||||
* Copyright (C) 2012, Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2012-2016, Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2012-2015, Milan Broz All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
@@ -68,6 +68,7 @@ struct reenc_ctx {
|
||||
uint64_t device_offset;
|
||||
uint64_t device_shift;
|
||||
|
||||
int stained:1;
|
||||
int in_progress:1;
|
||||
enum { FORWARD = 0, BACKWARD = 1 } reencrypt_direction;
|
||||
enum { REENCRYPT = 0, ENCRYPT = 1, DECRYPT = 2 } reencrypt_mode;
|
||||
@@ -195,6 +196,8 @@ static int device_check(struct reenc_ctx *rc, header_magic set_magic)
|
||||
log_err(_("Cannot write device %s.\n"), rc->device);
|
||||
r = -EIO;
|
||||
}
|
||||
if (s > 0 && set_magic == MAKE_UNUSABLE)
|
||||
rc->stained = 1;
|
||||
} else
|
||||
log_dbg("LUKS signature check failed for %s.", rc->device);
|
||||
out:
|
||||
@@ -365,6 +368,7 @@ static int open_log(struct reenc_ctx *rc)
|
||||
rc->log_fd = open(rc->log_file, O_RDWR|O_EXCL|O_CREAT|flags, S_IRUSR|S_IWUSR);
|
||||
if (rc->log_fd != -1) {
|
||||
log_dbg("Created LUKS reencryption log file %s.", rc->log_file);
|
||||
rc->stained = 0;
|
||||
} else if (errno == EEXIST) {
|
||||
log_std(_("Log file %s exists, resuming reencryption.\n"), rc->log_file);
|
||||
rc->log_fd = open(rc->log_file, O_RDWR|flags);
|
||||
@@ -646,8 +650,10 @@ static int restore_luks_header(struct reenc_ctx *rc)
|
||||
crypt_free(cd);
|
||||
if (r)
|
||||
log_err(_("Cannot restore LUKS header on device %s.\n"), rc->device);
|
||||
else
|
||||
else {
|
||||
log_verbose(_("LUKS header on device %s restored.\n"), rc->device);
|
||||
rc->stained = 0;
|
||||
}
|
||||
return r;
|
||||
}
|
||||
|
||||
@@ -784,6 +790,9 @@ static int copy_data_backward(struct reenc_ctx *rc, int fd_old, int fd_new,
|
||||
if (write_log(rc) < 0)
|
||||
return -EIO;
|
||||
|
||||
/* dirty the device during ENCRYPT mode */
|
||||
rc->stained = 1;
|
||||
|
||||
while (!quit && rc->device_offset) {
|
||||
if (rc->device_offset < block_size) {
|
||||
working_offset = 0;
|
||||
@@ -1175,10 +1184,7 @@ static void destroy_context(struct reenc_ctx *rc)
|
||||
close_log(rc);
|
||||
remove_headers(rc);
|
||||
|
||||
if ((rc->reencrypt_direction == FORWARD &&
|
||||
rc->device_offset == rc->device_size) ||
|
||||
(rc->reencrypt_direction == BACKWARD &&
|
||||
(rc->device_offset == 0 || rc->device_offset == (uint64_t)~0))) {
|
||||
if (!rc->stained) {
|
||||
unlink(rc->log_file);
|
||||
unlink(rc->header_file_org);
|
||||
unlink(rc->header_file_new);
|
||||
@@ -1194,7 +1200,9 @@ static void destroy_context(struct reenc_ctx *rc)
|
||||
static int run_reencrypt(const char *device)
|
||||
{
|
||||
int r = -EINVAL;
|
||||
static struct reenc_ctx rc = {};
|
||||
static struct reenc_ctx rc = {
|
||||
.stained = 1
|
||||
};
|
||||
|
||||
if (initialize_context(&rc, device))
|
||||
goto out;
|
||||
@@ -1237,6 +1245,8 @@ static int run_reencrypt(const char *device)
|
||||
// FIXME: fix error path above to not skip this
|
||||
if (rc.reencrypt_mode != DECRYPT)
|
||||
r = restore_luks_header(&rc);
|
||||
else
|
||||
rc.stained = 0;
|
||||
out:
|
||||
destroy_context(&rc);
|
||||
return r;
|
||||
|
||||
Reference in New Issue
Block a user