Skip to content

Commit c8424e7

Browse files
bauermannmimizohar
authored andcommitted
MODSIGN: Export module signature definitions
IMA will use the module_signature format for append signatures, so export the relevant definitions and factor out the code which verifies that the appended signature trailer is valid. Also, create a CONFIG_MODULE_SIG_FORMAT option so that IMA can select it and be able to use mod_check_sig() without having to depend on either CONFIG_MODULE_SIG or CONFIG_MODULES. s390 duplicated the definition of struct module_signature so now they can use the new <linux/module_signature.h> header instead. Signed-off-by: Thiago Jung Bauermann <[email protected]> Acked-by: Jessica Yu <[email protected]> Reviewed-by: Philipp Rudo <[email protected]> Cc: Heiko Carstens <[email protected]> Signed-off-by: Mimi Zohar <[email protected]>
1 parent b36f281 commit c8424e7

File tree

10 files changed

+108
-77
lines changed

10 files changed

+108
-77
lines changed

arch/s390/Kconfig

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -538,7 +538,7 @@ config ARCH_HAS_KEXEC_PURGATORY
538538

539539
config KEXEC_VERIFY_SIG
540540
bool "Verify kernel signature during kexec_file_load() syscall"
541-
depends on KEXEC_FILE && SYSTEM_DATA_VERIFICATION
541+
depends on KEXEC_FILE && MODULE_SIG_FORMAT
542542
help
543543
This option makes kernel signature verification mandatory for
544544
the kexec_file_load() syscall.

arch/s390/kernel/machine_kexec_file.c

Lines changed: 1 addition & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
#include <linux/elf.h>
1111
#include <linux/errno.h>
1212
#include <linux/kexec.h>
13-
#include <linux/module.h>
13+
#include <linux/module_signature.h>
1414
#include <linux/verification.h>
1515
#include <asm/boot_data.h>
1616
#include <asm/ipl.h>
@@ -23,28 +23,6 @@ const struct kexec_file_ops * const kexec_file_loaders[] = {
2323
};
2424

2525
#ifdef CONFIG_KEXEC_VERIFY_SIG
26-
/*
27-
* Module signature information block.
28-
*
29-
* The constituents of the signature section are, in order:
30-
*
31-
* - Signer's name
32-
* - Key identifier
33-
* - Signature data
34-
* - Information block
35-
*/
36-
struct module_signature {
37-
u8 algo; /* Public-key crypto algorithm [0] */
38-
u8 hash; /* Digest algorithm [0] */
39-
u8 id_type; /* Key identifier type [PKEY_ID_PKCS7] */
40-
u8 signer_len; /* Length of signer's name [0] */
41-
u8 key_id_len; /* Length of key identifier [0] */
42-
u8 __pad[3];
43-
__be32 sig_len; /* Length of signature data */
44-
};
45-
46-
#define PKEY_ID_PKCS7 2
47-
4826
int s390_verify_sig(const char *kernel, unsigned long kernel_len)
4927
{
5028
const unsigned long marker_len = sizeof(MODULE_SIG_STRING) - 1;

include/linux/module.h

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -26,9 +26,6 @@
2626
#include <linux/percpu.h>
2727
#include <asm/module.h>
2828

29-
/* In stripped ARM and x86-64 modules, ~ is surprisingly rare. */
30-
#define MODULE_SIG_STRING "~Module signature appended~\n"
31-
3229
/* Not Yet Implemented */
3330
#define MODULE_SUPPORTED_DEVICE(name)
3431

include/linux/module_signature.h

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
/* SPDX-License-Identifier: GPL-2.0+ */
2+
/*
3+
* Module signature handling.
4+
*
5+
* Copyright (C) 2012 Red Hat, Inc. All Rights Reserved.
6+
* Written by David Howells ([email protected])
7+
*/
8+
9+
#ifndef _LINUX_MODULE_SIGNATURE_H
10+
#define _LINUX_MODULE_SIGNATURE_H
11+
12+
/* In stripped ARM and x86-64 modules, ~ is surprisingly rare. */
13+
#define MODULE_SIG_STRING "~Module signature appended~\n"
14+
15+
enum pkey_id_type {
16+
PKEY_ID_PGP, /* OpenPGP generated key ID */
17+
PKEY_ID_X509, /* X.509 arbitrary subjectKeyIdentifier */
18+
PKEY_ID_PKCS7, /* Signature in PKCS#7 message */
19+
};
20+
21+
/*
22+
* Module signature information block.
23+
*
24+
* The constituents of the signature section are, in order:
25+
*
26+
* - Signer's name
27+
* - Key identifier
28+
* - Signature data
29+
* - Information block
30+
*/
31+
struct module_signature {
32+
u8 algo; /* Public-key crypto algorithm [0] */
33+
u8 hash; /* Digest algorithm [0] */
34+
u8 id_type; /* Key identifier type [PKEY_ID_PKCS7] */
35+
u8 signer_len; /* Length of signer's name [0] */
36+
u8 key_id_len; /* Length of key identifier [0] */
37+
u8 __pad[3];
38+
__be32 sig_len; /* Length of signature data */
39+
};
40+
41+
int mod_check_sig(const struct module_signature *ms, size_t file_len,
42+
const char *name);
43+
44+
#endif /* _LINUX_MODULE_SIGNATURE_H */

init/Kconfig

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1930,6 +1930,10 @@ config BASE_SMALL
19301930
default 0 if BASE_FULL
19311931
default 1 if !BASE_FULL
19321932

1933+
config MODULE_SIG_FORMAT
1934+
def_bool n
1935+
select SYSTEM_DATA_VERIFICATION
1936+
19331937
menuconfig MODULES
19341938
bool "Enable loadable module support"
19351939
option modules
@@ -2007,7 +2011,7 @@ config MODULE_SRCVERSION_ALL
20072011
config MODULE_SIG
20082012
bool "Module signature verification"
20092013
depends on MODULES
2010-
select SYSTEM_DATA_VERIFICATION
2014+
select MODULE_SIG_FORMAT
20112015
help
20122016
Check modules for valid signatures upon load: the signature
20132017
is simply appended to the module. For more information see

kernel/Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@ endif
5858
obj-$(CONFIG_UID16) += uid16.o
5959
obj-$(CONFIG_MODULES) += module.o
6060
obj-$(CONFIG_MODULE_SIG) += module_signing.o
61+
obj-$(CONFIG_MODULE_SIG_FORMAT) += module_signature.o
6162
obj-$(CONFIG_KALLSYMS) += kallsyms.o
6263
obj-$(CONFIG_BSD_PROCESS_ACCT) += acct.o
6364
obj-$(CONFIG_CRASH_CORE) += crash_core.o

kernel/module.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
#include <linux/export.h>
88
#include <linux/extable.h>
99
#include <linux/moduleloader.h>
10+
#include <linux/module_signature.h>
1011
#include <linux/trace_events.h>
1112
#include <linux/init.h>
1213
#include <linux/kallsyms.h>

kernel/module_signature.c

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
// SPDX-License-Identifier: GPL-2.0+
2+
/*
3+
* Module signature checker
4+
*
5+
* Copyright (C) 2012 Red Hat, Inc. All Rights Reserved.
6+
* Written by David Howells ([email protected])
7+
*/
8+
9+
#include <linux/errno.h>
10+
#include <linux/printk.h>
11+
#include <linux/module_signature.h>
12+
#include <asm/byteorder.h>
13+
14+
/**
15+
* mod_check_sig - check that the given signature is sane
16+
*
17+
* @ms: Signature to check.
18+
* @file_len: Size of the file to which @ms is appended.
19+
* @name: What is being checked. Used for error messages.
20+
*/
21+
int mod_check_sig(const struct module_signature *ms, size_t file_len,
22+
const char *name)
23+
{
24+
if (be32_to_cpu(ms->sig_len) >= file_len - sizeof(*ms))
25+
return -EBADMSG;
26+
27+
if (ms->id_type != PKEY_ID_PKCS7) {
28+
pr_err("%s: Module is not signed with expected PKCS#7 message\n",
29+
name);
30+
return -ENOPKG;
31+
}
32+
33+
if (ms->algo != 0 ||
34+
ms->hash != 0 ||
35+
ms->signer_len != 0 ||
36+
ms->key_id_len != 0 ||
37+
ms->__pad[0] != 0 ||
38+
ms->__pad[1] != 0 ||
39+
ms->__pad[2] != 0) {
40+
pr_err("%s: PKCS#7 signature info has unexpected non-zero params\n",
41+
name);
42+
return -EBADMSG;
43+
}
44+
45+
return 0;
46+
}

kernel/module_signing.c

Lines changed: 8 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -7,77 +7,37 @@
77

88
#include <linux/kernel.h>
99
#include <linux/errno.h>
10+
#include <linux/module.h>
11+
#include <linux/module_signature.h>
1012
#include <linux/string.h>
1113
#include <linux/verification.h>
1214
#include <crypto/public_key.h>
1315
#include "module-internal.h"
1416

15-
enum pkey_id_type {
16-
PKEY_ID_PGP, /* OpenPGP generated key ID */
17-
PKEY_ID_X509, /* X.509 arbitrary subjectKeyIdentifier */
18-
PKEY_ID_PKCS7, /* Signature in PKCS#7 message */
19-
};
20-
21-
/*
22-
* Module signature information block.
23-
*
24-
* The constituents of the signature section are, in order:
25-
*
26-
* - Signer's name
27-
* - Key identifier
28-
* - Signature data
29-
* - Information block
30-
*/
31-
struct module_signature {
32-
u8 algo; /* Public-key crypto algorithm [0] */
33-
u8 hash; /* Digest algorithm [0] */
34-
u8 id_type; /* Key identifier type [PKEY_ID_PKCS7] */
35-
u8 signer_len; /* Length of signer's name [0] */
36-
u8 key_id_len; /* Length of key identifier [0] */
37-
u8 __pad[3];
38-
__be32 sig_len; /* Length of signature data */
39-
};
40-
4117
/*
4218
* Verify the signature on a module.
4319
*/
4420
int mod_verify_sig(const void *mod, struct load_info *info)
4521
{
4622
struct module_signature ms;
4723
size_t sig_len, modlen = info->len;
24+
int ret;
4825

4926
pr_devel("==>%s(,%zu)\n", __func__, modlen);
5027

5128
if (modlen <= sizeof(ms))
5229
return -EBADMSG;
5330

5431
memcpy(&ms, mod + (modlen - sizeof(ms)), sizeof(ms));
55-
modlen -= sizeof(ms);
32+
33+
ret = mod_check_sig(&ms, modlen, info->name);
34+
if (ret)
35+
return ret;
5636

5737
sig_len = be32_to_cpu(ms.sig_len);
58-
if (sig_len >= modlen)
59-
return -EBADMSG;
60-
modlen -= sig_len;
38+
modlen -= sig_len + sizeof(ms);
6139
info->len = modlen;
6240

63-
if (ms.id_type != PKEY_ID_PKCS7) {
64-
pr_err("%s: Module is not signed with expected PKCS#7 message\n",
65-
info->name);
66-
return -ENOPKG;
67-
}
68-
69-
if (ms.algo != 0 ||
70-
ms.hash != 0 ||
71-
ms.signer_len != 0 ||
72-
ms.key_id_len != 0 ||
73-
ms.__pad[0] != 0 ||
74-
ms.__pad[1] != 0 ||
75-
ms.__pad[2] != 0) {
76-
pr_err("%s: PKCS#7 signature info has unexpected non-zero params\n",
77-
info->name);
78-
return -EBADMSG;
79-
}
80-
8141
return verify_pkcs7_signature(mod, modlen, mod + modlen, sig_len,
8242
VERIFY_USE_SECONDARY_KEYRING,
8343
VERIFYING_MODULE_SIGNATURE,

scripts/Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ hostprogs-$(CONFIG_VT) += conmakehash
1717
hostprogs-$(BUILD_C_RECORDMCOUNT) += recordmcount
1818
hostprogs-$(CONFIG_BUILDTIME_EXTABLE_SORT) += sortextable
1919
hostprogs-$(CONFIG_ASN1) += asn1_compiler
20-
hostprogs-$(CONFIG_MODULE_SIG) += sign-file
20+
hostprogs-$(CONFIG_MODULE_SIG_FORMAT) += sign-file
2121
hostprogs-$(CONFIG_SYSTEM_TRUSTED_KEYRING) += extract-cert
2222
hostprogs-$(CONFIG_SYSTEM_EXTRA_CERTIFICATE) += insert-sys-cert
2323

0 commit comments

Comments
 (0)