Allow LUKS2 repair to override blkid checks.

Allow user to run cryptsetup repair command and explicitly do
repair on corrupted LUKS2 headers where blkid decides it's no longer
a LUKS2 device.
This commit is contained in:
Ondrej Kozina
2018-06-28 15:48:13 +02:00
committed by Milan Broz
parent 2c1a6e3f94
commit 289c9ecf5d
3 changed files with 13 additions and 12 deletions

View File

@@ -135,7 +135,7 @@ struct luks2_keyslot_params {
int LUKS2_hdr_version_unlocked(struct crypt_device *cd, int LUKS2_hdr_version_unlocked(struct crypt_device *cd,
const char *backup_file); const char *backup_file);
int LUKS2_hdr_read(struct crypt_device *cd, struct luks2_hdr *hdr); int LUKS2_hdr_read(struct crypt_device *cd, struct luks2_hdr *hdr, int repair);
int LUKS2_hdr_write(struct crypt_device *cd, struct luks2_hdr *hdr); int LUKS2_hdr_write(struct crypt_device *cd, struct luks2_hdr *hdr);
int LUKS2_hdr_dump(struct crypt_device *cd, struct luks2_hdr *hdr); int LUKS2_hdr_dump(struct crypt_device *cd, struct luks2_hdr *hdr);

View File

@@ -842,7 +842,8 @@ int LUKS2_hdr_validate(json_object *hdr_jobj)
return 0; return 0;
} }
int LUKS2_hdr_read(struct crypt_device *cd, struct luks2_hdr *hdr) /* FIXME: should we expose do_recovery parameter explicitly? */
int LUKS2_hdr_read(struct crypt_device *cd, struct luks2_hdr *hdr, int repair)
{ {
int r; int r;
@@ -853,7 +854,7 @@ int LUKS2_hdr_read(struct crypt_device *cd, struct luks2_hdr *hdr)
return r; return r;
} }
r = LUKS2_disk_hdr_read(cd, hdr, crypt_metadata_device(cd), 1, 1); r = LUKS2_disk_hdr_read(cd, hdr, crypt_metadata_device(cd), 1, !repair);
if (r == -EAGAIN) { if (r == -EAGAIN) {
/* unlikely: auto-recovery is required and failed due to read lock being held */ /* unlikely: auto-recovery is required and failed due to read lock being held */
device_read_unlock(crypt_metadata_device(cd)); device_read_unlock(crypt_metadata_device(cd));
@@ -865,7 +866,7 @@ int LUKS2_hdr_read(struct crypt_device *cd, struct luks2_hdr *hdr)
return r; return r;
} }
r = LUKS2_disk_hdr_read(cd, hdr, crypt_metadata_device(cd), 1, 1); r = LUKS2_disk_hdr_read(cd, hdr, crypt_metadata_device(cd), 1, !repair);
device_write_unlock(crypt_metadata_device(cd)); device_write_unlock(crypt_metadata_device(cd));
} else } else
@@ -1050,7 +1051,7 @@ int LUKS2_hdr_restore(struct crypt_device *cd, struct luks2_hdr *hdr,
return r; return r;
} }
r = LUKS2_disk_hdr_read(cd, &hdr_file, backup_device, 0); r = LUKS2_disk_hdr_read(cd, &hdr_file, backup_device, 0, 0);
device_read_unlock(backup_device); device_read_unlock(backup_device);
device_free(backup_device); device_free(backup_device);
@@ -1089,7 +1090,7 @@ int LUKS2_hdr_restore(struct crypt_device *cd, struct luks2_hdr *hdr,
close(devfd); close(devfd);
devfd = -1; devfd = -1;
r = LUKS2_hdr_read(cd, &tmp_hdr); r = LUKS2_hdr_read(cd, &tmp_hdr, 0);
if (r == 0) { if (r == 0) {
log_dbg("Device %s already contains LUKS2 header, checking UUID and requirements.", device_path(device)); log_dbg("Device %s already contains LUKS2 header, checking UUID and requirements.", device_path(device));
r = LUKS2_config_get_requirements(cd, &tmp_hdr, &reqs); r = LUKS2_config_get_requirements(cd, &tmp_hdr, &reqs);
@@ -1176,7 +1177,7 @@ out:
if (!r) { if (!r) {
LUKS2_hdr_free(hdr); LUKS2_hdr_free(hdr);
r = LUKS2_hdr_read(cd, hdr); r = LUKS2_hdr_read(cd, hdr, 1);
} }
return r; return r;

View File

@@ -644,16 +644,16 @@ struct crypt_pbkdf_type *crypt_get_pbkdf(struct crypt_device *cd)
/* /*
* crypt_load() helpers * crypt_load() helpers
*/ */
static int _crypt_load_luks2(struct crypt_device *cd, int reload) static int _crypt_load_luks2(struct crypt_device *cd, int reload, int repair)
{ {
int r; int r;
char tmp_cipher[MAX_CIPHER_LEN], tmp_cipher_mode[MAX_CIPHER_LEN], char tmp_cipher[MAX_CIPHER_LEN], tmp_cipher_mode[MAX_CIPHER_LEN],
*cipher = NULL, *cipher_mode = NULL, *type = NULL; *cipher = NULL, *cipher_mode = NULL, *type = NULL;
struct luks2_hdr hdr2 = {}; struct luks2_hdr hdr2 = {};
log_dbg("%soading LUKS2 header.", reload ? "Rel" : "L"); log_dbg("%soading LUKS2 header (repair %sabled).", reload ? "Rel" : "L", repair ? "en" : "dis");
r = LUKS2_hdr_read(cd, &hdr2); r = LUKS2_hdr_read(cd, &hdr2, repair);
if (r) if (r)
return r; return r;
@@ -713,7 +713,7 @@ static void _luks2_reload(struct crypt_device *cd)
if (!cd || !isLUKS2(cd->type)) if (!cd || !isLUKS2(cd->type))
return; return;
(void) _crypt_load_luks2(cd, 1); (void) _crypt_load_luks2(cd, 1, 0);
} }
static int _crypt_load_luks(struct crypt_device *cd, const char *requested_type, static int _crypt_load_luks(struct crypt_device *cd, const char *requested_type,
@@ -768,7 +768,7 @@ static int _crypt_load_luks(struct crypt_device *cd, const char *requested_type,
return -EINVAL; return -EINVAL;
} }
r = _crypt_load_luks2(cd, cd->type != NULL); r = _crypt_load_luks2(cd, cd->type != NULL, repair);
} else } else
r = -EINVAL; r = -EINVAL;
out: out: