From: Maxim Uvarov Date: Mon, 30 Jan 2012 20:17:43 +0000 (-0800) Subject: update modsign X-Git-Tag: v2.6.39-400.9.0~613^2 X-Git-Url: https://www.infradead.org/git/?a=commitdiff_plain;h=bec4c5e3646d2ce0a9877786c2eb76366898c00c;p=users%2Fjedix%2Flinux-maple.git update modsign Orabug: 13615815 This patch updates modsign and makes force option work. Signed-off-by: Maxim Uvarov --- diff --git a/.gitignore b/.gitignore index 9dacde0a4b2dc..7889b6212fb73 100644 --- a/.gitignore +++ b/.gitignore @@ -19,6 +19,9 @@ *.so.dbg *.mod.c *.i +*.ko.unsigned +*.ko.digest.sig +*.ko.digest *.lst *.symtypes *.order diff --git a/crypto/signature/dsa.c b/crypto/signature/dsa.c index 469539c496065..12cd0b1d4f05f 100644 --- a/crypto/signature/dsa.c +++ b/crypto/signature/dsa.c @@ -94,3 +94,4 @@ cleanup: mpi_free(v); return rc; } +EXPORT_SYMBOL_GPL(DSA_verify); diff --git a/crypto/signature/ksign-parse.c b/crypto/signature/ksign-parse.c index f7026fa44e974..e8e220fd60203 100644 --- a/crypto/signature/ksign-parse.c +++ b/crypto/signature/ksign-parse.c @@ -83,7 +83,7 @@ void ksign_free_user_id(struct ksign_user_id *uid) /* * */ -static void ksign_calc_pk_keyid(struct hash_desc *sha1, +static void ksign_calc_pk_keyid(struct shash_desc *digest, struct ksign_public_key *pk) { unsigned n; @@ -94,8 +94,6 @@ static void ksign_calc_pk_keyid(struct hash_desc *sha1, int i; int npkey = DSA_NPKEY; - crypto_hash_init(sha1); - n = pk->version < 4 ? 8 : 6; for (i = 0; i < npkey; i++) { nb[i] = mpi_get_nbits(pk->pkey[i]); @@ -103,20 +101,20 @@ static void ksign_calc_pk_keyid(struct hash_desc *sha1, n += 2 + nn[i]; } - SHA1_putc(sha1, 0x99); /* ctb */ - SHA1_putc(sha1, n >> 8); /* 2 uint8_t length header */ - SHA1_putc(sha1, n); + SHA1_putc(digest, 0x99); /* ctb */ + SHA1_putc(digest, n >> 8); /* 2 uint8_t length header */ + SHA1_putc(digest, n); if (pk->version < 4) - SHA1_putc(sha1, 3); + SHA1_putc(digest, 3); else - SHA1_putc(sha1, 4); + SHA1_putc(digest, 4); a32 = pk->timestamp; - SHA1_putc(sha1, a32 >> 24 ); - SHA1_putc(sha1, a32 >> 16 ); - SHA1_putc(sha1, a32 >> 8 ); - SHA1_putc(sha1, a32 >> 0 ); + SHA1_putc(digest, a32 >> 24 ); + SHA1_putc(digest, a32 >> 16 ); + SHA1_putc(digest, a32 >> 8 ); + SHA1_putc(digest, a32 >> 0 ); if (pk->version < 4) { uint16_t a16; @@ -126,16 +124,16 @@ static void ksign_calc_pk_keyid(struct hash_desc *sha1, ((pk->expiredate - pk->timestamp) / 86400L); else a16 = 0; - SHA1_putc(sha1, a16 >> 8); - SHA1_putc(sha1, a16 >> 0); + SHA1_putc(digest, a16 >> 8); + SHA1_putc(digest, a16 >> 0); } - SHA1_putc(sha1, PUBKEY_ALGO_DSA); + SHA1_putc(digest, PUBKEY_ALGO_DSA); for (i = 0; i < npkey; i++) { - SHA1_putc(sha1, nb[i] >> 8); - SHA1_putc(sha1, nb[i]); - SHA1_write(sha1, pp[i], nn[i]); + SHA1_putc(digest, nb[i] >> 8); + SHA1_putc(digest, nb[i]); + SHA1_write(digest, pp[i], nn[i]); kfree(pp[i]); } } @@ -180,9 +178,10 @@ static int ksign_parse_key(const uint8_t *datap, const uint8_t *endp, ksign_public_key_actor_t pkfnx, void *fnxdata) { struct ksign_public_key *pk; - struct hash_desc sha1; + struct crypto_shash *tfm; + struct shash_desc *digest; unsigned long timestamp, expiredate; - uint8_t hash[SHA1_DIGEST_SIZE]; + uint8_t sha1[SHA1_DIGEST_SIZE]; int i, version; int is_v4 = 0; int rc = 0; @@ -242,23 +241,39 @@ static int ksign_parse_key(const uint8_t *datap, const uint8_t *endp, rc = -ENOMEM; - sha1.tfm = crypto_alloc_hash("sha1", 0, 0); - if (!sha1.tfm) - goto cleanup; - sha1.flags = 0; + tfm = crypto_alloc_shash("sha1", 0, 0); + if (!tfm) + goto cleanup_pubkey; + + digest = kmalloc(sizeof(*digest) + crypto_shash_descsize(tfm), + GFP_KERNEL); + if (!digest) + goto cleanup_tfm; + + digest->tfm = tfm; + digest->flags = CRYPTO_TFM_REQ_MAY_SLEEP; + rc = crypto_shash_init(digest); + if (rc < 0) + goto cleanup_sha1; + + ksign_calc_pk_keyid(digest, pk); - ksign_calc_pk_keyid(&sha1, pk); - crypto_hash_final(&sha1, hash); - crypto_free_hash(sha1.tfm); + rc = crypto_shash_final(digest, sha1); + if (rc < 0) + goto cleanup_sha1; - pk->keyid[0] = hash[12] << 24 | hash[13] << 16 | hash[14] << 8 | hash[15]; - pk->keyid[1] = hash[16] << 24 | hash[17] << 16 | hash[18] << 8 | hash[19]; + pk->keyid[0] = sha1[12] << 24 | sha1[13] << 16 | sha1[14] << 8 | sha1[15]; + pk->keyid[1] = sha1[16] << 24 | sha1[17] << 16 | sha1[18] << 8 | sha1[19]; rc = 0; if (pkfnx) rc = pkfnx(pk, fnxdata); -cleanup: +cleanup_sha1: + kfree(digest); +cleanup_tfm: + crypto_free_shash(tfm); +cleanup_pubkey: ksign_put_public_key(pk); return rc; } diff --git a/crypto/signature/ksign.c b/crypto/signature/ksign.c index 8dcccd489d494..8b318a3ef1343 100644 --- a/crypto/signature/ksign.c +++ b/crypto/signature/ksign.c @@ -13,20 +13,22 @@ #include #include "local.h" -#if 0 -#define _debug(FMT, ...) printk(KERN_DEBUG FMT, ##__VA_ARGS__) -#else -#define _debug(FMT, ...) do { ; } while (0) -#endif +int ksign_debug; +core_param(ksign_debug, ksign_debug, bool, 0644); + +#define _debug(FMT, ...) \ + do { \ + if (unlikely(ksign_debug)) \ + printk(KERN_DEBUG FMT, ##__VA_ARGS__); \ + } while(0) /* * check the signature which is contained in SIG. */ static int ksign_signature_check(const struct ksign_signature *sig, - struct crypto_hash *sha1_tfm) + struct shash_desc *digest) { struct ksign_public_key *pk; - struct hash_desc sha1_d; uint8_t sha1[SHA1_DIGEST_SIZE]; MPI result = NULL; int rc = 0; @@ -46,29 +48,26 @@ static int ksign_signature_check(const struct ksign_signature *sig, pk->timestamp - sig->timestamp, pk->timestamp, sig->timestamp); - sha1_d.tfm = sha1_tfm; - sha1_d.flags = 0; - /* complete the digest */ if (sig->version >= 4) - SHA1_putc(&sha1_d, sig->version); - SHA1_putc(&sha1_d, sig->sig_class); + SHA1_putc(digest, sig->version); + SHA1_putc(digest, sig->sig_class); if (sig->version < 4) { u32 a = sig->timestamp; - SHA1_putc(&sha1_d, (a >> 24) & 0xff); - SHA1_putc(&sha1_d, (a >> 16) & 0xff); - SHA1_putc(&sha1_d, (a >> 8) & 0xff); - SHA1_putc(&sha1_d, (a >> 0) & 0xff); + SHA1_putc(digest, (a >> 24) & 0xff); + SHA1_putc(digest, (a >> 16) & 0xff); + SHA1_putc(digest, (a >> 8) & 0xff); + SHA1_putc(digest, (a >> 0) & 0xff); } else { uint8_t buf[6]; size_t n; - SHA1_putc(&sha1_d, PUBKEY_ALGO_DSA); - SHA1_putc(&sha1_d, DIGEST_ALGO_SHA1); + SHA1_putc(digest, PUBKEY_ALGO_DSA); + SHA1_putc(digest, DIGEST_ALGO_SHA1); if (sig->hashed_data) { n = (sig->hashed_data[0] << 8) | sig->hashed_data[1]; - SHA1_write(&sha1_d, sig->hashed_data, n + 2); + SHA1_write(digest, sig->hashed_data, n + 2); n += 6; } else { @@ -82,12 +81,9 @@ static int ksign_signature_check(const struct ksign_signature *sig, buf[3] = n >> 16; buf[4] = n >> 8; buf[5] = n; - SHA1_write(&sha1_d, buf, 6); + SHA1_write(digest, buf, 6); } - - crypto_hash_final(&sha1_d, sha1); - crypto_free_hash(sha1_tfm); - + crypto_shash_final(digest, sha1); rc = -ENOMEM; result = mpi_alloc((SHA1_DIGEST_SIZE + BYTES_PER_MPI_LIMB - 1) / BYTES_PER_MPI_LIMB); @@ -132,15 +128,59 @@ static int ksign_grab_signature(struct ksign_signature *sig, void *fnxdata) /* * verify the signature of some data with one of the kernel's known public keys - * - the SHA1 context should be currently open with the signed data digested - * into it so that more data can be appended - * - the SHA1 context is finalised and freed before returning + * - the SHA1 digest supplied should have the data to be checked already loaded + * in to it */ int ksign_verify_signature(const char *sigdata, unsigned sig_size, - struct crypto_hash *sha1) + struct shash_desc *partial_digest) { struct ksign_signature *sig = NULL; - int retval; + struct shash_desc *digest = NULL; + uint8_t sha1[SHA1_DIGEST_SIZE]; + void *export_buf = NULL; + int retval, loop; + + /* copy the current state of the digest, something that we have to do + * by exporting the old state and importing into the new state + */ + export_buf = kmalloc(crypto_shash_statesize(partial_digest->tfm), + GFP_KERNEL); + if (!export_buf) + return -ENOMEM; + + retval = crypto_shash_export(partial_digest, export_buf); + if (retval < 0) + goto cleanup; + + retval = -ENOMEM; + digest = kmalloc(sizeof(*partial_digest) + + crypto_shash_descsize(partial_digest->tfm), + GFP_KERNEL); + if (!digest) + goto cleanup; + + digest->tfm = partial_digest->tfm; + digest->flags = CRYPTO_TFM_REQ_MAY_SLEEP; + + if (ksign_debug) { + /* print the partial digest for debugging purposes */ + retval = crypto_shash_import(digest, export_buf); + if (retval < 0) + goto cleanup; + + crypto_shash_final(digest, sha1); + printk(KERN_WARNING "Modsign digest: "); + for (loop = 0; loop < sizeof(sha1); loop++) + printk("%02x", sha1[loop]); + printk("\n"); + } + + retval = crypto_shash_import(digest, export_buf); + if (retval < 0) + goto cleanup; + + kfree(export_buf); + export_buf = NULL; /* parse the signature data to get the actual signature */ retval = ksign_parse_packets(sigdata, sig_size, @@ -152,14 +192,15 @@ int ksign_verify_signature(const char *sigdata, unsigned sig_size, if (!sig) { printk(KERN_NOTICE "Couldn't find valid DSA signature in module\n"); - return -ENOENT; + retval = -ENOENT; + goto cleanup; } _debug("signature keyid: %08x%08x ver=%u\n", sig->keyid[0], sig->keyid[1], sig->version); /* check the data SHA1 transformation against the public key */ - retval = ksign_signature_check(sig, sha1); + retval = ksign_signature_check(sig, digest); switch (retval) { case 0: _debug("ksign: Signature check succeeded\n"); @@ -168,15 +209,16 @@ int ksign_verify_signature(const char *sigdata, unsigned sig_size, _debug("ksign: Signature check ENOMEM\n"); break; default: - _debug("ksign: Signature check failed\n"); + _debug("ksign: Signature check failed: %d\n", retval); if (retval != -ENOKEY) retval = -EKEYREJECTED; break; } - cleanup: +cleanup: if (sig) ksign_free_signature(sig); - + kfree(export_buf); + kfree(digest); return retval; } diff --git a/crypto/signature/local.h b/crypto/signature/local.h index c7ad2adbd154c..3f910b1d76ffa 100644 --- a/crypto/signature/local.h +++ b/crypto/signature/local.h @@ -153,18 +153,12 @@ extern int DSA_verify(const MPI datahash, const MPI sig[], const MPI pkey[]); * - we _know_ the data is locked into kernel memory, so we don't want to have * to kmap() it */ -static inline void SHA1_putc(struct hash_desc *sha1, uint8_t ch) +static inline void SHA1_putc(struct shash_desc *digest, uint8_t ch) { - struct scatterlist sg; - - sg_init_one(&sg, &ch, 1); - crypto_hash_update(sha1, &sg, 1); + crypto_shash_update(digest, &ch, 1); } -static inline void SHA1_write(struct hash_desc *sha1, const void *s, size_t n) +static inline void SHA1_write(struct shash_desc *digest, const void *s, size_t n) { - struct scatterlist sg; - - sg_init_one(&sg, s, n); - crypto_hash_update(sha1, &sg, n); + crypto_shash_update(digest, s, n); } diff --git a/include/asm-generic/module.h b/include/asm-generic/module.h index ed5b44de4c915..8f05cae9b0a74 100644 --- a/include/asm-generic/module.h +++ b/include/asm-generic/module.h @@ -10,13 +10,23 @@ struct mod_arch_specific }; #ifdef CONFIG_64BIT +#define MODULES_ARE_ELF64 #define Elf_Shdr Elf64_Shdr #define Elf_Sym Elf64_Sym #define Elf_Ehdr Elf64_Ehdr +#define Elf_Rel Elf64_Rel +#define Elf_Rela Elf64_Rela +#define ELF_R_TYPE(X) ELF64_R_TYPE(X) +#define ELF_R_SYM(X) ELF64_R_SYM(X) #else +#define MODULES_ARE_ELF32 #define Elf_Shdr Elf32_Shdr #define Elf_Sym Elf32_Sym #define Elf_Ehdr Elf32_Ehdr +#define Elf_Rel Elf32_Rel +#define Elf_Rela Elf32_Rela +#define ELF_R_TYPE(X) ELF32_R_TYPE(X) +#define ELF_R_SYM(X) ELF32_R_SYM(X) #endif #endif /* __ASM_GENERIC_MODULE_H */ diff --git a/include/linux/crypto/ksign.h b/include/linux/crypto/ksign.h index 27c9e4acdfc9f..0fc084d054ec9 100644 --- a/include/linux/crypto/ksign.h +++ b/include/linux/crypto/ksign.h @@ -12,11 +12,12 @@ #ifndef _LINUX_CRYPTO_KSIGN_H #define _LINUX_CRYPTO_KSIGN_H -#include - #ifdef CONFIG_CRYPTO_SIGNATURE + +#include + extern int ksign_verify_signature(const char *sig, unsigned sig_size, - struct crypto_hash *sha1); + struct shash_desc *digest); #endif #endif /* _LINUX_CRYPTO_KSIGN_H */ diff --git a/include/linux/elfnote.h b/include/linux/elfnote.h index 4d5c5d56093f7..3bab35e599d2b 100644 --- a/include/linux/elfnote.h +++ b/include/linux/elfnote.h @@ -94,8 +94,8 @@ #define ELFNOTE32(name, type, desc) ELFNOTE(32, name, type, desc) #define ELFNOTE64(name, type, desc) ELFNOTE(64, name, type, desc) -#define ELFNOTE_NAME(name) #name -#define ELFNOTE_SECTION(name) ".note."#name +#define ELFNOTE_NAME(name) __stringify(name) +#define ELFNOTE_SECTION(name) ".note."ELFNOTE_NAME(name) #endif /* __ASSEMBLER__ */ #endif /* _LINUX_ELFNOTE_H */ diff --git a/kernel/module-verify-elf.c b/kernel/module-verify-elf.c index f18015b421d47..4dea8d08fdffa 100644 --- a/kernel/module-verify-elf.c +++ b/kernel/module-verify-elf.c @@ -13,9 +13,7 @@ #include #include #include -#include -#include -#include +#include "module-verify.h" #if 0 #define _debug(FMT, ...) printk(FMT, ##__VA_ARGS__) diff --git a/kernel/module-verify-sig.c b/kernel/module-verify-sig.c index 9810ee32b3680..b009d8e59764e 100644 --- a/kernel/module-verify-sig.c +++ b/kernel/module-verify-sig.c @@ -14,20 +14,18 @@ #include #include #include -#include -#include #include #include -#include -#include +#include "module-verify.h" -#undef MODSIGN_DEBUG +int modsign_debug; +core_param(modsign_debug, modsign_debug, bool, 0644); -#ifdef MODSIGN_DEBUG -#define _debug(FMT, ...) printk(FMT, ##__VA_ARGS__) -#else -#define _debug(FMT, ...) do {} while (0) -#endif +#define _debug(FMT, ...) \ + do { \ + if (unlikely(modsign_debug)) \ + printk(FMT, ##__VA_ARGS__); \ + } while(0) #ifdef MODSIGN_DEBUG #define count_and_csum(C, __p, __n) \ @@ -48,22 +46,18 @@ do { \ #define crypto_digest_update_data(C, PTR, N) \ do { \ - struct scatterlist sg; \ uint8_t *__p = (uint8_t *)(PTR); \ size_t __n = (N); \ count_and_csum((C), __p, __n); \ - sg_init_one(&sg, __p, __n); \ - crypto_hash_update(&(C)->hash, &sg, __n); \ + crypto_shash_update((C)->hash, __p, __n); \ } while (0) -#define crypto_digest_update_val(C, VAL) \ +#define crypto_digest_update_val(C, VAL) \ do { \ - struct scatterlist sg; \ uint8_t *__p = (uint8_t *)&(VAL); \ size_t __n = sizeof(VAL); \ count_and_csum((C), __p, __n); \ - sg_init_one(&sg, __p, __n); \ - crypto_hash_update(&(C)->hash, &sg, __n); \ + crypto_shash_update((C)->hash, __p, __n); \ } while (0) static int module_verify_canonicalise(struct module_verify_data *mvdata); @@ -101,18 +95,21 @@ int module_verify_signature(struct module_verify_data *mvdata, int *_gpgsig_ok) { const struct elf_note *note; + struct crypto_shash *tfm; const Elf_Shdr *sechdrs = mvdata->sections; const char *secstrings = mvdata->secstrings; const char *sig; unsigned note_size, sig_size, note_namesz; - int i, ret; + int loop, ret; - for (i = 1; i < mvdata->nsects; i++) { - switch (sechdrs[i].sh_type) { + _debug("looking for sig section '%s'\n", modsign_note_section); + + for (loop = 1; loop < mvdata->nsects; loop++) { + switch (sechdrs[loop].sh_type) { case SHT_NOTE: - if (strcmp(mvdata->secstrings + sechdrs[i].sh_name, + if (strcmp(mvdata->secstrings + sechdrs[loop].sh_name, modsign_note_section) == 0) - mvdata->sig_index = i; + mvdata->sig_index = loop; break; } } @@ -150,29 +147,43 @@ int module_verify_signature(struct module_verify_data *mvdata, /* grab an SHA1 transformation context * - !!! if this tries to load the sha1.ko module, we will deadlock!!! */ - mvdata->hash.tfm = crypto_alloc_hash("sha1", 0, 0); - if (!mvdata->hash.tfm) { - printk("Couldn't load module - SHA1 transform unavailable\n"); + tfm = crypto_alloc_shash("sha1", 0, 0); + if (!tfm) { + printk(KERN_ERR + "Couldn't load module - SHA1 transform unavailable\n"); return -EPERM; } - crypto_hash_init(&mvdata->hash); + mvdata->hash = kmalloc(sizeof(*mvdata->hash) + + crypto_shash_descsize(tfm), + GFP_KERNEL); + if (!mvdata->hash) { + crypto_free_shash(tfm); + return -ENOMEM; + } + + mvdata->hash->tfm = tfm; + mvdata->hash->flags = CRYPTO_TFM_REQ_MAY_SLEEP; + ret = crypto_shash_init(mvdata->hash); + if (ret < 0) { + crypto_free_shash(mvdata->hash->tfm); + kfree(mvdata->hash); + return -ENOMEM; + } #ifdef MODSIGN_DEBUG mvdata->xcsum = 0; #endif /* load data from each relevant section into the digest */ - for (i = 1; i < mvdata->nsects; i++) { - unsigned long sh_type = sechdrs[i].sh_type; - unsigned long sh_info = sechdrs[i].sh_info; - unsigned long sh_size = sechdrs[i].sh_size; - unsigned long sh_flags = sechdrs[i].sh_flags; - const char *sh_name = secstrings + sechdrs[i].sh_name; - const void *data = mvdata->buffer + sechdrs[i].sh_offset; - - if (i == mvdata->sig_index) - continue; + for (loop = 0; loop < mvdata->ncanon; loop++) { + int sect = mvdata->canonlist[loop]; + unsigned long sh_type = sechdrs[sect].sh_type; + unsigned long sh_info = sechdrs[sect].sh_info; + unsigned long sh_size = sechdrs[sect].sh_size; + unsigned long sh_flags = sechdrs[sect].sh_flags; + const char *sh_name = secstrings + sechdrs[sect].sh_name; + const void *data = mvdata->buffer + sechdrs[sect].sh_offset; #ifdef MODSIGN_DEBUG mvdata->csum = 0; @@ -183,36 +194,43 @@ int module_verify_signature(struct module_verify_data *mvdata, * contents, because the symtab gets changed when sections are * added or removed */ if (sh_type == SHT_REL || sh_type == SHT_RELA) { - if (mvdata->canonlist[sh_info]) { - uint32_t xsh_info = mvdata->canonmap[sh_info]; - - crypto_digest_update_data(mvdata, sh_name, strlen(sh_name)); - crypto_digest_update_val(mvdata, sechdrs[i].sh_type); - crypto_digest_update_val(mvdata, sechdrs[i].sh_flags); - crypto_digest_update_val(mvdata, sechdrs[i].sh_size); - crypto_digest_update_val(mvdata, sechdrs[i].sh_addralign); - crypto_digest_update_val(mvdata, xsh_info); - - if (sh_type == SHT_RELA) - ret = extract_elf_rela( - mvdata, i, - data, - sh_size / sizeof(Elf_Rela), - sh_name); - else - ret = extract_elf_rel( - mvdata, i, - data, - sh_size / sizeof(Elf_Rel), - sh_name); - - if (ret < 0) - goto format_error; - } - + uint32_t xsh_info = mvdata->canonmap[sh_info]; + + crypto_digest_update_data(mvdata, sh_name, strlen(sh_name)); + crypto_digest_update_val(mvdata, sechdrs[sect].sh_type); + crypto_digest_update_val(mvdata, sechdrs[sect].sh_flags); + crypto_digest_update_val(mvdata, sechdrs[sect].sh_size); + crypto_digest_update_val(mvdata, sechdrs[sect].sh_addralign); + crypto_digest_update_val(mvdata, xsh_info); + + if (sh_type == SHT_RELA) + ret = extract_elf_rela( + mvdata, sect, + data, + sh_size / sizeof(Elf_Rela), + sh_name); + else + ret = extract_elf_rel( + mvdata, sect, + data, + sh_size / sizeof(Elf_Rel), + sh_name); + + if (ret < 0) + goto format_error; continue; } + /* include the headers of BSS sections */ + if (sh_type == SHT_NOBITS && sh_flags & SHF_ALLOC) { + crypto_digest_update_data(mvdata, sh_name, strlen(sh_name)); + crypto_digest_update_val(mvdata, sechdrs[sect].sh_type); + crypto_digest_update_val(mvdata, sechdrs[sect].sh_flags); + crypto_digest_update_val(mvdata, sechdrs[sect].sh_size); + crypto_digest_update_val(mvdata, sechdrs[sect].sh_addralign); + goto digested; + } + /* ignore gcc's build ID section as it seems to get modified by * the build process */ if (strcmp(sh_name, ".note.gnu.build-id") == 0) @@ -226,23 +244,26 @@ int module_verify_signature(struct module_verify_data *mvdata, include_section: crypto_digest_update_data(mvdata, sh_name, strlen(sh_name)); - crypto_digest_update_val(mvdata, sechdrs[i].sh_type); - crypto_digest_update_val(mvdata, sechdrs[i].sh_flags); - crypto_digest_update_val(mvdata, sechdrs[i].sh_size); - crypto_digest_update_val(mvdata, sechdrs[i].sh_addralign); + crypto_digest_update_val(mvdata, sechdrs[sect].sh_type); + crypto_digest_update_val(mvdata, sechdrs[sect].sh_flags); + crypto_digest_update_val(mvdata, sechdrs[sect].sh_size); + crypto_digest_update_val(mvdata, sechdrs[sect].sh_addralign); + crypto_digest_update_data(mvdata, data, sh_size); + digested: _debug("%08zx %02x digested the %s section, size %ld\n", mvdata->signed_size, mvdata->csum, sh_name, sh_size); - - mvdata->canonlist[i] = 1; } _debug("Contributed %zu bytes to the digest (csum 0x%02x)\n", mvdata->signed_size, mvdata->xcsum); /* do the actual signature verification */ - ret = ksign_verify_signature(sig, sig_size, mvdata->hash.tfm); + ret = ksign_verify_signature(sig, sig_size, mvdata->hash); + + crypto_free_shash(mvdata->hash->tfm); + kfree(mvdata->hash); _debug("verify-sig : %d\n", ret); @@ -263,13 +284,15 @@ int module_verify_signature(struct module_verify_data *mvdata, return ret; format_error: - crypto_free_hash(mvdata->hash.tfm); + crypto_free_shash(mvdata->hash->tfm); + kfree(mvdata->hash); format_error_no_free: printk(KERN_ERR "Module format error encountered\n"); return -ELIBBAD; /* deal with the case of an unsigned module */ no_signature: + _debug("no signature found\n"); if (!signedonly) return 0; printk(KERN_ERR "An attempt to load unsigned module was rejected\n"); @@ -297,11 +320,16 @@ static int module_verify_canonicalise(struct module_verify_data *mvdata) for (loop = 1; loop < mvdata->nsects; loop++) { const Elf_Shdr *section = mvdata->sections + loop; - if (loop != mvdata->sig_index) { - /* we only need to canonicalise allocatable sections */ - if (section->sh_flags & SHF_ALLOC) - mvdata->canonlist[canon++] = loop; - } + if (loop == mvdata->sig_index) + continue; + + /* we only need to canonicalise allocatable sections */ + if (section->sh_flags & SHF_ALLOC) + mvdata->canonlist[canon++] = loop; + else if ((section->sh_type == SHT_REL || + section->sh_type == SHT_RELA) && + mvdata->sections[section->sh_info].sh_flags & SHF_ALLOC) + mvdata->canonlist[canon++] = loop; } /* canonicalise the index numbers of the contributing section */ @@ -329,7 +357,7 @@ static int module_verify_canonicalise(struct module_verify_data *mvdata) for (loop = 0; loop < canon; loop++) mvdata->canonmap[mvdata->canonlist[loop]] = loop + 1; - + mvdata->ncanon = canon; return 0; } diff --git a/kernel/module-verify.c b/kernel/module-verify.c index 80ff866bc0ca7..1863243863759 100644 --- a/kernel/module-verify.c +++ b/kernel/module-verify.c @@ -11,7 +11,8 @@ #include #include #include -#include +#include +#include "module-verify.h" /* * verify a module's integrity @@ -36,6 +37,11 @@ int module_verify(const Elf_Ehdr *hdr, size_t size, int *_gpgsig_ok) } ret = module_verify_signature(&mvdata, _gpgsig_ok); +#ifdef CONFIG_CRYPTO_FIPS + if (ret < 0 && fips_enabled) + panic("Module verification failed with error %d in FIPS mode\n", + ret); +#endif error: kfree(mvdata.secsizes); diff --git a/include/linux/module-verify.h b/kernel/module-verify.h similarity index 93% rename from include/linux/module-verify.h rename to kernel/module-verify.h index 95995b291973c..4e7b8e4d38290 100644 --- a/include/linux/module-verify.h +++ b/kernel/module-verify.h @@ -10,12 +10,12 @@ */ #include -#include +#include #include #ifdef CONFIG_MODULE_VERIFY struct module_verify_data { - struct hash_desc hash; /* module signature digest */ + struct shash_desc *hash; /* module signature digest (SHA1) */ const void *buffer; /* module buffer */ const Elf_Ehdr *hdr; /* ELF header */ const Elf_Shdr *sections; /* ELF section table */ @@ -30,6 +30,7 @@ struct module_verify_data { size_t signed_size; /* count of bytes contributed to digest */ int *canonlist; /* list of canonicalised sections */ int *canonmap; /* section canonicalisation map */ + int ncanon; /* number of canonicalised sections */ int sig_index; /* module signature section index */ uint8_t xcsum; /* checksum of bytes contributed to digest */ uint8_t csum; /* checksum of bytes representing a section */ diff --git a/kernel/module.c b/kernel/module.c index 06cfec84ec366..c4f5b89ed03ec 100644 --- a/kernel/module.c +++ b/kernel/module.c @@ -58,7 +58,7 @@ #include #include #include -#include +#include "module-verify.h" #define CREATE_TRACE_POINTS #include diff --git a/scripts/Makefile.modpost b/scripts/Makefile.modpost index f4de5c1408504..809c5b8deed09 100644 --- a/scripts/Makefile.modpost +++ b/scripts/Makefile.modpost @@ -139,7 +139,7 @@ quiet_cmd_ld_ko_unsigned_o = LD [M] $@ $(modules:.ko=.ko.unsigned): %.ko.unsigned :%.o %.mod.o FORCE $(call if_changed,ld_ko_unsigned_o) -targets += $(modules) +targets += $(modules:.ko=.ko.unsigned) # Step 7), sign the modules MODSECKEY = ./kernel.sec @@ -150,14 +150,31 @@ KEYFLAGS += --default-key $(MODKEYNAME) endif ifeq ($(wildcard $(MODSECKEY))+$(wildcard $(MODPUBKEY)),$(MODSECKEY)+$(MODPUBKEY)) +ifeq ($(KBUILD_SRC),) + # no O= is being used + SCRIPTS_DIR := scripts +else + SCRIPTS_DIR := $(KBUILD_SRC)/scripts +endif +SIGN_MODULES := 1 +else +SIGN_MODULES := 0 +endif + +# only sign if it's an in-tree module +ifneq ($(KBUILD_EXTMOD),) +SIGN_MODULES := 0 +endif + +ifeq ($(SIGN_MODULES),1) quiet_cmd_sign_ko_ko_unsigned = SIGN [M] $@ cmd_sign_ko_ko_unsigned = \ scripts/mod/mod-extract $< $@.digest && \ rm -f $@.digest.sig && \ gpg --batch --no-greeting $(KEYFLAGS) -b $@.digest && \ - sh scripts/mod/modsign-note.sh $@.digest.sig | \ + sh $(SCRIPTS_DIR)/mod/modsign-note.sh $@.digest.sig | \ $(CC) -x assembler-with-cpp $(c_flags) $(CFLAGS_MODULE) -c -o $@.note.o - && \ - $(LD) -r -o $@ $< $@.note.o + $(LD) -r $(LDFLAGS) -o $@ $< $@.note.o else quiet_cmd_sign_ko_ko_unsigned = NO SIGN [M] $@ cmd_sign_ko_ko_unsigned = \ diff --git a/scripts/mod/mod-extract.c b/scripts/mod/mod-extract.c index 0922e3a9bb8f2..14e155713b54b 100644 --- a/scripts/mod/mod-extract.c +++ b/scripts/mod/mod-extract.c @@ -33,39 +33,39 @@ struct byteorder { void (*set64)(uint64_t *, uint64_t); }; -uint16_t get16_le(const uint16_t *p) { return __le16_to_cpu(*p); } -uint32_t get32_le(const uint32_t *p) { return __le32_to_cpu(*p); } -uint64_t get64_le(const uint64_t *p) { return __le64_to_cpu(*p); } -uint16_t get16_be(const uint16_t *p) { return __be16_to_cpu(*p); } -uint32_t get32_be(const uint32_t *p) { return __be32_to_cpu(*p); } -uint64_t get64_be(const uint64_t *p) { return __be64_to_cpu(*p); } - -void set16_le(uint16_t *p, uint16_t n) { *p = __cpu_to_le16(n); } -void set32_le(uint32_t *p, uint32_t n) { *p = __cpu_to_le32(n); } -void set64_le(uint64_t *p, uint64_t n) { *p = __cpu_to_le64(n); } -void set16_be(uint16_t *p, uint16_t n) { *p = __cpu_to_be16(n); } -void set32_be(uint32_t *p, uint32_t n) { *p = __cpu_to_be32(n); } -void set64_be(uint64_t *p, uint64_t n) { *p = __cpu_to_be64(n); } - -const struct byteorder byteorder_le = { +static uint16_t get16_le(const uint16_t *p) { return __le16_to_cpu(*p); } +static uint32_t get32_le(const uint32_t *p) { return __le32_to_cpu(*p); } +static uint64_t get64_le(const uint64_t *p) { return __le64_to_cpu(*p); } +static uint16_t get16_be(const uint16_t *p) { return __be16_to_cpu(*p); } +static uint32_t get32_be(const uint32_t *p) { return __be32_to_cpu(*p); } +static uint64_t get64_be(const uint64_t *p) { return __be64_to_cpu(*p); } + +static void set16_le(uint16_t *p, uint16_t n) { *p = __cpu_to_le16(n); } +static void set32_le(uint32_t *p, uint32_t n) { *p = __cpu_to_le32(n); } +static void set64_le(uint64_t *p, uint64_t n) { *p = __cpu_to_le64(n); } +static void set16_be(uint16_t *p, uint16_t n) { *p = __cpu_to_be16(n); } +static void set32_be(uint32_t *p, uint32_t n) { *p = __cpu_to_be32(n); } +static void set64_be(uint64_t *p, uint64_t n) { *p = __cpu_to_be64(n); } + +static const struct byteorder byteorder_le = { get16_le, get32_le, get64_le, set16_le, set32_le, set64_le }; -const struct byteorder byteorder_be = { +static const struct byteorder byteorder_be = { get16_be, get32_be, get64_be, set16_be, set32_be, set64_be }; -const struct byteorder *order; +static const struct byteorder *order; -uint16_t get16(const uint16_t *p) { return order->get16(p); } -uint32_t get32(const uint32_t *p) { return order->get32(p); } -uint64_t get64(const uint64_t *p) { return order->get64(p); } -void set16(uint16_t *p, uint16_t n) { order->set16(p, n); } -void set32(uint32_t *p, uint32_t n) { order->set32(p, n); } -void set64(uint64_t *p, uint64_t n) { order->set64(p, n); } +static inline uint16_t get16(const uint16_t *p) { return order->get16(p); } +static inline uint32_t get32(const uint32_t *p) { return order->get32(p); } +static inline uint64_t get64(const uint64_t *p) { return order->get64(p); } +static inline void set16(uint16_t *p, uint16_t n) { order->set16(p, n); } +static inline void set32(uint32_t *p, uint32_t n) { order->set32(p, n); } +static inline void set64(uint64_t *p, uint64_t n) { order->set64(p, n); } -FILE *outfd; -uint8_t csum, xcsum; +static FILE *outfd; +static uint8_t csum, xcsum; static void write_out(const void *data, size_t size) { @@ -235,8 +235,8 @@ static void extract_elf64_rela(const void *buffer, int secix, int targetix, set32(&relocation.r_type, ELF64_R_TYPE(r_info)); if (ELF64_R_SYM(r_info) >= nsyms) { - fprintf(stderr, "Invalid symbol ID %lx in relocation %zu\n", - ELF64_R_SYM(r_info), loop); + fprintf(stderr, "Invalid symbol ID %zx in relocation %zu\n", + (size_t)ELF64_R_SYM(r_info), loop); exit(1); } @@ -302,8 +302,8 @@ static void extract_elf64_rel(const void *buffer, int secix, int targetix, set32(&relocation.r_type, ELF64_R_TYPE(r_info)); if (ELF64_R_SYM(r_info) >= nsyms) { - fprintf(stderr, "Invalid symbol ID %lx in relocation %zi\n", - ELF64_R_SYM(r_info), loop); + fprintf(stderr, "Invalid symbol ID %zx in relocation %zu\n", + (size_t)ELF64_R_SYM(r_info), loop); exit(1); } @@ -369,6 +369,7 @@ static void extract_elf64(void *buffer, size_t len, Elf64_Ehdr *hdr) Elf64_Word sh_type = get32(§ions[loop].sh_type); Elf64_Xword sh_size = get64(§ions[loop].sh_size); Elf64_Xword sh_flags = get64(§ions[loop].sh_flags); + Elf64_Word sh_info = get32(§ions[loop].sh_info); Elf64_Off sh_offset = get64(§ions[loop].sh_offset); void *data = buffer + sh_offset; @@ -381,6 +382,9 @@ static void extract_elf64(void *buffer, size_t len, Elf64_Ehdr *hdr) /* we only need to canonicalise allocatable sections */ if (sh_flags & SHF_ALLOC) canonlist[canon++] = loop; + else if ((sh_type == SHT_REL || sh_type == SHT_RELA) && + get64(§ions[sh_info].sh_flags) & SHF_ALLOC) + canonlist[canon++] = loop; /* keep track of certain special sections */ switch (sh_type) { @@ -447,27 +451,28 @@ static void extract_elf64(void *buffer, size_t len, Elf64_Ehdr *hdr) } } - memset(canonlist, 0, sizeof(int) * shnum); - /* iterate through the section table looking for sections we want to * contribute to the signature */ verbose("\n"); - verbose("FILE POS CS SECT NAME\n"); - verbose("======== == ==== ==============================\n"); - - for (loop = 1; loop < shnum; loop++) { - const char *sh_name = secstrings + get32(§ions[loop].sh_name); - Elf64_Word sh_type = get32(§ions[loop].sh_type); - Elf64_Xword sh_size = get64(§ions[loop].sh_size); - Elf64_Xword sh_flags = get64(§ions[loop].sh_flags); - Elf64_Word sh_info = get32(§ions[loop].sh_info); - Elf64_Off sh_offset = get64(§ions[loop].sh_offset); + verbose("CAN FILE POS CS SECT NAME\n"); + verbose("=== ======== == ==== ==============================\n"); + + for (loop = 0; loop < canon; loop++) { + int sect = canonlist[loop]; + const char *sh_name = secstrings + get32(§ions[sect].sh_name); + Elf64_Word sh_type = get32(§ions[sect].sh_type); + Elf64_Xword sh_size = get64(§ions[sect].sh_size); + Elf64_Xword sh_flags = get64(§ions[sect].sh_flags); + Elf64_Word sh_info = get32(§ions[sect].sh_info); + Elf64_Off sh_offset = get64(§ions[sect].sh_offset); void *data = buffer + sh_offset; csum = 0; /* include canonicalised relocation sections */ if (sh_type == SHT_REL || sh_type == SHT_RELA) { + Elf32_Word canon_sh_info; + if (sh_info <= 0 && sh_info >= hdr->e_shnum) { fprintf(stderr, "Invalid ELF - REL/RELA sh_info does" @@ -475,41 +480,49 @@ static void extract_elf64(void *buffer, size_t len, Elf64_Ehdr *hdr) exit(3); } - if (canonlist[sh_info]) { - Elf32_Word xsh_info; - - verbose("%08lx ", ftell(outfd)); - - set32(&xsh_info, canonmap[sh_info]); - - /* write out selected portions of the section - * header */ - write_out(sh_name, strlen(sh_name)); - write_out_val(sections[loop].sh_type); - write_out_val(sections[loop].sh_flags); - write_out_val(sections[loop].sh_size); - write_out_val(sections[loop].sh_addralign); - write_out_val(xsh_info); - - if (sh_type == SHT_RELA) - extract_elf64_rela(buffer, loop, sh_info, - data, sh_size / sizeof(Elf64_Rela), - symbols, nsyms, - sections, shnum, canonmap, - strings, nstrings, - sh_name); - else - extract_elf64_rel(buffer, loop, sh_info, - data, sh_size / sizeof(Elf64_Rel), - symbols, nsyms, - sections, shnum, canonmap, - strings, nstrings, - sh_name); - } - + verbose("%3u %08lx ", loop, ftell(outfd)); + + set32(&canon_sh_info, canonmap[sh_info]); + + /* write out selected portions of the section header */ + write_out(sh_name, strlen(sh_name)); + write_out_val(sections[sect].sh_type); + write_out_val(sections[sect].sh_flags); + write_out_val(sections[sect].sh_size); + write_out_val(sections[sect].sh_addralign); + write_out_val(canon_sh_info); + + if (sh_type == SHT_RELA) + extract_elf64_rela(buffer, sect, sh_info, + data, sh_size / sizeof(Elf64_Rela), + symbols, nsyms, + sections, shnum, canonmap, + strings, nstrings, + sh_name); + else + extract_elf64_rel(buffer, sect, sh_info, + data, sh_size / sizeof(Elf64_Rel), + symbols, nsyms, + sections, shnum, canonmap, + strings, nstrings, + sh_name); continue; } + /* include the headers of BSS sections */ + if (sh_type == SHT_NOBITS && sh_flags & SHF_ALLOC) { + verbose("%3u %08lx ", loop, ftell(outfd)); + + /* write out selected portions of the section header */ + write_out(sh_name, strlen(sh_name)); + write_out_val(sections[sect].sh_type); + write_out_val(sections[sect].sh_flags); + write_out_val(sections[sect].sh_size); + write_out_val(sections[sect].sh_addralign); + + verbose("%02x %4d %s\n", csum, sect, sh_name); + } + /* ignore gcc's build ID section as it seems to get modified by * the build process */ if (strcmp(sh_name, ".note.gnu.build-id") == 0) @@ -523,22 +536,19 @@ static void extract_elf64(void *buffer, size_t len, Elf64_Ehdr *hdr) continue; include_section: - verbose("%08lx ", ftell(outfd)); + verbose("%3u %08lx ", loop, ftell(outfd)); /* write out selected portions of the section header */ write_out(sh_name, strlen(sh_name)); - write_out_val(sections[loop].sh_type); - write_out_val(sections[loop].sh_flags); - write_out_val(sections[loop].sh_size); - write_out_val(sections[loop].sh_addralign); + write_out_val(sections[sect].sh_type); + write_out_val(sections[sect].sh_flags); + write_out_val(sections[sect].sh_size); + write_out_val(sections[sect].sh_addralign); /* write out the section data */ write_out(data, sh_size); - verbose("%02x %4d %s\n", csum, loop, sh_name); - - /* note the section has been written */ - canonlist[loop] = 1; + verbose("%02x %4d %s\n", csum, sect, sh_name); } verbose("%08lx (%lu bytes csum 0x%02x)\n", @@ -720,6 +730,7 @@ static void extract_elf32(void *buffer, size_t len, Elf32_Ehdr *hdr) Elf32_Word sh_type = get32(§ions[loop].sh_type); Elf32_Xword sh_size = get32(§ions[loop].sh_size); Elf32_Xword sh_flags = get32(§ions[loop].sh_flags); + Elf64_Word sh_info = get32(§ions[loop].sh_info); Elf32_Off sh_offset = get32(§ions[loop].sh_offset); void *data = buffer + sh_offset; @@ -732,6 +743,9 @@ static void extract_elf32(void *buffer, size_t len, Elf32_Ehdr *hdr) /* we only need to canonicalise allocatable sections */ if (sh_flags & SHF_ALLOC) canonlist[canon++] = loop; + else if ((sh_type == SHT_REL || sh_type == SHT_RELA) && + get32(§ions[sh_info].sh_flags) & SHF_ALLOC) + canonlist[canon++] = loop; /* keep track of certain special sections */ switch (sh_type) { @@ -798,21 +812,20 @@ static void extract_elf32(void *buffer, size_t len, Elf32_Ehdr *hdr) } } - memset(canonlist, 0, sizeof(int) * shnum); - /* iterate through the section table looking for sections we want to * contribute to the signature */ verbose("\n"); - verbose("FILE POS CS SECT NAME\n"); - verbose("======== == ==== ==============================\n"); - - for (loop = 1; loop < shnum; loop++) { - const char *sh_name = secstrings + get32(§ions[loop].sh_name); - Elf32_Word sh_type = get32(§ions[loop].sh_type); - Elf32_Xword sh_size = get32(§ions[loop].sh_size); - Elf32_Xword sh_flags = get32(§ions[loop].sh_flags); - Elf32_Word sh_info = get32(§ions[loop].sh_info); - Elf32_Off sh_offset = get32(§ions[loop].sh_offset); + verbose("CAN FILE POS CS SECT NAME\n"); + verbose("=== ======== == ==== ==============================\n"); + + for (loop = 0; loop < canon; loop++) { + int sect = canonlist[loop]; + const char *sh_name = secstrings + get32(§ions[sect].sh_name); + Elf32_Word sh_type = get32(§ions[sect].sh_type); + Elf32_Xword sh_size = get32(§ions[sect].sh_size); + Elf32_Xword sh_flags = get32(§ions[sect].sh_flags); + Elf32_Word sh_info = get32(§ions[sect].sh_info); + Elf32_Off sh_offset = get32(§ions[sect].sh_offset); void *data = buffer + sh_offset; csum = 0; @@ -825,6 +838,8 @@ static void extract_elf32(void *buffer, size_t len, Elf32_Ehdr *hdr) /* include canonicalised relocation sections */ if (sh_type == SHT_REL || sh_type == SHT_RELA) { + Elf32_Word canon_sh_info; + if (sh_info <= 0 && sh_info >= hdr->e_shnum) { fprintf(stderr, "Invalid ELF - REL/RELA sh_info does" @@ -832,40 +847,49 @@ static void extract_elf32(void *buffer, size_t len, Elf32_Ehdr *hdr) exit(3); } - if (canonlist[sh_info]) { - Elf32_Word xsh_info; - - verbose("%08lx ", ftell(outfd)); - - set32(&xsh_info, canonmap[sh_info]); - - /* write out selected portions of the section header */ - write_out(sh_name, strlen(sh_name)); - write_out_val(sections[loop].sh_type); - write_out_val(sections[loop].sh_flags); - write_out_val(sections[loop].sh_size); - write_out_val(sections[loop].sh_addralign); - write_out_val(xsh_info); - - if (sh_type == SHT_RELA) - extract_elf32_rela(buffer, loop, sh_info, - data, sh_size / sizeof(Elf32_Rela), - symbols, nsyms, - sections, shnum, canonmap, - strings, nstrings, - sh_name); - else - extract_elf32_rel(buffer, loop, sh_info, - data, sh_size / sizeof(Elf32_Rel), - symbols, nsyms, - sections, shnum, canonmap, - strings, nstrings, - sh_name); - } - + verbose("%3u %08lx ", loop, ftell(outfd)); + + set32(&canon_sh_info, canonmap[sh_info]); + + /* write out selected portions of the section header */ + write_out(sh_name, strlen(sh_name)); + write_out_val(sections[sect].sh_type); + write_out_val(sections[sect].sh_flags); + write_out_val(sections[sect].sh_size); + write_out_val(sections[sect].sh_addralign); + write_out_val(canon_sh_info); + + if (sh_type == SHT_RELA) + extract_elf32_rela(buffer, sect, sh_info, + data, sh_size / sizeof(Elf32_Rela), + symbols, nsyms, + sections, shnum, canonmap, + strings, nstrings, + sh_name); + else + extract_elf32_rel(buffer, sect, sh_info, + data, sh_size / sizeof(Elf32_Rel), + symbols, nsyms, + sections, shnum, canonmap, + strings, nstrings, + sh_name); continue; } + /* include the headers of BSS sections */ + if (sh_type == SHT_NOBITS && sh_flags & SHF_ALLOC) { + verbose("%3u %08lx ", loop, ftell(outfd)); + + /* write out selected portions of the section header */ + write_out(sh_name, strlen(sh_name)); + write_out_val(sections[sect].sh_type); + write_out_val(sections[sect].sh_flags); + write_out_val(sections[sect].sh_size); + write_out_val(sections[sect].sh_addralign); + + verbose("%02x %4d %s\n", csum, sect, sh_name); + } + /* ignore gcc's build ID section as it seems to get modified by * the build process */ if (strcmp(sh_name, ".note.gnu.build-id") == 0) @@ -879,22 +903,19 @@ static void extract_elf32(void *buffer, size_t len, Elf32_Ehdr *hdr) continue; include_section: - verbose("%08lx ", ftell(outfd)); + verbose("%3u %08lx ", loop, ftell(outfd)); /* write out selected portions of the section header */ write_out(sh_name, strlen(sh_name)); - write_out_val(sections[loop].sh_type); - write_out_val(sections[loop].sh_flags); - write_out_val(sections[loop].sh_size); - write_out_val(sections[loop].sh_addralign); + write_out_val(sections[sect].sh_type); + write_out_val(sections[sect].sh_flags); + write_out_val(sections[sect].sh_size); + write_out_val(sections[sect].sh_addralign); /* write out the section data */ write_out(data, sh_size); - verbose("%02x %4d %s\n", csum, loop, sh_name); - - /* note the section has been written */ - canonlist[loop] = 1; + verbose("%02x %4d %s\n", csum, sect, sh_name); } verbose("%08lx (%lu bytes csum 0x%02x)\n", diff --git a/uek-rpm/ol5/kernel-uek.spec b/uek-rpm/ol5/kernel-uek.spec index b7b060ce4ead7..53c38f539fc8c 100644 --- a/uek-rpm/ol5/kernel-uek.spec +++ b/uek-rpm/ol5/kernel-uek.spec @@ -998,20 +998,36 @@ done # get rid of unwanted files resulting from patch fuzz find . \( -name "*.orig" -o -name "*~" \) -exec rm -f {} \; >/dev/null %if %{signmodules} - cp %{SOURCE19} . - pwd - gpg --homedir . --batch --gen-key %{SOURCE11} -# if there're external keys to be included - if [ -s %{SOURCE19} ]; then - gpg --homedir . --no-default-keyring --keyring kernel.pub --import %{SOURCE19} - fi - gpg --homedir . --export --keyring kernel.pub Oracle > extract.pub - gcc -o scripts/bin2c scripts/bin2c.c - scripts/bin2c ksign_def_public_key __initdata < extract.pub >crypto/signature/key.h -%endif - +cp %{SOURCE19} . +cat < extract.pub +gcc -o scripts/bin2c scripts/bin2c.c +scripts/bin2c ksign_def_public_key __initdata crypto/signature/key.h +%endif ### ### build diff --git a/uek-rpm/ol6/kernel-uek.spec b/uek-rpm/ol6/kernel-uek.spec index a998e1fdd2288..27babb3ea8a8d 100644 --- a/uek-rpm/ol6/kernel-uek.spec +++ b/uek-rpm/ol6/kernel-uek.spec @@ -1009,20 +1009,36 @@ done # get rid of unwanted files resulting from patch fuzz find . \( -name "*.orig" -o -name "*~" \) -exec rm -f {} \; >/dev/null %if %{signmodules} - cp %{SOURCE19} . - pwd - gpg --homedir . --batch --gen-key %{SOURCE11} +cp %{SOURCE19} . +cat < extract.pub - gcc -o scripts/bin2c scripts/bin2c.c - scripts/bin2c ksign_def_public_key __initdata < extract.pub >crypto/signature/key.h +if [ -s %{SOURCE19} ]; then + gpg --homedir . --no-default-keyring --keyring kernel.pub --import %{SOURCE19} +fi +gpg --homedir . --export --keyring ./kernel.pub Oracle > extract.pub +gcc -o scripts/bin2c scripts/bin2c.c +scripts/bin2c ksign_def_public_key __initdata crypto/signature/key.h %endif - - -cd .. ### ### build