mirror of
https://gitlab.com/cryptsetup/cryptsetup.git
synced 2025-12-13 03:40:05 +01:00
Detect kernel version for dm-crypt kernel key bugfix.
When loading first dm-crypt table (or action that triggers dm-crypt module load) we do not know dm-crypt version yet. Let's assume all kernels before 4.15.0 are flawed and reject VK load via kernel keyring service. When dm-crypt is already in kernel, check for correct target version instead (v1.18.1 or later).
This commit is contained in:
committed by
Milan Broz
parent
d12fb3d6e1
commit
598dd672bc
@@ -197,4 +197,11 @@ int crypt_get_integrity_tag_size(struct crypt_device *cd);
|
|||||||
int crypt_key_in_keyring(struct crypt_device *cd);
|
int crypt_key_in_keyring(struct crypt_device *cd);
|
||||||
void crypt_set_key_in_keyring(struct crypt_device *cd, unsigned key_in_keyring);
|
void crypt_set_key_in_keyring(struct crypt_device *cd, unsigned key_in_keyring);
|
||||||
|
|
||||||
|
static inline uint64_t version(uint16_t major, uint16_t minor, uint16_t patch, uint16_t release)
|
||||||
|
{
|
||||||
|
return (uint64_t)release | ((uint64_t)patch << 16) | ((uint64_t)minor << 32) | ((uint64_t)major << 48);
|
||||||
|
}
|
||||||
|
|
||||||
|
int kernel_version(uint64_t *kversion);
|
||||||
|
|
||||||
#endif /* INTERNAL_H */
|
#endif /* INTERNAL_H */
|
||||||
|
|||||||
11
lib/setup.c
11
lib/setup.c
@@ -4101,6 +4101,15 @@ static int kernel_keyring_support(void)
|
|||||||
return _kernel_keyring_supported;
|
return _kernel_keyring_supported;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int dmcrypt_keyring_bug(void)
|
||||||
|
{
|
||||||
|
uint64_t kversion;
|
||||||
|
|
||||||
|
if (kernel_version(&kversion))
|
||||||
|
return 1;
|
||||||
|
return kversion < version(4,15,0,0);
|
||||||
|
}
|
||||||
|
|
||||||
int crypt_use_keyring_for_vk(const struct crypt_device *cd)
|
int crypt_use_keyring_for_vk(const struct crypt_device *cd)
|
||||||
{
|
{
|
||||||
uint32_t dmc_flags;
|
uint32_t dmc_flags;
|
||||||
@@ -4113,7 +4122,7 @@ int crypt_use_keyring_for_vk(const struct crypt_device *cd)
|
|||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
if (dm_flags(DM_CRYPT, &dmc_flags))
|
if (dm_flags(DM_CRYPT, &dmc_flags))
|
||||||
return 1;
|
return dmcrypt_keyring_bug() ? 0 : 1;
|
||||||
|
|
||||||
return (dmc_flags & DM_KERNEL_KEYRING_SUPPORTED);
|
return (dmc_flags & DM_KERNEL_KEYRING_SUPPORTED);
|
||||||
}
|
}
|
||||||
|
|||||||
25
lib/utils.c
25
lib/utils.c
@@ -30,6 +30,7 @@
|
|||||||
#include <sys/resource.h>
|
#include <sys/resource.h>
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
|
#include <sys/utsname.h>
|
||||||
|
|
||||||
#include "internal.h"
|
#include "internal.h"
|
||||||
|
|
||||||
@@ -553,3 +554,27 @@ int crypt_keyfile_read(struct crypt_device *cd, const char *keyfile,
|
|||||||
return crypt_keyfile_device_read(cd, keyfile, key, key_size_read,
|
return crypt_keyfile_device_read(cd, keyfile, key, key_size_read,
|
||||||
keyfile_offset, keyfile_size_max, flags);
|
keyfile_offset, keyfile_size_max, flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int kernel_version(uint64_t *kversion)
|
||||||
|
{
|
||||||
|
struct utsname uts;
|
||||||
|
uint16_t maj, min, patch, rel;
|
||||||
|
int r = -EINVAL;
|
||||||
|
|
||||||
|
if (uname(&uts) < 0)
|
||||||
|
return r;
|
||||||
|
|
||||||
|
if (sscanf(uts.release, "%" SCNu16 ".%" SCNu16 ".%" SCNu16 "-%" SCNu16,
|
||||||
|
&maj, &min, &patch, &rel) == 4)
|
||||||
|
r = 0;
|
||||||
|
else if (sscanf(uts.release, "%" SCNu16 ".%" SCNu16 ".%" SCNu16,
|
||||||
|
&maj, &min, &patch) == 3) {
|
||||||
|
rel = 0;
|
||||||
|
r = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!r)
|
||||||
|
*kversion = version(maj, min, patch, rel);
|
||||||
|
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user