Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Merge branch 'next' of git://git.kernel.org/pub/scm/linux/kernel/git/jmorris/linux-security

Pull security subsystem updates from James Morris:
"In this release:

- PKCS#7 parser for the key management subsystem from David Howells
- appoint Kees Cook as seccomp maintainer
- bugfixes and general maintenance across the subsystem"

* 'next' of git://git.kernel.org/pub/scm/linux/kernel/git/jmorris/linux-security: (94 commits)
X.509: Need to export x509_request_asymmetric_key()
netlabel: shorter names for the NetLabel catmap funcs/structs
netlabel: fix the catmap walking functions
netlabel: fix the horribly broken catmap functions
netlabel: fix a problem when setting bits below the previously lowest bit
PKCS#7: X.509 certificate issuer and subject are mandatory fields in the ASN.1
tpm: simplify code by using %*phN specifier
tpm: Provide a generic means to override the chip returned timeouts
tpm: missing tpm_chip_put in tpm_get_random()
tpm: Properly clean sysfs entries in error path
tpm: Add missing tpm_do_selftest to ST33 I2C driver
PKCS#7: Use x509_request_asymmetric_key()
Revert "selinux: fix the default socket labeling in sock_graft()"
X.509: x509_request_asymmetric_keys() doesn't need string length arguments
PKCS#7: fix sparse non static symbol warning
KEYS: revert encrypted key change
ima: add support for measuring and appraising firmware
firmware_class: perform new LSM checks
security: introduce kernel_fw_from_file hook
PKCS#7: Missing inclusion of linux/err.h
...

+4487 -841
+3 -1
Documentation/ABI/testing/ima_policy
··· 26 26 option: [[appraise_type=]] [permit_directio] 27 27 28 28 base: func:= [BPRM_CHECK][MMAP_CHECK][FILE_CHECK][MODULE_CHECK] 29 + [FIRMWARE_CHECK] 29 30 mask:= [MAY_READ] [MAY_WRITE] [MAY_APPEND] [MAY_EXEC] 30 31 fsmagic:= hex value 31 32 fsuuid:= file system UUID (e.g 8bcbe394-4f13-4144-be8e-5aa9ea2ce2f6) ··· 58 57 measure func=BPRM_CHECK 59 58 measure func=FILE_MMAP mask=MAY_EXEC 60 59 measure func=FILE_CHECK mask=MAY_READ uid=0 61 - measure func=MODULE_CHECK uid=0 60 + measure func=MODULE_CHECK 61 + measure func=FIRMWARE_CHECK 62 62 appraise fowner=0 63 63 64 64 The default policy measures all executables in bprm_check,
+22
Documentation/kernel-parameters.txt
··· 566 566 possible to determine what the correct size should be. 567 567 This option provides an override for these situations. 568 568 569 + ca_keys= [KEYS] This parameter identifies a specific key(s) on 570 + the system trusted keyring to be used for certificate 571 + trust validation. 572 + format: { id:<keyid> | builtin } 573 + 569 574 ccw_timeout_log [S390] 570 575 See Documentation/s390/CommonIO for details. 571 576 ··· 1323 1318 Select one of defined IMA measurements template formats. 1324 1319 Formats: { "ima" | "ima-ng" } 1325 1320 Default: "ima-ng" 1321 + 1322 + ima.ahash_minsize= [IMA] Minimum file size for asynchronous hash usage 1323 + Format: <min_file_size> 1324 + Set the minimal file size for using asynchronous hash. 1325 + If left unspecified, ahash usage is disabled. 1326 + 1327 + ahash performance varies for different data sizes on 1328 + different crypto accelerators. This option can be used 1329 + to achieve the best performance for a particular HW. 1330 + 1331 + ima.ahash_bufsize= [IMA] Asynchronous hash buffer size 1332 + Format: <bufsize> 1333 + Set hashing buffer size. Default: 4k. 1334 + 1335 + ahash performance varies for different chunk sizes on 1336 + different crypto accelerators. This option can be used 1337 + to achieve best performance for particular HW. 1326 1338 1327 1339 init= [KNL] 1328 1340 Format: <full_path>
+10 -4
Documentation/security/keys.txt
··· 1150 1150 const void *data; 1151 1151 size_t datalen; 1152 1152 size_t quotalen; 1153 + time_t expiry; 1153 1154 }; 1154 1155 1155 1156 Before calling the method, the caller will fill in data and datalen with 1156 1157 the payload blob parameters; quotalen will be filled in with the default 1157 - quota size from the key type and the rest will be cleared. 1158 + quota size from the key type; expiry will be set to TIME_T_MAX and the 1159 + rest will be cleared. 1158 1160 1159 1161 If a description can be proposed from the payload contents, that should be 1160 1162 attached as a string to the description field. This will be used for the 1161 1163 key description if the caller of add_key() passes NULL or "". 1162 1164 1163 1165 The method can attach anything it likes to type_data[] and payload. These 1164 - are merely passed along to the instantiate() or update() operations. 1166 + are merely passed along to the instantiate() or update() operations. If 1167 + set, the expiry time will be applied to the key if it is instantiated from 1168 + this data. 1165 1169 1166 - The method should return 0 if success ful or a negative error code 1170 + The method should return 0 if successful or a negative error code 1167 1171 otherwise. 1168 1172 1169 1173 ··· 1176 1172 This method is only required if the preparse() method is provided, 1177 1173 otherwise it is unused. It cleans up anything attached to the 1178 1174 description, type_data and payload fields of the key_preparsed_payload 1179 - struct as filled in by the preparse() method. 1175 + struct as filled in by the preparse() method. It will always be called 1176 + after preparse() returns successfully, even if instantiate() or update() 1177 + succeed. 1180 1178 1181 1179 1182 1180 (*) int (*instantiate)(struct key *key, struct key_preparsed_payload *prep);
+10
MAINTAINERS
··· 8002 8002 F: drivers/mmc/host/sdhci.* 8003 8003 F: drivers/mmc/host/sdhci-pltfm.[ch] 8004 8004 8005 + SECURE COMPUTING 8006 + M: Kees Cook <keescook@chromium.org> 8007 + T: git git://git.kernel.org/pub/scm/linux/kernel/git/kees/linux.git seccomp 8008 + S: Supported 8009 + F: kernel/seccomp.c 8010 + F: include/uapi/linux/seccomp.h 8011 + F: include/linux/seccomp.h 8012 + K: \bsecure_computing 8013 + K: \bTIF_SECCOMP\b 8014 + 8005 8015 SECURE DIGITAL HOST CONTROLLER INTERFACE, OPEN FIRMWARE BINDINGS (SDHCI-OF) 8006 8016 M: Anton Vorontsov <anton@enomsg.org> 8007 8017 L: linuxppc-dev@lists.ozlabs.org
+1
arch/Kconfig
··· 321 321 - secure_computing is called from a ptrace_event()-safe context 322 322 - secure_computing return value is checked and a return value of -1 323 323 results in the system call being skipped immediately. 324 + - seccomp syscall wired up 324 325 325 326 config SECCOMP_FILTER 326 327 def_bool y
+1
arch/arm/include/uapi/asm/unistd.h
··· 409 409 #define __NR_sched_setattr (__NR_SYSCALL_BASE+380) 410 410 #define __NR_sched_getattr (__NR_SYSCALL_BASE+381) 411 411 #define __NR_renameat2 (__NR_SYSCALL_BASE+382) 412 + #define __NR_seccomp (__NR_SYSCALL_BASE+383) 412 413 413 414 /* 414 415 * The following SWIs are ARM private.
+1
arch/arm/kernel/calls.S
··· 392 392 /* 380 */ CALL(sys_sched_setattr) 393 393 CALL(sys_sched_getattr) 394 394 CALL(sys_renameat2) 395 + CALL(sys_seccomp) 395 396 #ifndef syscalls_counted 396 397 .equ syscalls_padding, ((NR_syscalls + 3) & ~3) - NR_syscalls 397 398 #define syscalls_counted
+9 -6
arch/mips/include/uapi/asm/unistd.h
··· 372 372 #define __NR_sched_setattr (__NR_Linux + 349) 373 373 #define __NR_sched_getattr (__NR_Linux + 350) 374 374 #define __NR_renameat2 (__NR_Linux + 351) 375 + #define __NR_seccomp (__NR_Linux + 352) 375 376 376 377 /* 377 378 * Offset of the last Linux o32 flavoured syscall 378 379 */ 379 - #define __NR_Linux_syscalls 351 380 + #define __NR_Linux_syscalls 352 380 381 381 382 #endif /* _MIPS_SIM == _MIPS_SIM_ABI32 */ 382 383 383 384 #define __NR_O32_Linux 4000 384 - #define __NR_O32_Linux_syscalls 351 385 + #define __NR_O32_Linux_syscalls 352 385 386 386 387 #if _MIPS_SIM == _MIPS_SIM_ABI64 387 388 ··· 702 701 #define __NR_sched_setattr (__NR_Linux + 309) 703 702 #define __NR_sched_getattr (__NR_Linux + 310) 704 703 #define __NR_renameat2 (__NR_Linux + 311) 704 + #define __NR_seccomp (__NR_Linux + 312) 705 705 706 706 /* 707 707 * Offset of the last Linux 64-bit flavoured syscall 708 708 */ 709 - #define __NR_Linux_syscalls 311 709 + #define __NR_Linux_syscalls 312 710 710 711 711 #endif /* _MIPS_SIM == _MIPS_SIM_ABI64 */ 712 712 713 713 #define __NR_64_Linux 5000 714 - #define __NR_64_Linux_syscalls 311 714 + #define __NR_64_Linux_syscalls 312 715 715 716 716 #if _MIPS_SIM == _MIPS_SIM_NABI32 717 717 ··· 1036 1034 #define __NR_sched_setattr (__NR_Linux + 313) 1037 1035 #define __NR_sched_getattr (__NR_Linux + 314) 1038 1036 #define __NR_renameat2 (__NR_Linux + 315) 1037 + #define __NR_seccomp (__NR_Linux + 316) 1039 1038 1040 1039 /* 1041 1040 * Offset of the last N32 flavoured syscall 1042 1041 */ 1043 - #define __NR_Linux_syscalls 315 1042 + #define __NR_Linux_syscalls 316 1044 1043 1045 1044 #endif /* _MIPS_SIM == _MIPS_SIM_NABI32 */ 1046 1045 1047 1046 #define __NR_N32_Linux 6000 1048 - #define __NR_N32_Linux_syscalls 315 1047 + #define __NR_N32_Linux_syscalls 316 1049 1048 1050 1049 #endif /* _UAPI_ASM_UNISTD_H */
+1
arch/mips/kernel/scall32-o32.S
··· 578 578 PTR sys_sched_setattr 579 579 PTR sys_sched_getattr /* 4350 */ 580 580 PTR sys_renameat2 581 + PTR sys_seccomp
+1
arch/mips/kernel/scall64-64.S
··· 431 431 PTR sys_sched_setattr 432 432 PTR sys_sched_getattr /* 5310 */ 433 433 PTR sys_renameat2 434 + PTR sys_seccomp 434 435 .size sys_call_table,.-sys_call_table
+1
arch/mips/kernel/scall64-n32.S
··· 424 424 PTR sys_sched_setattr 425 425 PTR sys_sched_getattr 426 426 PTR sys_renameat2 /* 6315 */ 427 + PTR sys_seccomp 427 428 .size sysn32_call_table,.-sysn32_call_table
+1
arch/mips/kernel/scall64-o32.S
··· 557 557 PTR sys_sched_setattr 558 558 PTR sys_sched_getattr /* 4350 */ 559 559 PTR sys_renameat2 560 + PTR sys_seccomp 560 561 .size sys32_call_table,.-sys32_call_table
+1
arch/x86/syscalls/syscall_32.tbl
··· 360 360 351 i386 sched_setattr sys_sched_setattr 361 361 352 i386 sched_getattr sys_sched_getattr 362 362 353 i386 renameat2 sys_renameat2 363 + 354 i386 seccomp sys_seccomp
+1
arch/x86/syscalls/syscall_64.tbl
··· 323 323 314 common sched_setattr sys_sched_setattr 324 324 315 common sched_getattr sys_sched_getattr 325 325 316 common renameat2 sys_renameat2 326 + 317 common seccomp sys_seccomp 326 327 327 328 # 328 329 # x32-specific system call numbers start at 512 to avoid cache impact
+32 -2
crypto/asymmetric_keys/Kconfig
··· 22 22 23 23 config PUBLIC_KEY_ALGO_RSA 24 24 tristate "RSA public-key algorithm" 25 - select MPILIB_EXTRA 26 25 select MPILIB 27 26 help 28 27 This option enables support for the RSA algorithm (PKCS#1, RFC3447). ··· 32 33 select ASN1 33 34 select OID_REGISTRY 34 35 help 35 - This option procides support for parsing X.509 format blobs for key 36 + This option provides support for parsing X.509 format blobs for key 36 37 data and provides the ability to instantiate a crypto key from a 37 38 public key packet found inside the certificate. 39 + 40 + config PKCS7_MESSAGE_PARSER 41 + tristate "PKCS#7 message parser" 42 + depends on X509_CERTIFICATE_PARSER 43 + select ASN1 44 + select OID_REGISTRY 45 + help 46 + This option provides support for parsing PKCS#7 format messages for 47 + signature data and provides the ability to verify the signature. 48 + 49 + config PKCS7_TEST_KEY 50 + tristate "PKCS#7 testing key type" 51 + depends on PKCS7_MESSAGE_PARSER 52 + select SYSTEM_TRUSTED_KEYRING 53 + help 54 + This option provides a type of key that can be loaded up from a 55 + PKCS#7 message - provided the message is signed by a trusted key. If 56 + it is, the PKCS#7 wrapper is discarded and reading the key returns 57 + just the payload. If it isn't, adding the key will fail with an 58 + error. 59 + 60 + This is intended for testing the PKCS#7 parser. 61 + 62 + config SIGNED_PE_FILE_VERIFICATION 63 + bool "Support for PE file signature verification" 64 + depends on PKCS7_MESSAGE_PARSER=y 65 + select ASN1 66 + select OID_REGISTRY 67 + help 68 + This option provides support for verifying the signature(s) on a 69 + signed PE binary. 38 70 39 71 endif # ASYMMETRIC_KEY_TYPE
+37
crypto/asymmetric_keys/Makefile
··· 25 25 26 26 clean-files += x509-asn1.c x509-asn1.h 27 27 clean-files += x509_rsakey-asn1.c x509_rsakey-asn1.h 28 + 29 + # 30 + # PKCS#7 message handling 31 + # 32 + obj-$(CONFIG_PKCS7_MESSAGE_PARSER) += pkcs7_message.o 33 + pkcs7_message-y := \ 34 + pkcs7-asn1.o \ 35 + pkcs7_parser.o \ 36 + pkcs7_trust.o \ 37 + pkcs7_verify.o 38 + 39 + $(obj)/pkcs7_parser.o: $(obj)/pkcs7-asn1.h 40 + $(obj)/pkcs7-asn1.o: $(obj)/pkcs7-asn1.c $(obj)/pkcs7-asn1.h 41 + 42 + clean-files += pkcs7-asn1.c pkcs7-asn1.h 43 + 44 + # 45 + # PKCS#7 parser testing key 46 + # 47 + obj-$(CONFIG_PKCS7_TEST_KEY) += pkcs7_test_key.o 48 + pkcs7_test_key-y := \ 49 + pkcs7_key_type.o 50 + 51 + # 52 + # Signed PE binary-wrapped key handling 53 + # 54 + obj-$(CONFIG_SIGNED_PE_FILE_VERIFICATION) += verify_signed_pefile.o 55 + 56 + verify_signed_pefile-y := \ 57 + verify_pefile.o \ 58 + mscode_parser.o \ 59 + mscode-asn1.o 60 + 61 + $(obj)/mscode_parser.o: $(obj)/mscode-asn1.h $(obj)/mscode-asn1.h 62 + $(obj)/mscode-asn1.o: $(obj)/mscode-asn1.c $(obj)/mscode-asn1.h 63 + 64 + clean-files += mscode-asn1.c mscode-asn1.h
+2
crypto/asymmetric_keys/asymmetric_keys.h
··· 9 9 * 2 of the Licence, or (at your option) any later version. 10 10 */ 11 11 12 + int asymmetric_keyid_match(const char *kid, const char *id); 13 + 12 14 static inline const char *asymmetric_key_id(const struct key *key) 13 15 { 14 16 return key->type_data.p[1];
+34 -44
crypto/asymmetric_keys/asymmetric_type.c
··· 23 23 static DECLARE_RWSEM(asymmetric_key_parsers_sem); 24 24 25 25 /* 26 + * Match asymmetric key id with partial match 27 + * @id: key id to match in a form "id:<id>" 28 + */ 29 + int asymmetric_keyid_match(const char *kid, const char *id) 30 + { 31 + size_t idlen, kidlen; 32 + 33 + if (!kid || !id) 34 + return 0; 35 + 36 + /* make it possible to use id as in the request: "id:<id>" */ 37 + if (strncmp(id, "id:", 3) == 0) 38 + id += 3; 39 + 40 + /* Anything after here requires a partial match on the ID string */ 41 + idlen = strlen(id); 42 + kidlen = strlen(kid); 43 + if (idlen > kidlen) 44 + return 0; 45 + 46 + kid += kidlen - idlen; 47 + if (strcasecmp(id, kid) != 0) 48 + return 0; 49 + 50 + return 1; 51 + } 52 + EXPORT_SYMBOL_GPL(asymmetric_keyid_match); 53 + 54 + /* 26 55 * Match asymmetric keys on (part of) their name 27 56 * We have some shorthand methods for matching keys. We allow: 28 57 * ··· 63 34 { 64 35 const struct asymmetric_key_subtype *subtype = asymmetric_key_subtype(key); 65 36 const char *spec = description; 66 - const char *id, *kid; 37 + const char *id; 67 38 ptrdiff_t speclen; 68 - size_t idlen, kidlen; 69 39 70 40 if (!subtype || !spec || !*spec) 71 41 return 0; ··· 83 55 speclen = id - spec; 84 56 id++; 85 57 86 - /* Anything after here requires a partial match on the ID string */ 87 - kid = asymmetric_key_id(key); 88 - if (!kid) 89 - return 0; 90 - 91 - idlen = strlen(id); 92 - kidlen = strlen(kid); 93 - if (idlen > kidlen) 94 - return 0; 95 - 96 - kid += kidlen - idlen; 97 - if (strcasecmp(id, kid) != 0) 98 - return 0; 99 - 100 - if (speclen == 2 && 101 - memcmp(spec, "id", 2) == 0) 102 - return 1; 58 + if (speclen == 2 && memcmp(spec, "id", 2) == 0) 59 + return asymmetric_keyid_match(asymmetric_key_id(key), id); 103 60 104 61 if (speclen == subtype->name_len && 105 62 memcmp(spec, subtype->name, speclen) == 0) ··· 169 156 pr_devel("==>%s()\n", __func__); 170 157 171 158 if (subtype) { 172 - subtype->destroy(prep->payload); 159 + subtype->destroy(prep->payload[0]); 173 160 module_put(subtype->owner); 174 161 } 175 162 kfree(prep->type_data[1]); 176 163 kfree(prep->description); 177 - } 178 - 179 - /* 180 - * Instantiate a asymmetric_key defined key. The key was preparsed, so we just 181 - * have to transfer the data here. 182 - */ 183 - static int asymmetric_key_instantiate(struct key *key, struct key_preparsed_payload *prep) 184 - { 185 - int ret; 186 - 187 - pr_devel("==>%s()\n", __func__); 188 - 189 - ret = key_payload_reserve(key, prep->quotalen); 190 - if (ret == 0) { 191 - key->type_data.p[0] = prep->type_data[0]; 192 - key->type_data.p[1] = prep->type_data[1]; 193 - key->payload.data = prep->payload; 194 - prep->type_data[0] = NULL; 195 - prep->type_data[1] = NULL; 196 - prep->payload = NULL; 197 - } 198 - pr_devel("<==%s() = %d\n", __func__, ret); 199 - return ret; 200 164 } 201 165 202 166 /* ··· 195 205 .name = "asymmetric", 196 206 .preparse = asymmetric_key_preparse, 197 207 .free_preparse = asymmetric_key_free_preparse, 198 - .instantiate = asymmetric_key_instantiate, 208 + .instantiate = generic_key_instantiate, 199 209 .match = asymmetric_key_match, 200 210 .destroy = asymmetric_key_destroy, 201 211 .describe = asymmetric_key_describe,
+28
crypto/asymmetric_keys/mscode.asn1
··· 1 + --- Microsoft individual code signing data blob parser 2 + --- 3 + --- Copyright (C) 2012 Red Hat, Inc. All Rights Reserved. 4 + --- Written by David Howells (dhowells@redhat.com) 5 + --- 6 + --- This program is free software; you can redistribute it and/or 7 + --- modify it under the terms of the GNU General Public Licence 8 + --- as published by the Free Software Foundation; either version 9 + --- 2 of the Licence, or (at your option) any later version. 10 + --- 11 + 12 + MSCode ::= SEQUENCE { 13 + type SEQUENCE { 14 + contentType ContentType, 15 + parameters ANY 16 + }, 17 + content SEQUENCE { 18 + digestAlgorithm DigestAlgorithmIdentifier, 19 + digest OCTET STRING ({ mscode_note_digest }) 20 + } 21 + } 22 + 23 + ContentType ::= OBJECT IDENTIFIER ({ mscode_note_content_type }) 24 + 25 + DigestAlgorithmIdentifier ::= SEQUENCE { 26 + algorithm OBJECT IDENTIFIER ({ mscode_note_digest_algo }), 27 + parameters ANY OPTIONAL 28 + }
+126
crypto/asymmetric_keys/mscode_parser.c
··· 1 + /* Parse a Microsoft Individual Code Signing blob 2 + * 3 + * Copyright (C) 2014 Red Hat, Inc. All Rights Reserved. 4 + * Written by David Howells (dhowells@redhat.com) 5 + * 6 + * This program is free software; you can redistribute it and/or 7 + * modify it under the terms of the GNU General Public Licence 8 + * as published by the Free Software Foundation; either version 9 + * 2 of the Licence, or (at your option) any later version. 10 + */ 11 + 12 + #define pr_fmt(fmt) "MSCODE: "fmt 13 + #include <linux/kernel.h> 14 + #include <linux/slab.h> 15 + #include <linux/err.h> 16 + #include <linux/oid_registry.h> 17 + #include <crypto/pkcs7.h> 18 + #include "verify_pefile.h" 19 + #include "mscode-asn1.h" 20 + 21 + /* 22 + * Parse a Microsoft Individual Code Signing blob 23 + */ 24 + int mscode_parse(struct pefile_context *ctx) 25 + { 26 + const void *content_data; 27 + size_t data_len; 28 + int ret; 29 + 30 + ret = pkcs7_get_content_data(ctx->pkcs7, &content_data, &data_len, 1); 31 + 32 + if (ret) { 33 + pr_debug("PKCS#7 message does not contain data\n"); 34 + return ret; 35 + } 36 + 37 + pr_devel("Data: %zu [%*ph]\n", data_len, (unsigned)(data_len), 38 + content_data); 39 + 40 + return asn1_ber_decoder(&mscode_decoder, ctx, content_data, data_len); 41 + } 42 + 43 + /* 44 + * Check the content type OID 45 + */ 46 + int mscode_note_content_type(void *context, size_t hdrlen, 47 + unsigned char tag, 48 + const void *value, size_t vlen) 49 + { 50 + enum OID oid; 51 + 52 + oid = look_up_OID(value, vlen); 53 + if (oid == OID__NR) { 54 + char buffer[50]; 55 + 56 + sprint_oid(value, vlen, buffer, sizeof(buffer)); 57 + pr_err("Unknown OID: %s\n", buffer); 58 + return -EBADMSG; 59 + } 60 + 61 + /* 62 + * pesign utility had a bug where it was putting 63 + * OID_msIndividualSPKeyPurpose instead of OID_msPeImageDataObjId 64 + * So allow both OIDs. 65 + */ 66 + if (oid != OID_msPeImageDataObjId && 67 + oid != OID_msIndividualSPKeyPurpose) { 68 + pr_err("Unexpected content type OID %u\n", oid); 69 + return -EBADMSG; 70 + } 71 + 72 + return 0; 73 + } 74 + 75 + /* 76 + * Note the digest algorithm OID 77 + */ 78 + int mscode_note_digest_algo(void *context, size_t hdrlen, 79 + unsigned char tag, 80 + const void *value, size_t vlen) 81 + { 82 + struct pefile_context *ctx = context; 83 + char buffer[50]; 84 + enum OID oid; 85 + 86 + oid = look_up_OID(value, vlen); 87 + switch (oid) { 88 + case OID_md4: 89 + ctx->digest_algo = HASH_ALGO_MD4; 90 + break; 91 + case OID_md5: 92 + ctx->digest_algo = HASH_ALGO_MD5; 93 + break; 94 + case OID_sha1: 95 + ctx->digest_algo = HASH_ALGO_SHA1; 96 + break; 97 + case OID_sha256: 98 + ctx->digest_algo = HASH_ALGO_SHA256; 99 + break; 100 + 101 + case OID__NR: 102 + sprint_oid(value, vlen, buffer, sizeof(buffer)); 103 + pr_err("Unknown OID: %s\n", buffer); 104 + return -EBADMSG; 105 + 106 + default: 107 + pr_err("Unsupported content type: %u\n", oid); 108 + return -ENOPKG; 109 + } 110 + 111 + return 0; 112 + } 113 + 114 + /* 115 + * Note the digest we're guaranteeing with this certificate 116 + */ 117 + int mscode_note_digest(void *context, size_t hdrlen, 118 + unsigned char tag, 119 + const void *value, size_t vlen) 120 + { 121 + struct pefile_context *ctx = context; 122 + 123 + ctx->digest = value; 124 + ctx->digest_len = vlen; 125 + return 0; 126 + }
+127
crypto/asymmetric_keys/pkcs7.asn1
··· 1 + PKCS7ContentInfo ::= SEQUENCE { 2 + contentType ContentType, 3 + content [0] EXPLICIT SignedData OPTIONAL 4 + } 5 + 6 + ContentType ::= OBJECT IDENTIFIER ({ pkcs7_note_OID }) 7 + 8 + SignedData ::= SEQUENCE { 9 + version INTEGER, 10 + digestAlgorithms DigestAlgorithmIdentifiers, 11 + contentInfo ContentInfo, 12 + certificates CHOICE { 13 + certSet [0] IMPLICIT ExtendedCertificatesAndCertificates, 14 + certSequence [2] IMPLICIT Certificates 15 + } OPTIONAL ({ pkcs7_note_certificate_list }), 16 + crls CHOICE { 17 + crlSet [1] IMPLICIT CertificateRevocationLists, 18 + crlSequence [3] IMPLICIT CRLSequence 19 + } OPTIONAL, 20 + signerInfos SignerInfos 21 + } 22 + 23 + ContentInfo ::= SEQUENCE { 24 + contentType ContentType, 25 + content [0] EXPLICIT Data OPTIONAL 26 + } 27 + 28 + Data ::= ANY ({ pkcs7_note_data }) 29 + 30 + DigestAlgorithmIdentifiers ::= CHOICE { 31 + daSet SET OF DigestAlgorithmIdentifier, 32 + daSequence SEQUENCE OF DigestAlgorithmIdentifier 33 + } 34 + 35 + DigestAlgorithmIdentifier ::= SEQUENCE { 36 + algorithm OBJECT IDENTIFIER ({ pkcs7_note_OID }), 37 + parameters ANY OPTIONAL 38 + } 39 + 40 + -- 41 + -- Certificates and certificate lists 42 + -- 43 + ExtendedCertificatesAndCertificates ::= SET OF ExtendedCertificateOrCertificate 44 + 45 + ExtendedCertificateOrCertificate ::= CHOICE { 46 + certificate Certificate, -- X.509 47 + extendedCertificate [0] IMPLICIT ExtendedCertificate -- PKCS#6 48 + } 49 + 50 + ExtendedCertificate ::= Certificate -- cheating 51 + 52 + Certificates ::= SEQUENCE OF Certificate 53 + 54 + CertificateRevocationLists ::= SET OF CertificateList 55 + 56 + CertificateList ::= SEQUENCE OF Certificate -- This may be defined incorrectly 57 + 58 + CRLSequence ::= SEQUENCE OF CertificateList 59 + 60 + Certificate ::= ANY ({ pkcs7_extract_cert }) -- X.509 61 + 62 + -- 63 + -- Signer information 64 + -- 65 + SignerInfos ::= CHOICE { 66 + siSet SET OF SignerInfo, 67 + siSequence SEQUENCE OF SignerInfo 68 + } 69 + 70 + SignerInfo ::= SEQUENCE { 71 + version INTEGER, 72 + issuerAndSerialNumber IssuerAndSerialNumber, 73 + digestAlgorithm DigestAlgorithmIdentifier ({ pkcs7_sig_note_digest_algo }), 74 + authenticatedAttributes CHOICE { 75 + aaSet [0] IMPLICIT SetOfAuthenticatedAttribute 76 + ({ pkcs7_sig_note_set_of_authattrs }), 77 + aaSequence [2] EXPLICIT SEQUENCE OF AuthenticatedAttribute 78 + -- Explicit because easier to compute digest on 79 + -- sequence of attributes and then reuse encoded 80 + -- sequence in aaSequence. 81 + } OPTIONAL, 82 + digestEncryptionAlgorithm 83 + DigestEncryptionAlgorithmIdentifier ({ pkcs7_sig_note_pkey_algo }), 84 + encryptedDigest EncryptedDigest, 85 + unauthenticatedAttributes CHOICE { 86 + uaSet [1] IMPLICIT SET OF UnauthenticatedAttribute, 87 + uaSequence [3] IMPLICIT SEQUENCE OF UnauthenticatedAttribute 88 + } OPTIONAL 89 + } ({ pkcs7_note_signed_info }) 90 + 91 + IssuerAndSerialNumber ::= SEQUENCE { 92 + issuer Name ({ pkcs7_sig_note_issuer }), 93 + serialNumber CertificateSerialNumber ({ pkcs7_sig_note_serial }) 94 + } 95 + 96 + CertificateSerialNumber ::= INTEGER 97 + 98 + SetOfAuthenticatedAttribute ::= SET OF AuthenticatedAttribute 99 + 100 + AuthenticatedAttribute ::= SEQUENCE { 101 + type OBJECT IDENTIFIER ({ pkcs7_note_OID }), 102 + values SET OF ANY ({ pkcs7_sig_note_authenticated_attr }) 103 + } 104 + 105 + UnauthenticatedAttribute ::= SEQUENCE { 106 + type OBJECT IDENTIFIER ({ pkcs7_note_OID }), 107 + values SET OF ANY 108 + } 109 + 110 + DigestEncryptionAlgorithmIdentifier ::= SEQUENCE { 111 + algorithm OBJECT IDENTIFIER ({ pkcs7_note_OID }), 112 + parameters ANY OPTIONAL 113 + } 114 + 115 + EncryptedDigest ::= OCTET STRING ({ pkcs7_sig_note_signature }) 116 + 117 + --- 118 + --- X.500 Name 119 + --- 120 + Name ::= SEQUENCE OF RelativeDistinguishedName 121 + 122 + RelativeDistinguishedName ::= SET OF AttributeValueAssertion 123 + 124 + AttributeValueAssertion ::= SEQUENCE { 125 + attributeType OBJECT IDENTIFIER ({ pkcs7_note_OID }), 126 + attributeValue ANY 127 + }
+100
crypto/asymmetric_keys/pkcs7_key_type.c
··· 1 + /* Testing module to load key from trusted PKCS#7 message 2 + * 3 + * Copyright (C) 2014 Red Hat, Inc. All Rights Reserved. 4 + * Written by David Howells (dhowells@redhat.com) 5 + * 6 + * This program is free software; you can redistribute it and/or 7 + * modify it under the terms of the GNU General Public Licence 8 + * as published by the Free Software Foundation; either version 9 + * 2 of the Licence, or (at your option) any later version. 10 + */ 11 + 12 + #define pr_fmt(fmt) "PKCS7key: "fmt 13 + #include <linux/key.h> 14 + #include <linux/err.h> 15 + #include <linux/key-type.h> 16 + #include <crypto/pkcs7.h> 17 + #include <keys/user-type.h> 18 + #include <keys/system_keyring.h> 19 + #include "pkcs7_parser.h" 20 + 21 + /* 22 + * Preparse a PKCS#7 wrapped and validated data blob. 23 + */ 24 + static int pkcs7_preparse(struct key_preparsed_payload *prep) 25 + { 26 + struct pkcs7_message *pkcs7; 27 + const void *data, *saved_prep_data; 28 + size_t datalen, saved_prep_datalen; 29 + bool trusted; 30 + int ret; 31 + 32 + kenter(""); 33 + 34 + saved_prep_data = prep->data; 35 + saved_prep_datalen = prep->datalen; 36 + pkcs7 = pkcs7_parse_message(saved_prep_data, saved_prep_datalen); 37 + if (IS_ERR(pkcs7)) { 38 + ret = PTR_ERR(pkcs7); 39 + goto error; 40 + } 41 + 42 + ret = pkcs7_verify(pkcs7); 43 + if (ret < 0) 44 + goto error_free; 45 + 46 + ret = pkcs7_validate_trust(pkcs7, system_trusted_keyring, &trusted); 47 + if (ret < 0) 48 + goto error_free; 49 + if (!trusted) 50 + pr_warn("PKCS#7 message doesn't chain back to a trusted key\n"); 51 + 52 + ret = pkcs7_get_content_data(pkcs7, &data, &datalen, false); 53 + if (ret < 0) 54 + goto error_free; 55 + 56 + prep->data = data; 57 + prep->datalen = datalen; 58 + ret = user_preparse(prep); 59 + prep->data = saved_prep_data; 60 + prep->datalen = saved_prep_datalen; 61 + 62 + error_free: 63 + pkcs7_free_message(pkcs7); 64 + error: 65 + kleave(" = %d", ret); 66 + return ret; 67 + } 68 + 69 + /* 70 + * user defined keys take an arbitrary string as the description and an 71 + * arbitrary blob of data as the payload 72 + */ 73 + static struct key_type key_type_pkcs7 = { 74 + .name = "pkcs7_test", 75 + .def_lookup_type = KEYRING_SEARCH_LOOKUP_DIRECT, 76 + .preparse = pkcs7_preparse, 77 + .free_preparse = user_free_preparse, 78 + .instantiate = generic_key_instantiate, 79 + .match = user_match, 80 + .revoke = user_revoke, 81 + .destroy = user_destroy, 82 + .describe = user_describe, 83 + .read = user_read, 84 + }; 85 + 86 + /* 87 + * Module stuff 88 + */ 89 + static int __init pkcs7_key_init(void) 90 + { 91 + return register_key_type(&key_type_pkcs7); 92 + } 93 + 94 + static void __exit pkcs7_key_cleanup(void) 95 + { 96 + unregister_key_type(&key_type_pkcs7); 97 + } 98 + 99 + module_init(pkcs7_key_init); 100 + module_exit(pkcs7_key_cleanup);
+396
crypto/asymmetric_keys/pkcs7_parser.c
··· 1 + /* PKCS#7 parser 2 + * 3 + * Copyright (C) 2012 Red Hat, Inc. All Rights Reserved. 4 + * Written by David Howells (dhowells@redhat.com) 5 + * 6 + * This program is free software; you can redistribute it and/or 7 + * modify it under the terms of the GNU General Public Licence 8 + * as published by the Free Software Foundation; either version 9 + * 2 of the Licence, or (at your option) any later version. 10 + */ 11 + 12 + #define pr_fmt(fmt) "PKCS7: "fmt 13 + #include <linux/kernel.h> 14 + #include <linux/export.h> 15 + #include <linux/slab.h> 16 + #include <linux/err.h> 17 + #include <linux/oid_registry.h> 18 + #include "public_key.h" 19 + #include "pkcs7_parser.h" 20 + #include "pkcs7-asn1.h" 21 + 22 + struct pkcs7_parse_context { 23 + struct pkcs7_message *msg; /* Message being constructed */ 24 + struct pkcs7_signed_info *sinfo; /* SignedInfo being constructed */ 25 + struct pkcs7_signed_info **ppsinfo; 26 + struct x509_certificate *certs; /* Certificate cache */ 27 + struct x509_certificate **ppcerts; 28 + unsigned long data; /* Start of data */ 29 + enum OID last_oid; /* Last OID encountered */ 30 + unsigned x509_index; 31 + unsigned sinfo_index; 32 + }; 33 + 34 + /** 35 + * pkcs7_free_message - Free a PKCS#7 message 36 + * @pkcs7: The PKCS#7 message to free 37 + */ 38 + void pkcs7_free_message(struct pkcs7_message *pkcs7) 39 + { 40 + struct x509_certificate *cert; 41 + struct pkcs7_signed_info *sinfo; 42 + 43 + if (pkcs7) { 44 + while (pkcs7->certs) { 45 + cert = pkcs7->certs; 46 + pkcs7->certs = cert->next; 47 + x509_free_certificate(cert); 48 + } 49 + while (pkcs7->crl) { 50 + cert = pkcs7->crl; 51 + pkcs7->crl = cert->next; 52 + x509_free_certificate(cert); 53 + } 54 + while (pkcs7->signed_infos) { 55 + sinfo = pkcs7->signed_infos; 56 + pkcs7->signed_infos = sinfo->next; 57 + mpi_free(sinfo->sig.mpi[0]); 58 + kfree(sinfo->sig.digest); 59 + kfree(sinfo); 60 + } 61 + kfree(pkcs7); 62 + } 63 + } 64 + EXPORT_SYMBOL_GPL(pkcs7_free_message); 65 + 66 + /** 67 + * pkcs7_parse_message - Parse a PKCS#7 message 68 + * @data: The raw binary ASN.1 encoded message to be parsed 69 + * @datalen: The size of the encoded message 70 + */ 71 + struct pkcs7_message *pkcs7_parse_message(const void *data, size_t datalen) 72 + { 73 + struct pkcs7_parse_context *ctx; 74 + struct pkcs7_message *msg; 75 + long ret; 76 + 77 + ret = -ENOMEM; 78 + msg = kzalloc(sizeof(struct pkcs7_message), GFP_KERNEL); 79 + if (!msg) 80 + goto error_no_sig; 81 + ctx = kzalloc(sizeof(struct pkcs7_parse_context), GFP_KERNEL); 82 + if (!ctx) 83 + goto error_no_ctx; 84 + ctx->sinfo = kzalloc(sizeof(struct pkcs7_signed_info), GFP_KERNEL); 85 + if (!ctx->sinfo) 86 + goto error_no_sinfo; 87 + 88 + ctx->msg = msg; 89 + ctx->data = (unsigned long)data; 90 + ctx->ppcerts = &ctx->certs; 91 + ctx->ppsinfo = &ctx->msg->signed_infos; 92 + 93 + /* Attempt to decode the signature */ 94 + ret = asn1_ber_decoder(&pkcs7_decoder, ctx, data, datalen); 95 + if (ret < 0) 96 + goto error_decode; 97 + 98 + while (ctx->certs) { 99 + struct x509_certificate *cert = ctx->certs; 100 + ctx->certs = cert->next; 101 + x509_free_certificate(cert); 102 + } 103 + mpi_free(ctx->sinfo->sig.mpi[0]); 104 + kfree(ctx->sinfo->sig.digest); 105 + kfree(ctx->sinfo); 106 + kfree(ctx); 107 + return msg; 108 + 109 + error_decode: 110 + mpi_free(ctx->sinfo->sig.mpi[0]); 111 + kfree(ctx->sinfo->sig.digest); 112 + kfree(ctx->sinfo); 113 + error_no_sinfo: 114 + kfree(ctx); 115 + error_no_ctx: 116 + pkcs7_free_message(msg); 117 + error_no_sig: 118 + return ERR_PTR(ret); 119 + } 120 + EXPORT_SYMBOL_GPL(pkcs7_parse_message); 121 + 122 + /** 123 + * pkcs7_get_content_data - Get access to the PKCS#7 content 124 + * @pkcs7: The preparsed PKCS#7 message to access 125 + * @_data: Place to return a pointer to the data 126 + * @_data_len: Place to return the data length 127 + * @want_wrapper: True if the ASN.1 object header should be included in the data 128 + * 129 + * Get access to the data content of the PKCS#7 message, including, optionally, 130 + * the header of the ASN.1 object that contains it. Returns -ENODATA if the 131 + * data object was missing from the message. 132 + */ 133 + int pkcs7_get_content_data(const struct pkcs7_message *pkcs7, 134 + const void **_data, size_t *_data_len, 135 + bool want_wrapper) 136 + { 137 + size_t wrapper; 138 + 139 + if (!pkcs7->data) 140 + return -ENODATA; 141 + 142 + wrapper = want_wrapper ? pkcs7->data_hdrlen : 0; 143 + *_data = pkcs7->data - wrapper; 144 + *_data_len = pkcs7->data_len + wrapper; 145 + return 0; 146 + } 147 + EXPORT_SYMBOL_GPL(pkcs7_get_content_data); 148 + 149 + /* 150 + * Note an OID when we find one for later processing when we know how 151 + * to interpret it. 152 + */ 153 + int pkcs7_note_OID(void *context, size_t hdrlen, 154 + unsigned char tag, 155 + const void *value, size_t vlen) 156 + { 157 + struct pkcs7_parse_context *ctx = context; 158 + 159 + ctx->last_oid = look_up_OID(value, vlen); 160 + if (ctx->last_oid == OID__NR) { 161 + char buffer[50]; 162 + sprint_oid(value, vlen, buffer, sizeof(buffer)); 163 + printk("PKCS7: Unknown OID: [%lu] %s\n", 164 + (unsigned long)value - ctx->data, buffer); 165 + } 166 + return 0; 167 + } 168 + 169 + /* 170 + * Note the digest algorithm for the signature. 171 + */ 172 + int pkcs7_sig_note_digest_algo(void *context, size_t hdrlen, 173 + unsigned char tag, 174 + const void *value, size_t vlen) 175 + { 176 + struct pkcs7_parse_context *ctx = context; 177 + 178 + switch (ctx->last_oid) { 179 + case OID_md4: 180 + ctx->sinfo->sig.pkey_hash_algo = HASH_ALGO_MD4; 181 + break; 182 + case OID_md5: 183 + ctx->sinfo->sig.pkey_hash_algo = HASH_ALGO_MD5; 184 + break; 185 + case OID_sha1: 186 + ctx->sinfo->sig.pkey_hash_algo = HASH_ALGO_SHA1; 187 + break; 188 + case OID_sha256: 189 + ctx->sinfo->sig.pkey_hash_algo = HASH_ALGO_SHA256; 190 + break; 191 + default: 192 + printk("Unsupported digest algo: %u\n", ctx->last_oid); 193 + return -ENOPKG; 194 + } 195 + return 0; 196 + } 197 + 198 + /* 199 + * Note the public key algorithm for the signature. 200 + */ 201 + int pkcs7_sig_note_pkey_algo(void *context, size_t hdrlen, 202 + unsigned char tag, 203 + const void *value, size_t vlen) 204 + { 205 + struct pkcs7_parse_context *ctx = context; 206 + 207 + switch (ctx->last_oid) { 208 + case OID_rsaEncryption: 209 + ctx->sinfo->sig.pkey_algo = PKEY_ALGO_RSA; 210 + break; 211 + default: 212 + printk("Unsupported pkey algo: %u\n", ctx->last_oid); 213 + return -ENOPKG; 214 + } 215 + return 0; 216 + } 217 + 218 + /* 219 + * Extract a certificate and store it in the context. 220 + */ 221 + int pkcs7_extract_cert(void *context, size_t hdrlen, 222 + unsigned char tag, 223 + const void *value, size_t vlen) 224 + { 225 + struct pkcs7_parse_context *ctx = context; 226 + struct x509_certificate *x509; 227 + 228 + if (tag != ((ASN1_UNIV << 6) | ASN1_CONS_BIT | ASN1_SEQ)) { 229 + pr_debug("Cert began with tag %02x at %lu\n", 230 + tag, (unsigned long)ctx - ctx->data); 231 + return -EBADMSG; 232 + } 233 + 234 + /* We have to correct for the header so that the X.509 parser can start 235 + * from the beginning. Note that since X.509 stipulates DER, there 236 + * probably shouldn't be an EOC trailer - but it is in PKCS#7 (which 237 + * stipulates BER). 238 + */ 239 + value -= hdrlen; 240 + vlen += hdrlen; 241 + 242 + if (((u8*)value)[1] == 0x80) 243 + vlen += 2; /* Indefinite length - there should be an EOC */ 244 + 245 + x509 = x509_cert_parse(value, vlen); 246 + if (IS_ERR(x509)) 247 + return PTR_ERR(x509); 248 + 249 + pr_debug("Got cert for %s\n", x509->subject); 250 + pr_debug("- fingerprint %s\n", x509->fingerprint); 251 + 252 + x509->index = ++ctx->x509_index; 253 + *ctx->ppcerts = x509; 254 + ctx->ppcerts = &x509->next; 255 + return 0; 256 + } 257 + 258 + /* 259 + * Save the certificate list 260 + */ 261 + int pkcs7_note_certificate_list(void *context, size_t hdrlen, 262 + unsigned char tag, 263 + const void *value, size_t vlen) 264 + { 265 + struct pkcs7_parse_context *ctx = context; 266 + 267 + pr_devel("Got cert list (%02x)\n", tag); 268 + 269 + *ctx->ppcerts = ctx->msg->certs; 270 + ctx->msg->certs = ctx->certs; 271 + ctx->certs = NULL; 272 + ctx->ppcerts = &ctx->certs; 273 + return 0; 274 + } 275 + 276 + /* 277 + * Extract the data from the message and store that and its content type OID in 278 + * the context. 279 + */ 280 + int pkcs7_note_data(void *context, size_t hdrlen, 281 + unsigned char tag, 282 + const void *value, size_t vlen) 283 + { 284 + struct pkcs7_parse_context *ctx = context; 285 + 286 + pr_debug("Got data\n"); 287 + 288 + ctx->msg->data = value; 289 + ctx->msg->data_len = vlen; 290 + ctx->msg->data_hdrlen = hdrlen; 291 + ctx->msg->data_type = ctx->last_oid; 292 + return 0; 293 + } 294 + 295 + /* 296 + * Parse authenticated attributes 297 + */ 298 + int pkcs7_sig_note_authenticated_attr(void *context, size_t hdrlen, 299 + unsigned char tag, 300 + const void *value, size_t vlen) 301 + { 302 + struct pkcs7_parse_context *ctx = context; 303 + 304 + pr_devel("AuthAttr: %02x %zu [%*ph]\n", tag, vlen, (unsigned)vlen, value); 305 + 306 + switch (ctx->last_oid) { 307 + case OID_messageDigest: 308 + if (tag != ASN1_OTS) 309 + return -EBADMSG; 310 + ctx->sinfo->msgdigest = value; 311 + ctx->sinfo->msgdigest_len = vlen; 312 + return 0; 313 + default: 314 + return 0; 315 + } 316 + } 317 + 318 + /* 319 + * Note the set of auth attributes for digestion purposes [RFC2315 9.3] 320 + */ 321 + int pkcs7_sig_note_set_of_authattrs(void *context, size_t hdrlen, 322 + unsigned char tag, 323 + const void *value, size_t vlen) 324 + { 325 + struct pkcs7_parse_context *ctx = context; 326 + 327 + /* We need to switch the 'CONT 0' to a 'SET OF' when we digest */ 328 + ctx->sinfo->authattrs = value - (hdrlen - 1); 329 + ctx->sinfo->authattrs_len = vlen + (hdrlen - 1); 330 + return 0; 331 + } 332 + 333 + /* 334 + * Note the issuing certificate serial number 335 + */ 336 + int pkcs7_sig_note_serial(void *context, size_t hdrlen, 337 + unsigned char tag, 338 + const void *value, size_t vlen) 339 + { 340 + struct pkcs7_parse_context *ctx = context; 341 + ctx->sinfo->raw_serial = value; 342 + ctx->sinfo->raw_serial_size = vlen; 343 + return 0; 344 + } 345 + 346 + /* 347 + * Note the issuer's name 348 + */ 349 + int pkcs7_sig_note_issuer(void *context, size_t hdrlen, 350 + unsigned char tag, 351 + const void *value, size_t vlen) 352 + { 353 + struct pkcs7_parse_context *ctx = context; 354 + ctx->sinfo->raw_issuer = value; 355 + ctx->sinfo->raw_issuer_size = vlen; 356 + return 0; 357 + } 358 + 359 + /* 360 + * Note the signature data 361 + */ 362 + int pkcs7_sig_note_signature(void *context, size_t hdrlen, 363 + unsigned char tag, 364 + const void *value, size_t vlen) 365 + { 366 + struct pkcs7_parse_context *ctx = context; 367 + MPI mpi; 368 + 369 + BUG_ON(ctx->sinfo->sig.pkey_algo != PKEY_ALGO_RSA); 370 + 371 + mpi = mpi_read_raw_data(value, vlen); 372 + if (!mpi) 373 + return -ENOMEM; 374 + 375 + ctx->sinfo->sig.mpi[0] = mpi; 376 + ctx->sinfo->sig.nr_mpi = 1; 377 + return 0; 378 + } 379 + 380 + /* 381 + * Note a signature information block 382 + */ 383 + int pkcs7_note_signed_info(void *context, size_t hdrlen, 384 + unsigned char tag, 385 + const void *value, size_t vlen) 386 + { 387 + struct pkcs7_parse_context *ctx = context; 388 + 389 + ctx->sinfo->index = ++ctx->sinfo_index; 390 + *ctx->ppsinfo = ctx->sinfo; 391 + ctx->ppsinfo = &ctx->sinfo->next; 392 + ctx->sinfo = kzalloc(sizeof(struct pkcs7_signed_info), GFP_KERNEL); 393 + if (!ctx->sinfo) 394 + return -ENOMEM; 395 + return 0; 396 + }
+61
crypto/asymmetric_keys/pkcs7_parser.h
··· 1 + /* PKCS#7 crypto data parser internal definitions 2 + * 3 + * Copyright (C) 2012 Red Hat, Inc. All Rights Reserved. 4 + * Written by David Howells (dhowells@redhat.com) 5 + * 6 + * This program is free software; you can redistribute it and/or 7 + * modify it under the terms of the GNU General Public Licence 8 + * as published by the Free Software Foundation; either version 9 + * 2 of the Licence, or (at your option) any later version. 10 + */ 11 + 12 + #include <linux/oid_registry.h> 13 + #include <crypto/pkcs7.h> 14 + #include "x509_parser.h" 15 + 16 + #define kenter(FMT, ...) \ 17 + pr_devel("==> %s("FMT")\n", __func__, ##__VA_ARGS__) 18 + #define kleave(FMT, ...) \ 19 + pr_devel("<== %s()"FMT"\n", __func__, ##__VA_ARGS__) 20 + 21 + struct pkcs7_signed_info { 22 + struct pkcs7_signed_info *next; 23 + struct x509_certificate *signer; /* Signing certificate (in msg->certs) */ 24 + unsigned index; 25 + bool trusted; 26 + 27 + /* Message digest - the digest of the Content Data (or NULL) */ 28 + const void *msgdigest; 29 + unsigned msgdigest_len; 30 + 31 + /* Authenticated Attribute data (or NULL) */ 32 + unsigned authattrs_len; 33 + const void *authattrs; 34 + 35 + /* Issuing cert serial number and issuer's name */ 36 + const void *raw_serial; 37 + unsigned raw_serial_size; 38 + unsigned raw_issuer_size; 39 + const void *raw_issuer; 40 + 41 + /* Message signature. 42 + * 43 + * This contains the generated digest of _either_ the Content Data or 44 + * the Authenticated Attributes [RFC2315 9.3]. If the latter, one of 45 + * the attributes contains the digest of the the Content Data within 46 + * it. 47 + */ 48 + struct public_key_signature sig; 49 + }; 50 + 51 + struct pkcs7_message { 52 + struct x509_certificate *certs; /* Certificate list */ 53 + struct x509_certificate *crl; /* Revocation list */ 54 + struct pkcs7_signed_info *signed_infos; 55 + 56 + /* Content Data (or NULL) */ 57 + enum OID data_type; /* Type of Data */ 58 + size_t data_len; /* Length of Data */ 59 + size_t data_hdrlen; /* Length of Data ASN.1 header */ 60 + const void *data; /* Content Data (or 0) */ 61 + };
+166
crypto/asymmetric_keys/pkcs7_trust.c
··· 1 + /* Validate the trust chain of a PKCS#7 message. 2 + * 3 + * Copyright (C) 2012 Red Hat, Inc. All Rights Reserved. 4 + * Written by David Howells (dhowells@redhat.com) 5 + * 6 + * This program is free software; you can redistribute it and/or 7 + * modify it under the terms of the GNU General Public Licence 8 + * as published by the Free Software Foundation; either version 9 + * 2 of the Licence, or (at your option) any later version. 10 + */ 11 + 12 + #define pr_fmt(fmt) "PKCS7: "fmt 13 + #include <linux/kernel.h> 14 + #include <linux/export.h> 15 + #include <linux/slab.h> 16 + #include <linux/err.h> 17 + #include <linux/asn1.h> 18 + #include <linux/key.h> 19 + #include <keys/asymmetric-type.h> 20 + #include "public_key.h" 21 + #include "pkcs7_parser.h" 22 + 23 + /** 24 + * Check the trust on one PKCS#7 SignedInfo block. 25 + */ 26 + int pkcs7_validate_trust_one(struct pkcs7_message *pkcs7, 27 + struct pkcs7_signed_info *sinfo, 28 + struct key *trust_keyring) 29 + { 30 + struct public_key_signature *sig = &sinfo->sig; 31 + struct x509_certificate *x509, *last = NULL, *p; 32 + struct key *key; 33 + bool trusted; 34 + int ret; 35 + 36 + kenter(",%u,", sinfo->index); 37 + 38 + for (x509 = sinfo->signer; x509; x509 = x509->signer) { 39 + if (x509->seen) { 40 + if (x509->verified) { 41 + trusted = x509->trusted; 42 + goto verified; 43 + } 44 + kleave(" = -ENOKEY [cached]"); 45 + return -ENOKEY; 46 + } 47 + x509->seen = true; 48 + 49 + /* Look to see if this certificate is present in the trusted 50 + * keys. 51 + */ 52 + key = x509_request_asymmetric_key(trust_keyring, x509->subject, 53 + x509->fingerprint); 54 + if (!IS_ERR(key)) 55 + /* One of the X.509 certificates in the PKCS#7 message 56 + * is apparently the same as one we already trust. 57 + * Verify that the trusted variant can also validate 58 + * the signature on the descendant. 59 + */ 60 + goto matched; 61 + if (key == ERR_PTR(-ENOMEM)) 62 + return -ENOMEM; 63 + 64 + /* Self-signed certificates form roots of their own, and if we 65 + * don't know them, then we can't accept them. 66 + */ 67 + if (x509->next == x509) { 68 + kleave(" = -ENOKEY [unknown self-signed]"); 69 + return -ENOKEY; 70 + } 71 + 72 + might_sleep(); 73 + last = x509; 74 + sig = &last->sig; 75 + } 76 + 77 + /* No match - see if the root certificate has a signer amongst the 78 + * trusted keys. 79 + */ 80 + if (!last || !last->issuer || !last->authority) { 81 + kleave(" = -ENOKEY [no backref]"); 82 + return -ENOKEY; 83 + } 84 + 85 + key = x509_request_asymmetric_key(trust_keyring, last->issuer, 86 + last->authority); 87 + if (IS_ERR(key)) 88 + return PTR_ERR(key) == -ENOMEM ? -ENOMEM : -ENOKEY; 89 + x509 = last; 90 + 91 + matched: 92 + ret = verify_signature(key, sig); 93 + trusted = test_bit(KEY_FLAG_TRUSTED, &key->flags); 94 + key_put(key); 95 + if (ret < 0) { 96 + if (ret == -ENOMEM) 97 + return ret; 98 + kleave(" = -EKEYREJECTED [verify %d]", ret); 99 + return -EKEYREJECTED; 100 + } 101 + 102 + verified: 103 + x509->verified = true; 104 + for (p = sinfo->signer; p != x509; p = p->signer) { 105 + p->verified = true; 106 + p->trusted = trusted; 107 + } 108 + sinfo->trusted = trusted; 109 + kleave(" = 0"); 110 + return 0; 111 + } 112 + 113 + /** 114 + * pkcs7_validate_trust - Validate PKCS#7 trust chain 115 + * @pkcs7: The PKCS#7 certificate to validate 116 + * @trust_keyring: Signing certificates to use as starting points 117 + * @_trusted: Set to true if trustworth, false otherwise 118 + * 119 + * Validate that the certificate chain inside the PKCS#7 message intersects 120 + * keys we already know and trust. 121 + * 122 + * Returns, in order of descending priority: 123 + * 124 + * (*) -EKEYREJECTED if a signature failed to match for which we have a valid 125 + * key, or: 126 + * 127 + * (*) 0 if at least one signature chain intersects with the keys in the trust 128 + * keyring, or: 129 + * 130 + * (*) -ENOPKG if a suitable crypto module couldn't be found for a check on a 131 + * chain. 132 + * 133 + * (*) -ENOKEY if we couldn't find a match for any of the signature chains in 134 + * the message. 135 + * 136 + * May also return -ENOMEM. 137 + */ 138 + int pkcs7_validate_trust(struct pkcs7_message *pkcs7, 139 + struct key *trust_keyring, 140 + bool *_trusted) 141 + { 142 + struct pkcs7_signed_info *sinfo; 143 + struct x509_certificate *p; 144 + int cached_ret = 0, ret; 145 + 146 + for (p = pkcs7->certs; p; p = p->next) 147 + p->seen = false; 148 + 149 + for (sinfo = pkcs7->signed_infos; sinfo; sinfo = sinfo->next) { 150 + ret = pkcs7_validate_trust_one(pkcs7, sinfo, trust_keyring); 151 + if (ret < 0) { 152 + if (ret == -ENOPKG) { 153 + cached_ret = -ENOPKG; 154 + } else if (ret == -ENOKEY) { 155 + if (cached_ret == 0) 156 + cached_ret = -ENOKEY; 157 + } else { 158 + return ret; 159 + } 160 + } 161 + *_trusted |= sinfo->trusted; 162 + } 163 + 164 + return cached_ret; 165 + } 166 + EXPORT_SYMBOL_GPL(pkcs7_validate_trust);
+321
crypto/asymmetric_keys/pkcs7_verify.c
··· 1 + /* Verify the signature on a PKCS#7 message. 2 + * 3 + * Copyright (C) 2012 Red Hat, Inc. All Rights Reserved. 4 + * Written by David Howells (dhowells@redhat.com) 5 + * 6 + * This program is free software; you can redistribute it and/or 7 + * modify it under the terms of the GNU General Public Licence 8 + * as published by the Free Software Foundation; either version 9 + * 2 of the Licence, or (at your option) any later version. 10 + */ 11 + 12 + #define pr_fmt(fmt) "PKCS7: "fmt 13 + #include <linux/kernel.h> 14 + #include <linux/export.h> 15 + #include <linux/slab.h> 16 + #include <linux/err.h> 17 + #include <linux/asn1.h> 18 + #include <crypto/hash.h> 19 + #include "public_key.h" 20 + #include "pkcs7_parser.h" 21 + 22 + /* 23 + * Digest the relevant parts of the PKCS#7 data 24 + */ 25 + static int pkcs7_digest(struct pkcs7_message *pkcs7, 26 + struct pkcs7_signed_info *sinfo) 27 + { 28 + struct crypto_shash *tfm; 29 + struct shash_desc *desc; 30 + size_t digest_size, desc_size; 31 + void *digest; 32 + int ret; 33 + 34 + kenter(",%u,%u", sinfo->index, sinfo->sig.pkey_hash_algo); 35 + 36 + if (sinfo->sig.pkey_hash_algo >= PKEY_HASH__LAST || 37 + !hash_algo_name[sinfo->sig.pkey_hash_algo]) 38 + return -ENOPKG; 39 + 40 + /* Allocate the hashing algorithm we're going to need and find out how 41 + * big the hash operational data will be. 42 + */ 43 + tfm = crypto_alloc_shash(hash_algo_name[sinfo->sig.pkey_hash_algo], 44 + 0, 0); 45 + if (IS_ERR(tfm)) 46 + return (PTR_ERR(tfm) == -ENOENT) ? -ENOPKG : PTR_ERR(tfm); 47 + 48 + desc_size = crypto_shash_descsize(tfm) + sizeof(*desc); 49 + sinfo->sig.digest_size = digest_size = crypto_shash_digestsize(tfm); 50 + 51 + ret = -ENOMEM; 52 + digest = kzalloc(digest_size + desc_size, GFP_KERNEL); 53 + if (!digest) 54 + goto error_no_desc; 55 + 56 + desc = digest + digest_size; 57 + desc->tfm = tfm; 58 + desc->flags = CRYPTO_TFM_REQ_MAY_SLEEP; 59 + 60 + /* Digest the message [RFC2315 9.3] */ 61 + ret = crypto_shash_init(desc); 62 + if (ret < 0) 63 + goto error; 64 + ret = crypto_shash_finup(desc, pkcs7->data, pkcs7->data_len, digest); 65 + if (ret < 0) 66 + goto error; 67 + pr_devel("MsgDigest = [%*ph]\n", 8, digest); 68 + 69 + /* However, if there are authenticated attributes, there must be a 70 + * message digest attribute amongst them which corresponds to the 71 + * digest we just calculated. 72 + */ 73 + if (sinfo->msgdigest) { 74 + u8 tag; 75 + 76 + if (sinfo->msgdigest_len != sinfo->sig.digest_size) { 77 + pr_debug("Sig %u: Invalid digest size (%u)\n", 78 + sinfo->index, sinfo->msgdigest_len); 79 + ret = -EBADMSG; 80 + goto error; 81 + } 82 + 83 + if (memcmp(digest, sinfo->msgdigest, sinfo->msgdigest_len) != 0) { 84 + pr_debug("Sig %u: Message digest doesn't match\n", 85 + sinfo->index); 86 + ret = -EKEYREJECTED; 87 + goto error; 88 + } 89 + 90 + /* We then calculate anew, using the authenticated attributes 91 + * as the contents of the digest instead. Note that we need to 92 + * convert the attributes from a CONT.0 into a SET before we 93 + * hash it. 94 + */ 95 + memset(digest, 0, sinfo->sig.digest_size); 96 + 97 + ret = crypto_shash_init(desc); 98 + if (ret < 0) 99 + goto error; 100 + tag = ASN1_CONS_BIT | ASN1_SET; 101 + ret = crypto_shash_update(desc, &tag, 1); 102 + if (ret < 0) 103 + goto error; 104 + ret = crypto_shash_finup(desc, sinfo->authattrs, 105 + sinfo->authattrs_len, digest); 106 + if (ret < 0) 107 + goto error; 108 + pr_devel("AADigest = [%*ph]\n", 8, digest); 109 + } 110 + 111 + sinfo->sig.digest = digest; 112 + digest = NULL; 113 + 114 + error: 115 + kfree(digest); 116 + error_no_desc: 117 + crypto_free_shash(tfm); 118 + kleave(" = %d", ret); 119 + return ret; 120 + } 121 + 122 + /* 123 + * Find the key (X.509 certificate) to use to verify a PKCS#7 message. PKCS#7 124 + * uses the issuer's name and the issuing certificate serial number for 125 + * matching purposes. These must match the certificate issuer's name (not 126 + * subject's name) and the certificate serial number [RFC 2315 6.7]. 127 + */ 128 + static int pkcs7_find_key(struct pkcs7_message *pkcs7, 129 + struct pkcs7_signed_info *sinfo) 130 + { 131 + struct x509_certificate *x509; 132 + unsigned certix = 1; 133 + 134 + kenter("%u,%u,%u", 135 + sinfo->index, sinfo->raw_serial_size, sinfo->raw_issuer_size); 136 + 137 + for (x509 = pkcs7->certs; x509; x509 = x509->next, certix++) { 138 + /* I'm _assuming_ that the generator of the PKCS#7 message will 139 + * encode the fields from the X.509 cert in the same way in the 140 + * PKCS#7 message - but I can't be 100% sure of that. It's 141 + * possible this will need element-by-element comparison. 142 + */ 143 + if (x509->raw_serial_size != sinfo->raw_serial_size || 144 + memcmp(x509->raw_serial, sinfo->raw_serial, 145 + sinfo->raw_serial_size) != 0) 146 + continue; 147 + pr_devel("Sig %u: Found cert serial match X.509[%u]\n", 148 + sinfo->index, certix); 149 + 150 + if (x509->raw_issuer_size != sinfo->raw_issuer_size || 151 + memcmp(x509->raw_issuer, sinfo->raw_issuer, 152 + sinfo->raw_issuer_size) != 0) { 153 + pr_warn("Sig %u: X.509 subject and PKCS#7 issuer don't match\n", 154 + sinfo->index); 155 + continue; 156 + } 157 + 158 + if (x509->pub->pkey_algo != sinfo->sig.pkey_algo) { 159 + pr_warn("Sig %u: X.509 algo and PKCS#7 sig algo don't match\n", 160 + sinfo->index); 161 + continue; 162 + } 163 + 164 + sinfo->signer = x509; 165 + return 0; 166 + } 167 + pr_warn("Sig %u: Issuing X.509 cert not found (#%*ph)\n", 168 + sinfo->index, sinfo->raw_serial_size, sinfo->raw_serial); 169 + return -ENOKEY; 170 + } 171 + 172 + /* 173 + * Verify the internal certificate chain as best we can. 174 + */ 175 + static int pkcs7_verify_sig_chain(struct pkcs7_message *pkcs7, 176 + struct pkcs7_signed_info *sinfo) 177 + { 178 + struct x509_certificate *x509 = sinfo->signer, *p; 179 + int ret; 180 + 181 + kenter(""); 182 + 183 + for (p = pkcs7->certs; p; p = p->next) 184 + p->seen = false; 185 + 186 + for (;;) { 187 + pr_debug("verify %s: %s\n", x509->subject, x509->fingerprint); 188 + x509->seen = true; 189 + ret = x509_get_sig_params(x509); 190 + if (ret < 0) 191 + return ret; 192 + 193 + pr_debug("- issuer %s\n", x509->issuer); 194 + if (x509->authority) 195 + pr_debug("- authkeyid %s\n", x509->authority); 196 + 197 + if (!x509->authority || 198 + strcmp(x509->subject, x509->issuer) == 0) { 199 + /* If there's no authority certificate specified, then 200 + * the certificate must be self-signed and is the root 201 + * of the chain. Likewise if the cert is its own 202 + * authority. 203 + */ 204 + pr_debug("- no auth?\n"); 205 + if (x509->raw_subject_size != x509->raw_issuer_size || 206 + memcmp(x509->raw_subject, x509->raw_issuer, 207 + x509->raw_issuer_size) != 0) 208 + return 0; 209 + 210 + ret = x509_check_signature(x509->pub, x509); 211 + if (ret < 0) 212 + return ret; 213 + x509->signer = x509; 214 + pr_debug("- self-signed\n"); 215 + return 0; 216 + } 217 + 218 + /* Look through the X.509 certificates in the PKCS#7 message's 219 + * list to see if the next one is there. 220 + */ 221 + pr_debug("- want %s\n", x509->authority); 222 + for (p = pkcs7->certs; p; p = p->next) { 223 + pr_debug("- cmp [%u] %s\n", p->index, p->fingerprint); 224 + if (p->raw_subject_size == x509->raw_issuer_size && 225 + strcmp(p->fingerprint, x509->authority) == 0 && 226 + memcmp(p->raw_subject, x509->raw_issuer, 227 + x509->raw_issuer_size) == 0) 228 + goto found_issuer; 229 + } 230 + 231 + /* We didn't find the root of this chain */ 232 + pr_debug("- top\n"); 233 + return 0; 234 + 235 + found_issuer: 236 + pr_debug("- issuer %s\n", p->subject); 237 + if (p->seen) { 238 + pr_warn("Sig %u: X.509 chain contains loop\n", 239 + sinfo->index); 240 + return 0; 241 + } 242 + ret = x509_check_signature(p->pub, x509); 243 + if (ret < 0) 244 + return ret; 245 + x509->signer = p; 246 + if (x509 == p) { 247 + pr_debug("- self-signed\n"); 248 + return 0; 249 + } 250 + x509 = p; 251 + might_sleep(); 252 + } 253 + } 254 + 255 + /* 256 + * Verify one signed information block from a PKCS#7 message. 257 + */ 258 + static int pkcs7_verify_one(struct pkcs7_message *pkcs7, 259 + struct pkcs7_signed_info *sinfo) 260 + { 261 + int ret; 262 + 263 + kenter(",%u", sinfo->index); 264 + 265 + /* First of all, digest the data in the PKCS#7 message and the 266 + * signed information block 267 + */ 268 + ret = pkcs7_digest(pkcs7, sinfo); 269 + if (ret < 0) 270 + return ret; 271 + 272 + /* Find the key for the signature */ 273 + ret = pkcs7_find_key(pkcs7, sinfo); 274 + if (ret < 0) 275 + return ret; 276 + 277 + pr_devel("Using X.509[%u] for sig %u\n", 278 + sinfo->signer->index, sinfo->index); 279 + 280 + /* Verify the PKCS#7 binary against the key */ 281 + ret = public_key_verify_signature(sinfo->signer->pub, &sinfo->sig); 282 + if (ret < 0) 283 + return ret; 284 + 285 + pr_devel("Verified signature %u\n", sinfo->index); 286 + 287 + /* Verify the internal certificate chain */ 288 + return pkcs7_verify_sig_chain(pkcs7, sinfo); 289 + } 290 + 291 + /** 292 + * pkcs7_verify - Verify a PKCS#7 message 293 + * @pkcs7: The PKCS#7 message to be verified 294 + */ 295 + int pkcs7_verify(struct pkcs7_message *pkcs7) 296 + { 297 + struct pkcs7_signed_info *sinfo; 298 + struct x509_certificate *x509; 299 + int ret, n; 300 + 301 + kenter(""); 302 + 303 + for (n = 0, x509 = pkcs7->certs; x509; x509 = x509->next, n++) { 304 + ret = x509_get_sig_params(x509); 305 + if (ret < 0) 306 + return ret; 307 + pr_debug("X.509[%u] %s\n", n, x509->authority); 308 + } 309 + 310 + for (sinfo = pkcs7->signed_infos; sinfo; sinfo = sinfo->next) { 311 + ret = pkcs7_verify_one(pkcs7, sinfo); 312 + if (ret < 0) { 313 + kleave(" = %d", ret); 314 + return ret; 315 + } 316 + } 317 + 318 + kleave(" = 0"); 319 + return 0; 320 + } 321 + EXPORT_SYMBOL_GPL(pkcs7_verify);
+457
crypto/asymmetric_keys/verify_pefile.c
··· 1 + /* Parse a signed PE binary 2 + * 3 + * Copyright (C) 2014 Red Hat, Inc. All Rights Reserved. 4 + * Written by David Howells (dhowells@redhat.com) 5 + * 6 + * This program is free software; you can redistribute it and/or 7 + * modify it under the terms of the GNU General Public Licence 8 + * as published by the Free Software Foundation; either version 9 + * 2 of the Licence, or (at your option) any later version. 10 + */ 11 + 12 + #define pr_fmt(fmt) "PEFILE: "fmt 13 + #include <linux/module.h> 14 + #include <linux/kernel.h> 15 + #include <linux/slab.h> 16 + #include <linux/err.h> 17 + #include <linux/pe.h> 18 + #include <linux/asn1.h> 19 + #include <crypto/pkcs7.h> 20 + #include <crypto/hash.h> 21 + #include "verify_pefile.h" 22 + 23 + /* 24 + * Parse a PE binary. 25 + */ 26 + static int pefile_parse_binary(const void *pebuf, unsigned int pelen, 27 + struct pefile_context *ctx) 28 + { 29 + const struct mz_hdr *mz = pebuf; 30 + const struct pe_hdr *pe; 31 + const struct pe32_opt_hdr *pe32; 32 + const struct pe32plus_opt_hdr *pe64; 33 + const struct data_directory *ddir; 34 + const struct data_dirent *dde; 35 + const struct section_header *secs, *sec; 36 + size_t cursor, datalen = pelen; 37 + 38 + kenter(""); 39 + 40 + #define chkaddr(base, x, s) \ 41 + do { \ 42 + if ((x) < base || (s) >= datalen || (x) > datalen - (s)) \ 43 + return -ELIBBAD; \ 44 + } while (0) 45 + 46 + chkaddr(0, 0, sizeof(*mz)); 47 + if (mz->magic != MZ_MAGIC) 48 + return -ELIBBAD; 49 + cursor = sizeof(*mz); 50 + 51 + chkaddr(cursor, mz->peaddr, sizeof(*pe)); 52 + pe = pebuf + mz->peaddr; 53 + if (pe->magic != PE_MAGIC) 54 + return -ELIBBAD; 55 + cursor = mz->peaddr + sizeof(*pe); 56 + 57 + chkaddr(0, cursor, sizeof(pe32->magic)); 58 + pe32 = pebuf + cursor; 59 + pe64 = pebuf + cursor; 60 + 61 + switch (pe32->magic) { 62 + case PE_OPT_MAGIC_PE32: 63 + chkaddr(0, cursor, sizeof(*pe32)); 64 + ctx->image_checksum_offset = 65 + (unsigned long)&pe32->csum - (unsigned long)pebuf; 66 + ctx->header_size = pe32->header_size; 67 + cursor += sizeof(*pe32); 68 + ctx->n_data_dirents = pe32->data_dirs; 69 + break; 70 + 71 + case PE_OPT_MAGIC_PE32PLUS: 72 + chkaddr(0, cursor, sizeof(*pe64)); 73 + ctx->image_checksum_offset = 74 + (unsigned long)&pe64->csum - (unsigned long)pebuf; 75 + ctx->header_size = pe64->header_size; 76 + cursor += sizeof(*pe64); 77 + ctx->n_data_dirents = pe64->data_dirs; 78 + break; 79 + 80 + default: 81 + pr_debug("Unknown PEOPT magic = %04hx\n", pe32->magic); 82 + return -ELIBBAD; 83 + } 84 + 85 + pr_debug("checksum @ %x\n", ctx->image_checksum_offset); 86 + pr_debug("header size = %x\n", ctx->header_size); 87 + 88 + if (cursor >= ctx->header_size || ctx->header_size >= datalen) 89 + return -ELIBBAD; 90 + 91 + if (ctx->n_data_dirents > (ctx->header_size - cursor) / sizeof(*dde)) 92 + return -ELIBBAD; 93 + 94 + ddir = pebuf + cursor; 95 + cursor += sizeof(*dde) * ctx->n_data_dirents; 96 + 97 + ctx->cert_dirent_offset = 98 + (unsigned long)&ddir->certs - (unsigned long)pebuf; 99 + ctx->certs_size = ddir->certs.size; 100 + 101 + if (!ddir->certs.virtual_address || !ddir->certs.size) { 102 + pr_debug("Unsigned PE binary\n"); 103 + return -EKEYREJECTED; 104 + } 105 + 106 + chkaddr(ctx->header_size, ddir->certs.virtual_address, 107 + ddir->certs.size); 108 + ctx->sig_offset = ddir->certs.virtual_address; 109 + ctx->sig_len = ddir->certs.size; 110 + pr_debug("cert = %x @%x [%*ph]\n", 111 + ctx->sig_len, ctx->sig_offset, 112 + ctx->sig_len, pebuf + ctx->sig_offset); 113 + 114 + ctx->n_sections = pe->sections; 115 + if (ctx->n_sections > (ctx->header_size - cursor) / sizeof(*sec)) 116 + return -ELIBBAD; 117 + ctx->secs = secs = pebuf + cursor; 118 + 119 + return 0; 120 + } 121 + 122 + /* 123 + * Check and strip the PE wrapper from around the signature and check that the 124 + * remnant looks something like PKCS#7. 125 + */ 126 + static int pefile_strip_sig_wrapper(const void *pebuf, 127 + struct pefile_context *ctx) 128 + { 129 + struct win_certificate wrapper; 130 + const u8 *pkcs7; 131 + 132 + if (ctx->sig_len < sizeof(wrapper)) { 133 + pr_debug("Signature wrapper too short\n"); 134 + return -ELIBBAD; 135 + } 136 + 137 + memcpy(&wrapper, pebuf + ctx->sig_offset, sizeof(wrapper)); 138 + pr_debug("sig wrapper = { %x, %x, %x }\n", 139 + wrapper.length, wrapper.revision, wrapper.cert_type); 140 + 141 + /* Both pesign and sbsign round up the length of certificate table 142 + * (in optional header data directories) to 8 byte alignment. 143 + */ 144 + if (round_up(wrapper.length, 8) != ctx->sig_len) { 145 + pr_debug("Signature wrapper len wrong\n"); 146 + return -ELIBBAD; 147 + } 148 + if (wrapper.revision != WIN_CERT_REVISION_2_0) { 149 + pr_debug("Signature is not revision 2.0\n"); 150 + return -ENOTSUPP; 151 + } 152 + if (wrapper.cert_type != WIN_CERT_TYPE_PKCS_SIGNED_DATA) { 153 + pr_debug("Signature certificate type is not PKCS\n"); 154 + return -ENOTSUPP; 155 + } 156 + 157 + /* Looks like actual pkcs signature length is in wrapper->length. 158 + * size obtained from data dir entries lists the total size of 159 + * certificate table which is also aligned to octawrod boundary. 160 + * 161 + * So set signature length field appropriately. 162 + */ 163 + ctx->sig_len = wrapper.length; 164 + ctx->sig_offset += sizeof(wrapper); 165 + ctx->sig_len -= sizeof(wrapper); 166 + if (ctx->sig_len == 0) { 167 + pr_debug("Signature data missing\n"); 168 + return -EKEYREJECTED; 169 + } 170 + 171 + /* What's left should a PKCS#7 cert */ 172 + pkcs7 = pebuf + ctx->sig_offset; 173 + if (pkcs7[0] == (ASN1_CONS_BIT | ASN1_SEQ)) { 174 + if (pkcs7[1] == 0x82 && 175 + pkcs7[2] == (((ctx->sig_len - 4) >> 8) & 0xff) && 176 + pkcs7[3] == ((ctx->sig_len - 4) & 0xff)) 177 + return 0; 178 + if (pkcs7[1] == 0x80) 179 + return 0; 180 + if (pkcs7[1] > 0x82) 181 + return -EMSGSIZE; 182 + } 183 + 184 + pr_debug("Signature data not PKCS#7\n"); 185 + return -ELIBBAD; 186 + } 187 + 188 + /* 189 + * Compare two sections for canonicalisation. 190 + */ 191 + static int pefile_compare_shdrs(const void *a, const void *b) 192 + { 193 + const struct section_header *shdra = a; 194 + const struct section_header *shdrb = b; 195 + int rc; 196 + 197 + if (shdra->data_addr > shdrb->data_addr) 198 + return 1; 199 + if (shdrb->data_addr > shdra->data_addr) 200 + return -1; 201 + 202 + if (shdra->virtual_address > shdrb->virtual_address) 203 + return 1; 204 + if (shdrb->virtual_address > shdra->virtual_address) 205 + return -1; 206 + 207 + rc = strcmp(shdra->name, shdrb->name); 208 + if (rc != 0) 209 + return rc; 210 + 211 + if (shdra->virtual_size > shdrb->virtual_size) 212 + return 1; 213 + if (shdrb->virtual_size > shdra->virtual_size) 214 + return -1; 215 + 216 + if (shdra->raw_data_size > shdrb->raw_data_size) 217 + return 1; 218 + if (shdrb->raw_data_size > shdra->raw_data_size) 219 + return -1; 220 + 221 + return 0; 222 + } 223 + 224 + /* 225 + * Load the contents of the PE binary into the digest, leaving out the image 226 + * checksum and the certificate data block. 227 + */ 228 + static int pefile_digest_pe_contents(const void *pebuf, unsigned int pelen, 229 + struct pefile_context *ctx, 230 + struct shash_desc *desc) 231 + { 232 + unsigned *canon, tmp, loop, i, hashed_bytes; 233 + int ret; 234 + 235 + /* Digest the header and data directory, but leave out the image 236 + * checksum and the data dirent for the signature. 237 + */ 238 + ret = crypto_shash_update(desc, pebuf, ctx->image_checksum_offset); 239 + if (ret < 0) 240 + return ret; 241 + 242 + tmp = ctx->image_checksum_offset + sizeof(uint32_t); 243 + ret = crypto_shash_update(desc, pebuf + tmp, 244 + ctx->cert_dirent_offset - tmp); 245 + if (ret < 0) 246 + return ret; 247 + 248 + tmp = ctx->cert_dirent_offset + sizeof(struct data_dirent); 249 + ret = crypto_shash_update(desc, pebuf + tmp, ctx->header_size - tmp); 250 + if (ret < 0) 251 + return ret; 252 + 253 + canon = kcalloc(ctx->n_sections, sizeof(unsigned), GFP_KERNEL); 254 + if (!canon) 255 + return -ENOMEM; 256 + 257 + /* We have to canonicalise the section table, so we perform an 258 + * insertion sort. 259 + */ 260 + canon[0] = 0; 261 + for (loop = 1; loop < ctx->n_sections; loop++) { 262 + for (i = 0; i < loop; i++) { 263 + if (pefile_compare_shdrs(&ctx->secs[canon[i]], 264 + &ctx->secs[loop]) > 0) { 265 + memmove(&canon[i + 1], &canon[i], 266 + (loop - i) * sizeof(canon[0])); 267 + break; 268 + } 269 + } 270 + canon[i] = loop; 271 + } 272 + 273 + hashed_bytes = ctx->header_size; 274 + for (loop = 0; loop < ctx->n_sections; loop++) { 275 + i = canon[loop]; 276 + if (ctx->secs[i].raw_data_size == 0) 277 + continue; 278 + ret = crypto_shash_update(desc, 279 + pebuf + ctx->secs[i].data_addr, 280 + ctx->secs[i].raw_data_size); 281 + if (ret < 0) { 282 + kfree(canon); 283 + return ret; 284 + } 285 + hashed_bytes += ctx->secs[i].raw_data_size; 286 + } 287 + kfree(canon); 288 + 289 + if (pelen > hashed_bytes) { 290 + tmp = hashed_bytes + ctx->certs_size; 291 + ret = crypto_shash_update(desc, 292 + pebuf + hashed_bytes, 293 + pelen - tmp); 294 + if (ret < 0) 295 + return ret; 296 + } 297 + 298 + return 0; 299 + } 300 + 301 + /* 302 + * Digest the contents of the PE binary, leaving out the image checksum and the 303 + * certificate data block. 304 + */ 305 + static int pefile_digest_pe(const void *pebuf, unsigned int pelen, 306 + struct pefile_context *ctx) 307 + { 308 + struct crypto_shash *tfm; 309 + struct shash_desc *desc; 310 + size_t digest_size, desc_size; 311 + void *digest; 312 + int ret; 313 + 314 + kenter(",%u", ctx->digest_algo); 315 + 316 + /* Allocate the hashing algorithm we're going to need and find out how 317 + * big the hash operational data will be. 318 + */ 319 + tfm = crypto_alloc_shash(hash_algo_name[ctx->digest_algo], 0, 0); 320 + if (IS_ERR(tfm)) 321 + return (PTR_ERR(tfm) == -ENOENT) ? -ENOPKG : PTR_ERR(tfm); 322 + 323 + desc_size = crypto_shash_descsize(tfm) + sizeof(*desc); 324 + digest_size = crypto_shash_digestsize(tfm); 325 + 326 + if (digest_size != ctx->digest_len) { 327 + pr_debug("Digest size mismatch (%zx != %x)\n", 328 + digest_size, ctx->digest_len); 329 + ret = -EBADMSG; 330 + goto error_no_desc; 331 + } 332 + pr_debug("Digest: desc=%zu size=%zu\n", desc_size, digest_size); 333 + 334 + ret = -ENOMEM; 335 + desc = kzalloc(desc_size + digest_size, GFP_KERNEL); 336 + if (!desc) 337 + goto error_no_desc; 338 + 339 + desc->tfm = tfm; 340 + desc->flags = CRYPTO_TFM_REQ_MAY_SLEEP; 341 + ret = crypto_shash_init(desc); 342 + if (ret < 0) 343 + goto error; 344 + 345 + ret = pefile_digest_pe_contents(pebuf, pelen, ctx, desc); 346 + if (ret < 0) 347 + goto error; 348 + 349 + digest = (void *)desc + desc_size; 350 + ret = crypto_shash_final(desc, digest); 351 + if (ret < 0) 352 + goto error; 353 + 354 + pr_debug("Digest calc = [%*ph]\n", ctx->digest_len, digest); 355 + 356 + /* Check that the PE file digest matches that in the MSCODE part of the 357 + * PKCS#7 certificate. 358 + */ 359 + if (memcmp(digest, ctx->digest, ctx->digest_len) != 0) { 360 + pr_debug("Digest mismatch\n"); 361 + ret = -EKEYREJECTED; 362 + } else { 363 + pr_debug("The digests match!\n"); 364 + } 365 + 366 + error: 367 + kfree(desc); 368 + error_no_desc: 369 + crypto_free_shash(tfm); 370 + kleave(" = %d", ret); 371 + return ret; 372 + } 373 + 374 + /** 375 + * verify_pefile_signature - Verify the signature on a PE binary image 376 + * @pebuf: Buffer containing the PE binary image 377 + * @pelen: Length of the binary image 378 + * @trust_keyring: Signing certificates to use as starting points 379 + * @_trusted: Set to true if trustworth, false otherwise 380 + * 381 + * Validate that the certificate chain inside the PKCS#7 message inside the PE 382 + * binary image intersects keys we already know and trust. 383 + * 384 + * Returns, in order of descending priority: 385 + * 386 + * (*) -ELIBBAD if the image cannot be parsed, or: 387 + * 388 + * (*) -EKEYREJECTED if a signature failed to match for which we have a valid 389 + * key, or: 390 + * 391 + * (*) 0 if at least one signature chain intersects with the keys in the trust 392 + * keyring, or: 393 + * 394 + * (*) -ENOPKG if a suitable crypto module couldn't be found for a check on a 395 + * chain. 396 + * 397 + * (*) -ENOKEY if we couldn't find a match for any of the signature chains in 398 + * the message. 399 + * 400 + * May also return -ENOMEM. 401 + */ 402 + int verify_pefile_signature(const void *pebuf, unsigned pelen, 403 + struct key *trusted_keyring, bool *_trusted) 404 + { 405 + struct pkcs7_message *pkcs7; 406 + struct pefile_context ctx; 407 + const void *data; 408 + size_t datalen; 409 + int ret; 410 + 411 + kenter(""); 412 + 413 + memset(&ctx, 0, sizeof(ctx)); 414 + ret = pefile_parse_binary(pebuf, pelen, &ctx); 415 + if (ret < 0) 416 + return ret; 417 + 418 + ret = pefile_strip_sig_wrapper(pebuf, &ctx); 419 + if (ret < 0) 420 + return ret; 421 + 422 + pkcs7 = pkcs7_parse_message(pebuf + ctx.sig_offset, ctx.sig_len); 423 + if (IS_ERR(pkcs7)) 424 + return PTR_ERR(pkcs7); 425 + ctx.pkcs7 = pkcs7; 426 + 427 + ret = pkcs7_get_content_data(ctx.pkcs7, &data, &datalen, false); 428 + if (ret < 0 || datalen == 0) { 429 + pr_devel("PKCS#7 message does not contain data\n"); 430 + ret = -EBADMSG; 431 + goto error; 432 + } 433 + 434 + ret = mscode_parse(&ctx); 435 + if (ret < 0) 436 + goto error; 437 + 438 + pr_debug("Digest: %u [%*ph]\n", 439 + ctx.digest_len, ctx.digest_len, ctx.digest); 440 + 441 + /* Generate the digest and check against the PKCS7 certificate 442 + * contents. 443 + */ 444 + ret = pefile_digest_pe(pebuf, pelen, &ctx); 445 + if (ret < 0) 446 + goto error; 447 + 448 + ret = pkcs7_verify(pkcs7); 449 + if (ret < 0) 450 + goto error; 451 + 452 + ret = pkcs7_validate_trust(pkcs7, trusted_keyring, _trusted); 453 + 454 + error: 455 + pkcs7_free_message(ctx.pkcs7); 456 + return ret; 457 + }
+42
crypto/asymmetric_keys/verify_pefile.h
··· 1 + /* PE Binary parser bits 2 + * 3 + * Copyright (C) 2014 Red Hat, Inc. All Rights Reserved. 4 + * Written by David Howells (dhowells@redhat.com) 5 + * 6 + * This program is free software; you can redistribute it and/or 7 + * modify it under the terms of the GNU General Public Licence 8 + * as published by the Free Software Foundation; either version 9 + * 2 of the Licence, or (at your option) any later version. 10 + */ 11 + 12 + #include <linux/verify_pefile.h> 13 + #include <crypto/pkcs7.h> 14 + #include <crypto/hash_info.h> 15 + 16 + struct pefile_context { 17 + unsigned header_size; 18 + unsigned image_checksum_offset; 19 + unsigned cert_dirent_offset; 20 + unsigned n_data_dirents; 21 + unsigned n_sections; 22 + unsigned certs_size; 23 + unsigned sig_offset; 24 + unsigned sig_len; 25 + const struct section_header *secs; 26 + struct pkcs7_message *pkcs7; 27 + 28 + /* PKCS#7 MS Individual Code Signing content */ 29 + const void *digest; /* Digest */ 30 + unsigned digest_len; /* Digest length */ 31 + enum hash_algo digest_algo; /* Digest algorithm */ 32 + }; 33 + 34 + #define kenter(FMT, ...) \ 35 + pr_devel("==> %s("FMT")\n", __func__, ##__VA_ARGS__) 36 + #define kleave(FMT, ...) \ 37 + pr_devel("<== %s()"FMT"\n", __func__, ##__VA_ARGS__) 38 + 39 + /* 40 + * mscode_parser.c 41 + */ 42 + extern int mscode_parse(struct pefile_context *ctx);
+1 -1
crypto/asymmetric_keys/x509.asn1
··· 6 6 7 7 TBSCertificate ::= SEQUENCE { 8 8 version [ 0 ] Version DEFAULT, 9 - serialNumber CertificateSerialNumber, 9 + serialNumber CertificateSerialNumber ({ x509_note_serial }), 10 10 signature AlgorithmIdentifier ({ x509_note_pkey_algo }), 11 11 issuer Name ({ x509_note_issuer }), 12 12 validity Validity,
+20
crypto/asymmetric_keys/x509_cert_parser.c
··· 11 11 12 12 #define pr_fmt(fmt) "X.509: "fmt 13 13 #include <linux/kernel.h> 14 + #include <linux/export.h> 14 15 #include <linux/slab.h> 15 16 #include <linux/err.h> 16 17 #include <linux/oid_registry.h> ··· 53 52 kfree(cert); 54 53 } 55 54 } 55 + EXPORT_SYMBOL_GPL(x509_free_certificate); 56 56 57 57 /* 58 58 * Parse an X.509 certificate ··· 99 97 error_no_cert: 100 98 return ERR_PTR(ret); 101 99 } 100 + EXPORT_SYMBOL_GPL(x509_cert_parse); 102 101 103 102 /* 104 103 * Note an OID when we find one for later processing when we know how ··· 210 207 211 208 ctx->cert->raw_sig = value; 212 209 ctx->cert->raw_sig_size = vlen; 210 + return 0; 211 + } 212 + 213 + /* 214 + * Note the certificate serial number 215 + */ 216 + int x509_note_serial(void *context, size_t hdrlen, 217 + unsigned char tag, 218 + const void *value, size_t vlen) 219 + { 220 + struct x509_parse_context *ctx = context; 221 + ctx->cert->raw_serial = value; 222 + ctx->cert->raw_serial_size = vlen; 213 223 return 0; 214 224 } 215 225 ··· 338 322 const void *value, size_t vlen) 339 323 { 340 324 struct x509_parse_context *ctx = context; 325 + ctx->cert->raw_issuer = value; 326 + ctx->cert->raw_issuer_size = vlen; 341 327 return x509_fabricate_name(ctx, hdrlen, tag, &ctx->cert->issuer, vlen); 342 328 } 343 329 ··· 348 330 const void *value, size_t vlen) 349 331 { 350 332 struct x509_parse_context *ctx = context; 333 + ctx->cert->raw_subject = value; 334 + ctx->cert->raw_subject_size = vlen; 351 335 return x509_fabricate_name(ctx, hdrlen, tag, &ctx->cert->subject, vlen); 352 336 } 353 337
+12 -1
crypto/asymmetric_keys/x509_parser.h
··· 14 14 15 15 struct x509_certificate { 16 16 struct x509_certificate *next; 17 + struct x509_certificate *signer; /* Certificate that signed this one */ 17 18 struct public_key *pub; /* Public key details */ 19 + struct public_key_signature sig; /* Signature parameters */ 18 20 char *issuer; /* Name of certificate issuer */ 19 21 char *subject; /* Name of certificate subject */ 20 22 char *fingerprint; /* Key fingerprint as hex */ ··· 27 25 unsigned tbs_size; /* Size of signed data */ 28 26 unsigned raw_sig_size; /* Size of sigature */ 29 27 const void *raw_sig; /* Signature data */ 30 - struct public_key_signature sig; /* Signature parameters */ 28 + const void *raw_serial; /* Raw serial number in ASN.1 */ 29 + unsigned raw_serial_size; 30 + unsigned raw_issuer_size; 31 + const void *raw_issuer; /* Raw issuer name in ASN.1 */ 32 + const void *raw_subject; /* Raw subject name in ASN.1 */ 33 + unsigned raw_subject_size; 34 + unsigned index; 35 + bool seen; /* Infinite recursion prevention */ 36 + bool verified; 37 + bool trusted; 31 38 }; 32 39 33 40 /*
+113 -2
crypto/asymmetric_keys/x509_public_key.c
··· 18 18 #include <linux/asn1_decoder.h> 19 19 #include <keys/asymmetric-subtype.h> 20 20 #include <keys/asymmetric-parser.h> 21 + #include <keys/system_keyring.h> 21 22 #include <crypto/hash.h> 22 23 #include "asymmetric_keys.h" 23 24 #include "public_key.h" 24 25 #include "x509_parser.h" 26 + 27 + static bool use_builtin_keys; 28 + static char *ca_keyid; 29 + 30 + #ifndef MODULE 31 + static int __init ca_keys_setup(char *str) 32 + { 33 + if (!str) /* default system keyring */ 34 + return 1; 35 + 36 + if (strncmp(str, "id:", 3) == 0) 37 + ca_keyid = str; /* owner key 'id:xxxxxx' */ 38 + else if (strcmp(str, "builtin") == 0) 39 + use_builtin_keys = true; 40 + 41 + return 1; 42 + } 43 + __setup("ca_keys=", ca_keys_setup); 44 + #endif 45 + 46 + /** 47 + * x509_request_asymmetric_key - Request a key by X.509 certificate params. 48 + * @keyring: The keys to search. 49 + * @subject: The name of the subject to whom the key belongs. 50 + * @key_id: The subject key ID as a hex string. 51 + * 52 + * Find a key in the given keyring by subject name and key ID. These might, 53 + * for instance, be the issuer name and the authority key ID of an X.509 54 + * certificate that needs to be verified. 55 + */ 56 + struct key *x509_request_asymmetric_key(struct key *keyring, 57 + const char *subject, 58 + const char *key_id) 59 + { 60 + key_ref_t key; 61 + size_t subject_len = strlen(subject), key_id_len = strlen(key_id); 62 + char *id; 63 + 64 + /* Construct an identifier "<subjname>:<keyid>". */ 65 + id = kmalloc(subject_len + 2 + key_id_len + 1, GFP_KERNEL); 66 + if (!id) 67 + return ERR_PTR(-ENOMEM); 68 + 69 + memcpy(id, subject, subject_len); 70 + id[subject_len + 0] = ':'; 71 + id[subject_len + 1] = ' '; 72 + memcpy(id + subject_len + 2, key_id, key_id_len); 73 + id[subject_len + 2 + key_id_len] = 0; 74 + 75 + pr_debug("Look up: \"%s\"\n", id); 76 + 77 + key = keyring_search(make_key_ref(keyring, 1), 78 + &key_type_asymmetric, id); 79 + if (IS_ERR(key)) 80 + pr_debug("Request for key '%s' err %ld\n", id, PTR_ERR(key)); 81 + kfree(id); 82 + 83 + if (IS_ERR(key)) { 84 + switch (PTR_ERR(key)) { 85 + /* Hide some search errors */ 86 + case -EACCES: 87 + case -ENOTDIR: 88 + case -EAGAIN: 89 + return ERR_PTR(-ENOKEY); 90 + default: 91 + return ERR_CAST(key); 92 + } 93 + } 94 + 95 + pr_devel("<==%s() = 0 [%x]\n", __func__, 96 + key_serial(key_ref_to_ptr(key))); 97 + return key_ref_to_ptr(key); 98 + } 99 + EXPORT_SYMBOL_GPL(x509_request_asymmetric_key); 25 100 26 101 /* 27 102 * Set up the signature parameters in an X.509 certificate. This involves ··· 178 103 EXPORT_SYMBOL_GPL(x509_check_signature); 179 104 180 105 /* 106 + * Check the new certificate against the ones in the trust keyring. If one of 107 + * those is the signing key and validates the new certificate, then mark the 108 + * new certificate as being trusted. 109 + * 110 + * Return 0 if the new certificate was successfully validated, 1 if we couldn't 111 + * find a matching parent certificate in the trusted list and an error if there 112 + * is a matching certificate but the signature check fails. 113 + */ 114 + static int x509_validate_trust(struct x509_certificate *cert, 115 + struct key *trust_keyring) 116 + { 117 + struct key *key; 118 + int ret = 1; 119 + 120 + if (!trust_keyring) 121 + return -EOPNOTSUPP; 122 + 123 + if (ca_keyid && !asymmetric_keyid_match(cert->authority, ca_keyid)) 124 + return -EPERM; 125 + 126 + key = x509_request_asymmetric_key(trust_keyring, 127 + cert->issuer, cert->authority); 128 + if (!IS_ERR(key)) { 129 + if (!use_builtin_keys 130 + || test_bit(KEY_FLAG_BUILTIN, &key->flags)) 131 + ret = x509_check_signature(key->payload.data, cert); 132 + key_put(key); 133 + } 134 + return ret; 135 + } 136 + 137 + /* 181 138 * Attempt to parse a data blob for a key as an X509 certificate. 182 139 */ 183 140 static int x509_key_preparse(struct key_preparsed_payload *prep) ··· 262 155 /* Check the signature on the key if it appears to be self-signed */ 263 156 if (!cert->authority || 264 157 strcmp(cert->fingerprint, cert->authority) == 0) { 265 - ret = x509_check_signature(cert->pub, cert); 158 + ret = x509_check_signature(cert->pub, cert); /* self-signed */ 266 159 if (ret < 0) 267 160 goto error_free_cert; 161 + } else if (!prep->trusted) { 162 + ret = x509_validate_trust(cert, get_system_trusted_keyring()); 163 + if (!ret) 164 + prep->trusted = 1; 268 165 } 269 166 270 167 /* Propose a description */ ··· 288 177 __module_get(public_key_subtype.owner); 289 178 prep->type_data[0] = &public_key_subtype; 290 179 prep->type_data[1] = cert->fingerprint; 291 - prep->payload = cert->pub; 180 + prep->payload[0] = cert->pub; 292 181 prep->description = desc; 293 182 prep->quotalen = 100; 294 183
+26 -4
drivers/base/firmware_class.c
··· 28 28 #include <linux/suspend.h> 29 29 #include <linux/syscore_ops.h> 30 30 #include <linux/reboot.h> 31 + #include <linux/security.h> 31 32 32 33 #include <generated/utsrelease.h> 33 34 ··· 304 303 if (rc != size) { 305 304 if (rc > 0) 306 305 rc = -EIO; 307 - vfree(buf); 308 - return rc; 306 + goto fail; 309 307 } 308 + rc = security_kernel_fw_from_file(file, buf, size); 309 + if (rc) 310 + goto fail; 310 311 fw_buf->data = buf; 311 312 fw_buf->size = size; 312 313 return 0; 314 + fail: 315 + vfree(buf); 316 + return rc; 313 317 } 314 318 315 319 static int fw_get_filesystem_firmware(struct device *device, ··· 618 612 { 619 613 struct firmware_priv *fw_priv = to_firmware_priv(dev); 620 614 struct firmware_buf *fw_buf; 615 + ssize_t written = count; 621 616 int loading = simple_strtol(buf, NULL, 10); 622 617 int i; 623 618 ··· 642 635 break; 643 636 case 0: 644 637 if (test_bit(FW_STATUS_LOADING, &fw_buf->status)) { 638 + int rc; 639 + 645 640 set_bit(FW_STATUS_DONE, &fw_buf->status); 646 641 clear_bit(FW_STATUS_LOADING, &fw_buf->status); 647 642 ··· 653 644 * see the mapped 'buf->data' once the loading 654 645 * is completed. 655 646 * */ 656 - if (fw_map_pages_buf(fw_buf)) 647 + rc = fw_map_pages_buf(fw_buf); 648 + if (rc) 657 649 dev_err(dev, "%s: map pages failed\n", 658 650 __func__); 651 + else 652 + rc = security_kernel_fw_from_file(NULL, 653 + fw_buf->data, fw_buf->size); 654 + 655 + /* 656 + * Same logic as fw_load_abort, only the DONE bit 657 + * is ignored and we set ABORT only on failure. 658 + */ 659 659 list_del_init(&fw_buf->pending_list); 660 + if (rc) { 661 + set_bit(FW_STATUS_ABORT, &fw_buf->status); 662 + written = rc; 663 + } 660 664 complete_all(&fw_buf->completion); 661 665 break; 662 666 } ··· 683 661 } 684 662 out: 685 663 mutex_unlock(&fw_lock); 686 - return count; 664 + return written; 687 665 } 688 666 689 667 static DEVICE_ATTR(loading, 0644, firmware_loading_show, firmware_loading_store);
+48 -25
drivers/char/tpm/tpm-interface.c
··· 491 491 int tpm_get_timeouts(struct tpm_chip *chip) 492 492 { 493 493 struct tpm_cmd_t tpm_cmd; 494 - struct timeout_t *timeout_cap; 494 + unsigned long new_timeout[4]; 495 + unsigned long old_timeout[4]; 495 496 struct duration_t *duration_cap; 496 497 ssize_t rc; 497 - u32 timeout; 498 - unsigned int scale = 1; 499 498 500 499 tpm_cmd.header.in = tpm_getcap_header; 501 500 tpm_cmd.params.getcap_in.cap = TPM_CAP_PROP; ··· 528 529 != sizeof(tpm_cmd.header.out) + sizeof(u32) + 4 * sizeof(u32)) 529 530 return -EINVAL; 530 531 531 - timeout_cap = &tpm_cmd.params.getcap_out.cap.timeout; 532 - /* Don't overwrite default if value is 0 */ 533 - timeout = be32_to_cpu(timeout_cap->a); 534 - if (timeout && timeout < 1000) { 535 - /* timeouts in msec rather usec */ 536 - scale = 1000; 537 - chip->vendor.timeout_adjusted = true; 532 + old_timeout[0] = be32_to_cpu(tpm_cmd.params.getcap_out.cap.timeout.a); 533 + old_timeout[1] = be32_to_cpu(tpm_cmd.params.getcap_out.cap.timeout.b); 534 + old_timeout[2] = be32_to_cpu(tpm_cmd.params.getcap_out.cap.timeout.c); 535 + old_timeout[3] = be32_to_cpu(tpm_cmd.params.getcap_out.cap.timeout.d); 536 + memcpy(new_timeout, old_timeout, sizeof(new_timeout)); 537 + 538 + /* 539 + * Provide ability for vendor overrides of timeout values in case 540 + * of misreporting. 541 + */ 542 + if (chip->ops->update_timeouts != NULL) 543 + chip->vendor.timeout_adjusted = 544 + chip->ops->update_timeouts(chip, new_timeout); 545 + 546 + if (!chip->vendor.timeout_adjusted) { 547 + /* Don't overwrite default if value is 0 */ 548 + if (new_timeout[0] != 0 && new_timeout[0] < 1000) { 549 + int i; 550 + 551 + /* timeouts in msec rather usec */ 552 + for (i = 0; i != ARRAY_SIZE(new_timeout); i++) 553 + new_timeout[i] *= 1000; 554 + chip->vendor.timeout_adjusted = true; 555 + } 538 556 } 539 - if (timeout) 540 - chip->vendor.timeout_a = usecs_to_jiffies(timeout * scale); 541 - timeout = be32_to_cpu(timeout_cap->b); 542 - if (timeout) 543 - chip->vendor.timeout_b = usecs_to_jiffies(timeout * scale); 544 - timeout = be32_to_cpu(timeout_cap->c); 545 - if (timeout) 546 - chip->vendor.timeout_c = usecs_to_jiffies(timeout * scale); 547 - timeout = be32_to_cpu(timeout_cap->d); 548 - if (timeout) 549 - chip->vendor.timeout_d = usecs_to_jiffies(timeout * scale); 557 + 558 + /* Report adjusted timeouts */ 559 + if (chip->vendor.timeout_adjusted) { 560 + dev_info(chip->dev, 561 + HW_ERR "Adjusting reported timeouts: A %lu->%luus B %lu->%luus C %lu->%luus D %lu->%luus\n", 562 + old_timeout[0], new_timeout[0], 563 + old_timeout[1], new_timeout[1], 564 + old_timeout[2], new_timeout[2], 565 + old_timeout[3], new_timeout[3]); 566 + } 567 + 568 + chip->vendor.timeout_a = usecs_to_jiffies(new_timeout[0]); 569 + chip->vendor.timeout_b = usecs_to_jiffies(new_timeout[1]); 570 + chip->vendor.timeout_c = usecs_to_jiffies(new_timeout[2]); 571 + chip->vendor.timeout_d = usecs_to_jiffies(new_timeout[3]); 550 572 551 573 duration: 552 574 tpm_cmd.header.in = tpm_getcap_header; ··· 1011 991 int err, total = 0, retries = 5; 1012 992 u8 *dest = out; 1013 993 994 + if (!out || !num_bytes || max > TPM_MAX_RNG_DATA) 995 + return -EINVAL; 996 + 1014 997 chip = tpm_chip_find_get(chip_num); 1015 998 if (chip == NULL) 1016 999 return -ENODEV; 1017 - 1018 - if (!out || !num_bytes || max > TPM_MAX_RNG_DATA) 1019 - return -EINVAL; 1020 1000 1021 1001 do { 1022 1002 tpm_cmd.header.in = tpm_getrandom_header; ··· 1036 1016 num_bytes -= recd; 1037 1017 } while (retries-- && total < max); 1038 1018 1019 + tpm_chip_put(chip); 1039 1020 return total ? total : -EIO; 1040 1021 } 1041 1022 EXPORT_SYMBOL_GPL(tpm_get_random); ··· 1116 1095 goto del_misc; 1117 1096 1118 1097 if (tpm_add_ppi(&dev->kobj)) 1119 - goto del_misc; 1098 + goto del_sysfs; 1120 1099 1121 1100 chip->bios_dir = tpm_bios_log_setup(chip->devname); 1122 1101 ··· 1127 1106 1128 1107 return chip; 1129 1108 1109 + del_sysfs: 1110 + tpm_sysfs_del_device(chip); 1130 1111 del_misc: 1131 1112 tpm_dev_del_device(chip); 1132 1113 put_device:
+1 -3
drivers/char/tpm/tpm_eventlog.c
··· 235 235 static int tpm_ascii_bios_measurements_show(struct seq_file *m, void *v) 236 236 { 237 237 int len = 0; 238 - int i; 239 238 char *eventname; 240 239 struct tcpa_event *event = v; 241 240 unsigned char *event_entry = ··· 250 251 seq_printf(m, "%2d ", event->pcr_index); 251 252 252 253 /* 2nd: SHA1 */ 253 - for (i = 0; i < 20; i++) 254 - seq_printf(m, "%02x", event->pcr_value[i]); 254 + seq_printf(m, "%20phN", event->pcr_value); 255 255 256 256 /* 3rd: event type identifier */ 257 257 seq_printf(m, " %02x", event->event_type);
+1
drivers/char/tpm/tpm_i2c_stm_st33.c
··· 714 714 } 715 715 716 716 tpm_get_timeouts(chip); 717 + tpm_do_selftest(chip); 717 718 718 719 dev_info(chip->dev, "TPM I2C Initialized\n"); 719 720 return 0;
+31
drivers/char/tpm/tpm_tis.c
··· 373 373 return rc; 374 374 } 375 375 376 + struct tis_vendor_timeout_override { 377 + u32 did_vid; 378 + unsigned long timeout_us[4]; 379 + }; 380 + 381 + static const struct tis_vendor_timeout_override vendor_timeout_overrides[] = { 382 + /* Atmel 3204 */ 383 + { 0x32041114, { (TIS_SHORT_TIMEOUT*1000), (TIS_LONG_TIMEOUT*1000), 384 + (TIS_SHORT_TIMEOUT*1000), (TIS_SHORT_TIMEOUT*1000) } }, 385 + }; 386 + 387 + static bool tpm_tis_update_timeouts(struct tpm_chip *chip, 388 + unsigned long *timeout_cap) 389 + { 390 + int i; 391 + u32 did_vid; 392 + 393 + did_vid = ioread32(chip->vendor.iobase + TPM_DID_VID(0)); 394 + 395 + for (i = 0; i != ARRAY_SIZE(vendor_timeout_overrides); i++) { 396 + if (vendor_timeout_overrides[i].did_vid != did_vid) 397 + continue; 398 + memcpy(timeout_cap, vendor_timeout_overrides[i].timeout_us, 399 + sizeof(vendor_timeout_overrides[i].timeout_us)); 400 + return true; 401 + } 402 + 403 + return false; 404 + } 405 + 376 406 /* 377 407 * Early probing for iTPM with STS_DATA_EXPECT flaw. 378 408 * Try sending command without itpm flag set and if that ··· 467 437 .recv = tpm_tis_recv, 468 438 .send = tpm_tis_send, 469 439 .cancel = tpm_tis_ready, 440 + .update_timeouts = tpm_tis_update_timeouts, 470 441 .req_complete_mask = TPM_STS_DATA_AVAIL | TPM_STS_VALID, 471 442 .req_complete_val = TPM_STS_DATA_AVAIL | TPM_STS_VALID, 472 443 .req_canceled = tpm_tis_req_canceled,
+3 -3
fs/exec.c
··· 1216 1216 /* 1217 1217 * determine how safe it is to execute the proposed program 1218 1218 * - the caller must hold ->cred_guard_mutex to protect against 1219 - * PTRACE_ATTACH 1219 + * PTRACE_ATTACH or seccomp thread-sync 1220 1220 */ 1221 1221 static void check_unsafe_exec(struct linux_binprm *bprm) 1222 1222 { ··· 1234 1234 * This isn't strictly necessary, but it makes it harder for LSMs to 1235 1235 * mess up. 1236 1236 */ 1237 - if (current->no_new_privs) 1237 + if (task_no_new_privs(current)) 1238 1238 bprm->unsafe |= LSM_UNSAFE_NO_NEW_PRIVS; 1239 1239 1240 1240 t = p; ··· 1272 1272 bprm->cred->egid = current_egid(); 1273 1273 1274 1274 if (!(bprm->file->f_path.mnt->mnt_flags & MNT_NOSUID) && 1275 - !current->no_new_privs && 1275 + !task_no_new_privs(current) && 1276 1276 kuid_has_mapping(bprm->cred->user_ns, inode->i_uid) && 1277 1277 kgid_has_mapping(bprm->cred->user_ns, inode->i_gid)) { 1278 1278 /* Set-uid? */
+8 -2
fs/nfs/idmap.c
··· 174 174 175 175 static struct key_type key_type_id_resolver = { 176 176 .name = "id_resolver", 177 - .instantiate = user_instantiate, 177 + .preparse = user_preparse, 178 + .free_preparse = user_free_preparse, 179 + .instantiate = generic_key_instantiate, 178 180 .match = user_match, 179 181 .revoke = user_revoke, 180 182 .destroy = user_destroy, ··· 284 282 desc, "", 0, idmap); 285 283 mutex_unlock(&idmap->idmap_mutex); 286 284 } 285 + if (!IS_ERR(rkey)) 286 + set_bit(KEY_FLAG_ROOT_CAN_INVAL, &rkey->flags); 287 287 288 288 kfree(desc); 289 289 return rkey; ··· 398 394 399 395 static struct key_type key_type_id_resolver_legacy = { 400 396 .name = "id_legacy", 401 - .instantiate = user_instantiate, 397 + .preparse = user_preparse, 398 + .free_preparse = user_free_preparse, 399 + .instantiate = generic_key_instantiate, 402 400 .match = user_match, 403 401 .revoke = user_revoke, 404 402 .destroy = user_destroy,
+1 -10
fs/proc/array.c
··· 297 297 seq_puts(m, header); 298 298 CAP_FOR_EACH_U32(__capi) { 299 299 seq_printf(m, "%08x", 300 - a->cap[(_KERNEL_CAPABILITY_U32S-1) - __capi]); 300 + a->cap[CAP_LAST_U32 - __capi]); 301 301 } 302 302 seq_putc(m, '\n'); 303 303 } 304 - 305 - /* Remove non-existent capabilities */ 306 - #define NORM_CAPS(v) (v.cap[CAP_TO_INDEX(CAP_LAST_CAP)] &= \ 307 - CAP_TO_MASK(CAP_LAST_CAP + 1) - 1) 308 304 309 305 static inline void task_cap(struct seq_file *m, struct task_struct *p) 310 306 { ··· 314 318 cap_effective = cred->cap_effective; 315 319 cap_bset = cred->cap_bset; 316 320 rcu_read_unlock(); 317 - 318 - NORM_CAPS(cap_inheritable); 319 - NORM_CAPS(cap_permitted); 320 - NORM_CAPS(cap_effective); 321 - NORM_CAPS(cap_bset); 322 321 323 322 render_cap_t(m, "CapInh:\t", &cap_inheritable); 324 323 render_cap_t(m, "CapPrm:\t", &cap_permitted);
+36
include/crypto/pkcs7.h
··· 1 + /* PKCS#7 crypto data parser 2 + * 3 + * Copyright (C) 2012 Red Hat, Inc. All Rights Reserved. 4 + * Written by David Howells (dhowells@redhat.com) 5 + * 6 + * This program is free software; you can redistribute it and/or 7 + * modify it under the terms of the GNU General Public Licence 8 + * as published by the Free Software Foundation; either version 9 + * 2 of the Licence, or (at your option) any later version. 10 + */ 11 + 12 + struct key; 13 + struct pkcs7_message; 14 + 15 + /* 16 + * pkcs7_parser.c 17 + */ 18 + extern struct pkcs7_message *pkcs7_parse_message(const void *data, 19 + size_t datalen); 20 + extern void pkcs7_free_message(struct pkcs7_message *pkcs7); 21 + 22 + extern int pkcs7_get_content_data(const struct pkcs7_message *pkcs7, 23 + const void **_data, size_t *_datalen, 24 + bool want_wrapper); 25 + 26 + /* 27 + * pkcs7_trust.c 28 + */ 29 + extern int pkcs7_validate_trust(struct pkcs7_message *pkcs7, 30 + struct key *trust_keyring, 31 + bool *_trusted); 32 + 33 + /* 34 + * pkcs7_verify.c 35 + */ 36 + extern int pkcs7_verify(struct pkcs7_message *pkcs7);
+4
include/crypto/public_key.h
··· 98 98 extern int verify_signature(const struct key *key, 99 99 const struct public_key_signature *sig); 100 100 101 + extern struct key *x509_request_asymmetric_key(struct key *keyring, 102 + const char *issuer, 103 + const char *key_id); 104 + 101 105 #endif /* _LINUX_PUBLIC_KEY_H */
+2 -1
include/keys/big_key-type.h
··· 16 16 17 17 extern struct key_type key_type_big_key; 18 18 19 - extern int big_key_instantiate(struct key *key, struct key_preparsed_payload *prep); 19 + extern int big_key_preparse(struct key_preparsed_payload *prep); 20 + extern void big_key_free_preparse(struct key_preparsed_payload *prep); 20 21 extern void big_key_revoke(struct key *key); 21 22 extern void big_key_destroy(struct key *key); 22 23 extern void big_key_describe(const struct key *big_key, struct seq_file *m);
+9 -1
include/keys/system_keyring.h
··· 17 17 #include <linux/key.h> 18 18 19 19 extern struct key *system_trusted_keyring; 20 - 20 + static inline struct key *get_system_trusted_keyring(void) 21 + { 22 + return system_trusted_keyring; 23 + } 24 + #else 25 + static inline struct key *get_system_trusted_keyring(void) 26 + { 27 + return NULL; 28 + } 21 29 #endif 22 30 23 31 #endif /* _KEYS_SYSTEM_KEYRING_H */
+2 -1
include/keys/user-type.h
··· 37 37 38 38 struct key_preparsed_payload; 39 39 40 - extern int user_instantiate(struct key *key, struct key_preparsed_payload *prep); 40 + extern int user_preparse(struct key_preparsed_payload *prep); 41 + extern void user_free_preparse(struct key_preparsed_payload *prep); 41 42 extern int user_update(struct key *key, struct key_preparsed_payload *prep); 42 43 extern int user_match(const struct key *key, const void *criterion); 43 44 extern void user_revoke(struct key *key);
+4 -1
include/linux/capability.h
··· 78 78 # error Fix up hand-coded capability macro initializers 79 79 #else /* HAND-CODED capability initializers */ 80 80 81 + #define CAP_LAST_U32 ((_KERNEL_CAPABILITY_U32S) - 1) 82 + #define CAP_LAST_U32_VALID_MASK (CAP_TO_MASK(CAP_LAST_CAP + 1) -1) 83 + 81 84 # define CAP_EMPTY_SET ((kernel_cap_t){{ 0, 0 }}) 82 - # define CAP_FULL_SET ((kernel_cap_t){{ ~0, ~0 }}) 85 + # define CAP_FULL_SET ((kernel_cap_t){{ ~0, CAP_LAST_U32_VALID_MASK }}) 83 86 # define CAP_FS_SET ((kernel_cap_t){{ CAP_FS_MASK_B0 \ 84 87 | CAP_TO_MASK(CAP_LINUX_IMMUTABLE), \ 85 88 CAP_FS_MASK_B1 } })
+6
include/linux/ima.h
··· 19 19 extern void ima_file_free(struct file *file); 20 20 extern int ima_file_mmap(struct file *file, unsigned long prot); 21 21 extern int ima_module_check(struct file *file); 22 + extern int ima_fw_from_file(struct file *file, char *buf, size_t size); 22 23 23 24 #else 24 25 static inline int ima_bprm_check(struct linux_binprm *bprm) ··· 43 42 } 44 43 45 44 static inline int ima_module_check(struct file *file) 45 + { 46 + return 0; 47 + } 48 + 49 + static inline int ima_fw_from_file(struct file *file, char *buf, size_t size) 46 50 { 47 51 return 0; 48 52 }
+4 -1
include/linux/key-type.h
··· 41 41 struct key_preparsed_payload { 42 42 char *description; /* Proposed key description (or NULL) */ 43 43 void *type_data[2]; /* Private key-type data */ 44 - void *payload; /* Proposed payload */ 44 + void *payload[2]; /* Proposed payload */ 45 45 const void *data; /* Raw data */ 46 46 size_t datalen; /* Raw datalen */ 47 47 size_t quotalen; /* Quota length for proposed payload */ 48 + time_t expiry; /* Expiry time of key */ 48 49 bool trusted; /* True if key is trusted */ 49 50 }; 50 51 ··· 159 158 { 160 159 return key_reject_and_link(key, timeout, ENOKEY, keyring, instkey); 161 160 } 161 + 162 + extern int generic_key_instantiate(struct key *key, struct key_preparsed_payload *prep); 162 163 163 164 #endif /* CONFIG_KEYS */ 164 165 #endif /* _LINUX_KEY_TYPE_H */
+2
include/linux/key.h
··· 170 170 #define KEY_FLAG_INVALIDATED 7 /* set if key has been invalidated */ 171 171 #define KEY_FLAG_TRUSTED 8 /* set if key is trusted */ 172 172 #define KEY_FLAG_TRUSTED_ONLY 9 /* set if keyring only accepts links to trusted keys */ 173 + #define KEY_FLAG_BUILTIN 10 /* set if key is builtin */ 174 + #define KEY_FLAG_ROOT_CAN_INVAL 11 /* set if key can be invalidated by root without permission */ 173 175 174 176 /* the key type and key description string 175 177 * - the desc is used to match a key against search criteria
+7 -1
include/linux/oid_registry.h
··· 52 52 OID_md4, /* 1.2.840.113549.2.4 */ 53 53 OID_md5, /* 1.2.840.113549.2.5 */ 54 54 55 - OID_certAuthInfoAccess, /* 1.3.6.1.5.5.7.1.1 */ 55 + /* Microsoft Authenticode & Software Publishing */ 56 + OID_msIndirectData, /* 1.3.6.1.4.1.311.2.1.4 */ 57 + OID_msPeImageDataObjId, /* 1.3.6.1.4.1.311.2.1.15 */ 58 + OID_msIndividualSPKeyPurpose, /* 1.3.6.1.4.1.311.2.1.21 */ 56 59 OID_msOutlookExpress, /* 1.3.6.1.4.1.311.16.4 */ 60 + 61 + OID_certAuthInfoAccess, /* 1.3.6.1.5.5.7.1.1 */ 57 62 OID_sha1, /* 1.3.14.3.2.26 */ 63 + OID_sha256, /* 2.16.840.1.101.3.4.2.1 */ 58 64 59 65 /* Distinguished Name attribute IDs [RFC 2256] */ 60 66 OID_commonName, /* 2.5.4.3 */
+448
include/linux/pe.h
··· 1 + /* 2 + * Copyright 2011 Red Hat, Inc. 3 + * All rights reserved. 4 + * 5 + * This program is free software; you can redistribute it and/or modify 6 + * it under the terms of the GNU General Public License as published by 7 + * the Free Software Foundation; version 2 of the License. 8 + * 9 + * This program is distributed in the hope that it will be useful, 10 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 + * GNU General Public License for more details. 13 + * 14 + * You should have received a copy of the GNU General Public License 15 + * along with this program. If not, see <http://www.gnu.org/licenses/>. 16 + * 17 + * Author(s): Peter Jones <pjones@redhat.com> 18 + */ 19 + #ifndef __LINUX_PE_H 20 + #define __LINUX_PE_H 21 + 22 + #include <linux/types.h> 23 + 24 + #define MZ_MAGIC 0x5a4d /* "MZ" */ 25 + 26 + struct mz_hdr { 27 + uint16_t magic; /* MZ_MAGIC */ 28 + uint16_t lbsize; /* size of last used block */ 29 + uint16_t blocks; /* pages in file, 0x3 */ 30 + uint16_t relocs; /* relocations */ 31 + uint16_t hdrsize; /* header size in "paragraphs" */ 32 + uint16_t min_extra_pps; /* .bss */ 33 + uint16_t max_extra_pps; /* runtime limit for the arena size */ 34 + uint16_t ss; /* relative stack segment */ 35 + uint16_t sp; /* initial %sp register */ 36 + uint16_t checksum; /* word checksum */ 37 + uint16_t ip; /* initial %ip register */ 38 + uint16_t cs; /* initial %cs relative to load segment */ 39 + uint16_t reloc_table_offset; /* offset of the first relocation */ 40 + uint16_t overlay_num; /* overlay number. set to 0. */ 41 + uint16_t reserved0[4]; /* reserved */ 42 + uint16_t oem_id; /* oem identifier */ 43 + uint16_t oem_info; /* oem specific */ 44 + uint16_t reserved1[10]; /* reserved */ 45 + uint32_t peaddr; /* address of pe header */ 46 + char message[64]; /* message to print */ 47 + }; 48 + 49 + struct mz_reloc { 50 + uint16_t offset; 51 + uint16_t segment; 52 + }; 53 + 54 + #define PE_MAGIC 0x00004550 /* "PE\0\0" */ 55 + #define PE_OPT_MAGIC_PE32 0x010b 56 + #define PE_OPT_MAGIC_PE32_ROM 0x0107 57 + #define PE_OPT_MAGIC_PE32PLUS 0x020b 58 + 59 + /* machine type */ 60 + #define IMAGE_FILE_MACHINE_UNKNOWN 0x0000 61 + #define IMAGE_FILE_MACHINE_AM33 0x01d3 62 + #define IMAGE_FILE_MACHINE_AMD64 0x8664 63 + #define IMAGE_FILE_MACHINE_ARM 0x01c0 64 + #define IMAGE_FILE_MACHINE_ARMV7 0x01c4 65 + #define IMAGE_FILE_MACHINE_EBC 0x0ebc 66 + #define IMAGE_FILE_MACHINE_I386 0x014c 67 + #define IMAGE_FILE_MACHINE_IA64 0x0200 68 + #define IMAGE_FILE_MACHINE_M32R 0x9041 69 + #define IMAGE_FILE_MACHINE_MIPS16 0x0266 70 + #define IMAGE_FILE_MACHINE_MIPSFPU 0x0366 71 + #define IMAGE_FILE_MACHINE_MIPSFPU16 0x0466 72 + #define IMAGE_FILE_MACHINE_POWERPC 0x01f0 73 + #define IMAGE_FILE_MACHINE_POWERPCFP 0x01f1 74 + #define IMAGE_FILE_MACHINE_R4000 0x0166 75 + #define IMAGE_FILE_MACHINE_SH3 0x01a2 76 + #define IMAGE_FILE_MACHINE_SH3DSP 0x01a3 77 + #define IMAGE_FILE_MACHINE_SH3E 0x01a4 78 + #define IMAGE_FILE_MACHINE_SH4 0x01a6 79 + #define IMAGE_FILE_MACHINE_SH5 0x01a8 80 + #define IMAGE_FILE_MACHINE_THUMB 0x01c2 81 + #define IMAGE_FILE_MACHINE_WCEMIPSV2 0x0169 82 + 83 + /* flags */ 84 + #define IMAGE_FILE_RELOCS_STRIPPED 0x0001 85 + #define IMAGE_FILE_EXECUTABLE_IMAGE 0x0002 86 + #define IMAGE_FILE_LINE_NUMS_STRIPPED 0x0004 87 + #define IMAGE_FILE_LOCAL_SYMS_STRIPPED 0x0008 88 + #define IMAGE_FILE_AGGRESSIVE_WS_TRIM 0x0010 89 + #define IMAGE_FILE_LARGE_ADDRESS_AWARE 0x0020 90 + #define IMAGE_FILE_16BIT_MACHINE 0x0040 91 + #define IMAGE_FILE_BYTES_REVERSED_LO 0x0080 92 + #define IMAGE_FILE_32BIT_MACHINE 0x0100 93 + #define IMAGE_FILE_DEBUG_STRIPPED 0x0200 94 + #define IMAGE_FILE_REMOVABLE_RUN_FROM_SWAP 0x0400 95 + #define IMAGE_FILE_NET_RUN_FROM_SWAP 0x0800 96 + #define IMAGE_FILE_SYSTEM 0x1000 97 + #define IMAGE_FILE_DLL 0x2000 98 + #define IMAGE_FILE_UP_SYSTEM_ONLY 0x4000 99 + #define IMAGE_FILE_BYTES_REVERSED_HI 0x8000 100 + 101 + struct pe_hdr { 102 + uint32_t magic; /* PE magic */ 103 + uint16_t machine; /* machine type */ 104 + uint16_t sections; /* number of sections */ 105 + uint32_t timestamp; /* time_t */ 106 + uint32_t symbol_table; /* symbol table offset */ 107 + uint32_t symbols; /* number of symbols */ 108 + uint16_t opt_hdr_size; /* size of optional header */ 109 + uint16_t flags; /* flags */ 110 + }; 111 + 112 + #define IMAGE_FILE_OPT_ROM_MAGIC 0x107 113 + #define IMAGE_FILE_OPT_PE32_MAGIC 0x10b 114 + #define IMAGE_FILE_OPT_PE32_PLUS_MAGIC 0x20b 115 + 116 + #define IMAGE_SUBSYSTEM_UNKNOWN 0 117 + #define IMAGE_SUBSYSTEM_NATIVE 1 118 + #define IMAGE_SUBSYSTEM_WINDOWS_GUI 2 119 + #define IMAGE_SUBSYSTEM_WINDOWS_CUI 3 120 + #define IMAGE_SUBSYSTEM_POSIX_CUI 7 121 + #define IMAGE_SUBSYSTEM_WINDOWS_CE_GUI 9 122 + #define IMAGE_SUBSYSTEM_EFI_APPLICATION 10 123 + #define IMAGE_SUBSYSTEM_EFI_BOOT_SERVICE_DRIVER 11 124 + #define IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIVER 12 125 + #define IMAGE_SUBSYSTEM_EFI_ROM_IMAGE 13 126 + #define IMAGE_SUBSYSTEM_XBOX 14 127 + 128 + #define IMAGE_DLL_CHARACTERISTICS_DYNAMIC_BASE 0x0040 129 + #define IMAGE_DLL_CHARACTERISTICS_FORCE_INTEGRITY 0x0080 130 + #define IMAGE_DLL_CHARACTERISTICS_NX_COMPAT 0x0100 131 + #define IMAGE_DLLCHARACTERISTICS_NO_ISOLATION 0x0200 132 + #define IMAGE_DLLCHARACTERISTICS_NO_SEH 0x0400 133 + #define IMAGE_DLLCHARACTERISTICS_NO_BIND 0x0800 134 + #define IMAGE_DLLCHARACTERISTICS_WDM_DRIVER 0x2000 135 + #define IMAGE_DLLCHARACTERISTICS_TERMINAL_SERVER_AWARE 0x8000 136 + 137 + /* the fact that pe32 isn't padded where pe32+ is 64-bit means union won't 138 + * work right. vomit. */ 139 + struct pe32_opt_hdr { 140 + /* "standard" header */ 141 + uint16_t magic; /* file type */ 142 + uint8_t ld_major; /* linker major version */ 143 + uint8_t ld_minor; /* linker minor version */ 144 + uint32_t text_size; /* size of text section(s) */ 145 + uint32_t data_size; /* size of data section(s) */ 146 + uint32_t bss_size; /* size of bss section(s) */ 147 + uint32_t entry_point; /* file offset of entry point */ 148 + uint32_t code_base; /* relative code addr in ram */ 149 + uint32_t data_base; /* relative data addr in ram */ 150 + /* "windows" header */ 151 + uint32_t image_base; /* preferred load address */ 152 + uint32_t section_align; /* alignment in bytes */ 153 + uint32_t file_align; /* file alignment in bytes */ 154 + uint16_t os_major; /* major OS version */ 155 + uint16_t os_minor; /* minor OS version */ 156 + uint16_t image_major; /* major image version */ 157 + uint16_t image_minor; /* minor image version */ 158 + uint16_t subsys_major; /* major subsystem version */ 159 + uint16_t subsys_minor; /* minor subsystem version */ 160 + uint32_t win32_version; /* reserved, must be 0 */ 161 + uint32_t image_size; /* image size */ 162 + uint32_t header_size; /* header size rounded up to 163 + file_align */ 164 + uint32_t csum; /* checksum */ 165 + uint16_t subsys; /* subsystem */ 166 + uint16_t dll_flags; /* more flags! */ 167 + uint32_t stack_size_req;/* amt of stack requested */ 168 + uint32_t stack_size; /* amt of stack required */ 169 + uint32_t heap_size_req; /* amt of heap requested */ 170 + uint32_t heap_size; /* amt of heap required */ 171 + uint32_t loader_flags; /* reserved, must be 0 */ 172 + uint32_t data_dirs; /* number of data dir entries */ 173 + }; 174 + 175 + struct pe32plus_opt_hdr { 176 + uint16_t magic; /* file type */ 177 + uint8_t ld_major; /* linker major version */ 178 + uint8_t ld_minor; /* linker minor version */ 179 + uint32_t text_size; /* size of text section(s) */ 180 + uint32_t data_size; /* size of data section(s) */ 181 + uint32_t bss_size; /* size of bss section(s) */ 182 + uint32_t entry_point; /* file offset of entry point */ 183 + uint32_t code_base; /* relative code addr in ram */ 184 + /* "windows" header */ 185 + uint64_t image_base; /* preferred load address */ 186 + uint32_t section_align; /* alignment in bytes */ 187 + uint32_t file_align; /* file alignment in bytes */ 188 + uint16_t os_major; /* major OS version */ 189 + uint16_t os_minor; /* minor OS version */ 190 + uint16_t image_major; /* major image version */ 191 + uint16_t image_minor; /* minor image version */ 192 + uint16_t subsys_major; /* major subsystem version */ 193 + uint16_t subsys_minor; /* minor subsystem version */ 194 + uint32_t win32_version; /* reserved, must be 0 */ 195 + uint32_t image_size; /* image size */ 196 + uint32_t header_size; /* header size rounded up to 197 + file_align */ 198 + uint32_t csum; /* checksum */ 199 + uint16_t subsys; /* subsystem */ 200 + uint16_t dll_flags; /* more flags! */ 201 + uint64_t stack_size_req;/* amt of stack requested */ 202 + uint64_t stack_size; /* amt of stack required */ 203 + uint64_t heap_size_req; /* amt of heap requested */ 204 + uint64_t heap_size; /* amt of heap required */ 205 + uint32_t loader_flags; /* reserved, must be 0 */ 206 + uint32_t data_dirs; /* number of data dir entries */ 207 + }; 208 + 209 + struct data_dirent { 210 + uint32_t virtual_address; /* relative to load address */ 211 + uint32_t size; 212 + }; 213 + 214 + struct data_directory { 215 + struct data_dirent exports; /* .edata */ 216 + struct data_dirent imports; /* .idata */ 217 + struct data_dirent resources; /* .rsrc */ 218 + struct data_dirent exceptions; /* .pdata */ 219 + struct data_dirent certs; /* certs */ 220 + struct data_dirent base_relocations; /* .reloc */ 221 + struct data_dirent debug; /* .debug */ 222 + struct data_dirent arch; /* reservered */ 223 + struct data_dirent global_ptr; /* global pointer reg. Size=0 */ 224 + struct data_dirent tls; /* .tls */ 225 + struct data_dirent load_config; /* load configuration structure */ 226 + struct data_dirent bound_imports; /* no idea */ 227 + struct data_dirent import_addrs; /* import address table */ 228 + struct data_dirent delay_imports; /* delay-load import table */ 229 + struct data_dirent clr_runtime_hdr; /* .cor (object only) */ 230 + struct data_dirent reserved; 231 + }; 232 + 233 + struct section_header { 234 + char name[8]; /* name or "/12\0" string tbl offset */ 235 + uint32_t virtual_size; /* size of loaded section in ram */ 236 + uint32_t virtual_address; /* relative virtual address */ 237 + uint32_t raw_data_size; /* size of the section */ 238 + uint32_t data_addr; /* file pointer to first page of sec */ 239 + uint32_t relocs; /* file pointer to relocation entries */ 240 + uint32_t line_numbers; /* line numbers! */ 241 + uint16_t num_relocs; /* number of relocations */ 242 + uint16_t num_lin_numbers; /* srsly. */ 243 + uint32_t flags; 244 + }; 245 + 246 + /* they actually defined 0x00000000 as well, but I think we'll skip that one. */ 247 + #define IMAGE_SCN_RESERVED_0 0x00000001 248 + #define IMAGE_SCN_RESERVED_1 0x00000002 249 + #define IMAGE_SCN_RESERVED_2 0x00000004 250 + #define IMAGE_SCN_TYPE_NO_PAD 0x00000008 /* don't pad - obsolete */ 251 + #define IMAGE_SCN_RESERVED_3 0x00000010 252 + #define IMAGE_SCN_CNT_CODE 0x00000020 /* .text */ 253 + #define IMAGE_SCN_CNT_INITIALIZED_DATA 0x00000040 /* .data */ 254 + #define IMAGE_SCN_CNT_UNINITIALIZED_DATA 0x00000080 /* .bss */ 255 + #define IMAGE_SCN_LNK_OTHER 0x00000100 /* reserved */ 256 + #define IMAGE_SCN_LNK_INFO 0x00000200 /* .drectve comments */ 257 + #define IMAGE_SCN_RESERVED_4 0x00000400 258 + #define IMAGE_SCN_LNK_REMOVE 0x00000800 /* .o only - scn to be rm'd*/ 259 + #define IMAGE_SCN_LNK_COMDAT 0x00001000 /* .o only - COMDAT data */ 260 + #define IMAGE_SCN_RESERVED_5 0x00002000 /* spec omits this */ 261 + #define IMAGE_SCN_RESERVED_6 0x00004000 /* spec omits this */ 262 + #define IMAGE_SCN_GPREL 0x00008000 /* global pointer referenced data */ 263 + /* spec lists 0x20000 twice, I suspect they meant 0x10000 for one of them */ 264 + #define IMAGE_SCN_MEM_PURGEABLE 0x00010000 /* reserved for "future" use */ 265 + #define IMAGE_SCN_16BIT 0x00020000 /* reserved for "future" use */ 266 + #define IMAGE_SCN_LOCKED 0x00040000 /* reserved for "future" use */ 267 + #define IMAGE_SCN_PRELOAD 0x00080000 /* reserved for "future" use */ 268 + /* and here they just stuck a 1-byte integer in the middle of a bitfield */ 269 + #define IMAGE_SCN_ALIGN_1BYTES 0x00100000 /* it does what it says on the box */ 270 + #define IMAGE_SCN_ALIGN_2BYTES 0x00200000 271 + #define IMAGE_SCN_ALIGN_4BYTES 0x00300000 272 + #define IMAGE_SCN_ALIGN_8BYTES 0x00400000 273 + #define IMAGE_SCN_ALIGN_16BYTES 0x00500000 274 + #define IMAGE_SCN_ALIGN_32BYTES 0x00600000 275 + #define IMAGE_SCN_ALIGN_64BYTES 0x00700000 276 + #define IMAGE_SCN_ALIGN_128BYTES 0x00800000 277 + #define IMAGE_SCN_ALIGN_256BYTES 0x00900000 278 + #define IMAGE_SCN_ALIGN_512BYTES 0x00a00000 279 + #define IMAGE_SCN_ALIGN_1024BYTES 0x00b00000 280 + #define IMAGE_SCN_ALIGN_2048BYTES 0x00c00000 281 + #define IMAGE_SCN_ALIGN_4096BYTES 0x00d00000 282 + #define IMAGE_SCN_ALIGN_8192BYTES 0x00e00000 283 + #define IMAGE_SCN_LNK_NRELOC_OVFL 0x01000000 /* extended relocations */ 284 + #define IMAGE_SCN_MEM_DISCARDABLE 0x02000000 /* scn can be discarded */ 285 + #define IMAGE_SCN_MEM_NOT_CACHED 0x04000000 /* cannot be cached */ 286 + #define IMAGE_SCN_MEM_NOT_PAGED 0x08000000 /* not pageable */ 287 + #define IMAGE_SCN_MEM_SHARED 0x10000000 /* can be shared */ 288 + #define IMAGE_SCN_MEM_EXECUTE 0x20000000 /* can be executed as code */ 289 + #define IMAGE_SCN_MEM_READ 0x40000000 /* readable */ 290 + #define IMAGE_SCN_MEM_WRITE 0x80000000 /* writeable */ 291 + 292 + enum x64_coff_reloc_type { 293 + IMAGE_REL_AMD64_ABSOLUTE = 0, 294 + IMAGE_REL_AMD64_ADDR64, 295 + IMAGE_REL_AMD64_ADDR32, 296 + IMAGE_REL_AMD64_ADDR32N, 297 + IMAGE_REL_AMD64_REL32, 298 + IMAGE_REL_AMD64_REL32_1, 299 + IMAGE_REL_AMD64_REL32_2, 300 + IMAGE_REL_AMD64_REL32_3, 301 + IMAGE_REL_AMD64_REL32_4, 302 + IMAGE_REL_AMD64_REL32_5, 303 + IMAGE_REL_AMD64_SECTION, 304 + IMAGE_REL_AMD64_SECREL, 305 + IMAGE_REL_AMD64_SECREL7, 306 + IMAGE_REL_AMD64_TOKEN, 307 + IMAGE_REL_AMD64_SREL32, 308 + IMAGE_REL_AMD64_PAIR, 309 + IMAGE_REL_AMD64_SSPAN32, 310 + }; 311 + 312 + enum arm_coff_reloc_type { 313 + IMAGE_REL_ARM_ABSOLUTE, 314 + IMAGE_REL_ARM_ADDR32, 315 + IMAGE_REL_ARM_ADDR32N, 316 + IMAGE_REL_ARM_BRANCH2, 317 + IMAGE_REL_ARM_BRANCH1, 318 + IMAGE_REL_ARM_SECTION, 319 + IMAGE_REL_ARM_SECREL, 320 + }; 321 + 322 + enum sh_coff_reloc_type { 323 + IMAGE_REL_SH3_ABSOLUTE, 324 + IMAGE_REL_SH3_DIRECT16, 325 + IMAGE_REL_SH3_DIRECT32, 326 + IMAGE_REL_SH3_DIRECT8, 327 + IMAGE_REL_SH3_DIRECT8_WORD, 328 + IMAGE_REL_SH3_DIRECT8_LONG, 329 + IMAGE_REL_SH3_DIRECT4, 330 + IMAGE_REL_SH3_DIRECT4_WORD, 331 + IMAGE_REL_SH3_DIRECT4_LONG, 332 + IMAGE_REL_SH3_PCREL8_WORD, 333 + IMAGE_REL_SH3_PCREL8_LONG, 334 + IMAGE_REL_SH3_PCREL12_WORD, 335 + IMAGE_REL_SH3_STARTOF_SECTION, 336 + IMAGE_REL_SH3_SIZEOF_SECTION, 337 + IMAGE_REL_SH3_SECTION, 338 + IMAGE_REL_SH3_SECREL, 339 + IMAGE_REL_SH3_DIRECT32_NB, 340 + IMAGE_REL_SH3_GPREL4_LONG, 341 + IMAGE_REL_SH3_TOKEN, 342 + IMAGE_REL_SHM_PCRELPT, 343 + IMAGE_REL_SHM_REFLO, 344 + IMAGE_REL_SHM_REFHALF, 345 + IMAGE_REL_SHM_RELLO, 346 + IMAGE_REL_SHM_RELHALF, 347 + IMAGE_REL_SHM_PAIR, 348 + IMAGE_REL_SHM_NOMODE, 349 + }; 350 + 351 + enum ppc_coff_reloc_type { 352 + IMAGE_REL_PPC_ABSOLUTE, 353 + IMAGE_REL_PPC_ADDR64, 354 + IMAGE_REL_PPC_ADDR32, 355 + IMAGE_REL_PPC_ADDR24, 356 + IMAGE_REL_PPC_ADDR16, 357 + IMAGE_REL_PPC_ADDR14, 358 + IMAGE_REL_PPC_REL24, 359 + IMAGE_REL_PPC_REL14, 360 + IMAGE_REL_PPC_ADDR32N, 361 + IMAGE_REL_PPC_SECREL, 362 + IMAGE_REL_PPC_SECTION, 363 + IMAGE_REL_PPC_SECREL16, 364 + IMAGE_REL_PPC_REFHI, 365 + IMAGE_REL_PPC_REFLO, 366 + IMAGE_REL_PPC_PAIR, 367 + IMAGE_REL_PPC_SECRELLO, 368 + IMAGE_REL_PPC_GPREL, 369 + IMAGE_REL_PPC_TOKEN, 370 + }; 371 + 372 + enum x86_coff_reloc_type { 373 + IMAGE_REL_I386_ABSOLUTE, 374 + IMAGE_REL_I386_DIR16, 375 + IMAGE_REL_I386_REL16, 376 + IMAGE_REL_I386_DIR32, 377 + IMAGE_REL_I386_DIR32NB, 378 + IMAGE_REL_I386_SEG12, 379 + IMAGE_REL_I386_SECTION, 380 + IMAGE_REL_I386_SECREL, 381 + IMAGE_REL_I386_TOKEN, 382 + IMAGE_REL_I386_SECREL7, 383 + IMAGE_REL_I386_REL32, 384 + }; 385 + 386 + enum ia64_coff_reloc_type { 387 + IMAGE_REL_IA64_ABSOLUTE, 388 + IMAGE_REL_IA64_IMM14, 389 + IMAGE_REL_IA64_IMM22, 390 + IMAGE_REL_IA64_IMM64, 391 + IMAGE_REL_IA64_DIR32, 392 + IMAGE_REL_IA64_DIR64, 393 + IMAGE_REL_IA64_PCREL21B, 394 + IMAGE_REL_IA64_PCREL21M, 395 + IMAGE_REL_IA64_PCREL21F, 396 + IMAGE_REL_IA64_GPREL22, 397 + IMAGE_REL_IA64_LTOFF22, 398 + IMAGE_REL_IA64_SECTION, 399 + IMAGE_REL_IA64_SECREL22, 400 + IMAGE_REL_IA64_SECREL64I, 401 + IMAGE_REL_IA64_SECREL32, 402 + IMAGE_REL_IA64_DIR32NB, 403 + IMAGE_REL_IA64_SREL14, 404 + IMAGE_REL_IA64_SREL22, 405 + IMAGE_REL_IA64_SREL32, 406 + IMAGE_REL_IA64_UREL32, 407 + IMAGE_REL_IA64_PCREL60X, 408 + IMAGE_REL_IA64_PCREL60B, 409 + IMAGE_REL_IA64_PCREL60F, 410 + IMAGE_REL_IA64_PCREL60I, 411 + IMAGE_REL_IA64_PCREL60M, 412 + IMAGE_REL_IA64_IMMGPREL6, 413 + IMAGE_REL_IA64_TOKEN, 414 + IMAGE_REL_IA64_GPREL32, 415 + IMAGE_REL_IA64_ADDEND, 416 + }; 417 + 418 + struct coff_reloc { 419 + uint32_t virtual_address; 420 + uint32_t symbol_table_index; 421 + union { 422 + enum x64_coff_reloc_type x64_type; 423 + enum arm_coff_reloc_type arm_type; 424 + enum sh_coff_reloc_type sh_type; 425 + enum ppc_coff_reloc_type ppc_type; 426 + enum x86_coff_reloc_type x86_type; 427 + enum ia64_coff_reloc_type ia64_type; 428 + uint16_t data; 429 + }; 430 + }; 431 + 432 + /* 433 + * Definitions for the contents of the certs data block 434 + */ 435 + #define WIN_CERT_TYPE_PKCS_SIGNED_DATA 0x0002 436 + #define WIN_CERT_TYPE_EFI_OKCS115 0x0EF0 437 + #define WIN_CERT_TYPE_EFI_GUID 0x0EF1 438 + 439 + #define WIN_CERT_REVISION_1_0 0x0100 440 + #define WIN_CERT_REVISION_2_0 0x0200 441 + 442 + struct win_certificate { 443 + uint32_t length; 444 + uint16_t revision; 445 + uint16_t cert_type; 446 + }; 447 + 448 + #endif /* __LINUX_PE_H */
+15 -3
include/linux/sched.h
··· 1304 1304 * execve */ 1305 1305 unsigned in_iowait:1; 1306 1306 1307 - /* task may not gain privileges */ 1308 - unsigned no_new_privs:1; 1309 - 1310 1307 /* Revert to default priority/policy when forking */ 1311 1308 unsigned sched_reset_on_fork:1; 1312 1309 unsigned sched_contributes_to_load:1; 1310 + 1311 + unsigned long atomic_flags; /* Flags needing atomic access. */ 1313 1312 1314 1313 pid_t pid; 1315 1314 pid_t tgid; ··· 1959 1960 static inline void memalloc_noio_restore(unsigned int flags) 1960 1961 { 1961 1962 current->flags = (current->flags & ~PF_MEMALLOC_NOIO) | flags; 1963 + } 1964 + 1965 + /* Per-process atomic flags. */ 1966 + #define PFA_NO_NEW_PRIVS 0x00000001 /* May not gain new privileges. */ 1967 + 1968 + static inline bool task_no_new_privs(struct task_struct *p) 1969 + { 1970 + return test_bit(PFA_NO_NEW_PRIVS, &p->atomic_flags); 1971 + } 1972 + 1973 + static inline void task_set_no_new_privs(struct task_struct *p) 1974 + { 1975 + set_bit(PFA_NO_NEW_PRIVS, &p->atomic_flags); 1962 1976 } 1963 1977 1964 1978 /*
+5 -3
include/linux/seccomp.h
··· 3 3 4 4 #include <uapi/linux/seccomp.h> 5 5 6 + #define SECCOMP_FILTER_FLAG_MASK (SECCOMP_FILTER_FLAG_TSYNC) 7 + 6 8 #ifdef CONFIG_SECCOMP 7 9 8 10 #include <linux/thread_info.h> ··· 16 14 * 17 15 * @mode: indicates one of the valid values above for controlled 18 16 * system calls available to a process. 19 - * @filter: The metadata and ruleset for determining what system calls 20 - * are allowed for a task. 17 + * @filter: must always point to a valid seccomp-filter or NULL as it is 18 + * accessed without locking during system call entry. 21 19 * 22 20 * @filter must only be accessed from the context of current as there 23 - * is no locking. 21 + * is no read locking. 24 22 */ 25 23 struct seccomp { 26 24 int mode;
+17
include/linux/security.h
··· 702 702 * @inode points to the inode to use as a reference. 703 703 * The current task must be the one that nominated @inode. 704 704 * Return 0 if successful. 705 + * @kernel_fw_from_file: 706 + * Load firmware from userspace (not called for built-in firmware). 707 + * @file contains the file structure pointing to the file containing 708 + * the firmware to load. This argument will be NULL if the firmware 709 + * was loaded via the uevent-triggered blob-based interface exposed 710 + * by CONFIG_FW_LOADER_USER_HELPER. 711 + * @buf pointer to buffer containing firmware contents. 712 + * @size length of the firmware contents. 713 + * Return 0 if permission is granted. 705 714 * @kernel_module_request: 706 715 * Ability to trigger the kernel to automatically upcall to userspace for 707 716 * userspace to load a kernel module with the given name. ··· 1574 1565 void (*cred_transfer)(struct cred *new, const struct cred *old); 1575 1566 int (*kernel_act_as)(struct cred *new, u32 secid); 1576 1567 int (*kernel_create_files_as)(struct cred *new, struct inode *inode); 1568 + int (*kernel_fw_from_file)(struct file *file, char *buf, size_t size); 1577 1569 int (*kernel_module_request)(char *kmod_name); 1578 1570 int (*kernel_module_from_file)(struct file *file); 1579 1571 int (*task_fix_setuid) (struct cred *new, const struct cred *old, ··· 1847 1837 void security_transfer_creds(struct cred *new, const struct cred *old); 1848 1838 int security_kernel_act_as(struct cred *new, u32 secid); 1849 1839 int security_kernel_create_files_as(struct cred *new, struct inode *inode); 1840 + int security_kernel_fw_from_file(struct file *file, char *buf, size_t size); 1850 1841 int security_kernel_module_request(char *kmod_name); 1851 1842 int security_kernel_module_from_file(struct file *file); 1852 1843 int security_task_fix_setuid(struct cred *new, const struct cred *old, ··· 2370 2359 2371 2360 static inline int security_kernel_create_files_as(struct cred *cred, 2372 2361 struct inode *inode) 2362 + { 2363 + return 0; 2364 + } 2365 + 2366 + static inline int security_kernel_fw_from_file(struct file *file, 2367 + char *buf, size_t size) 2373 2368 { 2374 2369 return 0; 2375 2370 }
+2
include/linux/syscalls.h
··· 866 866 asmlinkage long sys_kcmp(pid_t pid1, pid_t pid2, int type, 867 867 unsigned long idx1, unsigned long idx2); 868 868 asmlinkage long sys_finit_module(int fd, const char __user *uargs, int flags); 869 + asmlinkage long sys_seccomp(unsigned int op, unsigned int flags, 870 + const char __user *uargs); 869 871 #endif
+3
include/linux/tpm.h
··· 39 39 int (*send) (struct tpm_chip *chip, u8 *buf, size_t len); 40 40 void (*cancel) (struct tpm_chip *chip); 41 41 u8 (*status) (struct tpm_chip *chip); 42 + bool (*update_timeouts)(struct tpm_chip *chip, 43 + unsigned long *timeout_cap); 44 + 42 45 }; 43 46 44 47 #if defined(CONFIG_TCG_TPM) || defined(CONFIG_TCG_TPM_MODULE)
+18
include/linux/verify_pefile.h
··· 1 + /* Signed PE file verification 2 + * 3 + * Copyright (C) 2014 Red Hat, Inc. All Rights Reserved. 4 + * Written by David Howells (dhowells@redhat.com) 5 + * 6 + * This program is free software; you can redistribute it and/or 7 + * modify it under the terms of the GNU General Public Licence 8 + * as published by the Free Software Foundation; either version 9 + * 2 of the Licence, or (at your option) any later version. 10 + */ 11 + 12 + #ifndef _LINUX_VERIFY_PEFILE_H 13 + #define _LINUX_VERIFY_PEFILE_H 14 + 15 + extern int verify_pefile_signature(const void *pebuf, unsigned pelen, 16 + struct key *trusted_keyring, bool *_trusted); 17 + 18 + #endif /* _LINUX_VERIFY_PEFILE_H */
+53 -41
include/net/netlabel.h
··· 139 139 }; 140 140 141 141 /** 142 - * struct netlbl_lsm_secattr_catmap - NetLabel LSM secattr category bitmap 142 + * struct netlbl_lsm_catmap - NetLabel LSM secattr category bitmap 143 143 * @startbit: the value of the lowest order bit in the bitmap 144 144 * @bitmap: the category bitmap 145 145 * @next: pointer to the next bitmap "node" or NULL ··· 162 162 #define NETLBL_CATMAP_SIZE (NETLBL_CATMAP_MAPSIZE * \ 163 163 NETLBL_CATMAP_MAPCNT) 164 164 #define NETLBL_CATMAP_BIT (NETLBL_CATMAP_MAPTYPE)0x01 165 - struct netlbl_lsm_secattr_catmap { 165 + struct netlbl_lsm_catmap { 166 166 u32 startbit; 167 167 NETLBL_CATMAP_MAPTYPE bitmap[NETLBL_CATMAP_MAPCNT]; 168 - struct netlbl_lsm_secattr_catmap *next; 168 + struct netlbl_lsm_catmap *next; 169 169 }; 170 170 171 171 /** ··· 209 209 struct netlbl_lsm_cache *cache; 210 210 struct { 211 211 struct { 212 - struct netlbl_lsm_secattr_catmap *cat; 212 + struct netlbl_lsm_catmap *cat; 213 213 u32 lvl; 214 214 } mls; 215 215 u32 secid; ··· 258 258 } 259 259 260 260 /** 261 - * netlbl_secattr_catmap_alloc - Allocate a LSM secattr catmap 261 + * netlbl_catmap_alloc - Allocate a LSM secattr catmap 262 262 * @flags: memory allocation flags 263 263 * 264 264 * Description: ··· 266 266 * on failure. 267 267 * 268 268 */ 269 - static inline struct netlbl_lsm_secattr_catmap *netlbl_secattr_catmap_alloc( 270 - gfp_t flags) 269 + static inline struct netlbl_lsm_catmap *netlbl_catmap_alloc(gfp_t flags) 271 270 { 272 - return kzalloc(sizeof(struct netlbl_lsm_secattr_catmap), flags); 271 + return kzalloc(sizeof(struct netlbl_lsm_catmap), flags); 273 272 } 274 273 275 274 /** 276 - * netlbl_secattr_catmap_free - Free a LSM secattr catmap 275 + * netlbl_catmap_free - Free a LSM secattr catmap 277 276 * @catmap: the category bitmap 278 277 * 279 278 * Description: 280 279 * Free a LSM secattr catmap. 281 280 * 282 281 */ 283 - static inline void netlbl_secattr_catmap_free( 284 - struct netlbl_lsm_secattr_catmap *catmap) 282 + static inline void netlbl_catmap_free(struct netlbl_lsm_catmap *catmap) 285 283 { 286 - struct netlbl_lsm_secattr_catmap *iter; 284 + struct netlbl_lsm_catmap *iter; 287 285 288 - do { 286 + while (catmap) { 289 287 iter = catmap; 290 288 catmap = catmap->next; 291 289 kfree(iter); 292 - } while (catmap); 290 + } 293 291 } 294 292 295 293 /** ··· 319 321 if (secattr->flags & NETLBL_SECATTR_CACHE) 320 322 netlbl_secattr_cache_free(secattr->cache); 321 323 if (secattr->flags & NETLBL_SECATTR_MLS_CAT) 322 - netlbl_secattr_catmap_free(secattr->attr.mls.cat); 324 + netlbl_catmap_free(secattr->attr.mls.cat); 323 325 } 324 326 325 327 /** ··· 388 390 /* 389 391 * LSM security attribute operations 390 392 */ 391 - int netlbl_secattr_catmap_walk(struct netlbl_lsm_secattr_catmap *catmap, 392 - u32 offset); 393 - int netlbl_secattr_catmap_walk_rng(struct netlbl_lsm_secattr_catmap *catmap, 394 - u32 offset); 395 - int netlbl_secattr_catmap_setbit(struct netlbl_lsm_secattr_catmap *catmap, 396 - u32 bit, 397 - gfp_t flags); 398 - int netlbl_secattr_catmap_setrng(struct netlbl_lsm_secattr_catmap *catmap, 399 - u32 start, 400 - u32 end, 401 - gfp_t flags); 393 + int netlbl_catmap_walk(struct netlbl_lsm_catmap *catmap, u32 offset); 394 + int netlbl_catmap_walkrng(struct netlbl_lsm_catmap *catmap, u32 offset); 395 + int netlbl_catmap_getlong(struct netlbl_lsm_catmap *catmap, 396 + u32 *offset, 397 + unsigned long *bitmap); 398 + int netlbl_catmap_setbit(struct netlbl_lsm_catmap **catmap, 399 + u32 bit, 400 + gfp_t flags); 401 + int netlbl_catmap_setrng(struct netlbl_lsm_catmap **catmap, 402 + u32 start, 403 + u32 end, 404 + gfp_t flags); 405 + int netlbl_catmap_setlong(struct netlbl_lsm_catmap **catmap, 406 + u32 offset, 407 + unsigned long bitmap, 408 + gfp_t flags); 402 409 403 410 /* 404 411 * LSM protocol operations (NetLabel LSM/kernel API) ··· 495 492 { 496 493 return -ENOSYS; 497 494 } 498 - static inline int netlbl_secattr_catmap_walk( 499 - struct netlbl_lsm_secattr_catmap *catmap, 500 - u32 offset) 495 + static inline int netlbl_catmap_walk(struct netlbl_lsm_catmap *catmap, 496 + u32 offset) 501 497 { 502 498 return -ENOENT; 503 499 } 504 - static inline int netlbl_secattr_catmap_walk_rng( 505 - struct netlbl_lsm_secattr_catmap *catmap, 506 - u32 offset) 500 + static inline int netlbl_catmap_walkrng(struct netlbl_lsm_catmap *catmap, 501 + u32 offset) 507 502 { 508 503 return -ENOENT; 509 504 } 510 - static inline int netlbl_secattr_catmap_setbit( 511 - struct netlbl_lsm_secattr_catmap *catmap, 512 - u32 bit, 513 - gfp_t flags) 505 + static inline int netlbl_catmap_getlong(struct netlbl_lsm_catmap *catmap, 506 + u32 *offset, 507 + unsigned long *bitmap) 514 508 { 515 509 return 0; 516 510 } 517 - static inline int netlbl_secattr_catmap_setrng( 518 - struct netlbl_lsm_secattr_catmap *catmap, 519 - u32 start, 520 - u32 end, 521 - gfp_t flags) 511 + static inline int netlbl_catmap_setbit(struct netlbl_lsm_catmap **catmap, 512 + u32 bit, 513 + gfp_t flags) 514 + { 515 + return 0; 516 + } 517 + static inline int netlbl_catmap_setrng(struct netlbl_lsm_catmap **catmap, 518 + u32 start, 519 + u32 end, 520 + gfp_t flags) 521 + { 522 + return 0; 523 + } 524 + static int netlbl_catmap_setlong(struct netlbl_lsm_catmap **catmap, 525 + u32 offset, 526 + unsigned long bitmap, 527 + gfp_t flags) 522 528 { 523 529 return 0; 524 530 }
+3 -1
include/uapi/asm-generic/unistd.h
··· 699 699 __SYSCALL(__NR_sched_getattr, sys_sched_getattr) 700 700 #define __NR_renameat2 276 701 701 __SYSCALL(__NR_renameat2, sys_renameat2) 702 + #define __NR_seccomp 277 703 + __SYSCALL(__NR_seccomp, sys_seccomp) 702 704 703 705 #undef __NR_syscalls 704 - #define __NR_syscalls 277 706 + #define __NR_syscalls 278 705 707 706 708 /* 707 709 * All syscalls below here should go away really,
+7
include/uapi/linux/seccomp.h
··· 10 10 #define SECCOMP_MODE_STRICT 1 /* uses hard-coded filter. */ 11 11 #define SECCOMP_MODE_FILTER 2 /* uses user-supplied filter. */ 12 12 13 + /* Valid operations for seccomp syscall. */ 14 + #define SECCOMP_SET_MODE_STRICT 0 15 + #define SECCOMP_SET_MODE_FILTER 1 16 + 17 + /* Valid flags for SECCOMP_SET_MODE_FILTER */ 18 + #define SECCOMP_FILTER_FLAG_TSYNC 1 19 + 13 20 /* 14 21 * All BPF programs must return a 32-bit value. 15 22 * The bottom 16-bits are for optional return data.
+1 -1
kernel/audit.c
··· 1677 1677 audit_log_format(ab, " %s=", prefix); 1678 1678 CAP_FOR_EACH_U32(i) { 1679 1679 audit_log_format(ab, "%08x", 1680 - cap->cap[(_KERNEL_CAPABILITY_U32S-1) - i]); 1680 + cap->cap[CAP_LAST_U32 - i]); 1681 1681 } 1682 1682 } 1683 1683
+4
kernel/capability.c
··· 258 258 i++; 259 259 } 260 260 261 + effective.cap[CAP_LAST_U32] &= CAP_LAST_U32_VALID_MASK; 262 + permitted.cap[CAP_LAST_U32] &= CAP_LAST_U32_VALID_MASK; 263 + inheritable.cap[CAP_LAST_U32] &= CAP_LAST_U32_VALID_MASK; 264 + 261 265 new = prepare_creds(); 262 266 if (!new) 263 267 return -ENOMEM;
+48 -1
kernel/fork.c
··· 315 315 goto free_ti; 316 316 317 317 tsk->stack = ti; 318 + #ifdef CONFIG_SECCOMP 319 + /* 320 + * We must handle setting up seccomp filters once we're under 321 + * the sighand lock in case orig has changed between now and 322 + * then. Until then, filter must be NULL to avoid messing up 323 + * the usage counts on the error path calling free_task. 324 + */ 325 + tsk->seccomp.filter = NULL; 326 + #endif 318 327 319 328 setup_thread_stack(tsk, orig); 320 329 clear_user_return_notifier(tsk); ··· 1090 1081 return 0; 1091 1082 } 1092 1083 1084 + static void copy_seccomp(struct task_struct *p) 1085 + { 1086 + #ifdef CONFIG_SECCOMP 1087 + /* 1088 + * Must be called with sighand->lock held, which is common to 1089 + * all threads in the group. Holding cred_guard_mutex is not 1090 + * needed because this new task is not yet running and cannot 1091 + * be racing exec. 1092 + */ 1093 + BUG_ON(!spin_is_locked(&current->sighand->siglock)); 1094 + 1095 + /* Ref-count the new filter user, and assign it. */ 1096 + get_seccomp_filter(current); 1097 + p->seccomp = current->seccomp; 1098 + 1099 + /* 1100 + * Explicitly enable no_new_privs here in case it got set 1101 + * between the task_struct being duplicated and holding the 1102 + * sighand lock. The seccomp state and nnp must be in sync. 1103 + */ 1104 + if (task_no_new_privs(current)) 1105 + task_set_no_new_privs(p); 1106 + 1107 + /* 1108 + * If the parent gained a seccomp mode after copying thread 1109 + * flags and between before we held the sighand lock, we have 1110 + * to manually enable the seccomp thread flag here. 1111 + */ 1112 + if (p->seccomp.mode != SECCOMP_MODE_DISABLED) 1113 + set_tsk_thread_flag(p, TIF_SECCOMP); 1114 + #endif 1115 + } 1116 + 1093 1117 SYSCALL_DEFINE1(set_tid_address, int __user *, tidptr) 1094 1118 { 1095 1119 current->clear_child_tid = tidptr; ··· 1237 1195 goto fork_out; 1238 1196 1239 1197 ftrace_graph_init_task(p); 1240 - get_seccomp_filter(p); 1241 1198 1242 1199 rt_mutex_init_task(p); 1243 1200 ··· 1474 1433 } 1475 1434 1476 1435 spin_lock(&current->sighand->siglock); 1436 + 1437 + /* 1438 + * Copy seccomp details explicitly here, in case they were changed 1439 + * before holding sighand lock. 1440 + */ 1441 + copy_seccomp(p); 1477 1442 1478 1443 /* 1479 1444 * Process group and session signals need to be delivered to just the
+354 -60
kernel/seccomp.c
··· 18 18 #include <linux/compat.h> 19 19 #include <linux/sched.h> 20 20 #include <linux/seccomp.h> 21 + #include <linux/slab.h> 22 + #include <linux/syscalls.h> 21 23 22 24 /* #define SECCOMP_DEBUG 1 */ 23 25 24 26 #ifdef CONFIG_SECCOMP_FILTER 25 27 #include <asm/syscall.h> 26 28 #include <linux/filter.h> 29 + #include <linux/pid.h> 27 30 #include <linux/ptrace.h> 28 31 #include <linux/security.h> 29 - #include <linux/slab.h> 30 32 #include <linux/tracehook.h> 31 33 #include <linux/uaccess.h> 32 34 ··· 174 172 */ 175 173 static u32 seccomp_run_filters(int syscall) 176 174 { 177 - struct seccomp_filter *f; 175 + struct seccomp_filter *f = ACCESS_ONCE(current->seccomp.filter); 178 176 struct seccomp_data sd; 179 177 u32 ret = SECCOMP_RET_ALLOW; 180 178 181 179 /* Ensure unexpected behavior doesn't result in failing open. */ 182 - if (WARN_ON(current->seccomp.filter == NULL)) 180 + if (unlikely(WARN_ON(f == NULL))) 183 181 return SECCOMP_RET_KILL; 182 + 183 + /* Make sure cross-thread synced filter points somewhere sane. */ 184 + smp_read_barrier_depends(); 184 185 185 186 populate_seccomp_data(&sd); 186 187 ··· 191 186 * All filters in the list are evaluated and the lowest BPF return 192 187 * value always takes priority (ignoring the DATA). 193 188 */ 194 - for (f = current->seccomp.filter; f; f = f->prev) { 189 + for (; f; f = f->prev) { 195 190 u32 cur_ret = SK_RUN_FILTER(f->prog, (void *)&sd); 196 191 197 192 if ((cur_ret & SECCOMP_RET_ACTION) < (ret & SECCOMP_RET_ACTION)) ··· 199 194 } 200 195 return ret; 201 196 } 197 + #endif /* CONFIG_SECCOMP_FILTER */ 198 + 199 + static inline bool seccomp_may_assign_mode(unsigned long seccomp_mode) 200 + { 201 + BUG_ON(!spin_is_locked(&current->sighand->siglock)); 202 + 203 + if (current->seccomp.mode && current->seccomp.mode != seccomp_mode) 204 + return false; 205 + 206 + return true; 207 + } 208 + 209 + static inline void seccomp_assign_mode(struct task_struct *task, 210 + unsigned long seccomp_mode) 211 + { 212 + BUG_ON(!spin_is_locked(&task->sighand->siglock)); 213 + 214 + task->seccomp.mode = seccomp_mode; 215 + /* 216 + * Make sure TIF_SECCOMP cannot be set before the mode (and 217 + * filter) is set. 218 + */ 219 + smp_mb__before_atomic(); 220 + set_tsk_thread_flag(task, TIF_SECCOMP); 221 + } 222 + 223 + #ifdef CONFIG_SECCOMP_FILTER 224 + /* Returns 1 if the parent is an ancestor of the child. */ 225 + static int is_ancestor(struct seccomp_filter *parent, 226 + struct seccomp_filter *child) 227 + { 228 + /* NULL is the root ancestor. */ 229 + if (parent == NULL) 230 + return 1; 231 + for (; child; child = child->prev) 232 + if (child == parent) 233 + return 1; 234 + return 0; 235 + } 202 236 203 237 /** 204 - * seccomp_attach_filter: Attaches a seccomp filter to current. 238 + * seccomp_can_sync_threads: checks if all threads can be synchronized 239 + * 240 + * Expects sighand and cred_guard_mutex locks to be held. 241 + * 242 + * Returns 0 on success, -ve on error, or the pid of a thread which was 243 + * either not in the correct seccomp mode or it did not have an ancestral 244 + * seccomp filter. 245 + */ 246 + static inline pid_t seccomp_can_sync_threads(void) 247 + { 248 + struct task_struct *thread, *caller; 249 + 250 + BUG_ON(!mutex_is_locked(&current->signal->cred_guard_mutex)); 251 + BUG_ON(!spin_is_locked(&current->sighand->siglock)); 252 + 253 + /* Validate all threads being eligible for synchronization. */ 254 + caller = current; 255 + for_each_thread(caller, thread) { 256 + pid_t failed; 257 + 258 + /* Skip current, since it is initiating the sync. */ 259 + if (thread == caller) 260 + continue; 261 + 262 + if (thread->seccomp.mode == SECCOMP_MODE_DISABLED || 263 + (thread->seccomp.mode == SECCOMP_MODE_FILTER && 264 + is_ancestor(thread->seccomp.filter, 265 + caller->seccomp.filter))) 266 + continue; 267 + 268 + /* Return the first thread that cannot be synchronized. */ 269 + failed = task_pid_vnr(thread); 270 + /* If the pid cannot be resolved, then return -ESRCH */ 271 + if (unlikely(WARN_ON(failed == 0))) 272 + failed = -ESRCH; 273 + return failed; 274 + } 275 + 276 + return 0; 277 + } 278 + 279 + /** 280 + * seccomp_sync_threads: sets all threads to use current's filter 281 + * 282 + * Expects sighand and cred_guard_mutex locks to be held, and for 283 + * seccomp_can_sync_threads() to have returned success already 284 + * without dropping the locks. 285 + * 286 + */ 287 + static inline void seccomp_sync_threads(void) 288 + { 289 + struct task_struct *thread, *caller; 290 + 291 + BUG_ON(!mutex_is_locked(&current->signal->cred_guard_mutex)); 292 + BUG_ON(!spin_is_locked(&current->sighand->siglock)); 293 + 294 + /* Synchronize all threads. */ 295 + caller = current; 296 + for_each_thread(caller, thread) { 297 + /* Skip current, since it needs no changes. */ 298 + if (thread == caller) 299 + continue; 300 + 301 + /* Get a task reference for the new leaf node. */ 302 + get_seccomp_filter(caller); 303 + /* 304 + * Drop the task reference to the shared ancestor since 305 + * current's path will hold a reference. (This also 306 + * allows a put before the assignment.) 307 + */ 308 + put_seccomp_filter(thread); 309 + smp_store_release(&thread->seccomp.filter, 310 + caller->seccomp.filter); 311 + /* 312 + * Opt the other thread into seccomp if needed. 313 + * As threads are considered to be trust-realm 314 + * equivalent (see ptrace_may_access), it is safe to 315 + * allow one thread to transition the other. 316 + */ 317 + if (thread->seccomp.mode == SECCOMP_MODE_DISABLED) { 318 + /* 319 + * Don't let an unprivileged task work around 320 + * the no_new_privs restriction by creating 321 + * a thread that sets it up, enters seccomp, 322 + * then dies. 323 + */ 324 + if (task_no_new_privs(caller)) 325 + task_set_no_new_privs(thread); 326 + 327 + seccomp_assign_mode(thread, SECCOMP_MODE_FILTER); 328 + } 329 + } 330 + } 331 + 332 + /** 333 + * seccomp_prepare_filter: Prepares a seccomp filter for use. 205 334 * @fprog: BPF program to install 206 335 * 207 - * Returns 0 on success or an errno on failure. 336 + * Returns filter on success or an ERR_PTR on failure. 208 337 */ 209 - static long seccomp_attach_filter(struct sock_fprog *fprog) 338 + static struct seccomp_filter *seccomp_prepare_filter(struct sock_fprog *fprog) 210 339 { 211 340 struct seccomp_filter *filter; 212 - unsigned long fp_size = fprog->len * sizeof(struct sock_filter); 213 - unsigned long total_insns = fprog->len; 341 + unsigned long fp_size; 214 342 struct sock_filter *fp; 215 343 int new_len; 216 344 long ret; 217 345 218 346 if (fprog->len == 0 || fprog->len > BPF_MAXINSNS) 219 - return -EINVAL; 220 - 221 - for (filter = current->seccomp.filter; filter; filter = filter->prev) 222 - total_insns += filter->prog->len + 4; /* include a 4 instr penalty */ 223 - if (total_insns > MAX_INSNS_PER_PATH) 224 - return -ENOMEM; 347 + return ERR_PTR(-EINVAL); 348 + BUG_ON(INT_MAX / fprog->len < sizeof(struct sock_filter)); 349 + fp_size = fprog->len * sizeof(struct sock_filter); 225 350 226 351 /* 227 352 * Installing a seccomp filter requires that the task has ··· 359 224 * This avoids scenarios where unprivileged tasks can affect the 360 225 * behavior of privileged children. 361 226 */ 362 - if (!current->no_new_privs && 227 + if (!task_no_new_privs(current) && 363 228 security_capable_noaudit(current_cred(), current_user_ns(), 364 229 CAP_SYS_ADMIN) != 0) 365 - return -EACCES; 230 + return ERR_PTR(-EACCES); 366 231 367 232 fp = kzalloc(fp_size, GFP_KERNEL|__GFP_NOWARN); 368 233 if (!fp) 369 - return -ENOMEM; 234 + return ERR_PTR(-ENOMEM); 370 235 371 236 /* Copy the instructions from fprog. */ 372 237 ret = -EFAULT; ··· 410 275 411 276 sk_filter_select_runtime(filter->prog); 412 277 413 - /* 414 - * If there is an existing filter, make it the prev and don't drop its 415 - * task reference. 416 - */ 417 - filter->prev = current->seccomp.filter; 418 - current->seccomp.filter = filter; 419 - return 0; 278 + return filter; 420 279 421 280 free_filter_prog: 422 281 kfree(filter->prog); ··· 418 289 kfree(filter); 419 290 free_prog: 420 291 kfree(fp); 421 - return ret; 292 + return ERR_PTR(ret); 422 293 } 423 294 424 295 /** 425 - * seccomp_attach_user_filter - attaches a user-supplied sock_fprog 296 + * seccomp_prepare_user_filter - prepares a user-supplied sock_fprog 426 297 * @user_filter: pointer to the user data containing a sock_fprog. 427 298 * 428 299 * Returns 0 on success and non-zero otherwise. 429 300 */ 430 - static long seccomp_attach_user_filter(char __user *user_filter) 301 + static struct seccomp_filter * 302 + seccomp_prepare_user_filter(const char __user *user_filter) 431 303 { 432 304 struct sock_fprog fprog; 433 - long ret = -EFAULT; 305 + struct seccomp_filter *filter = ERR_PTR(-EFAULT); 434 306 435 307 #ifdef CONFIG_COMPAT 436 308 if (is_compat_task()) { ··· 444 314 #endif 445 315 if (copy_from_user(&fprog, user_filter, sizeof(fprog))) 446 316 goto out; 447 - ret = seccomp_attach_filter(&fprog); 317 + filter = seccomp_prepare_filter(&fprog); 448 318 out: 449 - return ret; 319 + return filter; 320 + } 321 + 322 + /** 323 + * seccomp_attach_filter: validate and attach filter 324 + * @flags: flags to change filter behavior 325 + * @filter: seccomp filter to add to the current process 326 + * 327 + * Caller must be holding current->sighand->siglock lock. 328 + * 329 + * Returns 0 on success, -ve on error. 330 + */ 331 + static long seccomp_attach_filter(unsigned int flags, 332 + struct seccomp_filter *filter) 333 + { 334 + unsigned long total_insns; 335 + struct seccomp_filter *walker; 336 + 337 + BUG_ON(!spin_is_locked(&current->sighand->siglock)); 338 + 339 + /* Validate resulting filter length. */ 340 + total_insns = filter->prog->len; 341 + for (walker = current->seccomp.filter; walker; walker = walker->prev) 342 + total_insns += walker->prog->len + 4; /* 4 instr penalty */ 343 + if (total_insns > MAX_INSNS_PER_PATH) 344 + return -ENOMEM; 345 + 346 + /* If thread sync has been requested, check that it is possible. */ 347 + if (flags & SECCOMP_FILTER_FLAG_TSYNC) { 348 + int ret; 349 + 350 + ret = seccomp_can_sync_threads(); 351 + if (ret) 352 + return ret; 353 + } 354 + 355 + /* 356 + * If there is an existing filter, make it the prev and don't drop its 357 + * task reference. 358 + */ 359 + filter->prev = current->seccomp.filter; 360 + current->seccomp.filter = filter; 361 + 362 + /* Now that the new filter is in place, synchronize to all threads. */ 363 + if (flags & SECCOMP_FILTER_FLAG_TSYNC) 364 + seccomp_sync_threads(); 365 + 366 + return 0; 450 367 } 451 368 452 369 /* get_seccomp_filter - increments the reference count of the filter on @tsk */ ··· 506 329 atomic_inc(&orig->usage); 507 330 } 508 331 332 + static inline void seccomp_filter_free(struct seccomp_filter *filter) 333 + { 334 + if (filter) { 335 + sk_filter_free(filter->prog); 336 + kfree(filter); 337 + } 338 + } 339 + 509 340 /* put_seccomp_filter - decrements the ref count of tsk->seccomp.filter */ 510 341 void put_seccomp_filter(struct task_struct *tsk) 511 342 { ··· 522 337 while (orig && atomic_dec_and_test(&orig->usage)) { 523 338 struct seccomp_filter *freeme = orig; 524 339 orig = orig->prev; 525 - sk_filter_free(freeme->prog); 526 - kfree(freeme); 340 + seccomp_filter_free(freeme); 527 341 } 528 342 } 529 343 ··· 566 382 567 383 int __secure_computing(int this_syscall) 568 384 { 569 - int mode = current->seccomp.mode; 570 385 int exit_sig = 0; 571 386 int *syscall; 572 387 u32 ret; 573 388 574 - switch (mode) { 389 + /* 390 + * Make sure that any changes to mode from another thread have 391 + * been seen after TIF_SECCOMP was seen. 392 + */ 393 + rmb(); 394 + 395 + switch (current->seccomp.mode) { 575 396 case SECCOMP_MODE_STRICT: 576 397 syscall = mode1_syscalls; 577 398 #ifdef CONFIG_COMPAT ··· 662 473 } 663 474 664 475 /** 665 - * prctl_set_seccomp: configures current->seccomp.mode 666 - * @seccomp_mode: requested mode to use 667 - * @filter: optional struct sock_fprog for use with SECCOMP_MODE_FILTER 668 - * 669 - * This function may be called repeatedly with a @seccomp_mode of 670 - * SECCOMP_MODE_FILTER to install additional filters. Every filter 671 - * successfully installed will be evaluated (in reverse order) for each system 672 - * call the task makes. 476 + * seccomp_set_mode_strict: internal function for setting strict seccomp 673 477 * 674 478 * Once current->seccomp.mode is non-zero, it may not be changed. 675 479 * 676 480 * Returns 0 on success or -EINVAL on failure. 677 481 */ 678 - long prctl_set_seccomp(unsigned long seccomp_mode, char __user *filter) 482 + static long seccomp_set_mode_strict(void) 679 483 { 484 + const unsigned long seccomp_mode = SECCOMP_MODE_STRICT; 680 485 long ret = -EINVAL; 681 486 682 - if (current->seccomp.mode && 683 - current->seccomp.mode != seccomp_mode) 487 + spin_lock_irq(&current->sighand->siglock); 488 + 489 + if (!seccomp_may_assign_mode(seccomp_mode)) 684 490 goto out; 491 + 492 + #ifdef TIF_NOTSC 493 + disable_TSC(); 494 + #endif 495 + seccomp_assign_mode(current, seccomp_mode); 496 + ret = 0; 497 + 498 + out: 499 + spin_unlock_irq(&current->sighand->siglock); 500 + 501 + return ret; 502 + } 503 + 504 + #ifdef CONFIG_SECCOMP_FILTER 505 + /** 506 + * seccomp_set_mode_filter: internal function for setting seccomp filter 507 + * @flags: flags to change filter behavior 508 + * @filter: struct sock_fprog containing filter 509 + * 510 + * This function may be called repeatedly to install additional filters. 511 + * Every filter successfully installed will be evaluated (in reverse order) 512 + * for each system call the task makes. 513 + * 514 + * Once current->seccomp.mode is non-zero, it may not be changed. 515 + * 516 + * Returns 0 on success or -EINVAL on failure. 517 + */ 518 + static long seccomp_set_mode_filter(unsigned int flags, 519 + const char __user *filter) 520 + { 521 + const unsigned long seccomp_mode = SECCOMP_MODE_FILTER; 522 + struct seccomp_filter *prepared = NULL; 523 + long ret = -EINVAL; 524 + 525 + /* Validate flags. */ 526 + if (flags & ~SECCOMP_FILTER_FLAG_MASK) 527 + return -EINVAL; 528 + 529 + /* Prepare the new filter before holding any locks. */ 530 + prepared = seccomp_prepare_user_filter(filter); 531 + if (IS_ERR(prepared)) 532 + return PTR_ERR(prepared); 533 + 534 + /* 535 + * Make sure we cannot change seccomp or nnp state via TSYNC 536 + * while another thread is in the middle of calling exec. 537 + */ 538 + if (flags & SECCOMP_FILTER_FLAG_TSYNC && 539 + mutex_lock_killable(&current->signal->cred_guard_mutex)) 540 + goto out_free; 541 + 542 + spin_lock_irq(&current->sighand->siglock); 543 + 544 + if (!seccomp_may_assign_mode(seccomp_mode)) 545 + goto out; 546 + 547 + ret = seccomp_attach_filter(flags, prepared); 548 + if (ret) 549 + goto out; 550 + /* Do not free the successfully attached filter. */ 551 + prepared = NULL; 552 + 553 + seccomp_assign_mode(current, seccomp_mode); 554 + out: 555 + spin_unlock_irq(&current->sighand->siglock); 556 + if (flags & SECCOMP_FILTER_FLAG_TSYNC) 557 + mutex_unlock(&current->signal->cred_guard_mutex); 558 + out_free: 559 + seccomp_filter_free(prepared); 560 + return ret; 561 + } 562 + #else 563 + static inline long seccomp_set_mode_filter(unsigned int flags, 564 + const char __user *filter) 565 + { 566 + return -EINVAL; 567 + } 568 + #endif 569 + 570 + /* Common entry point for both prctl and syscall. */ 571 + static long do_seccomp(unsigned int op, unsigned int flags, 572 + const char __user *uargs) 573 + { 574 + switch (op) { 575 + case SECCOMP_SET_MODE_STRICT: 576 + if (flags != 0 || uargs != NULL) 577 + return -EINVAL; 578 + return seccomp_set_mode_strict(); 579 + case SECCOMP_SET_MODE_FILTER: 580 + return seccomp_set_mode_filter(flags, uargs); 581 + default: 582 + return -EINVAL; 583 + } 584 + } 585 + 586 + SYSCALL_DEFINE3(seccomp, unsigned int, op, unsigned int, flags, 587 + const char __user *, uargs) 588 + { 589 + return do_seccomp(op, flags, uargs); 590 + } 591 + 592 + /** 593 + * prctl_set_seccomp: configures current->seccomp.mode 594 + * @seccomp_mode: requested mode to use 595 + * @filter: optional struct sock_fprog for use with SECCOMP_MODE_FILTER 596 + * 597 + * Returns 0 on success or -EINVAL on failure. 598 + */ 599 + long prctl_set_seccomp(unsigned long seccomp_mode, char __user *filter) 600 + { 601 + unsigned int op; 602 + char __user *uargs; 685 603 686 604 switch (seccomp_mode) { 687 605 case SECCOMP_MODE_STRICT: 688 - ret = 0; 689 - #ifdef TIF_NOTSC 690 - disable_TSC(); 691 - #endif 606 + op = SECCOMP_SET_MODE_STRICT; 607 + /* 608 + * Setting strict mode through prctl always ignored filter, 609 + * so make sure it is always NULL here to pass the internal 610 + * check in do_seccomp(). 611 + */ 612 + uargs = NULL; 692 613 break; 693 - #ifdef CONFIG_SECCOMP_FILTER 694 614 case SECCOMP_MODE_FILTER: 695 - ret = seccomp_attach_user_filter(filter); 696 - if (ret) 697 - goto out; 615 + op = SECCOMP_SET_MODE_FILTER; 616 + uargs = filter; 698 617 break; 699 - #endif 700 618 default: 701 - goto out; 619 + return -EINVAL; 702 620 } 703 621 704 - current->seccomp.mode = seccomp_mode; 705 - set_thread_flag(TIF_SECCOMP); 706 - out: 707 - return ret; 622 + /* prctl interface doesn't have flags, so they are always zero. */ 623 + return do_seccomp(op, 0, uargs); 708 624 }
+2 -2
kernel/sys.c
··· 1990 1990 if (arg2 != 1 || arg3 || arg4 || arg5) 1991 1991 return -EINVAL; 1992 1992 1993 - current->no_new_privs = 1; 1993 + task_set_no_new_privs(current); 1994 1994 break; 1995 1995 case PR_GET_NO_NEW_PRIVS: 1996 1996 if (arg2 || arg3 || arg4 || arg5) 1997 1997 return -EINVAL; 1998 - return current->no_new_privs ? 1 : 0; 1998 + return task_no_new_privs(current) ? 1 : 0; 1999 1999 case PR_GET_THP_DISABLE: 2000 2000 if (arg2 || arg3 || arg4 || arg5) 2001 2001 return -EINVAL;
+3
kernel/sys_ni.c
··· 213 213 214 214 /* compare kernel pointers */ 215 215 cond_syscall(sys_kcmp); 216 + 217 + /* operate on Secure Computing state */ 218 + cond_syscall(sys_seccomp);
+1
kernel/system_keyring.c
··· 89 89 pr_err("Problem loading in-kernel X.509 certificate (%ld)\n", 90 90 PTR_ERR(key)); 91 91 } else { 92 + set_bit(KEY_FLAG_BUILTIN, &key_ref_to_ptr(key)->flags); 92 93 pr_notice("Loaded X.509 cert '%s'\n", 93 94 key_ref_to_ptr(key)->description); 94 95 key_ref_put(key);
+2 -1
lib/Kconfig
··· 451 451 452 452 config SIGNATURE 453 453 tristate 454 - depends on KEYS && CRYPTO 454 + depends on KEYS 455 + select CRYPTO 455 456 select CRYPTO_SHA1 456 457 select MPILIB 457 458 help
+14 -12
net/ceph/crypto.c
··· 8 8 #include <linux/key-type.h> 9 9 10 10 #include <keys/ceph-type.h> 11 + #include <keys/user-type.h> 11 12 #include <linux/ceph/decode.h> 12 13 #include "crypto.h" 13 14 ··· 424 423 } 425 424 } 426 425 427 - static int ceph_key_instantiate(struct key *key, 428 - struct key_preparsed_payload *prep) 426 + static int ceph_key_preparse(struct key_preparsed_payload *prep) 429 427 { 430 428 struct ceph_crypto_key *ckey; 431 429 size_t datalen = prep->datalen; ··· 433 433 434 434 ret = -EINVAL; 435 435 if (datalen <= 0 || datalen > 32767 || !prep->data) 436 - goto err; 437 - 438 - ret = key_payload_reserve(key, datalen); 439 - if (ret < 0) 440 436 goto err; 441 437 442 438 ret = -ENOMEM; ··· 446 450 if (ret < 0) 447 451 goto err_ckey; 448 452 449 - key->payload.data = ckey; 453 + prep->payload[0] = ckey; 454 + prep->quotalen = datalen; 450 455 return 0; 451 456 452 457 err_ckey: ··· 456 459 return ret; 457 460 } 458 461 459 - static int ceph_key_match(const struct key *key, const void *description) 462 + static void ceph_key_free_preparse(struct key_preparsed_payload *prep) 460 463 { 461 - return strcmp(key->description, description) == 0; 464 + struct ceph_crypto_key *ckey = prep->payload[0]; 465 + ceph_crypto_key_destroy(ckey); 466 + kfree(ckey); 462 467 } 463 468 464 - static void ceph_key_destroy(struct key *key) { 469 + static void ceph_key_destroy(struct key *key) 470 + { 465 471 struct ceph_crypto_key *ckey = key->payload.data; 466 472 467 473 ceph_crypto_key_destroy(ckey); ··· 473 473 474 474 struct key_type key_type_ceph = { 475 475 .name = "ceph", 476 - .instantiate = ceph_key_instantiate, 477 - .match = ceph_key_match, 476 + .preparse = ceph_key_preparse, 477 + .free_preparse = ceph_key_free_preparse, 478 + .instantiate = generic_key_instantiate, 479 + .match = user_match, 478 480 .destroy = ceph_key_destroy, 479 481 }; 480 482
+25 -18
net/dns_resolver/dns_key.c
··· 46 46 #define DNS_ERRORNO_OPTION "dnserror" 47 47 48 48 /* 49 - * Instantiate a user defined key for dns_resolver. 49 + * Preparse instantiation data for a dns_resolver key. 50 50 * 51 51 * The data must be a NUL-terminated string, with the NUL char accounted in 52 52 * datalen. ··· 58 58 * "ip1,ip2,...#foo=bar" 59 59 */ 60 60 static int 61 - dns_resolver_instantiate(struct key *key, struct key_preparsed_payload *prep) 61 + dns_resolver_preparse(struct key_preparsed_payload *prep) 62 62 { 63 63 struct user_key_payload *upayload; 64 64 unsigned long derrno; 65 65 int ret; 66 - size_t datalen = prep->datalen, result_len = 0; 66 + int datalen = prep->datalen, result_len = 0; 67 67 const char *data = prep->data, *end, *opt; 68 68 69 - kenter("%%%d,%s,'%*.*s',%zu", 70 - key->serial, key->description, 71 - (int)datalen, (int)datalen, data, datalen); 69 + kenter("'%*.*s',%u", datalen, datalen, data, datalen); 72 70 73 71 if (datalen <= 1 || !data || data[datalen - 1] != '\0') 74 72 return -EINVAL; ··· 93 95 opt_len = next_opt - opt; 94 96 if (!opt_len) { 95 97 printk(KERN_WARNING 96 - "Empty option to dns_resolver key %d\n", 97 - key->serial); 98 + "Empty option to dns_resolver key\n"); 98 99 return -EINVAL; 99 100 } 100 101 ··· 122 125 goto bad_option_value; 123 126 124 127 kdebug("dns error no. = %lu", derrno); 125 - key->type_data.x[0] = -derrno; 128 + prep->type_data[0] = ERR_PTR(-derrno); 126 129 continue; 127 130 } 128 131 129 132 bad_option_value: 130 133 printk(KERN_WARNING 131 - "Option '%*.*s' to dns_resolver key %d:" 134 + "Option '%*.*s' to dns_resolver key:" 132 135 " bad/missing value\n", 133 - opt_nlen, opt_nlen, opt, key->serial); 136 + opt_nlen, opt_nlen, opt); 134 137 return -EINVAL; 135 138 } while (opt = next_opt + 1, opt < end); 136 139 } 137 140 138 141 /* don't cache the result if we're caching an error saying there's no 139 142 * result */ 140 - if (key->type_data.x[0]) { 141 - kleave(" = 0 [h_error %ld]", key->type_data.x[0]); 143 + if (prep->type_data[0]) { 144 + kleave(" = 0 [h_error %ld]", PTR_ERR(prep->type_data[0])); 142 145 return 0; 143 146 } 144 147 145 148 kdebug("store result"); 146 - ret = key_payload_reserve(key, result_len); 147 - if (ret < 0) 148 - return -EINVAL; 149 + prep->quotalen = result_len; 149 150 150 151 upayload = kmalloc(sizeof(*upayload) + result_len + 1, GFP_KERNEL); 151 152 if (!upayload) { ··· 154 159 upayload->datalen = result_len; 155 160 memcpy(upayload->data, data, result_len); 156 161 upayload->data[result_len] = '\0'; 157 - rcu_assign_pointer(key->payload.data, upayload); 158 162 163 + prep->payload[0] = upayload; 159 164 kleave(" = 0"); 160 165 return 0; 166 + } 167 + 168 + /* 169 + * Clean up the preparse data 170 + */ 171 + static void dns_resolver_free_preparse(struct key_preparsed_payload *prep) 172 + { 173 + pr_devel("==>%s()\n", __func__); 174 + 175 + kfree(prep->payload[0]); 161 176 } 162 177 163 178 /* ··· 239 234 240 235 struct key_type key_type_dns_resolver = { 241 236 .name = "dns_resolver", 242 - .instantiate = dns_resolver_instantiate, 237 + .preparse = dns_resolver_preparse, 238 + .free_preparse = dns_resolver_free_preparse, 239 + .instantiate = generic_key_instantiate, 243 240 .match = dns_resolver_match, 244 241 .revoke = user_revoke, 245 242 .destroy = user_destroy,
+1
net/dns_resolver/dns_query.c
··· 129 129 } 130 130 131 131 down_read(&rkey->sem); 132 + set_bit(KEY_FLAG_ROOT_CAN_INVAL, &rkey->flags); 132 133 rkey->perm |= KEY_USR_VIEW; 133 134 134 135 ret = key_validate(rkey);
+16 -31
net/ipv4/cipso_ipv4.c
··· 890 890 } 891 891 892 892 for (;;) { 893 - host_spot = netlbl_secattr_catmap_walk(secattr->attr.mls.cat, 894 - host_spot + 1); 893 + host_spot = netlbl_catmap_walk(secattr->attr.mls.cat, 894 + host_spot + 1); 895 895 if (host_spot < 0) 896 896 break; 897 897 ··· 973 973 return -EPERM; 974 974 break; 975 975 } 976 - ret_val = netlbl_secattr_catmap_setbit(secattr->attr.mls.cat, 976 + ret_val = netlbl_catmap_setbit(&secattr->attr.mls.cat, 977 977 host_spot, 978 978 GFP_ATOMIC); 979 979 if (ret_val != 0) ··· 1039 1039 u32 cat_iter = 0; 1040 1040 1041 1041 for (;;) { 1042 - cat = netlbl_secattr_catmap_walk(secattr->attr.mls.cat, 1043 - cat + 1); 1042 + cat = netlbl_catmap_walk(secattr->attr.mls.cat, cat + 1); 1044 1043 if (cat < 0) 1045 1044 break; 1046 1045 if ((cat_iter + 2) > net_cat_len) ··· 1074 1075 u32 iter; 1075 1076 1076 1077 for (iter = 0; iter < net_cat_len; iter += 2) { 1077 - ret_val = netlbl_secattr_catmap_setbit(secattr->attr.mls.cat, 1078 - get_unaligned_be16(&net_cat[iter]), 1079 - GFP_ATOMIC); 1078 + ret_val = netlbl_catmap_setbit(&secattr->attr.mls.cat, 1079 + get_unaligned_be16(&net_cat[iter]), 1080 + GFP_ATOMIC); 1080 1081 if (ret_val != 0) 1081 1082 return ret_val; 1082 1083 } ··· 1154 1155 return -ENOSPC; 1155 1156 1156 1157 for (;;) { 1157 - iter = netlbl_secattr_catmap_walk(secattr->attr.mls.cat, 1158 - iter + 1); 1158 + iter = netlbl_catmap_walk(secattr->attr.mls.cat, iter + 1); 1159 1159 if (iter < 0) 1160 1160 break; 1161 1161 cat_size += (iter == 0 ? 0 : sizeof(u16)); ··· 1162 1164 return -ENOSPC; 1163 1165 array[array_cnt++] = iter; 1164 1166 1165 - iter = netlbl_secattr_catmap_walk_rng(secattr->attr.mls.cat, 1166 - iter); 1167 + iter = netlbl_catmap_walkrng(secattr->attr.mls.cat, iter); 1167 1168 if (iter < 0) 1168 1169 return -EFAULT; 1169 1170 cat_size += sizeof(u16); ··· 1214 1217 else 1215 1218 cat_low = 0; 1216 1219 1217 - ret_val = netlbl_secattr_catmap_setrng(secattr->attr.mls.cat, 1218 - cat_low, 1219 - cat_high, 1220 - GFP_ATOMIC); 1220 + ret_val = netlbl_catmap_setrng(&secattr->attr.mls.cat, 1221 + cat_low, 1222 + cat_high, 1223 + GFP_ATOMIC); 1221 1224 if (ret_val != 0) 1222 1225 return ret_val; 1223 1226 } ··· 1332 1335 secattr->flags |= NETLBL_SECATTR_MLS_LVL; 1333 1336 1334 1337 if (tag_len > 4) { 1335 - secattr->attr.mls.cat = netlbl_secattr_catmap_alloc(GFP_ATOMIC); 1336 - if (secattr->attr.mls.cat == NULL) 1337 - return -ENOMEM; 1338 - 1339 1338 ret_val = cipso_v4_map_cat_rbm_ntoh(doi_def, 1340 1339 &tag[4], 1341 1340 tag_len - 4, 1342 1341 secattr); 1343 1342 if (ret_val != 0) { 1344 - netlbl_secattr_catmap_free(secattr->attr.mls.cat); 1343 + netlbl_catmap_free(secattr->attr.mls.cat); 1345 1344 return ret_val; 1346 1345 } 1347 1346 ··· 1423 1430 secattr->flags |= NETLBL_SECATTR_MLS_LVL; 1424 1431 1425 1432 if (tag_len > 4) { 1426 - secattr->attr.mls.cat = netlbl_secattr_catmap_alloc(GFP_ATOMIC); 1427 - if (secattr->attr.mls.cat == NULL) 1428 - return -ENOMEM; 1429 - 1430 1433 ret_val = cipso_v4_map_cat_enum_ntoh(doi_def, 1431 1434 &tag[4], 1432 1435 tag_len - 4, 1433 1436 secattr); 1434 1437 if (ret_val != 0) { 1435 - netlbl_secattr_catmap_free(secattr->attr.mls.cat); 1438 + netlbl_catmap_free(secattr->attr.mls.cat); 1436 1439 return ret_val; 1437 1440 } 1438 1441 ··· 1513 1524 secattr->flags |= NETLBL_SECATTR_MLS_LVL; 1514 1525 1515 1526 if (tag_len > 4) { 1516 - secattr->attr.mls.cat = netlbl_secattr_catmap_alloc(GFP_ATOMIC); 1517 - if (secattr->attr.mls.cat == NULL) 1518 - return -ENOMEM; 1519 - 1520 1527 ret_val = cipso_v4_map_cat_rng_ntoh(doi_def, 1521 1528 &tag[4], 1522 1529 tag_len - 4, 1523 1530 secattr); 1524 1531 if (ret_val != 0) { 1525 - netlbl_secattr_catmap_free(secattr->attr.mls.cat); 1532 + netlbl_catmap_free(secattr->attr.mls.cat); 1526 1533 return ret_val; 1527 1534 } 1528 1535
+226 -99
net/netlabel/netlabel_kapi.c
··· 405 405 * Security Attribute Functions 406 406 */ 407 407 408 + #define _CM_F_NONE 0x00000000 409 + #define _CM_F_ALLOC 0x00000001 410 + #define _CM_F_WALK 0x00000002 411 + 408 412 /** 409 - * netlbl_secattr_catmap_walk - Walk a LSM secattr catmap looking for a bit 413 + * _netlbl_catmap_getnode - Get a individual node from a catmap 414 + * @catmap: pointer to the category bitmap 415 + * @offset: the requested offset 416 + * @cm_flags: catmap flags, see _CM_F_* 417 + * @gfp_flags: memory allocation flags 418 + * 419 + * Description: 420 + * Iterate through the catmap looking for the node associated with @offset. 421 + * If the _CM_F_ALLOC flag is set in @cm_flags and there is no associated node, 422 + * one will be created and inserted into the catmap. If the _CM_F_WALK flag is 423 + * set in @cm_flags and there is no associated node, the next highest node will 424 + * be returned. Returns a pointer to the node on success, NULL on failure. 425 + * 426 + */ 427 + static struct netlbl_lsm_catmap *_netlbl_catmap_getnode( 428 + struct netlbl_lsm_catmap **catmap, 429 + u32 offset, 430 + unsigned int cm_flags, 431 + gfp_t gfp_flags) 432 + { 433 + struct netlbl_lsm_catmap *iter = *catmap; 434 + struct netlbl_lsm_catmap *prev = NULL; 435 + 436 + if (iter == NULL) 437 + goto catmap_getnode_alloc; 438 + if (offset < iter->startbit) 439 + goto catmap_getnode_walk; 440 + while (iter && offset >= (iter->startbit + NETLBL_CATMAP_SIZE)) { 441 + prev = iter; 442 + iter = iter->next; 443 + } 444 + if (iter == NULL || offset < iter->startbit) 445 + goto catmap_getnode_walk; 446 + 447 + return iter; 448 + 449 + catmap_getnode_walk: 450 + if (cm_flags & _CM_F_WALK) 451 + return iter; 452 + catmap_getnode_alloc: 453 + if (!(cm_flags & _CM_F_ALLOC)) 454 + return NULL; 455 + 456 + iter = netlbl_catmap_alloc(gfp_flags); 457 + if (iter == NULL) 458 + return NULL; 459 + iter->startbit = offset & ~(NETLBL_CATMAP_SIZE - 1); 460 + 461 + if (prev == NULL) { 462 + iter->next = *catmap; 463 + *catmap = iter; 464 + } else { 465 + iter->next = prev->next; 466 + prev->next = iter; 467 + } 468 + 469 + return iter; 470 + } 471 + 472 + /** 473 + * netlbl_catmap_walk - Walk a LSM secattr catmap looking for a bit 410 474 * @catmap: the category bitmap 411 475 * @offset: the offset to start searching at, in bits 412 476 * ··· 479 415 * returns the spot of the first set bit or -ENOENT if no bits are set. 480 416 * 481 417 */ 482 - int netlbl_secattr_catmap_walk(struct netlbl_lsm_secattr_catmap *catmap, 483 - u32 offset) 418 + int netlbl_catmap_walk(struct netlbl_lsm_catmap *catmap, u32 offset) 484 419 { 485 - struct netlbl_lsm_secattr_catmap *iter = catmap; 486 - u32 node_idx; 487 - u32 node_bit; 420 + struct netlbl_lsm_catmap *iter = catmap; 421 + u32 idx; 422 + u32 bit; 488 423 NETLBL_CATMAP_MAPTYPE bitmap; 489 424 425 + iter = _netlbl_catmap_getnode(&catmap, offset, _CM_F_WALK, 0); 426 + if (iter == NULL) 427 + return -ENOENT; 490 428 if (offset > iter->startbit) { 491 - while (offset >= (iter->startbit + NETLBL_CATMAP_SIZE)) { 492 - iter = iter->next; 493 - if (iter == NULL) 494 - return -ENOENT; 495 - } 496 - node_idx = (offset - iter->startbit) / NETLBL_CATMAP_MAPSIZE; 497 - node_bit = offset - iter->startbit - 498 - (NETLBL_CATMAP_MAPSIZE * node_idx); 429 + offset -= iter->startbit; 430 + idx = offset / NETLBL_CATMAP_MAPSIZE; 431 + bit = offset % NETLBL_CATMAP_MAPSIZE; 499 432 } else { 500 - node_idx = 0; 501 - node_bit = 0; 433 + idx = 0; 434 + bit = 0; 502 435 } 503 - bitmap = iter->bitmap[node_idx] >> node_bit; 436 + bitmap = iter->bitmap[idx] >> bit; 504 437 505 438 for (;;) { 506 439 if (bitmap != 0) { 507 440 while ((bitmap & NETLBL_CATMAP_BIT) == 0) { 508 441 bitmap >>= 1; 509 - node_bit++; 442 + bit++; 510 443 } 511 444 return iter->startbit + 512 - (NETLBL_CATMAP_MAPSIZE * node_idx) + node_bit; 445 + (NETLBL_CATMAP_MAPSIZE * idx) + bit; 513 446 } 514 - if (++node_idx >= NETLBL_CATMAP_MAPCNT) { 447 + if (++idx >= NETLBL_CATMAP_MAPCNT) { 515 448 if (iter->next != NULL) { 516 449 iter = iter->next; 517 - node_idx = 0; 450 + idx = 0; 518 451 } else 519 452 return -ENOENT; 520 453 } 521 - bitmap = iter->bitmap[node_idx]; 522 - node_bit = 0; 454 + bitmap = iter->bitmap[idx]; 455 + bit = 0; 523 456 } 524 457 525 458 return -ENOENT; 526 459 } 527 460 528 461 /** 529 - * netlbl_secattr_catmap_walk_rng - Find the end of a string of set bits 462 + * netlbl_catmap_walkrng - Find the end of a string of set bits 530 463 * @catmap: the category bitmap 531 464 * @offset: the offset to start searching at, in bits 532 465 * ··· 533 472 * the end of the bitmap. 534 473 * 535 474 */ 536 - int netlbl_secattr_catmap_walk_rng(struct netlbl_lsm_secattr_catmap *catmap, 537 - u32 offset) 475 + int netlbl_catmap_walkrng(struct netlbl_lsm_catmap *catmap, u32 offset) 538 476 { 539 - struct netlbl_lsm_secattr_catmap *iter = catmap; 540 - u32 node_idx; 541 - u32 node_bit; 477 + struct netlbl_lsm_catmap *iter; 478 + struct netlbl_lsm_catmap *prev = NULL; 479 + u32 idx; 480 + u32 bit; 542 481 NETLBL_CATMAP_MAPTYPE bitmask; 543 482 NETLBL_CATMAP_MAPTYPE bitmap; 544 483 484 + iter = _netlbl_catmap_getnode(&catmap, offset, _CM_F_WALK, 0); 485 + if (iter == NULL) 486 + return -ENOENT; 545 487 if (offset > iter->startbit) { 546 - while (offset >= (iter->startbit + NETLBL_CATMAP_SIZE)) { 547 - iter = iter->next; 548 - if (iter == NULL) 549 - return -ENOENT; 550 - } 551 - node_idx = (offset - iter->startbit) / NETLBL_CATMAP_MAPSIZE; 552 - node_bit = offset - iter->startbit - 553 - (NETLBL_CATMAP_MAPSIZE * node_idx); 488 + offset -= iter->startbit; 489 + idx = offset / NETLBL_CATMAP_MAPSIZE; 490 + bit = offset % NETLBL_CATMAP_MAPSIZE; 554 491 } else { 555 - node_idx = 0; 556 - node_bit = 0; 492 + idx = 0; 493 + bit = 0; 557 494 } 558 - bitmask = NETLBL_CATMAP_BIT << node_bit; 495 + bitmask = NETLBL_CATMAP_BIT << bit; 559 496 560 497 for (;;) { 561 - bitmap = iter->bitmap[node_idx]; 498 + bitmap = iter->bitmap[idx]; 562 499 while (bitmask != 0 && (bitmap & bitmask) != 0) { 563 500 bitmask <<= 1; 564 - node_bit++; 501 + bit++; 565 502 } 566 503 567 - if (bitmask != 0) 504 + if (prev && idx == 0 && bit == 0) 505 + return prev->startbit + NETLBL_CATMAP_SIZE - 1; 506 + else if (bitmask != 0) 568 507 return iter->startbit + 569 - (NETLBL_CATMAP_MAPSIZE * node_idx) + 570 - node_bit - 1; 571 - else if (++node_idx >= NETLBL_CATMAP_MAPCNT) { 508 + (NETLBL_CATMAP_MAPSIZE * idx) + bit - 1; 509 + else if (++idx >= NETLBL_CATMAP_MAPCNT) { 572 510 if (iter->next == NULL) 573 - return iter->startbit + NETLBL_CATMAP_SIZE - 1; 511 + return iter->startbit + NETLBL_CATMAP_SIZE - 1; 512 + prev = iter; 574 513 iter = iter->next; 575 - node_idx = 0; 514 + idx = 0; 576 515 } 577 516 bitmask = NETLBL_CATMAP_BIT; 578 - node_bit = 0; 517 + bit = 0; 579 518 } 580 519 581 520 return -ENOENT; 582 521 } 583 522 584 523 /** 585 - * netlbl_secattr_catmap_setbit - Set a bit in a LSM secattr catmap 586 - * @catmap: the category bitmap 524 + * netlbl_catmap_getlong - Export an unsigned long bitmap 525 + * @catmap: pointer to the category bitmap 526 + * @offset: pointer to the requested offset 527 + * @bitmap: the exported bitmap 528 + * 529 + * Description: 530 + * Export a bitmap with an offset greater than or equal to @offset and return 531 + * it in @bitmap. The @offset must be aligned to an unsigned long and will be 532 + * updated on return if different from what was requested; if the catmap is 533 + * empty at the requested offset and beyond, the @offset is set to (u32)-1. 534 + * Returns zero on sucess, negative values on failure. 535 + * 536 + */ 537 + int netlbl_catmap_getlong(struct netlbl_lsm_catmap *catmap, 538 + u32 *offset, 539 + unsigned long *bitmap) 540 + { 541 + struct netlbl_lsm_catmap *iter; 542 + u32 off = *offset; 543 + u32 idx; 544 + 545 + /* only allow aligned offsets */ 546 + if ((off & (BITS_PER_LONG - 1)) != 0) 547 + return -EINVAL; 548 + 549 + if (off < catmap->startbit) { 550 + off = catmap->startbit; 551 + *offset = off; 552 + } 553 + iter = _netlbl_catmap_getnode(&catmap, off, _CM_F_NONE, 0); 554 + if (iter == NULL) { 555 + *offset = (u32)-1; 556 + return 0; 557 + } 558 + 559 + if (off < iter->startbit) { 560 + off = iter->startbit; 561 + *offset = off; 562 + } else 563 + off -= iter->startbit; 564 + 565 + idx = off / NETLBL_CATMAP_MAPSIZE; 566 + *bitmap = iter->bitmap[idx] >> (off % NETLBL_CATMAP_SIZE); 567 + 568 + return 0; 569 + } 570 + 571 + /** 572 + * netlbl_catmap_setbit - Set a bit in a LSM secattr catmap 573 + * @catmap: pointer to the category bitmap 587 574 * @bit: the bit to set 588 575 * @flags: memory allocation flags 589 576 * ··· 640 531 * negative values on failure. 641 532 * 642 533 */ 643 - int netlbl_secattr_catmap_setbit(struct netlbl_lsm_secattr_catmap *catmap, 644 - u32 bit, 645 - gfp_t flags) 534 + int netlbl_catmap_setbit(struct netlbl_lsm_catmap **catmap, 535 + u32 bit, 536 + gfp_t flags) 646 537 { 647 - struct netlbl_lsm_secattr_catmap *iter = catmap; 648 - u32 node_bit; 649 - u32 node_idx; 538 + struct netlbl_lsm_catmap *iter; 539 + u32 idx; 650 540 651 - while (iter->next != NULL && 652 - bit >= (iter->startbit + NETLBL_CATMAP_SIZE)) 653 - iter = iter->next; 654 - if (bit >= (iter->startbit + NETLBL_CATMAP_SIZE)) { 655 - iter->next = netlbl_secattr_catmap_alloc(flags); 656 - if (iter->next == NULL) 657 - return -ENOMEM; 658 - iter = iter->next; 659 - iter->startbit = bit & ~(NETLBL_CATMAP_SIZE - 1); 660 - } 541 + iter = _netlbl_catmap_getnode(catmap, bit, _CM_F_ALLOC, flags); 542 + if (iter == NULL) 543 + return -ENOMEM; 661 544 662 - /* gcc always rounds to zero when doing integer division */ 663 - node_idx = (bit - iter->startbit) / NETLBL_CATMAP_MAPSIZE; 664 - node_bit = bit - iter->startbit - (NETLBL_CATMAP_MAPSIZE * node_idx); 665 - iter->bitmap[node_idx] |= NETLBL_CATMAP_BIT << node_bit; 545 + bit -= iter->startbit; 546 + idx = bit / NETLBL_CATMAP_MAPSIZE; 547 + iter->bitmap[idx] |= NETLBL_CATMAP_BIT << (bit % NETLBL_CATMAP_MAPSIZE); 666 548 667 549 return 0; 668 550 } 669 551 670 552 /** 671 - * netlbl_secattr_catmap_setrng - Set a range of bits in a LSM secattr catmap 672 - * @catmap: the category bitmap 553 + * netlbl_catmap_setrng - Set a range of bits in a LSM secattr catmap 554 + * @catmap: pointer to the category bitmap 673 555 * @start: the starting bit 674 556 * @end: the last bit in the string 675 557 * @flags: memory allocation flags ··· 670 570 * on success, negative values on failure. 671 571 * 672 572 */ 673 - int netlbl_secattr_catmap_setrng(struct netlbl_lsm_secattr_catmap *catmap, 674 - u32 start, 675 - u32 end, 676 - gfp_t flags) 573 + int netlbl_catmap_setrng(struct netlbl_lsm_catmap **catmap, 574 + u32 start, 575 + u32 end, 576 + gfp_t flags) 677 577 { 678 - int ret_val = 0; 679 - struct netlbl_lsm_secattr_catmap *iter = catmap; 680 - u32 iter_max_spot; 681 - u32 spot; 578 + int rc = 0; 579 + u32 spot = start; 682 580 683 - /* XXX - This could probably be made a bit faster by combining writes 684 - * to the catmap instead of setting a single bit each time, but for 685 - * right now skipping to the start of the range in the catmap should 686 - * be a nice improvement over calling the individual setbit function 687 - * repeatedly from a loop. */ 688 - 689 - while (iter->next != NULL && 690 - start >= (iter->startbit + NETLBL_CATMAP_SIZE)) 691 - iter = iter->next; 692 - iter_max_spot = iter->startbit + NETLBL_CATMAP_SIZE; 693 - 694 - for (spot = start; spot <= end && ret_val == 0; spot++) { 695 - if (spot >= iter_max_spot && iter->next != NULL) { 696 - iter = iter->next; 697 - iter_max_spot = iter->startbit + NETLBL_CATMAP_SIZE; 698 - } 699 - ret_val = netlbl_secattr_catmap_setbit(iter, spot, flags); 581 + while (rc == 0 && spot <= end) { 582 + if (((spot & (BITS_PER_LONG - 1)) != 0) && 583 + ((end - spot) > BITS_PER_LONG)) { 584 + rc = netlbl_catmap_setlong(catmap, 585 + spot, 586 + (unsigned long)-1, 587 + flags); 588 + spot += BITS_PER_LONG; 589 + } else 590 + rc = netlbl_catmap_setbit(catmap, spot++, flags); 700 591 } 701 592 702 - return ret_val; 593 + return rc; 594 + } 595 + 596 + /** 597 + * netlbl_catmap_setlong - Import an unsigned long bitmap 598 + * @catmap: pointer to the category bitmap 599 + * @offset: offset to the start of the imported bitmap 600 + * @bitmap: the bitmap to import 601 + * @flags: memory allocation flags 602 + * 603 + * Description: 604 + * Import the bitmap specified in @bitmap into @catmap, using the offset 605 + * in @offset. The offset must be aligned to an unsigned long. Returns zero 606 + * on success, negative values on failure. 607 + * 608 + */ 609 + int netlbl_catmap_setlong(struct netlbl_lsm_catmap **catmap, 610 + u32 offset, 611 + unsigned long bitmap, 612 + gfp_t flags) 613 + { 614 + struct netlbl_lsm_catmap *iter; 615 + u32 idx; 616 + 617 + /* only allow aligned offsets */ 618 + if ((offset & (BITS_PER_LONG - 1)) != 0) 619 + return -EINVAL; 620 + 621 + iter = _netlbl_catmap_getnode(catmap, offset, _CM_F_ALLOC, flags); 622 + if (iter == NULL) 623 + return -ENOMEM; 624 + 625 + offset -= iter->startbit; 626 + idx = offset / NETLBL_CATMAP_MAPSIZE; 627 + iter->bitmap[idx] |= bitmap << (offset % NETLBL_CATMAP_MAPSIZE); 628 + 629 + return 0; 703 630 } 704 631 705 632 /*
+105 -76
net/rxrpc/ar-key.c
··· 26 26 #include "ar-internal.h" 27 27 28 28 static int rxrpc_vet_description_s(const char *); 29 - static int rxrpc_instantiate(struct key *, struct key_preparsed_payload *); 30 - static int rxrpc_instantiate_s(struct key *, struct key_preparsed_payload *); 29 + static int rxrpc_preparse(struct key_preparsed_payload *); 30 + static int rxrpc_preparse_s(struct key_preparsed_payload *); 31 + static void rxrpc_free_preparse(struct key_preparsed_payload *); 32 + static void rxrpc_free_preparse_s(struct key_preparsed_payload *); 31 33 static void rxrpc_destroy(struct key *); 32 34 static void rxrpc_destroy_s(struct key *); 33 35 static void rxrpc_describe(const struct key *, struct seq_file *); ··· 41 39 */ 42 40 struct key_type key_type_rxrpc = { 43 41 .name = "rxrpc", 44 - .instantiate = rxrpc_instantiate, 42 + .preparse = rxrpc_preparse, 43 + .free_preparse = rxrpc_free_preparse, 44 + .instantiate = generic_key_instantiate, 45 45 .match = user_match, 46 46 .destroy = rxrpc_destroy, 47 47 .describe = rxrpc_describe, ··· 58 54 struct key_type key_type_rxrpc_s = { 59 55 .name = "rxrpc_s", 60 56 .vet_description = rxrpc_vet_description_s, 61 - .instantiate = rxrpc_instantiate_s, 57 + .preparse = rxrpc_preparse_s, 58 + .free_preparse = rxrpc_free_preparse_s, 59 + .instantiate = generic_key_instantiate, 62 60 .match = user_match, 63 61 .destroy = rxrpc_destroy_s, 64 62 .describe = rxrpc_describe, ··· 87 81 * parse an RxKAD type XDR format token 88 82 * - the caller guarantees we have at least 4 words 89 83 */ 90 - static int rxrpc_instantiate_xdr_rxkad(struct key *key, const __be32 *xdr, 91 - unsigned int toklen) 84 + static int rxrpc_preparse_xdr_rxkad(struct key_preparsed_payload *prep, 85 + size_t datalen, 86 + const __be32 *xdr, unsigned int toklen) 92 87 { 93 88 struct rxrpc_key_token *token, **pptoken; 94 89 size_t plen; 95 90 u32 tktlen; 96 - int ret; 97 91 98 92 _enter(",{%x,%x,%x,%x},%u", 99 93 ntohl(xdr[0]), ntohl(xdr[1]), ntohl(xdr[2]), ntohl(xdr[3]), ··· 109 103 return -EKEYREJECTED; 110 104 111 105 plen = sizeof(*token) + sizeof(*token->kad) + tktlen; 112 - ret = key_payload_reserve(key, key->datalen + plen); 113 - if (ret < 0) 114 - return ret; 106 + prep->quotalen = datalen + plen; 115 107 116 108 plen -= sizeof(*token); 117 109 token = kzalloc(sizeof(*token), GFP_KERNEL); ··· 150 146 token->kad->ticket[6], token->kad->ticket[7]); 151 147 152 148 /* count the number of tokens attached */ 153 - key->type_data.x[0]++; 149 + prep->type_data[0] = (void *)((unsigned long)prep->type_data[0] + 1); 154 150 155 151 /* attach the data */ 156 - for (pptoken = (struct rxrpc_key_token **)&key->payload.data; 152 + for (pptoken = (struct rxrpc_key_token **)&prep->payload[0]; 157 153 *pptoken; 158 154 pptoken = &(*pptoken)->next) 159 155 continue; 160 156 *pptoken = token; 161 - if (token->kad->expiry < key->expiry) 162 - key->expiry = token->kad->expiry; 157 + if (token->kad->expiry < prep->expiry) 158 + prep->expiry = token->kad->expiry; 163 159 164 160 _leave(" = 0"); 165 161 return 0; ··· 422 418 * parse an RxK5 type XDR format token 423 419 * - the caller guarantees we have at least 4 words 424 420 */ 425 - static int rxrpc_instantiate_xdr_rxk5(struct key *key, const __be32 *xdr, 426 - unsigned int toklen) 421 + static int rxrpc_preparse_xdr_rxk5(struct key_preparsed_payload *prep, 422 + size_t datalen, 423 + const __be32 *xdr, unsigned int toklen) 427 424 { 428 425 struct rxrpc_key_token *token, **pptoken; 429 426 struct rxk5_key *rxk5; ··· 437 432 438 433 /* reserve some payload space for this subkey - the length of the token 439 434 * is a reasonable approximation */ 440 - ret = key_payload_reserve(key, key->datalen + toklen); 441 - if (ret < 0) 442 - return ret; 435 + prep->quotalen = datalen + toklen; 443 436 444 437 token = kzalloc(sizeof(*token), GFP_KERNEL); 445 438 if (!token) ··· 523 520 if (toklen != 0) 524 521 goto inval; 525 522 526 - /* attach the payload to the key */ 527 - for (pptoken = (struct rxrpc_key_token **)&key->payload.data; 523 + /* attach the payload */ 524 + for (pptoken = (struct rxrpc_key_token **)&prep->payload[0]; 528 525 *pptoken; 529 526 pptoken = &(*pptoken)->next) 530 527 continue; 531 528 *pptoken = token; 532 - if (token->kad->expiry < key->expiry) 533 - key->expiry = token->kad->expiry; 529 + if (token->kad->expiry < prep->expiry) 530 + prep->expiry = token->kad->expiry; 534 531 535 532 _leave(" = 0"); 536 533 return 0; ··· 548 545 * attempt to parse the data as the XDR format 549 546 * - the caller guarantees we have more than 7 words 550 547 */ 551 - static int rxrpc_instantiate_xdr(struct key *key, const void *data, size_t datalen) 548 + static int rxrpc_preparse_xdr(struct key_preparsed_payload *prep) 552 549 { 553 - const __be32 *xdr = data, *token; 550 + const __be32 *xdr = prep->data, *token; 554 551 const char *cp; 555 552 unsigned int len, tmp, loop, ntoken, toklen, sec_ix; 553 + size_t datalen = prep->datalen; 556 554 int ret; 557 555 558 556 _enter(",{%x,%x,%x,%x},%zu", 559 557 ntohl(xdr[0]), ntohl(xdr[1]), ntohl(xdr[2]), ntohl(xdr[3]), 560 - datalen); 558 + prep->datalen); 561 559 562 560 if (datalen > AFSTOKEN_LENGTH_MAX) 563 561 goto not_xdr; ··· 639 635 640 636 switch (sec_ix) { 641 637 case RXRPC_SECURITY_RXKAD: 642 - ret = rxrpc_instantiate_xdr_rxkad(key, xdr, toklen); 638 + ret = rxrpc_preparse_xdr_rxkad(prep, datalen, xdr, toklen); 643 639 if (ret != 0) 644 640 goto error; 645 641 break; 646 642 647 643 case RXRPC_SECURITY_RXK5: 648 - ret = rxrpc_instantiate_xdr_rxk5(key, xdr, toklen); 644 + ret = rxrpc_preparse_xdr_rxk5(prep, datalen, xdr, toklen); 649 645 if (ret != 0) 650 646 goto error; 651 647 break; ··· 669 665 } 670 666 671 667 /* 672 - * instantiate an rxrpc defined key 673 - * data should be of the form: 668 + * Preparse an rxrpc defined key. 669 + * 670 + * Data should be of the form: 674 671 * OFFSET LEN CONTENT 675 672 * 0 4 key interface version number 676 673 * 4 2 security index (type) ··· 683 678 * 684 679 * if no data is provided, then a no-security key is made 685 680 */ 686 - static int rxrpc_instantiate(struct key *key, struct key_preparsed_payload *prep) 681 + static int rxrpc_preparse(struct key_preparsed_payload *prep) 687 682 { 688 683 const struct rxrpc_key_data_v1 *v1; 689 684 struct rxrpc_key_token *token, **pp; ··· 691 686 u32 kver; 692 687 int ret; 693 688 694 - _enter("{%x},,%zu", key_serial(key), prep->datalen); 689 + _enter("%zu", prep->datalen); 695 690 696 691 /* handle a no-security key */ 697 692 if (!prep->data && prep->datalen == 0) ··· 699 694 700 695 /* determine if the XDR payload format is being used */ 701 696 if (prep->datalen > 7 * 4) { 702 - ret = rxrpc_instantiate_xdr(key, prep->data, prep->datalen); 697 + ret = rxrpc_preparse_xdr(prep); 703 698 if (ret != -EPROTO) 704 699 return ret; 705 700 } ··· 748 743 goto error; 749 744 750 745 plen = sizeof(*token->kad) + v1->ticket_length; 751 - ret = key_payload_reserve(key, plen + sizeof(*token)); 752 - if (ret < 0) 753 - goto error; 746 + prep->quotalen = plen + sizeof(*token); 754 747 755 748 ret = -ENOMEM; 756 749 token = kzalloc(sizeof(*token), GFP_KERNEL); ··· 765 762 memcpy(&token->kad->session_key, &v1->session_key, 8); 766 763 memcpy(&token->kad->ticket, v1->ticket, v1->ticket_length); 767 764 768 - /* attach the data */ 769 - key->type_data.x[0]++; 765 + /* count the number of tokens attached */ 766 + prep->type_data[0] = (void *)((unsigned long)prep->type_data[0] + 1); 770 767 771 - pp = (struct rxrpc_key_token **)&key->payload.data; 768 + /* attach the data */ 769 + pp = (struct rxrpc_key_token **)&prep->payload[0]; 772 770 while (*pp) 773 771 pp = &(*pp)->next; 774 772 *pp = token; 775 - if (token->kad->expiry < key->expiry) 776 - key->expiry = token->kad->expiry; 773 + if (token->kad->expiry < prep->expiry) 774 + prep->expiry = token->kad->expiry; 777 775 token = NULL; 778 776 ret = 0; 779 777 ··· 785 781 } 786 782 787 783 /* 788 - * instantiate a server secret key 789 - * data should be a pointer to the 8-byte secret key 784 + * Free token list. 790 785 */ 791 - static int rxrpc_instantiate_s(struct key *key, 792 - struct key_preparsed_payload *prep) 786 + static void rxrpc_free_token_list(struct rxrpc_key_token *token) 793 787 { 794 - struct crypto_blkcipher *ci; 788 + struct rxrpc_key_token *next; 795 789 796 - _enter("{%x},,%zu", key_serial(key), prep->datalen); 797 - 798 - if (prep->datalen != 8) 799 - return -EINVAL; 800 - 801 - memcpy(&key->type_data, prep->data, 8); 802 - 803 - ci = crypto_alloc_blkcipher("pcbc(des)", 0, CRYPTO_ALG_ASYNC); 804 - if (IS_ERR(ci)) { 805 - _leave(" = %ld", PTR_ERR(ci)); 806 - return PTR_ERR(ci); 807 - } 808 - 809 - if (crypto_blkcipher_setkey(ci, prep->data, 8) < 0) 810 - BUG(); 811 - 812 - key->payload.data = ci; 813 - _leave(" = 0"); 814 - return 0; 815 - } 816 - 817 - /* 818 - * dispose of the data dangling from the corpse of a rxrpc key 819 - */ 820 - static void rxrpc_destroy(struct key *key) 821 - { 822 - struct rxrpc_key_token *token; 823 - 824 - while ((token = key->payload.data)) { 825 - key->payload.data = token->next; 790 + for (; token; token = next) { 791 + next = token->next; 826 792 switch (token->security_index) { 827 793 case RXRPC_SECURITY_RXKAD: 828 794 kfree(token->kad); ··· 809 835 810 836 kfree(token); 811 837 } 838 + } 839 + 840 + /* 841 + * Clean up preparse data. 842 + */ 843 + static void rxrpc_free_preparse(struct key_preparsed_payload *prep) 844 + { 845 + rxrpc_free_token_list(prep->payload[0]); 846 + } 847 + 848 + /* 849 + * Preparse a server secret key. 850 + * 851 + * The data should be the 8-byte secret key. 852 + */ 853 + static int rxrpc_preparse_s(struct key_preparsed_payload *prep) 854 + { 855 + struct crypto_blkcipher *ci; 856 + 857 + _enter("%zu", prep->datalen); 858 + 859 + if (prep->datalen != 8) 860 + return -EINVAL; 861 + 862 + memcpy(&prep->type_data, prep->data, 8); 863 + 864 + ci = crypto_alloc_blkcipher("pcbc(des)", 0, CRYPTO_ALG_ASYNC); 865 + if (IS_ERR(ci)) { 866 + _leave(" = %ld", PTR_ERR(ci)); 867 + return PTR_ERR(ci); 868 + } 869 + 870 + if (crypto_blkcipher_setkey(ci, prep->data, 8) < 0) 871 + BUG(); 872 + 873 + prep->payload[0] = ci; 874 + _leave(" = 0"); 875 + return 0; 876 + } 877 + 878 + /* 879 + * Clean up preparse data. 880 + */ 881 + static void rxrpc_free_preparse_s(struct key_preparsed_payload *prep) 882 + { 883 + if (prep->payload[0]) 884 + crypto_free_blkcipher(prep->payload[0]); 885 + } 886 + 887 + /* 888 + * dispose of the data dangling from the corpse of a rxrpc key 889 + */ 890 + static void rxrpc_destroy(struct key *key) 891 + { 892 + rxrpc_free_token_list(key->payload.data); 812 893 } 813 894 814 895 /*
-1
scripts/selinux/genheaders/Makefile
··· 2 2 HOST_EXTRACFLAGS += -Isecurity/selinux/include 3 3 4 4 always := $(hostprogs-y) 5 - clean-files := $(hostprogs-y)
+1 -1
scripts/selinux/mdp/Makefile
··· 2 2 HOST_EXTRACFLAGS += -Isecurity/selinux/include 3 3 4 4 always := $(hostprogs-y) 5 - clean-files := $(hostprogs-y) policy.* file_contexts 5 + clean-files := policy.* file_contexts
+2 -2
security/apparmor/domain.c
··· 621 621 * There is no exception for unconfined as change_hat is not 622 622 * available. 623 623 */ 624 - if (current->no_new_privs) 624 + if (task_no_new_privs(current)) 625 625 return -EPERM; 626 626 627 627 /* released below */ ··· 776 776 * no_new_privs is set because this aways results in a reduction 777 777 * of permissions. 778 778 */ 779 - if (current->no_new_privs && !unconfined(profile)) { 779 + if (task_no_new_privs(current) && !unconfined(profile)) { 780 780 put_cred(cred); 781 781 return -EPERM; 782 782 }
+6
security/capability.c
··· 401 401 return 0; 402 402 } 403 403 404 + static int cap_kernel_fw_from_file(struct file *file, char *buf, size_t size) 405 + { 406 + return 0; 407 + } 408 + 404 409 static int cap_kernel_module_request(char *kmod_name) 405 410 { 406 411 return 0; ··· 1020 1015 set_to_cap_if_null(ops, cred_transfer); 1021 1016 set_to_cap_if_null(ops, kernel_act_as); 1022 1017 set_to_cap_if_null(ops, kernel_create_files_as); 1018 + set_to_cap_if_null(ops, kernel_fw_from_file); 1023 1019 set_to_cap_if_null(ops, kernel_module_request); 1024 1020 set_to_cap_if_null(ops, kernel_module_from_file); 1025 1021 set_to_cap_if_null(ops, task_fix_setuid);
+33 -42
security/commoncap.c
··· 421 421 cpu_caps->inheritable.cap[i] = le32_to_cpu(caps.data[i].inheritable); 422 422 } 423 423 424 + cpu_caps->permitted.cap[CAP_LAST_U32] &= CAP_LAST_U32_VALID_MASK; 425 + cpu_caps->inheritable.cap[CAP_LAST_U32] &= CAP_LAST_U32_VALID_MASK; 426 + 424 427 return 0; 425 428 } 426 429 ··· 825 822 * Implement PR_CAPBSET_DROP. Attempt to remove the specified capability from 826 823 * the current task's bounding set. Returns 0 on success, -ve on error. 827 824 */ 828 - static long cap_prctl_drop(struct cred *new, unsigned long cap) 825 + static int cap_prctl_drop(unsigned long cap) 829 826 { 827 + struct cred *new; 828 + 830 829 if (!ns_capable(current_user_ns(), CAP_SETPCAP)) 831 830 return -EPERM; 832 831 if (!cap_valid(cap)) 833 832 return -EINVAL; 834 833 834 + new = prepare_creds(); 835 + if (!new) 836 + return -ENOMEM; 835 837 cap_lower(new->cap_bset, cap); 836 - return 0; 838 + return commit_creds(new); 837 839 } 838 840 839 841 /** ··· 856 848 int cap_task_prctl(int option, unsigned long arg2, unsigned long arg3, 857 849 unsigned long arg4, unsigned long arg5) 858 850 { 851 + const struct cred *old = current_cred(); 859 852 struct cred *new; 860 - long error = 0; 861 - 862 - new = prepare_creds(); 863 - if (!new) 864 - return -ENOMEM; 865 853 866 854 switch (option) { 867 855 case PR_CAPBSET_READ: 868 - error = -EINVAL; 869 856 if (!cap_valid(arg2)) 870 - goto error; 871 - error = !!cap_raised(new->cap_bset, arg2); 872 - goto no_change; 857 + return -EINVAL; 858 + return !!cap_raised(old->cap_bset, arg2); 873 859 874 860 case PR_CAPBSET_DROP: 875 - error = cap_prctl_drop(new, arg2); 876 - if (error < 0) 877 - goto error; 878 - goto changed; 861 + return cap_prctl_drop(arg2); 879 862 880 863 /* 881 864 * The next four prctl's remain to assist with transitioning a ··· 888 889 * capability-based-privilege environment. 889 890 */ 890 891 case PR_SET_SECUREBITS: 891 - error = -EPERM; 892 - if ((((new->securebits & SECURE_ALL_LOCKS) >> 1) 893 - & (new->securebits ^ arg2)) /*[1]*/ 894 - || ((new->securebits & SECURE_ALL_LOCKS & ~arg2)) /*[2]*/ 892 + if ((((old->securebits & SECURE_ALL_LOCKS) >> 1) 893 + & (old->securebits ^ arg2)) /*[1]*/ 894 + || ((old->securebits & SECURE_ALL_LOCKS & ~arg2)) /*[2]*/ 895 895 || (arg2 & ~(SECURE_ALL_LOCKS | SECURE_ALL_BITS)) /*[3]*/ 896 896 || (cap_capable(current_cred(), 897 897 current_cred()->user_ns, CAP_SETPCAP, ··· 904 906 */ 905 907 ) 906 908 /* cannot change a locked bit */ 907 - goto error; 909 + return -EPERM; 910 + 911 + new = prepare_creds(); 912 + if (!new) 913 + return -ENOMEM; 908 914 new->securebits = arg2; 909 - goto changed; 915 + return commit_creds(new); 910 916 911 917 case PR_GET_SECUREBITS: 912 - error = new->securebits; 913 - goto no_change; 918 + return old->securebits; 914 919 915 920 case PR_GET_KEEPCAPS: 916 - if (issecure(SECURE_KEEP_CAPS)) 917 - error = 1; 918 - goto no_change; 921 + return !!issecure(SECURE_KEEP_CAPS); 919 922 920 923 case PR_SET_KEEPCAPS: 921 - error = -EINVAL; 922 924 if (arg2 > 1) /* Note, we rely on arg2 being unsigned here */ 923 - goto error; 924 - error = -EPERM; 925 + return -EINVAL; 925 926 if (issecure(SECURE_KEEP_CAPS_LOCKED)) 926 - goto error; 927 + return -EPERM; 928 + 929 + new = prepare_creds(); 930 + if (!new) 931 + return -ENOMEM; 927 932 if (arg2) 928 933 new->securebits |= issecure_mask(SECURE_KEEP_CAPS); 929 934 else 930 935 new->securebits &= ~issecure_mask(SECURE_KEEP_CAPS); 931 - goto changed; 936 + return commit_creds(new); 932 937 933 938 default: 934 939 /* No functionality available - continue with default */ 935 - error = -ENOSYS; 936 - goto error; 940 + return -ENOSYS; 937 941 } 938 - 939 - /* Functionality provided */ 940 - changed: 941 - return commit_creds(new); 942 - 943 - no_change: 944 - error: 945 - abort_creds(new); 946 - return error; 947 942 } 948 943 949 944 /**
+28
security/integrity/digsig.c
··· 13 13 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt 14 14 15 15 #include <linux/err.h> 16 + #include <linux/sched.h> 16 17 #include <linux/rbtree.h> 18 + #include <linux/cred.h> 17 19 #include <linux/key-type.h> 18 20 #include <linux/digsig.h> 19 21 ··· 26 24 static const char *keyring_name[INTEGRITY_KEYRING_MAX] = { 27 25 "_evm", 28 26 "_module", 27 + #ifndef CONFIG_IMA_TRUSTED_KEYRING 29 28 "_ima", 29 + #else 30 + ".ima", 31 + #endif 30 32 }; 31 33 32 34 int integrity_digsig_verify(const unsigned int id, const char *sig, int siglen, ··· 61 55 } 62 56 63 57 return -EOPNOTSUPP; 58 + } 59 + 60 + int integrity_init_keyring(const unsigned int id) 61 + { 62 + const struct cred *cred = current_cred(); 63 + int err = 0; 64 + 65 + keyring[id] = keyring_alloc(keyring_name[id], KUIDT_INIT(0), 66 + KGIDT_INIT(0), cred, 67 + ((KEY_POS_ALL & ~KEY_POS_SETATTR) | 68 + KEY_USR_VIEW | KEY_USR_READ | 69 + KEY_USR_WRITE | KEY_USR_SEARCH), 70 + KEY_ALLOC_NOT_IN_QUOTA, NULL); 71 + if (!IS_ERR(keyring[id])) 72 + set_bit(KEY_FLAG_TRUSTED_ONLY, &keyring[id]->flags); 73 + else { 74 + err = PTR_ERR(keyring[id]); 75 + pr_info("Can't allocate %s keyring (%d)\n", 76 + keyring_name[id], err); 77 + keyring[id] = NULL; 78 + } 79 + return err; 64 80 }
+10
security/integrity/ima/Kconfig
··· 123 123 For more information on integrity appraisal refer to: 124 124 <http://linux-ima.sourceforge.net> 125 125 If unsure, say N. 126 + 127 + config IMA_TRUSTED_KEYRING 128 + bool "Require all keys on the .ima keyring be signed" 129 + depends on IMA_APPRAISE && SYSTEM_TRUSTED_KEYRING 130 + depends on INTEGRITY_ASYMMETRIC_KEYS 131 + select KEYS_DEBUG_PROC_KEYS 132 + default y 133 + help 134 + This option requires that all keys added to the .ima 135 + keyring be signed by a key on the system trusted keyring.
+14 -1
security/integrity/ima/ima.h
··· 158 158 struct integrity_iint_cache *integrity_iint_find(struct inode *inode); 159 159 160 160 /* IMA policy related functions */ 161 - enum ima_hooks { FILE_CHECK = 1, MMAP_CHECK, BPRM_CHECK, MODULE_CHECK, POST_SETATTR }; 161 + enum ima_hooks { FILE_CHECK = 1, MMAP_CHECK, BPRM_CHECK, MODULE_CHECK, FIRMWARE_CHECK, POST_SETATTR }; 162 162 163 163 int ima_match_policy(struct inode *inode, enum ima_hooks func, int mask, 164 164 int flags); ··· 171 171 #define IMA_APPRAISE_ENFORCE 0x01 172 172 #define IMA_APPRAISE_FIX 0x02 173 173 #define IMA_APPRAISE_MODULES 0x04 174 + #define IMA_APPRAISE_FIRMWARE 0x08 174 175 175 176 #ifdef CONFIG_IMA_APPRAISE 176 177 int ima_appraise_measurement(int func, struct integrity_iint_cache *iint, ··· 250 249 return -EINVAL; 251 250 } 252 251 #endif /* CONFIG_IMA_LSM_RULES */ 252 + 253 + #ifdef CONFIG_IMA_TRUSTED_KEYRING 254 + static inline int ima_init_keyring(const unsigned int id) 255 + { 256 + return integrity_init_keyring(id); 257 + } 258 + #else 259 + static inline int ima_init_keyring(const unsigned int id) 260 + { 261 + return 0; 262 + } 263 + #endif /* CONFIG_IMA_TRUSTED_KEYRING */ 253 264 #endif
+9 -1
security/integrity/ima/ima_appraise.c
··· 75 75 return iint->ima_bprm_status; 76 76 case MODULE_CHECK: 77 77 return iint->ima_module_status; 78 + case FIRMWARE_CHECK: 79 + return iint->ima_firmware_status; 78 80 case FILE_CHECK: 79 81 default: 80 82 return iint->ima_file_status; ··· 96 94 case MODULE_CHECK: 97 95 iint->ima_module_status = status; 98 96 break; 97 + case FIRMWARE_CHECK: 98 + iint->ima_firmware_status = status; 99 + break; 99 100 case FILE_CHECK: 100 101 default: 101 102 iint->ima_file_status = status; ··· 117 112 break; 118 113 case MODULE_CHECK: 119 114 iint->flags |= (IMA_MODULE_APPRAISED | IMA_APPRAISED); 115 + break; 116 + case FIRMWARE_CHECK: 117 + iint->flags |= (IMA_FIRMWARE_APPRAISED | IMA_APPRAISED); 120 118 break; 121 119 case FILE_CHECK: 122 120 default: ··· 222 214 hash_start = 1; 223 215 case IMA_XATTR_DIGEST: 224 216 if (iint->flags & IMA_DIGSIG_REQUIRED) { 225 - cause = "IMA signature required"; 217 + cause = "IMA-signature-required"; 226 218 status = INTEGRITY_FAIL; 227 219 break; 228 220 }
+309 -3
security/integrity/ima/ima_crypto.c
··· 16 16 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt 17 17 18 18 #include <linux/kernel.h> 19 + #include <linux/moduleparam.h> 20 + #include <linux/ratelimit.h> 19 21 #include <linux/file.h> 20 22 #include <linux/crypto.h> 21 23 #include <linux/scatterlist.h> ··· 27 25 #include <crypto/hash_info.h> 28 26 #include "ima.h" 29 27 28 + struct ahash_completion { 29 + struct completion completion; 30 + int err; 31 + }; 32 + 33 + /* minimum file size for ahash use */ 34 + static unsigned long ima_ahash_minsize; 35 + module_param_named(ahash_minsize, ima_ahash_minsize, ulong, 0644); 36 + MODULE_PARM_DESC(ahash_minsize, "Minimum file size for ahash use"); 37 + 38 + /* default is 0 - 1 page. */ 39 + static int ima_maxorder; 40 + static unsigned int ima_bufsize = PAGE_SIZE; 41 + 42 + static int param_set_bufsize(const char *val, const struct kernel_param *kp) 43 + { 44 + unsigned long long size; 45 + int order; 46 + 47 + size = memparse(val, NULL); 48 + order = get_order(size); 49 + if (order >= MAX_ORDER) 50 + return -EINVAL; 51 + ima_maxorder = order; 52 + ima_bufsize = PAGE_SIZE << order; 53 + return 0; 54 + } 55 + 56 + static struct kernel_param_ops param_ops_bufsize = { 57 + .set = param_set_bufsize, 58 + .get = param_get_uint, 59 + }; 60 + #define param_check_bufsize(name, p) __param_check(name, p, unsigned int) 61 + 62 + module_param_named(ahash_bufsize, ima_bufsize, bufsize, 0644); 63 + MODULE_PARM_DESC(ahash_bufsize, "Maximum ahash buffer size"); 64 + 30 65 static struct crypto_shash *ima_shash_tfm; 66 + static struct crypto_ahash *ima_ahash_tfm; 31 67 32 68 /** 33 69 * ima_kernel_read - read file content ··· 133 93 crypto_free_shash(tfm); 134 94 } 135 95 136 - /* 137 - * Calculate the MD5/SHA1 file digest 96 + /** 97 + * ima_alloc_pages() - Allocate contiguous pages. 98 + * @max_size: Maximum amount of memory to allocate. 99 + * @allocated_size: Returned size of actual allocation. 100 + * @last_warn: Should the min_size allocation warn or not. 101 + * 102 + * Tries to do opportunistic allocation for memory first trying to allocate 103 + * max_size amount of memory and then splitting that until zero order is 104 + * reached. Allocation is tried without generating allocation warnings unless 105 + * last_warn is set. Last_warn set affects only last allocation of zero order. 106 + * 107 + * By default, ima_maxorder is 0 and it is equivalent to kmalloc(GFP_KERNEL) 108 + * 109 + * Return pointer to allocated memory, or NULL on failure. 138 110 */ 111 + static void *ima_alloc_pages(loff_t max_size, size_t *allocated_size, 112 + int last_warn) 113 + { 114 + void *ptr; 115 + int order = ima_maxorder; 116 + gfp_t gfp_mask = __GFP_WAIT | __GFP_NOWARN | __GFP_NORETRY; 117 + 118 + if (order) 119 + order = min(get_order(max_size), order); 120 + 121 + for (; order; order--) { 122 + ptr = (void *)__get_free_pages(gfp_mask, order); 123 + if (ptr) { 124 + *allocated_size = PAGE_SIZE << order; 125 + return ptr; 126 + } 127 + } 128 + 129 + /* order is zero - one page */ 130 + 131 + gfp_mask = GFP_KERNEL; 132 + 133 + if (!last_warn) 134 + gfp_mask |= __GFP_NOWARN; 135 + 136 + ptr = (void *)__get_free_pages(gfp_mask, 0); 137 + if (ptr) { 138 + *allocated_size = PAGE_SIZE; 139 + return ptr; 140 + } 141 + 142 + *allocated_size = 0; 143 + return NULL; 144 + } 145 + 146 + /** 147 + * ima_free_pages() - Free pages allocated by ima_alloc_pages(). 148 + * @ptr: Pointer to allocated pages. 149 + * @size: Size of allocated buffer. 150 + */ 151 + static void ima_free_pages(void *ptr, size_t size) 152 + { 153 + if (!ptr) 154 + return; 155 + free_pages((unsigned long)ptr, get_order(size)); 156 + } 157 + 158 + static struct crypto_ahash *ima_alloc_atfm(enum hash_algo algo) 159 + { 160 + struct crypto_ahash *tfm = ima_ahash_tfm; 161 + int rc; 162 + 163 + if ((algo != ima_hash_algo && algo < HASH_ALGO__LAST) || !tfm) { 164 + tfm = crypto_alloc_ahash(hash_algo_name[algo], 0, 0); 165 + if (!IS_ERR(tfm)) { 166 + if (algo == ima_hash_algo) 167 + ima_ahash_tfm = tfm; 168 + } else { 169 + rc = PTR_ERR(tfm); 170 + pr_err("Can not allocate %s (reason: %d)\n", 171 + hash_algo_name[algo], rc); 172 + } 173 + } 174 + return tfm; 175 + } 176 + 177 + static void ima_free_atfm(struct crypto_ahash *tfm) 178 + { 179 + if (tfm != ima_ahash_tfm) 180 + crypto_free_ahash(tfm); 181 + } 182 + 183 + static void ahash_complete(struct crypto_async_request *req, int err) 184 + { 185 + struct ahash_completion *res = req->data; 186 + 187 + if (err == -EINPROGRESS) 188 + return; 189 + res->err = err; 190 + complete(&res->completion); 191 + } 192 + 193 + static int ahash_wait(int err, struct ahash_completion *res) 194 + { 195 + switch (err) { 196 + case 0: 197 + break; 198 + case -EINPROGRESS: 199 + case -EBUSY: 200 + wait_for_completion(&res->completion); 201 + reinit_completion(&res->completion); 202 + err = res->err; 203 + /* fall through */ 204 + default: 205 + pr_crit_ratelimited("ahash calculation failed: err: %d\n", err); 206 + } 207 + 208 + return err; 209 + } 210 + 211 + static int ima_calc_file_hash_atfm(struct file *file, 212 + struct ima_digest_data *hash, 213 + struct crypto_ahash *tfm) 214 + { 215 + loff_t i_size, offset; 216 + char *rbuf[2] = { NULL, }; 217 + int rc, read = 0, rbuf_len, active = 0, ahash_rc = 0; 218 + struct ahash_request *req; 219 + struct scatterlist sg[1]; 220 + struct ahash_completion res; 221 + size_t rbuf_size[2]; 222 + 223 + hash->length = crypto_ahash_digestsize(tfm); 224 + 225 + req = ahash_request_alloc(tfm, GFP_KERNEL); 226 + if (!req) 227 + return -ENOMEM; 228 + 229 + init_completion(&res.completion); 230 + ahash_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG | 231 + CRYPTO_TFM_REQ_MAY_SLEEP, 232 + ahash_complete, &res); 233 + 234 + rc = ahash_wait(crypto_ahash_init(req), &res); 235 + if (rc) 236 + goto out1; 237 + 238 + i_size = i_size_read(file_inode(file)); 239 + 240 + if (i_size == 0) 241 + goto out2; 242 + 243 + /* 244 + * Try to allocate maximum size of memory. 245 + * Fail if even a single page cannot be allocated. 246 + */ 247 + rbuf[0] = ima_alloc_pages(i_size, &rbuf_size[0], 1); 248 + if (!rbuf[0]) { 249 + rc = -ENOMEM; 250 + goto out1; 251 + } 252 + 253 + /* Only allocate one buffer if that is enough. */ 254 + if (i_size > rbuf_size[0]) { 255 + /* 256 + * Try to allocate secondary buffer. If that fails fallback to 257 + * using single buffering. Use previous memory allocation size 258 + * as baseline for possible allocation size. 259 + */ 260 + rbuf[1] = ima_alloc_pages(i_size - rbuf_size[0], 261 + &rbuf_size[1], 0); 262 + } 263 + 264 + if (!(file->f_mode & FMODE_READ)) { 265 + file->f_mode |= FMODE_READ; 266 + read = 1; 267 + } 268 + 269 + for (offset = 0; offset < i_size; offset += rbuf_len) { 270 + if (!rbuf[1] && offset) { 271 + /* Not using two buffers, and it is not the first 272 + * read/request, wait for the completion of the 273 + * previous ahash_update() request. 274 + */ 275 + rc = ahash_wait(ahash_rc, &res); 276 + if (rc) 277 + goto out3; 278 + } 279 + /* read buffer */ 280 + rbuf_len = min_t(loff_t, i_size - offset, rbuf_size[active]); 281 + rc = ima_kernel_read(file, offset, rbuf[active], rbuf_len); 282 + if (rc != rbuf_len) 283 + goto out3; 284 + 285 + if (rbuf[1] && offset) { 286 + /* Using two buffers, and it is not the first 287 + * read/request, wait for the completion of the 288 + * previous ahash_update() request. 289 + */ 290 + rc = ahash_wait(ahash_rc, &res); 291 + if (rc) 292 + goto out3; 293 + } 294 + 295 + sg_init_one(&sg[0], rbuf[active], rbuf_len); 296 + ahash_request_set_crypt(req, sg, NULL, rbuf_len); 297 + 298 + ahash_rc = crypto_ahash_update(req); 299 + 300 + if (rbuf[1]) 301 + active = !active; /* swap buffers, if we use two */ 302 + } 303 + /* wait for the last update request to complete */ 304 + rc = ahash_wait(ahash_rc, &res); 305 + out3: 306 + if (read) 307 + file->f_mode &= ~FMODE_READ; 308 + ima_free_pages(rbuf[0], rbuf_size[0]); 309 + ima_free_pages(rbuf[1], rbuf_size[1]); 310 + out2: 311 + if (!rc) { 312 + ahash_request_set_crypt(req, NULL, hash->digest, 0); 313 + rc = ahash_wait(crypto_ahash_final(req), &res); 314 + } 315 + out1: 316 + ahash_request_free(req); 317 + return rc; 318 + } 319 + 320 + static int ima_calc_file_ahash(struct file *file, struct ima_digest_data *hash) 321 + { 322 + struct crypto_ahash *tfm; 323 + int rc; 324 + 325 + tfm = ima_alloc_atfm(hash->algo); 326 + if (IS_ERR(tfm)) 327 + return PTR_ERR(tfm); 328 + 329 + rc = ima_calc_file_hash_atfm(file, hash, tfm); 330 + 331 + ima_free_atfm(tfm); 332 + 333 + return rc; 334 + } 335 + 139 336 static int ima_calc_file_hash_tfm(struct file *file, 140 337 struct ima_digest_data *hash, 141 338 struct crypto_shash *tfm) ··· 433 156 return rc; 434 157 } 435 158 436 - int ima_calc_file_hash(struct file *file, struct ima_digest_data *hash) 159 + static int ima_calc_file_shash(struct file *file, struct ima_digest_data *hash) 437 160 { 438 161 struct crypto_shash *tfm; 439 162 int rc; ··· 447 170 ima_free_tfm(tfm); 448 171 449 172 return rc; 173 + } 174 + 175 + /* 176 + * ima_calc_file_hash - calculate file hash 177 + * 178 + * Asynchronous hash (ahash) allows using HW acceleration for calculating 179 + * a hash. ahash performance varies for different data sizes on different 180 + * crypto accelerators. shash performance might be better for smaller files. 181 + * The 'ima.ahash_minsize' module parameter allows specifying the best 182 + * minimum file size for using ahash on the system. 183 + * 184 + * If the ima.ahash_minsize parameter is not specified, this function uses 185 + * shash for the hash calculation. If ahash fails, it falls back to using 186 + * shash. 187 + */ 188 + int ima_calc_file_hash(struct file *file, struct ima_digest_data *hash) 189 + { 190 + loff_t i_size; 191 + int rc; 192 + 193 + i_size = i_size_read(file_inode(file)); 194 + 195 + if (ima_ahash_minsize && i_size >= ima_ahash_minsize) { 196 + rc = ima_calc_file_ahash(file, hash); 197 + if (!rc) 198 + return 0; 199 + } 200 + 201 + return ima_calc_file_shash(file, hash); 450 202 } 451 203 452 204 /*
+21 -7
security/integrity/ima/ima_main.c
··· 88 88 if (!S_ISREG(inode->i_mode) || !ima_initialized) 89 89 return; 90 90 91 - mutex_lock(&inode->i_mutex); /* file metadata: permissions, xattr */ 92 - 93 91 if (mode & FMODE_WRITE) { 94 92 if (atomic_read(&inode->i_readcount) && IS_IMA(inode)) { 95 93 struct integrity_iint_cache *iint; ··· 101 103 ima_must_measure(inode, MAY_READ, FILE_CHECK)) 102 104 send_writers = true; 103 105 } 104 - 105 - mutex_unlock(&inode->i_mutex); 106 106 107 107 if (!send_tomtou && !send_writers) 108 108 return; ··· 159 163 { 160 164 struct inode *inode = file_inode(file); 161 165 struct integrity_iint_cache *iint; 162 - struct ima_template_desc *template_desc = ima_template_desc_current(); 166 + struct ima_template_desc *template_desc; 163 167 char *pathbuf = NULL; 164 168 const char *pathname = NULL; 165 169 int rc = -ENOMEM, action, must_appraise, _func; ··· 203 207 goto out_digsig; 204 208 } 205 209 210 + template_desc = ima_template_desc_current(); 206 211 if (strcmp(template_desc->name, IMA_TEMPLATE_IMA_NAME) == 0) { 207 212 if (action & IMA_APPRAISE_SUBMASK) 208 213 xattr_ptr = &xattr_value; ··· 319 322 return process_measurement(file, NULL, MAY_EXEC, MODULE_CHECK); 320 323 } 321 324 325 + int ima_fw_from_file(struct file *file, char *buf, size_t size) 326 + { 327 + if (!file) { 328 + if ((ima_appraise & IMA_APPRAISE_FIRMWARE) && 329 + (ima_appraise & IMA_APPRAISE_ENFORCE)) 330 + return -EACCES; /* INTEGRITY_UNKNOWN */ 331 + return 0; 332 + } 333 + return process_measurement(file, NULL, MAY_EXEC, FIRMWARE_CHECK); 334 + } 335 + 322 336 static int __init init_ima(void) 323 337 { 324 338 int error; 325 339 326 340 hash_setup(CONFIG_IMA_DEFAULT_HASH); 327 341 error = ima_init(); 328 - if (!error) 329 - ima_initialized = 1; 342 + if (error) 343 + goto out; 344 + 345 + error = ima_init_keyring(INTEGRITY_KEYRING_IMA); 346 + if (error) 347 + goto out; 348 + ima_initialized = 1; 349 + out: 330 350 return error; 331 351 } 332 352
+10 -3
security/integrity/ima/ima_policy.c
··· 84 84 {.action = MEASURE, .func = FILE_CHECK, .mask = MAY_READ, .uid = GLOBAL_ROOT_UID, 85 85 .flags = IMA_FUNC | IMA_MASK | IMA_UID}, 86 86 {.action = MEASURE, .func = MODULE_CHECK, .flags = IMA_FUNC}, 87 + {.action = MEASURE, .func = FIRMWARE_CHECK, .flags = IMA_FUNC}, 87 88 }; 88 89 89 90 static struct ima_rule_entry default_appraise_rules[] = { ··· 242 241 return IMA_BPRM_APPRAISE; 243 242 case MODULE_CHECK: 244 243 return IMA_MODULE_APPRAISE; 244 + case FIRMWARE_CHECK: 245 + return IMA_FIRMWARE_APPRAISE; 245 246 case FILE_CHECK: 246 247 default: 247 248 return IMA_FILE_APPRAISE; ··· 335 332 void ima_update_policy(void) 336 333 { 337 334 static const char op[] = "policy_update"; 338 - const char *cause = "already exists"; 335 + const char *cause = "already-exists"; 339 336 int result = 1; 340 337 int audit_info = 0; 341 338 ··· 489 486 entry->func = FILE_CHECK; 490 487 else if (strcmp(args[0].from, "MODULE_CHECK") == 0) 491 488 entry->func = MODULE_CHECK; 489 + else if (strcmp(args[0].from, "FIRMWARE_CHECK") == 0) 490 + entry->func = FIRMWARE_CHECK; 492 491 else if ((strcmp(args[0].from, "FILE_MMAP") == 0) 493 492 || (strcmp(args[0].from, "MMAP_CHECK") == 0)) 494 493 entry->func = MMAP_CHECK; ··· 641 636 result = -EINVAL; 642 637 else if (entry->func == MODULE_CHECK) 643 638 ima_appraise |= IMA_APPRAISE_MODULES; 639 + else if (entry->func == FIRMWARE_CHECK) 640 + ima_appraise |= IMA_APPRAISE_FIRMWARE; 644 641 audit_log_format(ab, "res=%d", !result); 645 642 audit_log_end(ab); 646 643 return result; ··· 666 659 /* Prevent installed policy from changing */ 667 660 if (ima_rules != &ima_default_rules) { 668 661 integrity_audit_msg(AUDIT_INTEGRITY_STATUS, NULL, 669 - NULL, op, "already exists", 662 + NULL, op, "already-exists", 670 663 -EACCES, audit_info); 671 664 return -EACCES; 672 665 } ··· 692 685 if (result) { 693 686 kfree(entry); 694 687 integrity_audit_msg(AUDIT_INTEGRITY_STATUS, NULL, 695 - NULL, op, "invalid policy", result, 688 + NULL, op, "invalid-policy", result, 696 689 audit_info); 697 690 return result; 698 691 }
+12 -2
security/integrity/integrity.h
··· 46 46 #define IMA_BPRM_APPRAISED 0x00002000 47 47 #define IMA_MODULE_APPRAISE 0x00004000 48 48 #define IMA_MODULE_APPRAISED 0x00008000 49 + #define IMA_FIRMWARE_APPRAISE 0x00010000 50 + #define IMA_FIRMWARE_APPRAISED 0x00020000 49 51 #define IMA_APPRAISE_SUBMASK (IMA_FILE_APPRAISE | IMA_MMAP_APPRAISE | \ 50 - IMA_BPRM_APPRAISE | IMA_MODULE_APPRAISE) 52 + IMA_BPRM_APPRAISE | IMA_MODULE_APPRAISE | \ 53 + IMA_FIRMWARE_APPRAISE) 51 54 #define IMA_APPRAISED_SUBMASK (IMA_FILE_APPRAISED | IMA_MMAP_APPRAISED | \ 52 - IMA_BPRM_APPRAISED | IMA_MODULE_APPRAISED) 55 + IMA_BPRM_APPRAISED | IMA_MODULE_APPRAISED | \ 56 + IMA_FIRMWARE_APPRAISED) 53 57 54 58 enum evm_ima_xattr_type { 55 59 IMA_XATTR_DIGEST = 0x01, ··· 108 104 enum integrity_status ima_mmap_status:4; 109 105 enum integrity_status ima_bprm_status:4; 110 106 enum integrity_status ima_module_status:4; 107 + enum integrity_status ima_firmware_status:4; 111 108 enum integrity_status evm_status:4; 112 109 struct ima_digest_data *ima_hash; 113 110 }; ··· 129 124 int integrity_digsig_verify(const unsigned int id, const char *sig, int siglen, 130 125 const char *digest, int digestlen); 131 126 127 + int integrity_init_keyring(const unsigned int id); 132 128 #else 133 129 134 130 static inline int integrity_digsig_verify(const unsigned int id, ··· 139 133 return -EOPNOTSUPP; 140 134 } 141 135 136 + static inline int integrity_init_keyring(const unsigned int id) 137 + { 138 + return 0; 139 + } 142 140 #endif /* CONFIG_INTEGRITY_SIGNATURE */ 143 141 144 142 #ifdef CONFIG_INTEGRITY_ASYMMETRIC_KEYS
+25 -16
security/keys/big_key.c
··· 34 34 struct key_type key_type_big_key = { 35 35 .name = "big_key", 36 36 .def_lookup_type = KEYRING_SEARCH_LOOKUP_DIRECT, 37 - .instantiate = big_key_instantiate, 37 + .preparse = big_key_preparse, 38 + .free_preparse = big_key_free_preparse, 39 + .instantiate = generic_key_instantiate, 38 40 .match = user_match, 39 41 .revoke = big_key_revoke, 40 42 .destroy = big_key_destroy, ··· 45 43 }; 46 44 47 45 /* 48 - * Instantiate a big key 46 + * Preparse a big key 49 47 */ 50 - int big_key_instantiate(struct key *key, struct key_preparsed_payload *prep) 48 + int big_key_preparse(struct key_preparsed_payload *prep) 51 49 { 52 - struct path *path = (struct path *)&key->payload.data2; 50 + struct path *path = (struct path *)&prep->payload; 53 51 struct file *file; 54 52 ssize_t written; 55 53 size_t datalen = prep->datalen; ··· 60 58 goto error; 61 59 62 60 /* Set an arbitrary quota */ 63 - ret = key_payload_reserve(key, 16); 64 - if (ret < 0) 65 - goto error; 61 + prep->quotalen = 16; 66 62 67 - key->type_data.x[1] = datalen; 63 + prep->type_data[1] = (void *)(unsigned long)datalen; 68 64 69 65 if (datalen > BIG_KEY_FILE_THRESHOLD) { 70 66 /* Create a shmem file to store the data in. This will permit the data ··· 73 73 file = shmem_kernel_file_setup("", datalen, 0); 74 74 if (IS_ERR(file)) { 75 75 ret = PTR_ERR(file); 76 - goto err_quota; 76 + goto error; 77 77 } 78 78 79 79 written = kernel_write(file, prep->data, prep->datalen, 0); ··· 93 93 } else { 94 94 /* Just store the data in a buffer */ 95 95 void *data = kmalloc(datalen, GFP_KERNEL); 96 - if (!data) { 97 - ret = -ENOMEM; 98 - goto err_quota; 99 - } 96 + if (!data) 97 + return -ENOMEM; 100 98 101 - key->payload.data = memcpy(data, prep->data, prep->datalen); 99 + prep->payload[0] = memcpy(data, prep->data, prep->datalen); 102 100 } 103 101 return 0; 104 102 105 103 err_fput: 106 104 fput(file); 107 - err_quota: 108 - key_payload_reserve(key, 0); 109 105 error: 110 106 return ret; 107 + } 108 + 109 + /* 110 + * Clear preparsement. 111 + */ 112 + void big_key_free_preparse(struct key_preparsed_payload *prep) 113 + { 114 + if (prep->datalen > BIG_KEY_FILE_THRESHOLD) { 115 + struct path *path = (struct path *)&prep->payload; 116 + path_put(path); 117 + } else { 118 + kfree(prep->payload[0]); 119 + } 111 120 } 112 121 113 122 /*
+44 -5
security/keys/key.c
··· 437 437 /* disable the authorisation key */ 438 438 if (authkey) 439 439 key_revoke(authkey); 440 + 441 + if (prep->expiry != TIME_T_MAX) { 442 + key->expiry = prep->expiry; 443 + key_schedule_gc(prep->expiry + key_gc_delay); 444 + } 440 445 } 441 446 } 442 447 ··· 484 479 prep.data = data; 485 480 prep.datalen = datalen; 486 481 prep.quotalen = key->type->def_datalen; 482 + prep.expiry = TIME_T_MAX; 487 483 if (key->type->preparse) { 488 484 ret = key->type->preparse(&prep); 489 485 if (ret < 0) ··· 494 488 if (keyring) { 495 489 ret = __key_link_begin(keyring, &key->index_key, &edit); 496 490 if (ret < 0) 497 - goto error_free_preparse; 491 + goto error; 498 492 } 499 493 500 494 ret = __key_instantiate_and_link(key, &prep, keyring, authkey, &edit); ··· 502 496 if (keyring) 503 497 __key_link_end(keyring, &key->index_key, edit); 504 498 505 - error_free_preparse: 499 + error: 506 500 if (key->type->preparse) 507 501 key->type->free_preparse(&prep); 508 - error: 509 502 return ret; 510 503 } 511 504 ··· 816 811 prep.datalen = plen; 817 812 prep.quotalen = index_key.type->def_datalen; 818 813 prep.trusted = flags & KEY_ALLOC_TRUSTED; 814 + prep.expiry = TIME_T_MAX; 819 815 if (index_key.type->preparse) { 820 816 ret = index_key.type->preparse(&prep); 821 817 if (ret < 0) { 822 818 key_ref = ERR_PTR(ret); 823 - goto error_put_type; 819 + goto error_free_prep; 824 820 } 825 821 if (!index_key.description) 826 822 index_key.description = prep.description; ··· 947 941 prep.data = payload; 948 942 prep.datalen = plen; 949 943 prep.quotalen = key->type->def_datalen; 944 + prep.expiry = TIME_T_MAX; 950 945 if (key->type->preparse) { 951 946 ret = key->type->preparse(&prep); 952 947 if (ret < 0) ··· 963 956 964 957 up_write(&key->sem); 965 958 959 + error: 966 960 if (key->type->preparse) 967 961 key->type->free_preparse(&prep); 968 - error: 969 962 return ret; 970 963 } 971 964 EXPORT_SYMBOL(key_update); ··· 1029 1022 } 1030 1023 } 1031 1024 EXPORT_SYMBOL(key_invalidate); 1025 + 1026 + /** 1027 + * generic_key_instantiate - Simple instantiation of a key from preparsed data 1028 + * @key: The key to be instantiated 1029 + * @prep: The preparsed data to load. 1030 + * 1031 + * Instantiate a key from preparsed data. We assume we can just copy the data 1032 + * in directly and clear the old pointers. 1033 + * 1034 + * This can be pointed to directly by the key type instantiate op pointer. 1035 + */ 1036 + int generic_key_instantiate(struct key *key, struct key_preparsed_payload *prep) 1037 + { 1038 + int ret; 1039 + 1040 + pr_devel("==>%s()\n", __func__); 1041 + 1042 + ret = key_payload_reserve(key, prep->quotalen); 1043 + if (ret == 0) { 1044 + key->type_data.p[0] = prep->type_data[0]; 1045 + key->type_data.p[1] = prep->type_data[1]; 1046 + rcu_assign_keypointer(key, prep->payload[0]); 1047 + key->payload.data2[1] = prep->payload[1]; 1048 + prep->type_data[0] = NULL; 1049 + prep->type_data[1] = NULL; 1050 + prep->payload[0] = NULL; 1051 + prep->payload[1] = NULL; 1052 + } 1053 + pr_devel("<==%s() = %d\n", __func__, ret); 1054 + return ret; 1055 + } 1056 + EXPORT_SYMBOL(generic_key_instantiate); 1032 1057 1033 1058 /** 1034 1059 * register_key_type - Register a type of key.
+18 -3
security/keys/keyctl.c
··· 37 37 return ret; 38 38 if (ret == 0 || ret >= len) 39 39 return -EINVAL; 40 - if (type[0] == '.') 41 - return -EPERM; 42 40 type[len - 1] = '\0'; 43 41 return 0; 44 42 } ··· 84 86 if (!*description) { 85 87 kfree(description); 86 88 description = NULL; 89 + } else if ((description[0] == '.') && 90 + (strncmp(type, "keyring", 7) == 0)) { 91 + ret = -EPERM; 92 + goto error2; 87 93 } 88 94 } 89 95 ··· 406 404 key_ref = lookup_user_key(id, 0, KEY_NEED_SEARCH); 407 405 if (IS_ERR(key_ref)) { 408 406 ret = PTR_ERR(key_ref); 407 + 408 + /* Root is permitted to invalidate certain special keys */ 409 + if (capable(CAP_SYS_ADMIN)) { 410 + key_ref = lookup_user_key(id, 0, 0); 411 + if (IS_ERR(key_ref)) 412 + goto error; 413 + if (test_bit(KEY_FLAG_ROOT_CAN_INVAL, 414 + &key_ref_to_ptr(key_ref)->flags)) 415 + goto invalidate; 416 + goto error_put; 417 + } 418 + 409 419 goto error; 410 420 } 411 421 422 + invalidate: 412 423 key_invalidate(key_ref_to_ptr(key_ref)); 413 424 ret = 0; 414 - 425 + error_put: 415 426 key_ref_put(key_ref); 416 427 error: 417 428 kleave(" = %ld", ret);
+23 -11
security/keys/keyring.c
··· 73 73 * can be treated as ordinary keys in addition to having their own special 74 74 * operations. 75 75 */ 76 + static int keyring_preparse(struct key_preparsed_payload *prep); 77 + static void keyring_free_preparse(struct key_preparsed_payload *prep); 76 78 static int keyring_instantiate(struct key *keyring, 77 79 struct key_preparsed_payload *prep); 78 80 static void keyring_revoke(struct key *keyring); ··· 86 84 struct key_type key_type_keyring = { 87 85 .name = "keyring", 88 86 .def_datalen = 0, 87 + .preparse = keyring_preparse, 88 + .free_preparse = keyring_free_preparse, 89 89 .instantiate = keyring_instantiate, 90 90 .match = user_match, 91 91 .revoke = keyring_revoke, ··· 127 123 } 128 124 129 125 /* 126 + * Preparse a keyring payload 127 + */ 128 + static int keyring_preparse(struct key_preparsed_payload *prep) 129 + { 130 + return prep->datalen != 0 ? -EINVAL : 0; 131 + } 132 + 133 + /* 134 + * Free a preparse of a user defined key payload 135 + */ 136 + static void keyring_free_preparse(struct key_preparsed_payload *prep) 137 + { 138 + } 139 + 140 + /* 130 141 * Initialise a keyring. 131 142 * 132 143 * Returns 0 on success, -EINVAL if given any data. ··· 149 130 static int keyring_instantiate(struct key *keyring, 150 131 struct key_preparsed_payload *prep) 151 132 { 152 - int ret; 153 - 154 - ret = -EINVAL; 155 - if (prep->datalen == 0) { 156 - assoc_array_init(&keyring->keys); 157 - /* make the keyring available by name if it has one */ 158 - keyring_publish_name(keyring); 159 - ret = 0; 160 - } 161 - 162 - return ret; 133 + assoc_array_init(&keyring->keys); 134 + /* make the keyring available by name if it has one */ 135 + keyring_publish_name(keyring); 136 + return 0; 163 137 } 164 138 165 139 /*
+13
security/keys/request_key_auth.c
··· 20 20 #include "internal.h" 21 21 #include <keys/user-type.h> 22 22 23 + static int request_key_auth_preparse(struct key_preparsed_payload *); 24 + static void request_key_auth_free_preparse(struct key_preparsed_payload *); 23 25 static int request_key_auth_instantiate(struct key *, 24 26 struct key_preparsed_payload *); 25 27 static void request_key_auth_describe(const struct key *, struct seq_file *); ··· 35 33 struct key_type key_type_request_key_auth = { 36 34 .name = ".request_key_auth", 37 35 .def_datalen = sizeof(struct request_key_auth), 36 + .preparse = request_key_auth_preparse, 37 + .free_preparse = request_key_auth_free_preparse, 38 38 .instantiate = request_key_auth_instantiate, 39 39 .describe = request_key_auth_describe, 40 40 .revoke = request_key_auth_revoke, 41 41 .destroy = request_key_auth_destroy, 42 42 .read = request_key_auth_read, 43 43 }; 44 + 45 + int request_key_auth_preparse(struct key_preparsed_payload *prep) 46 + { 47 + return 0; 48 + } 49 + 50 + void request_key_auth_free_preparse(struct key_preparsed_payload *prep) 51 + { 52 + } 44 53 45 54 /* 46 55 * Instantiate a request-key authorisation key.
+22 -19
security/keys/user_defined.c
··· 27 27 struct key_type key_type_user = { 28 28 .name = "user", 29 29 .def_lookup_type = KEYRING_SEARCH_LOOKUP_DIRECT, 30 - .instantiate = user_instantiate, 30 + .preparse = user_preparse, 31 + .free_preparse = user_free_preparse, 32 + .instantiate = generic_key_instantiate, 31 33 .update = user_update, 32 34 .match = user_match, 33 35 .revoke = user_revoke, ··· 49 47 struct key_type key_type_logon = { 50 48 .name = "logon", 51 49 .def_lookup_type = KEYRING_SEARCH_LOOKUP_DIRECT, 52 - .instantiate = user_instantiate, 50 + .preparse = user_preparse, 51 + .free_preparse = user_free_preparse, 52 + .instantiate = generic_key_instantiate, 53 53 .update = user_update, 54 54 .match = user_match, 55 55 .revoke = user_revoke, ··· 62 58 EXPORT_SYMBOL_GPL(key_type_logon); 63 59 64 60 /* 65 - * instantiate a user defined key 61 + * Preparse a user defined key payload 66 62 */ 67 - int user_instantiate(struct key *key, struct key_preparsed_payload *prep) 63 + int user_preparse(struct key_preparsed_payload *prep) 68 64 { 69 65 struct user_key_payload *upayload; 70 66 size_t datalen = prep->datalen; 71 - int ret; 72 67 73 - ret = -EINVAL; 74 68 if (datalen <= 0 || datalen > 32767 || !prep->data) 75 - goto error; 69 + return -EINVAL; 76 70 77 - ret = key_payload_reserve(key, datalen); 78 - if (ret < 0) 79 - goto error; 80 - 81 - ret = -ENOMEM; 82 71 upayload = kmalloc(sizeof(*upayload) + datalen, GFP_KERNEL); 83 72 if (!upayload) 84 - goto error; 73 + return -ENOMEM; 85 74 86 75 /* attach the data */ 76 + prep->quotalen = datalen; 77 + prep->payload[0] = upayload; 87 78 upayload->datalen = datalen; 88 79 memcpy(upayload->data, prep->data, datalen); 89 - rcu_assign_keypointer(key, upayload); 90 - ret = 0; 91 - 92 - error: 93 - return ret; 80 + return 0; 94 81 } 82 + EXPORT_SYMBOL_GPL(user_preparse); 95 83 96 - EXPORT_SYMBOL_GPL(user_instantiate); 84 + /* 85 + * Free a preparse of a user defined key payload 86 + */ 87 + void user_free_preparse(struct key_preparsed_payload *prep) 88 + { 89 + kfree(prep->payload[0]); 90 + } 91 + EXPORT_SYMBOL_GPL(user_free_preparse); 97 92 98 93 /* 99 94 * update a user defined key
+11
security/security.c
··· 845 845 return security_ops->kernel_create_files_as(new, inode); 846 846 } 847 847 848 + int security_kernel_fw_from_file(struct file *file, char *buf, size_t size) 849 + { 850 + int ret; 851 + 852 + ret = security_ops->kernel_fw_from_file(file, buf, size); 853 + if (ret) 854 + return ret; 855 + return ima_fw_from_file(file, buf, size); 856 + } 857 + EXPORT_SYMBOL_GPL(security_kernel_fw_from_file); 858 + 848 859 int security_kernel_module_request(char *kmod_name) 849 860 { 850 861 return security_ops->kernel_module_request(kmod_name);
+14
security/selinux/hooks.c
··· 161 161 return (selinux_policycap_alwaysnetwork || netlbl_enabled() || selinux_xfrm_enabled()); 162 162 } 163 163 164 + static int selinux_netcache_avc_callback(u32 event) 165 + { 166 + if (event == AVC_CALLBACK_RESET) { 167 + sel_netif_flush(); 168 + sel_netnode_flush(); 169 + sel_netport_flush(); 170 + synchronize_net(); 171 + } 172 + return 0; 173 + } 174 + 164 175 /* 165 176 * initialise the security for the init task 166 177 */ ··· 6003 5992 6004 5993 if (register_security(&selinux_ops)) 6005 5994 panic("SELinux: Unable to register with kernel.\n"); 5995 + 5996 + if (avc_add_callback(selinux_netcache_avc_callback, AVC_CALLBACK_RESET)) 5997 + panic("SELinux: Unable to register AVC netcache callback\n"); 6006 5998 6007 5999 if (selinux_enforcing) 6008 6000 printk(KERN_DEBUG "SELinux: Starting in enforcing mode\n");
+2
security/selinux/include/netif.h
··· 17 17 #ifndef _SELINUX_NETIF_H_ 18 18 #define _SELINUX_NETIF_H_ 19 19 20 + void sel_netif_flush(void); 21 + 20 22 int sel_netif_sid(int ifindex, u32 *sid); 21 23 22 24 #endif /* _SELINUX_NETIF_H_ */
+2
security/selinux/include/netnode.h
··· 27 27 #ifndef _SELINUX_NETNODE_H 28 28 #define _SELINUX_NETNODE_H 29 29 30 + void sel_netnode_flush(void); 31 + 30 32 int sel_netnode_sid(void *addr, u16 family, u32 *sid); 31 33 32 34 #endif
+2
security/selinux/include/netport.h
··· 26 26 #ifndef _SELINUX_NETPORT_H 27 27 #define _SELINUX_NETPORT_H 28 28 29 + void sel_netport_flush(void); 30 + 29 31 int sel_netport_sid(u8 protocol, u16 pnum, u32 *sid); 30 32 31 33 #endif
+2 -1
security/selinux/include/security.h
··· 8 8 #ifndef _SELINUX_SECURITY_H_ 9 9 #define _SELINUX_SECURITY_H_ 10 10 11 + #include <linux/compiler.h> 11 12 #include <linux/dcache.h> 12 13 #include <linux/magic.h> 13 14 #include <linux/types.h> ··· 221 220 /* 222 221 * The version > 0 supports above members. 223 222 */ 224 - } __attribute__((packed)); 223 + } __packed; 225 224 226 225 extern void selinux_status_update_setenforce(int enforcing); 227 226 extern void selinux_status_update_policyload(int seqno);
+1 -14
security/selinux/netif.c
··· 240 240 * Remove all entries from the network interface table. 241 241 * 242 242 */ 243 - static void sel_netif_flush(void) 243 + void sel_netif_flush(void) 244 244 { 245 245 int idx; 246 246 struct sel_netif *netif; ··· 250 250 list_for_each_entry(netif, &sel_netif_hash[idx], list) 251 251 sel_netif_destroy(netif); 252 252 spin_unlock_bh(&sel_netif_lock); 253 - } 254 - 255 - static int sel_netif_avc_callback(u32 event) 256 - { 257 - if (event == AVC_CALLBACK_RESET) { 258 - sel_netif_flush(); 259 - synchronize_net(); 260 - } 261 - return 0; 262 253 } 263 254 264 255 static int sel_netif_netdev_notifier_handler(struct notifier_block *this, ··· 281 290 INIT_LIST_HEAD(&sel_netif_hash[i]); 282 291 283 292 register_netdevice_notifier(&sel_netif_netdev_notifier); 284 - 285 - err = avc_add_callback(sel_netif_avc_callback, AVC_CALLBACK_RESET); 286 - if (err) 287 - panic("avc_add_callback() failed, error %d\n", err); 288 293 289 294 return err; 290 295 }
+1 -14
security/selinux/netnode.c
··· 283 283 * Remove all entries from the network address table. 284 284 * 285 285 */ 286 - static void sel_netnode_flush(void) 286 + void sel_netnode_flush(void) 287 287 { 288 288 unsigned int idx; 289 289 struct sel_netnode *node, *node_tmp; ··· 300 300 spin_unlock_bh(&sel_netnode_lock); 301 301 } 302 302 303 - static int sel_netnode_avc_callback(u32 event) 304 - { 305 - if (event == AVC_CALLBACK_RESET) { 306 - sel_netnode_flush(); 307 - synchronize_net(); 308 - } 309 - return 0; 310 - } 311 - 312 303 static __init int sel_netnode_init(void) 313 304 { 314 305 int iter; ··· 312 321 INIT_LIST_HEAD(&sel_netnode_hash[iter].list); 313 322 sel_netnode_hash[iter].size = 0; 314 323 } 315 - 316 - ret = avc_add_callback(sel_netnode_avc_callback, AVC_CALLBACK_RESET); 317 - if (ret != 0) 318 - panic("avc_add_callback() failed, error %d\n", ret); 319 324 320 325 return ret; 321 326 }
+1 -14
security/selinux/netport.c
··· 217 217 * Remove all entries from the network address table. 218 218 * 219 219 */ 220 - static void sel_netport_flush(void) 220 + void sel_netport_flush(void) 221 221 { 222 222 unsigned int idx; 223 223 struct sel_netport *port, *port_tmp; ··· 234 234 spin_unlock_bh(&sel_netport_lock); 235 235 } 236 236 237 - static int sel_netport_avc_callback(u32 event) 238 - { 239 - if (event == AVC_CALLBACK_RESET) { 240 - sel_netport_flush(); 241 - synchronize_net(); 242 - } 243 - return 0; 244 - } 245 - 246 237 static __init int sel_netport_init(void) 247 238 { 248 239 int iter; ··· 246 255 INIT_LIST_HEAD(&sel_netport_hash[iter].list); 247 256 sel_netport_hash[iter].size = 0; 248 257 } 249 - 250 - ret = avc_add_callback(sel_netport_avc_callback, AVC_CALLBACK_RESET); 251 - if (ret != 0) 252 - panic("avc_add_callback() failed, error %d\n", ret); 253 258 254 259 return ret; 255 260 }
+3 -8
security/selinux/ss/conditional.c
··· 402 402 int rc; 403 403 struct cond_expr *expr = NULL, *last = NULL; 404 404 405 - rc = next_entry(buf, fp, sizeof(u32)); 405 + rc = next_entry(buf, fp, sizeof(u32) * 2); 406 406 if (rc) 407 - return rc; 407 + goto err; 408 408 409 409 node->cur_state = le32_to_cpu(buf[0]); 410 410 411 - len = 0; 412 - rc = next_entry(buf, fp, sizeof(u32)); 413 - if (rc) 414 - return rc; 415 - 416 411 /* expr */ 417 - len = le32_to_cpu(buf[0]); 412 + len = le32_to_cpu(buf[1]); 418 413 419 414 for (i = 0; i < len; i++) { 420 415 rc = next_entry(buf, fp, sizeof(u32) * 2);
+51 -80
security/selinux/ss/ebitmap.c
··· 86 86 * 87 87 */ 88 88 int ebitmap_netlbl_export(struct ebitmap *ebmap, 89 - struct netlbl_lsm_secattr_catmap **catmap) 89 + struct netlbl_lsm_catmap **catmap) 90 90 { 91 91 struct ebitmap_node *e_iter = ebmap->node; 92 - struct netlbl_lsm_secattr_catmap *c_iter; 93 - u32 cmap_idx, cmap_sft; 94 - int i; 95 - 96 - /* NetLabel's NETLBL_CATMAP_MAPTYPE is defined as an array of u64, 97 - * however, it is not always compatible with an array of unsigned long 98 - * in ebitmap_node. 99 - * In addition, you should pay attention the following implementation 100 - * assumes unsigned long has a width equal with or less than 64-bit. 101 - */ 92 + unsigned long e_map; 93 + u32 offset; 94 + unsigned int iter; 95 + int rc; 102 96 103 97 if (e_iter == NULL) { 104 98 *catmap = NULL; 105 99 return 0; 106 100 } 107 101 108 - c_iter = netlbl_secattr_catmap_alloc(GFP_ATOMIC); 109 - if (c_iter == NULL) 110 - return -ENOMEM; 111 - *catmap = c_iter; 112 - c_iter->startbit = e_iter->startbit & ~(NETLBL_CATMAP_SIZE - 1); 102 + if (*catmap != NULL) 103 + netlbl_catmap_free(*catmap); 104 + *catmap = NULL; 113 105 114 106 while (e_iter) { 115 - for (i = 0; i < EBITMAP_UNIT_NUMS; i++) { 116 - unsigned int delta, e_startbit, c_endbit; 117 - 118 - e_startbit = e_iter->startbit + i * EBITMAP_UNIT_SIZE; 119 - c_endbit = c_iter->startbit + NETLBL_CATMAP_SIZE; 120 - if (e_startbit >= c_endbit) { 121 - c_iter->next 122 - = netlbl_secattr_catmap_alloc(GFP_ATOMIC); 123 - if (c_iter->next == NULL) 107 + offset = e_iter->startbit; 108 + for (iter = 0; iter < EBITMAP_UNIT_NUMS; iter++) { 109 + e_map = e_iter->maps[iter]; 110 + if (e_map != 0) { 111 + rc = netlbl_catmap_setlong(catmap, 112 + offset, 113 + e_map, 114 + GFP_ATOMIC); 115 + if (rc != 0) 124 116 goto netlbl_export_failure; 125 - c_iter = c_iter->next; 126 - c_iter->startbit 127 - = e_startbit & ~(NETLBL_CATMAP_SIZE - 1); 128 117 } 129 - delta = e_startbit - c_iter->startbit; 130 - cmap_idx = delta / NETLBL_CATMAP_MAPSIZE; 131 - cmap_sft = delta % NETLBL_CATMAP_MAPSIZE; 132 - c_iter->bitmap[cmap_idx] 133 - |= e_iter->maps[i] << cmap_sft; 118 + offset += EBITMAP_UNIT_SIZE; 134 119 } 135 120 e_iter = e_iter->next; 136 121 } ··· 123 138 return 0; 124 139 125 140 netlbl_export_failure: 126 - netlbl_secattr_catmap_free(*catmap); 141 + netlbl_catmap_free(*catmap); 127 142 return -ENOMEM; 128 143 } 129 144 ··· 138 153 * 139 154 */ 140 155 int ebitmap_netlbl_import(struct ebitmap *ebmap, 141 - struct netlbl_lsm_secattr_catmap *catmap) 156 + struct netlbl_lsm_catmap *catmap) 142 157 { 158 + int rc; 143 159 struct ebitmap_node *e_iter = NULL; 144 - struct ebitmap_node *emap_prev = NULL; 145 - struct netlbl_lsm_secattr_catmap *c_iter = catmap; 146 - u32 c_idx, c_pos, e_idx, e_sft; 160 + struct ebitmap_node *e_prev = NULL; 161 + u32 offset = 0, idx; 162 + unsigned long bitmap; 147 163 148 - /* NetLabel's NETLBL_CATMAP_MAPTYPE is defined as an array of u64, 149 - * however, it is not always compatible with an array of unsigned long 150 - * in ebitmap_node. 151 - * In addition, you should pay attention the following implementation 152 - * assumes unsigned long has a width equal with or less than 64-bit. 153 - */ 164 + for (;;) { 165 + rc = netlbl_catmap_getlong(catmap, &offset, &bitmap); 166 + if (rc < 0) 167 + goto netlbl_import_failure; 168 + if (offset == (u32)-1) 169 + return 0; 154 170 155 - do { 156 - for (c_idx = 0; c_idx < NETLBL_CATMAP_MAPCNT; c_idx++) { 157 - unsigned int delta; 158 - u64 map = c_iter->bitmap[c_idx]; 159 - 160 - if (!map) 161 - continue; 162 - 163 - c_pos = c_iter->startbit 164 - + c_idx * NETLBL_CATMAP_MAPSIZE; 165 - if (!e_iter 166 - || c_pos >= e_iter->startbit + EBITMAP_SIZE) { 167 - e_iter = kzalloc(sizeof(*e_iter), GFP_ATOMIC); 168 - if (!e_iter) 169 - goto netlbl_import_failure; 170 - e_iter->startbit 171 - = c_pos - (c_pos % EBITMAP_SIZE); 172 - if (emap_prev == NULL) 173 - ebmap->node = e_iter; 174 - else 175 - emap_prev->next = e_iter; 176 - emap_prev = e_iter; 177 - } 178 - delta = c_pos - e_iter->startbit; 179 - e_idx = delta / EBITMAP_UNIT_SIZE; 180 - e_sft = delta % EBITMAP_UNIT_SIZE; 181 - while (map) { 182 - e_iter->maps[e_idx++] |= map & (-1UL); 183 - map = EBITMAP_SHIFT_UNIT_SIZE(map); 184 - } 171 + if (e_iter == NULL || 172 + offset >= e_iter->startbit + EBITMAP_SIZE) { 173 + e_prev = e_iter; 174 + e_iter = kzalloc(sizeof(*e_iter), GFP_ATOMIC); 175 + if (e_iter == NULL) 176 + goto netlbl_import_failure; 177 + e_iter->startbit = offset & ~(EBITMAP_SIZE - 1); 178 + if (e_prev == NULL) 179 + ebmap->node = e_iter; 180 + else 181 + e_prev->next = e_iter; 182 + ebmap->highbit = e_iter->startbit + EBITMAP_SIZE; 185 183 } 186 - c_iter = c_iter->next; 187 - } while (c_iter); 188 - if (e_iter != NULL) 189 - ebmap->highbit = e_iter->startbit + EBITMAP_SIZE; 190 - else 191 - ebitmap_destroy(ebmap); 192 184 185 + /* offset will always be aligned to an unsigned long */ 186 + idx = EBITMAP_NODE_INDEX(e_iter, offset); 187 + e_iter->maps[idx] = bitmap; 188 + 189 + /* next */ 190 + offset += EBITMAP_UNIT_SIZE; 191 + } 192 + 193 + /* NOTE: we should never reach this return */ 193 194 return 0; 194 195 195 196 netlbl_import_failure:
+4 -4
security/selinux/ss/ebitmap.h
··· 132 132 133 133 #ifdef CONFIG_NETLABEL 134 134 int ebitmap_netlbl_export(struct ebitmap *ebmap, 135 - struct netlbl_lsm_secattr_catmap **catmap); 135 + struct netlbl_lsm_catmap **catmap); 136 136 int ebitmap_netlbl_import(struct ebitmap *ebmap, 137 - struct netlbl_lsm_secattr_catmap *catmap); 137 + struct netlbl_lsm_catmap *catmap); 138 138 #else 139 139 static inline int ebitmap_netlbl_export(struct ebitmap *ebmap, 140 - struct netlbl_lsm_secattr_catmap **catmap) 140 + struct netlbl_lsm_catmap **catmap) 141 141 { 142 142 return -ENOMEM; 143 143 } 144 144 static inline int ebitmap_netlbl_import(struct ebitmap *ebmap, 145 - struct netlbl_lsm_secattr_catmap *catmap) 145 + struct netlbl_lsm_catmap *catmap) 146 146 { 147 147 return -ENOMEM; 148 148 }
+41 -100
security/selinux/ss/policydb.c
··· 1080 1080 * binary representation file. 1081 1081 */ 1082 1082 1083 + static int str_read(char **strp, gfp_t flags, void *fp, u32 len) 1084 + { 1085 + int rc; 1086 + char *str; 1087 + 1088 + str = kmalloc(len + 1, flags); 1089 + if (!str) 1090 + return -ENOMEM; 1091 + 1092 + /* it's expected the caller should free the str */ 1093 + *strp = str; 1094 + 1095 + rc = next_entry(str, fp, len); 1096 + if (rc) 1097 + return rc; 1098 + 1099 + str[len] = '\0'; 1100 + return 0; 1101 + } 1102 + 1083 1103 static int perm_read(struct policydb *p, struct hashtab *h, void *fp) 1084 1104 { 1085 1105 char *key = NULL; ··· 1120 1100 len = le32_to_cpu(buf[0]); 1121 1101 perdatum->value = le32_to_cpu(buf[1]); 1122 1102 1123 - rc = -ENOMEM; 1124 - key = kmalloc(len + 1, GFP_KERNEL); 1125 - if (!key) 1126 - goto bad; 1127 - 1128 - rc = next_entry(key, fp, len); 1103 + rc = str_read(&key, GFP_KERNEL, fp, len); 1129 1104 if (rc) 1130 1105 goto bad; 1131 - key[len] = '\0'; 1132 1106 1133 1107 rc = hashtab_insert(h, key, perdatum); 1134 1108 if (rc) ··· 1160 1146 comdatum->permissions.nprim = le32_to_cpu(buf[2]); 1161 1147 nel = le32_to_cpu(buf[3]); 1162 1148 1163 - rc = -ENOMEM; 1164 - key = kmalloc(len + 1, GFP_KERNEL); 1165 - if (!key) 1166 - goto bad; 1167 - 1168 - rc = next_entry(key, fp, len); 1149 + rc = str_read(&key, GFP_KERNEL, fp, len); 1169 1150 if (rc) 1170 1151 goto bad; 1171 - key[len] = '\0'; 1172 1152 1173 1153 for (i = 0; i < nel; i++) { 1174 1154 rc = perm_read(p, comdatum->permissions.table, fp); ··· 1329 1321 1330 1322 ncons = le32_to_cpu(buf[5]); 1331 1323 1332 - rc = -ENOMEM; 1333 - key = kmalloc(len + 1, GFP_KERNEL); 1334 - if (!key) 1335 - goto bad; 1336 - 1337 - rc = next_entry(key, fp, len); 1324 + rc = str_read(&key, GFP_KERNEL, fp, len); 1338 1325 if (rc) 1339 1326 goto bad; 1340 - key[len] = '\0'; 1341 1327 1342 1328 if (len2) { 1343 - rc = -ENOMEM; 1344 - cladatum->comkey = kmalloc(len2 + 1, GFP_KERNEL); 1345 - if (!cladatum->comkey) 1346 - goto bad; 1347 - rc = next_entry(cladatum->comkey, fp, len2); 1329 + rc = str_read(&cladatum->comkey, GFP_KERNEL, fp, len2); 1348 1330 if (rc) 1349 1331 goto bad; 1350 - cladatum->comkey[len2] = '\0'; 1351 1332 1352 1333 rc = -EINVAL; 1353 1334 cladatum->comdatum = hashtab_search(p->p_commons.table, cladatum->comkey); ··· 1419 1422 if (p->policyvers >= POLICYDB_VERSION_BOUNDARY) 1420 1423 role->bounds = le32_to_cpu(buf[2]); 1421 1424 1422 - rc = -ENOMEM; 1423 - key = kmalloc(len + 1, GFP_KERNEL); 1424 - if (!key) 1425 - goto bad; 1426 - 1427 - rc = next_entry(key, fp, len); 1425 + rc = str_read(&key, GFP_KERNEL, fp, len); 1428 1426 if (rc) 1429 1427 goto bad; 1430 - key[len] = '\0'; 1431 1428 1432 1429 rc = ebitmap_read(&role->dominates, fp); 1433 1430 if (rc) ··· 1486 1495 typdatum->primary = le32_to_cpu(buf[2]); 1487 1496 } 1488 1497 1489 - rc = -ENOMEM; 1490 - key = kmalloc(len + 1, GFP_KERNEL); 1491 - if (!key) 1492 - goto bad; 1493 - rc = next_entry(key, fp, len); 1498 + rc = str_read(&key, GFP_KERNEL, fp, len); 1494 1499 if (rc) 1495 1500 goto bad; 1496 - key[len] = '\0'; 1497 1501 1498 1502 rc = hashtab_insert(h, key, typdatum); 1499 1503 if (rc) ··· 1551 1565 if (p->policyvers >= POLICYDB_VERSION_BOUNDARY) 1552 1566 usrdatum->bounds = le32_to_cpu(buf[2]); 1553 1567 1554 - rc = -ENOMEM; 1555 - key = kmalloc(len + 1, GFP_KERNEL); 1556 - if (!key) 1557 - goto bad; 1558 - rc = next_entry(key, fp, len); 1568 + rc = str_read(&key, GFP_KERNEL, fp, len); 1559 1569 if (rc) 1560 1570 goto bad; 1561 - key[len] = '\0'; 1562 1571 1563 1572 rc = ebitmap_read(&usrdatum->roles, fp); 1564 1573 if (rc) ··· 1597 1616 len = le32_to_cpu(buf[0]); 1598 1617 levdatum->isalias = le32_to_cpu(buf[1]); 1599 1618 1600 - rc = -ENOMEM; 1601 - key = kmalloc(len + 1, GFP_ATOMIC); 1602 - if (!key) 1603 - goto bad; 1604 - rc = next_entry(key, fp, len); 1619 + rc = str_read(&key, GFP_ATOMIC, fp, len); 1605 1620 if (rc) 1606 1621 goto bad; 1607 - key[len] = '\0'; 1608 1622 1609 1623 rc = -ENOMEM; 1610 1624 levdatum->level = kmalloc(sizeof(struct mls_level), GFP_ATOMIC); ··· 1640 1664 catdatum->value = le32_to_cpu(buf[1]); 1641 1665 catdatum->isalias = le32_to_cpu(buf[2]); 1642 1666 1643 - rc = -ENOMEM; 1644 - key = kmalloc(len + 1, GFP_ATOMIC); 1645 - if (!key) 1646 - goto bad; 1647 - rc = next_entry(key, fp, len); 1667 + rc = str_read(&key, GFP_ATOMIC, fp, len); 1648 1668 if (rc) 1649 1669 goto bad; 1650 - key[len] = '\0'; 1651 1670 1652 1671 rc = hashtab_insert(h, key, catdatum); 1653 1672 if (rc) ··· 1939 1968 goto out; 1940 1969 len = le32_to_cpu(buf[0]); 1941 1970 1942 - rc = -ENOMEM; 1943 - name = kmalloc(len + 1, GFP_KERNEL); 1944 - if (!name) 1971 + /* path component string */ 1972 + rc = str_read(&name, GFP_KERNEL, fp, len); 1973 + if (rc) 1945 1974 goto out; 1946 1975 1947 1976 ft->name = name; 1948 - 1949 - /* path component string */ 1950 - rc = next_entry(name, fp, len); 1951 - if (rc) 1952 - goto out; 1953 - name[len] = 0; 1954 1977 1955 1978 rc = next_entry(buf, fp, sizeof(u32) * 4); 1956 1979 if (rc) ··· 2010 2045 if (!newgenfs) 2011 2046 goto out; 2012 2047 2013 - rc = -ENOMEM; 2014 - newgenfs->fstype = kmalloc(len + 1, GFP_KERNEL); 2015 - if (!newgenfs->fstype) 2016 - goto out; 2017 - 2018 - rc = next_entry(newgenfs->fstype, fp, len); 2048 + rc = str_read(&newgenfs->fstype, GFP_KERNEL, fp, len); 2019 2049 if (rc) 2020 2050 goto out; 2021 - 2022 - newgenfs->fstype[len] = 0; 2023 2051 2024 2052 for (genfs_p = NULL, genfs = p->genfs; genfs; 2025 2053 genfs_p = genfs, genfs = genfs->next) { ··· 2049 2091 if (!newc) 2050 2092 goto out; 2051 2093 2052 - rc = -ENOMEM; 2053 - newc->u.name = kmalloc(len + 1, GFP_KERNEL); 2054 - if (!newc->u.name) 2055 - goto out; 2056 - 2057 - rc = next_entry(newc->u.name, fp, len); 2094 + rc = str_read(&newc->u.name, GFP_KERNEL, fp, len); 2058 2095 if (rc) 2059 2096 goto out; 2060 - newc->u.name[len] = 0; 2061 2097 2062 2098 rc = next_entry(buf, fp, sizeof(u32)); 2063 2099 if (rc) ··· 2141 2189 goto out; 2142 2190 len = le32_to_cpu(buf[0]); 2143 2191 2144 - rc = -ENOMEM; 2145 - c->u.name = kmalloc(len + 1, GFP_KERNEL); 2146 - if (!c->u.name) 2147 - goto out; 2148 - 2149 - rc = next_entry(c->u.name, fp, len); 2192 + rc = str_read(&c->u.name, GFP_KERNEL, fp, len); 2150 2193 if (rc) 2151 2194 goto out; 2152 2195 2153 - c->u.name[len] = 0; 2154 2196 rc = context_read_and_validate(&c->context[0], p, fp); 2155 2197 if (rc) 2156 2198 goto out; ··· 2186 2240 if (c->v.behavior > SECURITY_FS_USE_MAX) 2187 2241 goto out; 2188 2242 2189 - rc = -ENOMEM; 2190 2243 len = le32_to_cpu(buf[1]); 2191 - c->u.name = kmalloc(len + 1, GFP_KERNEL); 2192 - if (!c->u.name) 2193 - goto out; 2194 - 2195 - rc = next_entry(c->u.name, fp, len); 2244 + rc = str_read(&c->u.name, GFP_KERNEL, fp, len); 2196 2245 if (rc) 2197 2246 goto out; 2198 - c->u.name[len] = 0; 2247 + 2199 2248 rc = context_read_and_validate(&c->context[0], p, fp); 2200 2249 if (rc) 2201 2250 goto out; ··· 2549 2608 if (!eq) 2550 2609 buf[2] = cpu_to_le32(r->level[1].sens); 2551 2610 2552 - BUG_ON(items > (sizeof(buf)/sizeof(buf[0]))); 2611 + BUG_ON(items > ARRAY_SIZE(buf)); 2553 2612 2554 2613 rc = put_entry(buf, sizeof(u32), items, fp); 2555 2614 if (rc) ··· 2931 2990 if (p->policyvers >= POLICYDB_VERSION_BOUNDARY) 2932 2991 buf[items++] = cpu_to_le32(role->bounds); 2933 2992 2934 - BUG_ON(items > (sizeof(buf)/sizeof(buf[0]))); 2993 + BUG_ON(items > ARRAY_SIZE(buf)); 2935 2994 2936 2995 rc = put_entry(buf, sizeof(u32), items, fp); 2937 2996 if (rc) ··· 2981 3040 } else { 2982 3041 buf[items++] = cpu_to_le32(typdatum->primary); 2983 3042 } 2984 - BUG_ON(items > (sizeof(buf) / sizeof(buf[0]))); 3043 + BUG_ON(items > ARRAY_SIZE(buf)); 2985 3044 rc = put_entry(buf, sizeof(u32), items, fp); 2986 3045 if (rc) 2987 3046 return rc; ··· 3010 3069 buf[items++] = cpu_to_le32(usrdatum->value); 3011 3070 if (p->policyvers >= POLICYDB_VERSION_BOUNDARY) 3012 3071 buf[items++] = cpu_to_le32(usrdatum->bounds); 3013 - BUG_ON(items > (sizeof(buf) / sizeof(buf[0]))); 3072 + BUG_ON(items > ARRAY_SIZE(buf)); 3014 3073 rc = put_entry(buf, sizeof(u32), items, fp); 3015 3074 if (rc) 3016 3075 return rc;
+32 -9
security/selinux/ss/services.c
··· 2277 2277 } 2278 2278 2279 2279 /** 2280 - * security_genfs_sid - Obtain a SID for a file in a filesystem 2280 + * __security_genfs_sid - Helper to obtain a SID for a file in a filesystem 2281 2281 * @fstype: filesystem type 2282 2282 * @path: path from root of mount 2283 2283 * @sclass: file security class ··· 2286 2286 * Obtain a SID to use for a file in a filesystem that 2287 2287 * cannot support xattr or use a fixed labeling behavior like 2288 2288 * transition SIDs or task SIDs. 2289 + * 2290 + * The caller must acquire the policy_rwlock before calling this function. 2289 2291 */ 2290 - int security_genfs_sid(const char *fstype, 2291 - char *path, 2292 - u16 orig_sclass, 2293 - u32 *sid) 2292 + static inline int __security_genfs_sid(const char *fstype, 2293 + char *path, 2294 + u16 orig_sclass, 2295 + u32 *sid) 2294 2296 { 2295 2297 int len; 2296 2298 u16 sclass; ··· 2302 2300 2303 2301 while (path[0] == '/' && path[1] == '/') 2304 2302 path++; 2305 - 2306 - read_lock(&policy_rwlock); 2307 2303 2308 2304 sclass = unmap_class(orig_sclass); 2309 2305 *sid = SECINITSID_UNLABELED; ··· 2336 2336 *sid = c->sid[0]; 2337 2337 rc = 0; 2338 2338 out: 2339 - read_unlock(&policy_rwlock); 2340 2339 return rc; 2340 + } 2341 + 2342 + /** 2343 + * security_genfs_sid - Obtain a SID for a file in a filesystem 2344 + * @fstype: filesystem type 2345 + * @path: path from root of mount 2346 + * @sclass: file security class 2347 + * @sid: SID for path 2348 + * 2349 + * Acquire policy_rwlock before calling __security_genfs_sid() and release 2350 + * it afterward. 2351 + */ 2352 + int security_genfs_sid(const char *fstype, 2353 + char *path, 2354 + u16 orig_sclass, 2355 + u32 *sid) 2356 + { 2357 + int retval; 2358 + 2359 + read_lock(&policy_rwlock); 2360 + retval = __security_genfs_sid(fstype, path, orig_sclass, sid); 2361 + read_unlock(&policy_rwlock); 2362 + return retval; 2341 2363 } 2342 2364 2343 2365 /** ··· 2392 2370 } 2393 2371 sbsec->sid = c->sid[0]; 2394 2372 } else { 2395 - rc = security_genfs_sid(fstype, "/", SECCLASS_DIR, &sbsec->sid); 2373 + rc = __security_genfs_sid(fstype, "/", SECCLASS_DIR, 2374 + &sbsec->sid); 2396 2375 if (rc) { 2397 2376 sbsec->behavior = SECURITY_FS_USE_NONE; 2398 2377 rc = 0;
+4 -7
security/smack/smack_access.c
··· 457 457 458 458 sap->flags |= NETLBL_SECATTR_MLS_CAT; 459 459 sap->attr.mls.lvl = level; 460 - sap->attr.mls.cat = netlbl_secattr_catmap_alloc(GFP_ATOMIC); 461 - if (!sap->attr.mls.cat) 462 - return -ENOMEM; 463 - sap->attr.mls.cat->startbit = 0; 460 + sap->attr.mls.cat = NULL; 464 461 465 462 for (cat = 1, cp = catset, byte = 0; byte < len; cp++, byte++) 466 463 for (m = 0x80; m != 0; m >>= 1, cat++) { 467 464 if ((m & *cp) == 0) 468 465 continue; 469 - rc = netlbl_secattr_catmap_setbit(sap->attr.mls.cat, 470 - cat, GFP_ATOMIC); 466 + rc = netlbl_catmap_setbit(&sap->attr.mls.cat, 467 + cat, GFP_ATOMIC); 471 468 if (rc < 0) { 472 - netlbl_secattr_catmap_free(sap->attr.mls.cat); 469 + netlbl_catmap_free(sap->attr.mls.cat); 473 470 return rc; 474 471 } 475 472 }
+3 -3
security/smack/smack_lsm.c
··· 3209 3209 break; 3210 3210 } 3211 3211 for (acat = -1, kcat = -1; acat == kcat; ) { 3212 - acat = netlbl_secattr_catmap_walk( 3213 - sap->attr.mls.cat, acat + 1); 3214 - kcat = netlbl_secattr_catmap_walk( 3212 + acat = netlbl_catmap_walk(sap->attr.mls.cat, 3213 + acat + 1); 3214 + kcat = netlbl_catmap_walk( 3215 3215 skp->smk_netlabel.attr.mls.cat, 3216 3216 kcat + 1); 3217 3217 if (acat < 0 || kcat < 0)
+7 -7
security/smack/smackfs.c
··· 787 787 struct list_head *list = v; 788 788 struct smack_known *skp = 789 789 list_entry(list, struct smack_known, list); 790 - struct netlbl_lsm_secattr_catmap *cmp = skp->smk_netlabel.attr.mls.cat; 790 + struct netlbl_lsm_catmap *cmp = skp->smk_netlabel.attr.mls.cat; 791 791 char sep = '/'; 792 792 int i; 793 793 ··· 804 804 805 805 seq_printf(s, "%s %3d", skp->smk_known, skp->smk_netlabel.attr.mls.lvl); 806 806 807 - for (i = netlbl_secattr_catmap_walk(cmp, 0); i >= 0; 808 - i = netlbl_secattr_catmap_walk(cmp, i + 1)) { 807 + for (i = netlbl_catmap_walk(cmp, 0); i >= 0; 808 + i = netlbl_catmap_walk(cmp, i + 1)) { 809 809 seq_printf(s, "%c%d", sep, i); 810 810 sep = ','; 811 811 } ··· 926 926 927 927 rc = smk_netlbl_mls(maplevel, mapcatset, &ncats, SMK_CIPSOLEN); 928 928 if (rc >= 0) { 929 - netlbl_secattr_catmap_free(skp->smk_netlabel.attr.mls.cat); 929 + netlbl_catmap_free(skp->smk_netlabel.attr.mls.cat); 930 930 skp->smk_netlabel.attr.mls.cat = ncats.attr.mls.cat; 931 931 skp->smk_netlabel.attr.mls.lvl = ncats.attr.mls.lvl; 932 932 rc = count; ··· 976 976 struct list_head *list = v; 977 977 struct smack_known *skp = 978 978 list_entry(list, struct smack_known, list); 979 - struct netlbl_lsm_secattr_catmap *cmp = skp->smk_netlabel.attr.mls.cat; 979 + struct netlbl_lsm_catmap *cmp = skp->smk_netlabel.attr.mls.cat; 980 980 char sep = '/'; 981 981 int i; 982 982 983 983 seq_printf(s, "%s %3d", skp->smk_known, skp->smk_netlabel.attr.mls.lvl); 984 984 985 - for (i = netlbl_secattr_catmap_walk(cmp, 0); i >= 0; 986 - i = netlbl_secattr_catmap_walk(cmp, i + 1)) { 985 + for (i = netlbl_catmap_walk(cmp, 0); i >= 0; 986 + i = netlbl_catmap_walk(cmp, i + 1)) { 987 987 seq_printf(s, "%c%d", sep, i); 988 988 sep = ','; 989 989 }