diff options
| author | Hendrik Brueckner <brueckner@linux.vnet.ibm.com> | 2013-12-05 08:48:22 -0500 |
|---|---|---|
| committer | David Howells <dhowells@redhat.com> | 2013-12-10 13:25:28 -0500 |
| commit | 62226983da070f7e51068ec2e3a4da34672964c7 (patch) | |
| tree | 04a0e1bc11282cc966f7c7c0521fa1e0f70b8956 /kernel | |
| parent | 7cfe5b3310a1b45f385ff18647bddb487a6c5525 (diff) | |
KEYS: correct alignment of system_certificate_list content in assembly file
Apart from data-type specific alignment constraints, there are also
architecture-specific alignment requirements.
For example, on s390 symbols must be on even addresses implying a 2-byte
alignment. If the system_certificate_list_end symbol is on an odd address
and if this address is loaded, the least-significant bit is ignored. As a
result, the load_system_certificate_list() fails to load the certificates
because of a wrong certificate length calculation.
To be safe, align system_certificate_list on an 8-byte boundary. Also improve
the length calculation of the system_certificate_list content. Introduce a
system_certificate_list_size (8-byte aligned because of unsigned long) variable
that stores the length. Let the linker calculate this size by introducing
a start and end label for the certificate content.
Signed-off-by: Hendrik Brueckner <brueckner@linux.vnet.ibm.com>
Signed-off-by: David Howells <dhowells@redhat.com>
Diffstat (limited to 'kernel')
| -rw-r--r-- | kernel/system_certificates.S | 14 | ||||
| -rw-r--r-- | kernel/system_keyring.c | 4 |
2 files changed, 14 insertions, 4 deletions
diff --git a/kernel/system_certificates.S b/kernel/system_certificates.S index 4aef390671cb..3e9868d47535 100644 --- a/kernel/system_certificates.S +++ b/kernel/system_certificates.S | |||
| @@ -3,8 +3,18 @@ | |||
| 3 | 3 | ||
| 4 | __INITRODATA | 4 | __INITRODATA |
| 5 | 5 | ||
| 6 | .align 8 | ||
| 6 | .globl VMLINUX_SYMBOL(system_certificate_list) | 7 | .globl VMLINUX_SYMBOL(system_certificate_list) |
| 7 | VMLINUX_SYMBOL(system_certificate_list): | 8 | VMLINUX_SYMBOL(system_certificate_list): |
| 9 | __cert_list_start: | ||
| 8 | .incbin "kernel/x509_certificate_list" | 10 | .incbin "kernel/x509_certificate_list" |
| 9 | .globl VMLINUX_SYMBOL(system_certificate_list_end) | 11 | __cert_list_end: |
| 10 | VMLINUX_SYMBOL(system_certificate_list_end): | 12 | |
| 13 | .align 8 | ||
| 14 | .globl VMLINUX_SYMBOL(system_certificate_list_size) | ||
| 15 | VMLINUX_SYMBOL(system_certificate_list_size): | ||
| 16 | #ifdef CONFIG_64BIT | ||
| 17 | .quad __cert_list_end - __cert_list_start | ||
| 18 | #else | ||
| 19 | .long __cert_list_end - __cert_list_start | ||
| 20 | #endif | ||
diff --git a/kernel/system_keyring.c b/kernel/system_keyring.c index 564dd93430a2..52ebc70263f4 100644 --- a/kernel/system_keyring.c +++ b/kernel/system_keyring.c | |||
| @@ -22,7 +22,7 @@ struct key *system_trusted_keyring; | |||
| 22 | EXPORT_SYMBOL_GPL(system_trusted_keyring); | 22 | EXPORT_SYMBOL_GPL(system_trusted_keyring); |
| 23 | 23 | ||
| 24 | extern __initconst const u8 system_certificate_list[]; | 24 | extern __initconst const u8 system_certificate_list[]; |
| 25 | extern __initconst const u8 system_certificate_list_end[]; | 25 | extern __initconst const unsigned long system_certificate_list_size; |
| 26 | 26 | ||
| 27 | /* | 27 | /* |
| 28 | * Load the compiled-in keys | 28 | * Load the compiled-in keys |
| @@ -60,8 +60,8 @@ static __init int load_system_certificate_list(void) | |||
| 60 | 60 | ||
| 61 | pr_notice("Loading compiled-in X.509 certificates\n"); | 61 | pr_notice("Loading compiled-in X.509 certificates\n"); |
| 62 | 62 | ||
| 63 | end = system_certificate_list_end; | ||
| 64 | p = system_certificate_list; | 63 | p = system_certificate_list; |
| 64 | end = p + system_certificate_list_size; | ||
| 65 | while (p < end) { | 65 | while (p < end) { |
| 66 | /* Each cert begins with an ASN.1 SEQUENCE tag and must be more | 66 | /* Each cert begins with an ASN.1 SEQUENCE tag and must be more |
| 67 | * than 256 bytes in size. | 67 | * than 256 bytes in size. |
