mirror of
https://gitlab.com/cryptsetup/cryptsetup.git
synced 2025-12-11 10:50:01 +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);
|
||||
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 */
|
||||
|
||||
11
lib/setup.c
11
lib/setup.c
@@ -4101,6 +4101,15 @@ static int kernel_keyring_support(void)
|
||||
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)
|
||||
{
|
||||
uint32_t dmc_flags;
|
||||
@@ -4113,7 +4122,7 @@ int crypt_use_keyring_for_vk(const struct crypt_device *cd)
|
||||
return 0;
|
||||
|
||||
if (dm_flags(DM_CRYPT, &dmc_flags))
|
||||
return 1;
|
||||
return dmcrypt_keyring_bug() ? 0 : 1;
|
||||
|
||||
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/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/utsname.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,
|
||||
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