diff options
53 files changed, 1281 insertions, 374 deletions
diff --git a/Documentation/security/keys-trusted-encrypted.txt b/Documentation/security/keys-trusted-encrypted.txt index e105ae97a4f5..324ddf5223b3 100644 --- a/Documentation/security/keys-trusted-encrypted.txt +++ b/Documentation/security/keys-trusted-encrypted.txt | |||
@@ -27,17 +27,26 @@ Usage: | |||
27 | keyctl print keyid | 27 | keyctl print keyid |
28 | 28 | ||
29 | options: | 29 | options: |
30 | keyhandle= ascii hex value of sealing key default 0x40000000 (SRK) | 30 | keyhandle= ascii hex value of sealing key default 0x40000000 (SRK) |
31 | keyauth= ascii hex auth for sealing key default 0x00...i | 31 | keyauth= ascii hex auth for sealing key default 0x00...i |
32 | (40 ascii zeros) | 32 | (40 ascii zeros) |
33 | blobauth= ascii hex auth for sealed data default 0x00... | 33 | blobauth= ascii hex auth for sealed data default 0x00... |
34 | (40 ascii zeros) | 34 | (40 ascii zeros) |
35 | blobauth= ascii hex auth for sealed data default 0x00... | 35 | blobauth= ascii hex auth for sealed data default 0x00... |
36 | (40 ascii zeros) | 36 | (40 ascii zeros) |
37 | pcrinfo= ascii hex of PCR_INFO or PCR_INFO_LONG (no default) | 37 | pcrinfo= ascii hex of PCR_INFO or PCR_INFO_LONG (no default) |
38 | pcrlock= pcr number to be extended to "lock" blob | 38 | pcrlock= pcr number to be extended to "lock" blob |
39 | migratable= 0|1 indicating permission to reseal to new PCR values, | 39 | migratable= 0|1 indicating permission to reseal to new PCR values, |
40 | default 1 (resealing allowed) | 40 | default 1 (resealing allowed) |
41 | hash= hash algorithm name as a string. For TPM 1.x the only | ||
42 | allowed value is sha1. For TPM 2.x the allowed values | ||
43 | are sha1, sha256, sha384, sha512 and sm3-256. | ||
44 | policydigest= digest for the authorization policy. must be calculated | ||
45 | with the same hash algorithm as specified by the 'hash=' | ||
46 | option. | ||
47 | policyhandle= handle to an authorization policy session that defines the | ||
48 | same policy and with the same hash algorithm as was used to | ||
49 | seal the key. | ||
41 | 50 | ||
42 | "keyctl print" returns an ascii hex copy of the sealed key, which is in standard | 51 | "keyctl print" returns an ascii hex copy of the sealed key, which is in standard |
43 | TPM_STORED_DATA format. The key length for new keys are always in bytes. | 52 | TPM_STORED_DATA format. The key length for new keys are always in bytes. |
diff --git a/crypto/asymmetric_keys/x509_public_key.c b/crypto/asymmetric_keys/x509_public_key.c index 2a44b3752471..9e9e5a6a9ed6 100644 --- a/crypto/asymmetric_keys/x509_public_key.c +++ b/crypto/asymmetric_keys/x509_public_key.c | |||
@@ -321,6 +321,8 @@ static int x509_key_preparse(struct key_preparsed_payload *prep) | |||
321 | goto error_free_cert; | 321 | goto error_free_cert; |
322 | } else if (!prep->trusted) { | 322 | } else if (!prep->trusted) { |
323 | ret = x509_validate_trust(cert, get_system_trusted_keyring()); | 323 | ret = x509_validate_trust(cert, get_system_trusted_keyring()); |
324 | if (ret) | ||
325 | ret = x509_validate_trust(cert, get_ima_mok_keyring()); | ||
324 | if (!ret) | 326 | if (!ret) |
325 | prep->trusted = 1; | 327 | prep->trusted = 1; |
326 | } | 328 | } |
diff --git a/crypto/hash_info.c b/crypto/hash_info.c index 3e7ff46f26e8..7b1e0b188ce6 100644 --- a/crypto/hash_info.c +++ b/crypto/hash_info.c | |||
@@ -31,6 +31,7 @@ const char *const hash_algo_name[HASH_ALGO__LAST] = { | |||
31 | [HASH_ALGO_TGR_128] = "tgr128", | 31 | [HASH_ALGO_TGR_128] = "tgr128", |
32 | [HASH_ALGO_TGR_160] = "tgr160", | 32 | [HASH_ALGO_TGR_160] = "tgr160", |
33 | [HASH_ALGO_TGR_192] = "tgr192", | 33 | [HASH_ALGO_TGR_192] = "tgr192", |
34 | [HASH_ALGO_SM3_256] = "sm3-256", | ||
34 | }; | 35 | }; |
35 | EXPORT_SYMBOL_GPL(hash_algo_name); | 36 | EXPORT_SYMBOL_GPL(hash_algo_name); |
36 | 37 | ||
@@ -52,5 +53,6 @@ const int hash_digest_size[HASH_ALGO__LAST] = { | |||
52 | [HASH_ALGO_TGR_128] = TGR128_DIGEST_SIZE, | 53 | [HASH_ALGO_TGR_128] = TGR128_DIGEST_SIZE, |
53 | [HASH_ALGO_TGR_160] = TGR160_DIGEST_SIZE, | 54 | [HASH_ALGO_TGR_160] = TGR160_DIGEST_SIZE, |
54 | [HASH_ALGO_TGR_192] = TGR192_DIGEST_SIZE, | 55 | [HASH_ALGO_TGR_192] = TGR192_DIGEST_SIZE, |
56 | [HASH_ALGO_SM3_256] = SM3256_DIGEST_SIZE, | ||
55 | }; | 57 | }; |
56 | EXPORT_SYMBOL_GPL(hash_digest_size); | 58 | EXPORT_SYMBOL_GPL(hash_digest_size); |
diff --git a/drivers/char/tpm/tpm-interface.c b/drivers/char/tpm/tpm-interface.c index c50637db3a8a..e2fa89c88304 100644 --- a/drivers/char/tpm/tpm-interface.c +++ b/drivers/char/tpm/tpm-interface.c | |||
@@ -310,10 +310,12 @@ unsigned long tpm_calc_ordinal_duration(struct tpm_chip *chip, | |||
310 | { | 310 | { |
311 | int duration_idx = TPM_UNDEFINED; | 311 | int duration_idx = TPM_UNDEFINED; |
312 | int duration = 0; | 312 | int duration = 0; |
313 | u8 category = (ordinal >> 24) & 0xFF; | ||
314 | 313 | ||
315 | if ((category == TPM_PROTECTED_COMMAND && ordinal < TPM_MAX_ORDINAL) || | 314 | /* |
316 | (category == TPM_CONNECTION_COMMAND && ordinal < TSC_MAX_ORDINAL)) | 315 | * We only have a duration table for protected commands, where the upper |
316 | * 16 bits are 0. For the few other ordinals the fallback will be used. | ||
317 | */ | ||
318 | if (ordinal < TPM_MAX_ORDINAL) | ||
317 | duration_idx = tpm_ordinal_duration[ordinal]; | 319 | duration_idx = tpm_ordinal_duration[ordinal]; |
318 | 320 | ||
319 | if (duration_idx != TPM_UNDEFINED) | 321 | if (duration_idx != TPM_UNDEFINED) |
@@ -501,6 +503,21 @@ int tpm_get_timeouts(struct tpm_chip *chip) | |||
501 | struct duration_t *duration_cap; | 503 | struct duration_t *duration_cap; |
502 | ssize_t rc; | 504 | ssize_t rc; |
503 | 505 | ||
506 | if (chip->flags & TPM_CHIP_FLAG_TPM2) { | ||
507 | /* Fixed timeouts for TPM2 */ | ||
508 | chip->vendor.timeout_a = msecs_to_jiffies(TPM2_TIMEOUT_A); | ||
509 | chip->vendor.timeout_b = msecs_to_jiffies(TPM2_TIMEOUT_B); | ||
510 | chip->vendor.timeout_c = msecs_to_jiffies(TPM2_TIMEOUT_C); | ||
511 | chip->vendor.timeout_d = msecs_to_jiffies(TPM2_TIMEOUT_D); | ||
512 | chip->vendor.duration[TPM_SHORT] = | ||
513 | msecs_to_jiffies(TPM2_DURATION_SHORT); | ||
514 | chip->vendor.duration[TPM_MEDIUM] = | ||
515 | msecs_to_jiffies(TPM2_DURATION_MEDIUM); | ||
516 | chip->vendor.duration[TPM_LONG] = | ||
517 | msecs_to_jiffies(TPM2_DURATION_LONG); | ||
518 | return 0; | ||
519 | } | ||
520 | |||
504 | tpm_cmd.header.in = tpm_getcap_header; | 521 | tpm_cmd.header.in = tpm_getcap_header; |
505 | tpm_cmd.params.getcap_in.cap = TPM_CAP_PROP; | 522 | tpm_cmd.params.getcap_in.cap = TPM_CAP_PROP; |
506 | tpm_cmd.params.getcap_in.subcap_size = cpu_to_be32(4); | 523 | tpm_cmd.params.getcap_in.subcap_size = cpu_to_be32(4); |
diff --git a/drivers/char/tpm/tpm.h b/drivers/char/tpm/tpm.h index a4257a32964f..542a80cbfd9c 100644 --- a/drivers/char/tpm/tpm.h +++ b/drivers/char/tpm/tpm.h | |||
@@ -83,16 +83,20 @@ enum tpm2_structures { | |||
83 | }; | 83 | }; |
84 | 84 | ||
85 | enum tpm2_return_codes { | 85 | enum tpm2_return_codes { |
86 | TPM2_RC_INITIALIZE = 0x0100, | 86 | TPM2_RC_HASH = 0x0083, /* RC_FMT1 */ |
87 | TPM2_RC_TESTING = 0x090A, | 87 | TPM2_RC_INITIALIZE = 0x0100, /* RC_VER1 */ |
88 | TPM2_RC_DISABLED = 0x0120, | 88 | TPM2_RC_DISABLED = 0x0120, |
89 | TPM2_RC_TESTING = 0x090A, /* RC_WARN */ | ||
89 | }; | 90 | }; |
90 | 91 | ||
91 | enum tpm2_algorithms { | 92 | enum tpm2_algorithms { |
92 | TPM2_ALG_SHA1 = 0x0004, | 93 | TPM2_ALG_SHA1 = 0x0004, |
93 | TPM2_ALG_KEYEDHASH = 0x0008, | 94 | TPM2_ALG_KEYEDHASH = 0x0008, |
94 | TPM2_ALG_SHA256 = 0x000B, | 95 | TPM2_ALG_SHA256 = 0x000B, |
95 | TPM2_ALG_NULL = 0x0010 | 96 | TPM2_ALG_SHA384 = 0x000C, |
97 | TPM2_ALG_SHA512 = 0x000D, | ||
98 | TPM2_ALG_NULL = 0x0010, | ||
99 | TPM2_ALG_SM3_256 = 0x0012, | ||
96 | }; | 100 | }; |
97 | 101 | ||
98 | enum tpm2_command_codes { | 102 | enum tpm2_command_codes { |
@@ -138,7 +142,6 @@ struct tpm_vendor_specific { | |||
138 | unsigned long base; /* TPM base address */ | 142 | unsigned long base; /* TPM base address */ |
139 | 143 | ||
140 | int irq; | 144 | int irq; |
141 | int probed_irq; | ||
142 | 145 | ||
143 | int region_size; | 146 | int region_size; |
144 | int have_region; | 147 | int have_region; |
diff --git a/drivers/char/tpm/tpm2-cmd.c b/drivers/char/tpm/tpm2-cmd.c index c12130485fc1..45a634016f95 100644 --- a/drivers/char/tpm/tpm2-cmd.c +++ b/drivers/char/tpm/tpm2-cmd.c | |||
@@ -16,6 +16,7 @@ | |||
16 | */ | 16 | */ |
17 | 17 | ||
18 | #include "tpm.h" | 18 | #include "tpm.h" |
19 | #include <crypto/hash_info.h> | ||
19 | #include <keys/trusted-type.h> | 20 | #include <keys/trusted-type.h> |
20 | 21 | ||
21 | enum tpm2_object_attributes { | 22 | enum tpm2_object_attributes { |
@@ -104,6 +105,19 @@ struct tpm2_cmd { | |||
104 | union tpm2_cmd_params params; | 105 | union tpm2_cmd_params params; |
105 | } __packed; | 106 | } __packed; |
106 | 107 | ||
108 | struct tpm2_hash { | ||
109 | unsigned int crypto_id; | ||
110 | unsigned int tpm_id; | ||
111 | }; | ||
112 | |||
113 | static struct tpm2_hash tpm2_hash_map[] = { | ||
114 | {HASH_ALGO_SHA1, TPM2_ALG_SHA1}, | ||
115 | {HASH_ALGO_SHA256, TPM2_ALG_SHA256}, | ||
116 | {HASH_ALGO_SHA384, TPM2_ALG_SHA384}, | ||
117 | {HASH_ALGO_SHA512, TPM2_ALG_SHA512}, | ||
118 | {HASH_ALGO_SM3_256, TPM2_ALG_SM3_256}, | ||
119 | }; | ||
120 | |||
107 | /* | 121 | /* |
108 | * Array with one entry per ordinal defining the maximum amount | 122 | * Array with one entry per ordinal defining the maximum amount |
109 | * of time the chip could take to return the result. The values | 123 | * of time the chip could take to return the result. The values |
@@ -429,8 +443,20 @@ int tpm2_seal_trusted(struct tpm_chip *chip, | |||
429 | { | 443 | { |
430 | unsigned int blob_len; | 444 | unsigned int blob_len; |
431 | struct tpm_buf buf; | 445 | struct tpm_buf buf; |
446 | u32 hash; | ||
447 | int i; | ||
432 | int rc; | 448 | int rc; |
433 | 449 | ||
450 | for (i = 0; i < ARRAY_SIZE(tpm2_hash_map); i++) { | ||
451 | if (options->hash == tpm2_hash_map[i].crypto_id) { | ||
452 | hash = tpm2_hash_map[i].tpm_id; | ||
453 | break; | ||
454 | } | ||
455 | } | ||
456 | |||
457 | if (i == ARRAY_SIZE(tpm2_hash_map)) | ||
458 | return -EINVAL; | ||
459 | |||
434 | rc = tpm_buf_init(&buf, TPM2_ST_SESSIONS, TPM2_CC_CREATE); | 460 | rc = tpm_buf_init(&buf, TPM2_ST_SESSIONS, TPM2_CC_CREATE); |
435 | if (rc) | 461 | if (rc) |
436 | return rc; | 462 | return rc; |
@@ -452,12 +478,26 @@ int tpm2_seal_trusted(struct tpm_chip *chip, | |||
452 | tpm_buf_append_u8(&buf, payload->migratable); | 478 | tpm_buf_append_u8(&buf, payload->migratable); |
453 | 479 | ||
454 | /* public */ | 480 | /* public */ |
455 | tpm_buf_append_u16(&buf, 14); | 481 | if (options->policydigest) |
482 | tpm_buf_append_u16(&buf, 14 + options->digest_len); | ||
483 | else | ||
484 | tpm_buf_append_u16(&buf, 14); | ||
456 | 485 | ||
457 | tpm_buf_append_u16(&buf, TPM2_ALG_KEYEDHASH); | 486 | tpm_buf_append_u16(&buf, TPM2_ALG_KEYEDHASH); |
458 | tpm_buf_append_u16(&buf, TPM2_ALG_SHA256); | 487 | tpm_buf_append_u16(&buf, hash); |
459 | tpm_buf_append_u32(&buf, TPM2_ATTR_USER_WITH_AUTH); | 488 | |
460 | tpm_buf_append_u16(&buf, 0); /* policy digest size */ | 489 | /* policy */ |
490 | if (options->policydigest) { | ||
491 | tpm_buf_append_u32(&buf, 0); | ||
492 | tpm_buf_append_u16(&buf, options->digest_len); | ||
493 | tpm_buf_append(&buf, options->policydigest, | ||
494 | options->digest_len); | ||
495 | } else { | ||
496 | tpm_buf_append_u32(&buf, TPM2_ATTR_USER_WITH_AUTH); | ||
497 | tpm_buf_append_u16(&buf, 0); | ||
498 | } | ||
499 | |||
500 | /* public parameters */ | ||
461 | tpm_buf_append_u16(&buf, TPM2_ALG_NULL); | 501 | tpm_buf_append_u16(&buf, TPM2_ALG_NULL); |
462 | tpm_buf_append_u16(&buf, 0); | 502 | tpm_buf_append_u16(&buf, 0); |
463 | 503 | ||
@@ -488,8 +528,12 @@ int tpm2_seal_trusted(struct tpm_chip *chip, | |||
488 | out: | 528 | out: |
489 | tpm_buf_destroy(&buf); | 529 | tpm_buf_destroy(&buf); |
490 | 530 | ||
491 | if (rc > 0) | 531 | if (rc > 0) { |
492 | rc = -EPERM; | 532 | if ((rc & TPM2_RC_HASH) == TPM2_RC_HASH) |
533 | rc = -EINVAL; | ||
534 | else | ||
535 | rc = -EPERM; | ||
536 | } | ||
493 | 537 | ||
494 | return rc; | 538 | return rc; |
495 | } | 539 | } |
@@ -583,7 +627,9 @@ static int tpm2_unseal(struct tpm_chip *chip, | |||
583 | return rc; | 627 | return rc; |
584 | 628 | ||
585 | tpm_buf_append_u32(&buf, blob_handle); | 629 | tpm_buf_append_u32(&buf, blob_handle); |
586 | tpm2_buf_append_auth(&buf, TPM2_RS_PW, | 630 | tpm2_buf_append_auth(&buf, |
631 | options->policyhandle ? | ||
632 | options->policyhandle : TPM2_RS_PW, | ||
587 | NULL /* nonce */, 0, | 633 | NULL /* nonce */, 0, |
588 | 0 /* session_attributes */, | 634 | 0 /* session_attributes */, |
589 | options->blobauth /* hmac */, | 635 | options->blobauth /* hmac */, |
diff --git a/drivers/char/tpm/tpm_crb.c b/drivers/char/tpm/tpm_crb.c index 4bb9727c1047..8342cf51ffdc 100644 --- a/drivers/char/tpm/tpm_crb.c +++ b/drivers/char/tpm/tpm_crb.c | |||
@@ -284,17 +284,9 @@ static int crb_acpi_add(struct acpi_device *device) | |||
284 | 284 | ||
285 | chip->vendor.priv = priv; | 285 | chip->vendor.priv = priv; |
286 | 286 | ||
287 | /* Default timeouts and durations */ | 287 | rc = tpm_get_timeouts(chip); |
288 | chip->vendor.timeout_a = msecs_to_jiffies(TPM2_TIMEOUT_A); | 288 | if (rc) |
289 | chip->vendor.timeout_b = msecs_to_jiffies(TPM2_TIMEOUT_B); | 289 | return rc; |
290 | chip->vendor.timeout_c = msecs_to_jiffies(TPM2_TIMEOUT_C); | ||
291 | chip->vendor.timeout_d = msecs_to_jiffies(TPM2_TIMEOUT_D); | ||
292 | chip->vendor.duration[TPM_SHORT] = | ||
293 | msecs_to_jiffies(TPM2_DURATION_SHORT); | ||
294 | chip->vendor.duration[TPM_MEDIUM] = | ||
295 | msecs_to_jiffies(TPM2_DURATION_MEDIUM); | ||
296 | chip->vendor.duration[TPM_LONG] = | ||
297 | msecs_to_jiffies(TPM2_DURATION_LONG); | ||
298 | 290 | ||
299 | chip->acpi_dev_handle = device->handle; | 291 | chip->acpi_dev_handle = device->handle; |
300 | 292 | ||
diff --git a/drivers/char/tpm/tpm_ibmvtpm.c b/drivers/char/tpm/tpm_ibmvtpm.c index 3e6a22658b63..b0a9a9e34241 100644 --- a/drivers/char/tpm/tpm_ibmvtpm.c +++ b/drivers/char/tpm/tpm_ibmvtpm.c | |||
@@ -90,7 +90,7 @@ static int tpm_ibmvtpm_recv(struct tpm_chip *chip, u8 *buf, size_t count) | |||
90 | return 0; | 90 | return 0; |
91 | } | 91 | } |
92 | 92 | ||
93 | sig = wait_event_interruptible(ibmvtpm->wq, ibmvtpm->res_len != 0); | 93 | sig = wait_event_interruptible(ibmvtpm->wq, !ibmvtpm->tpm_processing_cmd); |
94 | if (sig) | 94 | if (sig) |
95 | return -EINTR; | 95 | return -EINTR; |
96 | 96 | ||
@@ -125,7 +125,7 @@ static int tpm_ibmvtpm_send(struct tpm_chip *chip, u8 *buf, size_t count) | |||
125 | struct ibmvtpm_dev *ibmvtpm; | 125 | struct ibmvtpm_dev *ibmvtpm; |
126 | struct ibmvtpm_crq crq; | 126 | struct ibmvtpm_crq crq; |
127 | __be64 *word = (__be64 *)&crq; | 127 | __be64 *word = (__be64 *)&crq; |
128 | int rc; | 128 | int rc, sig; |
129 | 129 | ||
130 | ibmvtpm = (struct ibmvtpm_dev *)TPM_VPRIV(chip); | 130 | ibmvtpm = (struct ibmvtpm_dev *)TPM_VPRIV(chip); |
131 | 131 | ||
@@ -141,18 +141,35 @@ static int tpm_ibmvtpm_send(struct tpm_chip *chip, u8 *buf, size_t count) | |||
141 | return -EIO; | 141 | return -EIO; |
142 | } | 142 | } |
143 | 143 | ||
144 | if (ibmvtpm->tpm_processing_cmd) { | ||
145 | dev_info(ibmvtpm->dev, | ||
146 | "Need to wait for TPM to finish\n"); | ||
147 | /* wait for previous command to finish */ | ||
148 | sig = wait_event_interruptible(ibmvtpm->wq, !ibmvtpm->tpm_processing_cmd); | ||
149 | if (sig) | ||
150 | return -EINTR; | ||
151 | } | ||
152 | |||
144 | spin_lock(&ibmvtpm->rtce_lock); | 153 | spin_lock(&ibmvtpm->rtce_lock); |
154 | ibmvtpm->res_len = 0; | ||
145 | memcpy((void *)ibmvtpm->rtce_buf, (void *)buf, count); | 155 | memcpy((void *)ibmvtpm->rtce_buf, (void *)buf, count); |
146 | crq.valid = (u8)IBMVTPM_VALID_CMD; | 156 | crq.valid = (u8)IBMVTPM_VALID_CMD; |
147 | crq.msg = (u8)VTPM_TPM_COMMAND; | 157 | crq.msg = (u8)VTPM_TPM_COMMAND; |
148 | crq.len = cpu_to_be16(count); | 158 | crq.len = cpu_to_be16(count); |
149 | crq.data = cpu_to_be32(ibmvtpm->rtce_dma_handle); | 159 | crq.data = cpu_to_be32(ibmvtpm->rtce_dma_handle); |
150 | 160 | ||
161 | /* | ||
162 | * set the processing flag before the Hcall, since we may get the | ||
163 | * result (interrupt) before even being able to check rc. | ||
164 | */ | ||
165 | ibmvtpm->tpm_processing_cmd = true; | ||
166 | |||
151 | rc = ibmvtpm_send_crq(ibmvtpm->vdev, be64_to_cpu(word[0]), | 167 | rc = ibmvtpm_send_crq(ibmvtpm->vdev, be64_to_cpu(word[0]), |
152 | be64_to_cpu(word[1])); | 168 | be64_to_cpu(word[1])); |
153 | if (rc != H_SUCCESS) { | 169 | if (rc != H_SUCCESS) { |
154 | dev_err(ibmvtpm->dev, "tpm_ibmvtpm_send failed rc=%d\n", rc); | 170 | dev_err(ibmvtpm->dev, "tpm_ibmvtpm_send failed rc=%d\n", rc); |
155 | rc = 0; | 171 | rc = 0; |
172 | ibmvtpm->tpm_processing_cmd = false; | ||
156 | } else | 173 | } else |
157 | rc = count; | 174 | rc = count; |
158 | 175 | ||
@@ -515,6 +532,7 @@ static void ibmvtpm_crq_process(struct ibmvtpm_crq *crq, | |||
515 | case VTPM_TPM_COMMAND_RES: | 532 | case VTPM_TPM_COMMAND_RES: |
516 | /* len of the data in rtce buffer */ | 533 | /* len of the data in rtce buffer */ |
517 | ibmvtpm->res_len = be16_to_cpu(crq->len); | 534 | ibmvtpm->res_len = be16_to_cpu(crq->len); |
535 | ibmvtpm->tpm_processing_cmd = false; | ||
518 | wake_up_interruptible(&ibmvtpm->wq); | 536 | wake_up_interruptible(&ibmvtpm->wq); |
519 | return; | 537 | return; |
520 | default: | 538 | default: |
diff --git a/drivers/char/tpm/tpm_ibmvtpm.h b/drivers/char/tpm/tpm_ibmvtpm.h index 6af92890518f..91dfe766d080 100644 --- a/drivers/char/tpm/tpm_ibmvtpm.h +++ b/drivers/char/tpm/tpm_ibmvtpm.h | |||
@@ -45,6 +45,7 @@ struct ibmvtpm_dev { | |||
45 | wait_queue_head_t wq; | 45 | wait_queue_head_t wq; |
46 | u16 res_len; | 46 | u16 res_len; |
47 | u32 vtpm_version; | 47 | u32 vtpm_version; |
48 | bool tpm_processing_cmd; | ||
48 | }; | 49 | }; |
49 | 50 | ||
50 | #define CRQ_RES_BUF_SIZE PAGE_SIZE | 51 | #define CRQ_RES_BUF_SIZE PAGE_SIZE |
diff --git a/drivers/char/tpm/tpm_tis.c b/drivers/char/tpm/tpm_tis.c index 65f7eecc45b0..8a3509cb10da 100644 --- a/drivers/char/tpm/tpm_tis.c +++ b/drivers/char/tpm/tpm_tis.c | |||
@@ -401,7 +401,7 @@ static void disable_interrupts(struct tpm_chip *chip) | |||
401 | iowrite32(intmask, | 401 | iowrite32(intmask, |
402 | chip->vendor.iobase + | 402 | chip->vendor.iobase + |
403 | TPM_INT_ENABLE(chip->vendor.locality)); | 403 | TPM_INT_ENABLE(chip->vendor.locality)); |
404 | free_irq(chip->vendor.irq, chip); | 404 | devm_free_irq(chip->pdev, chip->vendor.irq, chip); |
405 | chip->vendor.irq = 0; | 405 | chip->vendor.irq = 0; |
406 | } | 406 | } |
407 | 407 | ||
@@ -461,11 +461,8 @@ static int tpm_tis_send(struct tpm_chip *chip, u8 *buf, size_t len) | |||
461 | chip->vendor.irq = irq; | 461 | chip->vendor.irq = irq; |
462 | if (!priv->irq_tested) | 462 | if (!priv->irq_tested) |
463 | msleep(1); | 463 | msleep(1); |
464 | if (!priv->irq_tested) { | 464 | if (!priv->irq_tested) |
465 | disable_interrupts(chip); | 465 | disable_interrupts(chip); |
466 | dev_err(chip->pdev, | ||
467 | FW_BUG "TPM interrupt not working, polling instead\n"); | ||
468 | } | ||
469 | priv->irq_tested = true; | 466 | priv->irq_tested = true; |
470 | return rc; | 467 | return rc; |
471 | } | 468 | } |
@@ -570,26 +567,6 @@ static const struct tpm_class_ops tpm_tis = { | |||
570 | .req_canceled = tpm_tis_req_canceled, | 567 | .req_canceled = tpm_tis_req_canceled, |
571 | }; | 568 | }; |
572 | 569 | ||
573 | static irqreturn_t tis_int_probe(int irq, void *dev_id) | ||
574 | { | ||
575 | struct tpm_chip *chip = dev_id; | ||
576 | u32 interrupt; | ||
577 | |||
578 | interrupt = ioread32(chip->vendor.iobase + | ||
579 | TPM_INT_STATUS(chip->vendor.locality)); | ||
580 | |||
581 | if (interrupt == 0) | ||
582 | return IRQ_NONE; | ||
583 | |||
584 | chip->vendor.probed_irq = irq; | ||
585 | |||
586 | /* Clear interrupts handled with TPM_EOI */ | ||
587 | iowrite32(interrupt, | ||
588 | chip->vendor.iobase + | ||
589 | TPM_INT_STATUS(chip->vendor.locality)); | ||
590 | return IRQ_HANDLED; | ||
591 | } | ||
592 | |||
593 | static irqreturn_t tis_int_handler(int dummy, void *dev_id) | 570 | static irqreturn_t tis_int_handler(int dummy, void *dev_id) |
594 | { | 571 | { |
595 | struct tpm_chip *chip = dev_id; | 572 | struct tpm_chip *chip = dev_id; |
@@ -622,6 +599,84 @@ static irqreturn_t tis_int_handler(int dummy, void *dev_id) | |||
622 | return IRQ_HANDLED; | 599 | return IRQ_HANDLED; |
623 | } | 600 | } |
624 | 601 | ||
602 | /* Register the IRQ and issue a command that will cause an interrupt. If an | ||
603 | * irq is seen then leave the chip setup for IRQ operation, otherwise reverse | ||
604 | * everything and leave in polling mode. Returns 0 on success. | ||
605 | */ | ||
606 | static int tpm_tis_probe_irq_single(struct tpm_chip *chip, u32 intmask, | ||
607 | int flags, int irq) | ||
608 | { | ||
609 | struct priv_data *priv = chip->vendor.priv; | ||
610 | u8 original_int_vec; | ||
611 | |||
612 | if (devm_request_irq(chip->pdev, irq, tis_int_handler, flags, | ||
613 | chip->devname, chip) != 0) { | ||
614 | dev_info(chip->pdev, "Unable to request irq: %d for probe\n", | ||
615 | irq); | ||
616 | return -1; | ||
617 | } | ||
618 | chip->vendor.irq = irq; | ||
619 | |||
620 | original_int_vec = ioread8(chip->vendor.iobase + | ||
621 | TPM_INT_VECTOR(chip->vendor.locality)); | ||
622 | iowrite8(irq, | ||
623 | chip->vendor.iobase + TPM_INT_VECTOR(chip->vendor.locality)); | ||
624 | |||
625 | /* Clear all existing */ | ||
626 | iowrite32(ioread32(chip->vendor.iobase + | ||
627 | TPM_INT_STATUS(chip->vendor.locality)), | ||
628 | chip->vendor.iobase + TPM_INT_STATUS(chip->vendor.locality)); | ||
629 | |||
630 | /* Turn on */ | ||
631 | iowrite32(intmask | TPM_GLOBAL_INT_ENABLE, | ||
632 | chip->vendor.iobase + TPM_INT_ENABLE(chip->vendor.locality)); | ||
633 | |||
634 | priv->irq_tested = false; | ||
635 | |||
636 | /* Generate an interrupt by having the core call through to | ||
637 | * tpm_tis_send | ||
638 | */ | ||
639 | if (chip->flags & TPM_CHIP_FLAG_TPM2) | ||
640 | tpm2_gen_interrupt(chip); | ||
641 | else | ||
642 | tpm_gen_interrupt(chip); | ||
643 | |||
644 | /* tpm_tis_send will either confirm the interrupt is working or it | ||
645 | * will call disable_irq which undoes all of the above. | ||
646 | */ | ||
647 | if (!chip->vendor.irq) { | ||
648 | iowrite8(original_int_vec, | ||
649 | chip->vendor.iobase + | ||
650 | TPM_INT_VECTOR(chip->vendor.locality)); | ||
651 | return 1; | ||
652 | } | ||
653 | |||
654 | return 0; | ||
655 | } | ||
656 | |||
657 | /* Try to find the IRQ the TPM is using. This is for legacy x86 systems that | ||
658 | * do not have ACPI/etc. We typically expect the interrupt to be declared if | ||
659 | * present. | ||
660 | */ | ||
661 | static void tpm_tis_probe_irq(struct tpm_chip *chip, u32 intmask) | ||
662 | { | ||
663 | u8 original_int_vec; | ||
664 | int i; | ||
665 | |||
666 | original_int_vec = ioread8(chip->vendor.iobase + | ||
667 | TPM_INT_VECTOR(chip->vendor.locality)); | ||
668 | |||
669 | if (!original_int_vec) { | ||
670 | if (IS_ENABLED(CONFIG_X86)) | ||
671 | for (i = 3; i <= 15; i++) | ||
672 | if (!tpm_tis_probe_irq_single(chip, intmask, 0, | ||
673 | i)) | ||
674 | return; | ||
675 | } else if (!tpm_tis_probe_irq_single(chip, intmask, 0, | ||
676 | original_int_vec)) | ||
677 | return; | ||
678 | } | ||
679 | |||
625 | static bool interrupts = true; | 680 | static bool interrupts = true; |
626 | module_param(interrupts, bool, 0444); | 681 | module_param(interrupts, bool, 0444); |
627 | MODULE_PARM_DESC(interrupts, "Enable interrupts"); | 682 | MODULE_PARM_DESC(interrupts, "Enable interrupts"); |
@@ -644,8 +699,7 @@ static int tpm_tis_init(struct device *dev, struct tpm_info *tpm_info, | |||
644 | acpi_handle acpi_dev_handle) | 699 | acpi_handle acpi_dev_handle) |
645 | { | 700 | { |
646 | u32 vendor, intfcaps, intmask; | 701 | u32 vendor, intfcaps, intmask; |
647 | int rc, i, irq_s, irq_e, probe; | 702 | int rc, probe; |
648 | int irq_r = -1; | ||
649 | struct tpm_chip *chip; | 703 | struct tpm_chip *chip; |
650 | struct priv_data *priv; | 704 | struct priv_data *priv; |
651 | 705 | ||
@@ -677,6 +731,15 @@ static int tpm_tis_init(struct device *dev, struct tpm_info *tpm_info, | |||
677 | goto out_err; | 731 | goto out_err; |
678 | } | 732 | } |
679 | 733 | ||
734 | /* Take control of the TPM's interrupt hardware and shut it off */ | ||
735 | intmask = ioread32(chip->vendor.iobase + | ||
736 | TPM_INT_ENABLE(chip->vendor.locality)); | ||
737 | intmask |= TPM_INTF_CMD_READY_INT | TPM_INTF_LOCALITY_CHANGE_INT | | ||
738 | TPM_INTF_DATA_AVAIL_INT | TPM_INTF_STS_VALID_INT; | ||
739 | intmask &= ~TPM_GLOBAL_INT_ENABLE; | ||
740 | iowrite32(intmask, | ||
741 | chip->vendor.iobase + TPM_INT_ENABLE(chip->vendor.locality)); | ||
742 | |||
680 | if (request_locality(chip, 0) != 0) { | 743 | if (request_locality(chip, 0) != 0) { |
681 | rc = -ENODEV; | 744 | rc = -ENODEV; |
682 | goto out_err; | 745 | goto out_err; |
@@ -731,126 +794,31 @@ static int tpm_tis_init(struct device *dev, struct tpm_info *tpm_info, | |||
731 | if (intfcaps & TPM_INTF_DATA_AVAIL_INT) | 794 | if (intfcaps & TPM_INTF_DATA_AVAIL_INT) |
732 | dev_dbg(dev, "\tData Avail Int Support\n"); | 795 | dev_dbg(dev, "\tData Avail Int Support\n"); |
733 | 796 | ||
797 | /* Very early on issue a command to the TPM in polling mode to make | ||
798 | * sure it works. May as well use that command to set the proper | ||
799 | * timeouts for the driver. | ||
800 | */ | ||
801 | if (tpm_get_timeouts(chip)) { | ||
802 | dev_err(dev, "Could not get TPM timeouts and durations\n"); | ||
803 | rc = -ENODEV; | ||
804 | goto out_err; | ||
805 | } | ||
806 | |||
734 | /* INTERRUPT Setup */ | 807 | /* INTERRUPT Setup */ |
735 | init_waitqueue_head(&chip->vendor.read_queue); | 808 | init_waitqueue_head(&chip->vendor.read_queue); |
736 | init_waitqueue_head(&chip->vendor.int_queue); | 809 | init_waitqueue_head(&chip->vendor.int_queue); |
737 | 810 | if (interrupts) { | |
738 | intmask = | 811 | if (tpm_info->irq) { |
739 | ioread32(chip->vendor.iobase + | 812 | tpm_tis_probe_irq_single(chip, intmask, IRQF_SHARED, |
740 | TPM_INT_ENABLE(chip->vendor.locality)); | 813 | tpm_info->irq); |
741 | 814 | if (!chip->vendor.irq) | |
742 | intmask |= TPM_INTF_CMD_READY_INT | 815 | dev_err(chip->pdev, FW_BUG |
743 | | TPM_INTF_LOCALITY_CHANGE_INT | TPM_INTF_DATA_AVAIL_INT | 816 | "TPM interrupt not working, polling instead\n"); |
744 | | TPM_INTF_STS_VALID_INT; | 817 | } else |
745 | 818 | tpm_tis_probe_irq(chip, intmask); | |
746 | iowrite32(intmask, | ||
747 | chip->vendor.iobase + | ||
748 | TPM_INT_ENABLE(chip->vendor.locality)); | ||
749 | if (interrupts) | ||
750 | chip->vendor.irq = tpm_info->irq; | ||
751 | if (interrupts && !chip->vendor.irq) { | ||
752 | irq_s = | ||
753 | ioread8(chip->vendor.iobase + | ||
754 | TPM_INT_VECTOR(chip->vendor.locality)); | ||
755 | irq_r = irq_s; | ||
756 | if (irq_s) { | ||
757 | irq_e = irq_s; | ||
758 | } else { | ||
759 | irq_s = 3; | ||
760 | irq_e = 15; | ||
761 | } | ||
762 | |||
763 | for (i = irq_s; i <= irq_e && chip->vendor.irq == 0; i++) { | ||
764 | iowrite8(i, chip->vendor.iobase + | ||
765 | TPM_INT_VECTOR(chip->vendor.locality)); | ||
766 | if (devm_request_irq | ||
767 | (dev, i, tis_int_probe, IRQF_SHARED, | ||
768 | chip->devname, chip) != 0) { | ||
769 | dev_info(chip->pdev, | ||
770 | "Unable to request irq: %d for probe\n", | ||
771 | i); | ||
772 | continue; | ||
773 | } | ||
774 | |||
775 | /* Clear all existing */ | ||
776 | iowrite32(ioread32 | ||
777 | (chip->vendor.iobase + | ||
778 | TPM_INT_STATUS(chip->vendor.locality)), | ||
779 | chip->vendor.iobase + | ||
780 | TPM_INT_STATUS(chip->vendor.locality)); | ||
781 | |||
782 | /* Turn on */ | ||
783 | iowrite32(intmask | TPM_GLOBAL_INT_ENABLE, | ||
784 | chip->vendor.iobase + | ||
785 | TPM_INT_ENABLE(chip->vendor.locality)); | ||
786 | |||
787 | chip->vendor.probed_irq = 0; | ||
788 | |||
789 | /* Generate Interrupts */ | ||
790 | if (chip->flags & TPM_CHIP_FLAG_TPM2) | ||
791 | tpm2_gen_interrupt(chip); | ||
792 | else | ||
793 | tpm_gen_interrupt(chip); | ||
794 | |||
795 | chip->vendor.irq = chip->vendor.probed_irq; | ||
796 | |||
797 | /* free_irq will call into tis_int_probe; | ||
798 | clear all irqs we haven't seen while doing | ||
799 | tpm_gen_interrupt */ | ||
800 | iowrite32(ioread32 | ||
801 | (chip->vendor.iobase + | ||
802 | TPM_INT_STATUS(chip->vendor.locality)), | ||
803 | chip->vendor.iobase + | ||
804 | TPM_INT_STATUS(chip->vendor.locality)); | ||
805 | |||
806 | /* Turn off */ | ||
807 | iowrite32(intmask, | ||
808 | chip->vendor.iobase + | ||
809 | TPM_INT_ENABLE(chip->vendor.locality)); | ||
810 | |||
811 | devm_free_irq(dev, i, chip); | ||
812 | } | ||
813 | } | 819 | } |
814 | if (chip->vendor.irq) { | ||
815 | iowrite8(chip->vendor.irq, | ||
816 | chip->vendor.iobase + | ||
817 | TPM_INT_VECTOR(chip->vendor.locality)); | ||
818 | if (devm_request_irq | ||
819 | (dev, chip->vendor.irq, tis_int_handler, IRQF_SHARED, | ||
820 | chip->devname, chip) != 0) { | ||
821 | dev_info(chip->pdev, | ||
822 | "Unable to request irq: %d for use\n", | ||
823 | chip->vendor.irq); | ||
824 | chip->vendor.irq = 0; | ||
825 | } else { | ||
826 | /* Clear all existing */ | ||
827 | iowrite32(ioread32 | ||
828 | (chip->vendor.iobase + | ||
829 | TPM_INT_STATUS(chip->vendor.locality)), | ||
830 | chip->vendor.iobase + | ||
831 | TPM_INT_STATUS(chip->vendor.locality)); | ||
832 | |||
833 | /* Turn on */ | ||
834 | iowrite32(intmask | TPM_GLOBAL_INT_ENABLE, | ||
835 | chip->vendor.iobase + | ||
836 | TPM_INT_ENABLE(chip->vendor.locality)); | ||
837 | } | ||
838 | } else if (irq_r != -1) | ||
839 | iowrite8(irq_r, chip->vendor.iobase + | ||
840 | TPM_INT_VECTOR(chip->vendor.locality)); | ||
841 | 820 | ||
842 | if (chip->flags & TPM_CHIP_FLAG_TPM2) { | 821 | if (chip->flags & TPM_CHIP_FLAG_TPM2) { |
843 | chip->vendor.timeout_a = msecs_to_jiffies(TPM2_TIMEOUT_A); | ||
844 | chip->vendor.timeout_b = msecs_to_jiffies(TPM2_TIMEOUT_B); | ||
845 | chip->vendor.timeout_c = msecs_to_jiffies(TPM2_TIMEOUT_C); | ||
846 | chip->vendor.timeout_d = msecs_to_jiffies(TPM2_TIMEOUT_D); | ||
847 | chip->vendor.duration[TPM_SHORT] = | ||
848 | msecs_to_jiffies(TPM2_DURATION_SHORT); | ||
849 | chip->vendor.duration[TPM_MEDIUM] = | ||
850 | msecs_to_jiffies(TPM2_DURATION_MEDIUM); | ||
851 | chip->vendor.duration[TPM_LONG] = | ||
852 | msecs_to_jiffies(TPM2_DURATION_LONG); | ||
853 | |||
854 | rc = tpm2_do_selftest(chip); | 822 | rc = tpm2_do_selftest(chip); |
855 | if (rc == TPM2_RC_INITIALIZE) { | 823 | if (rc == TPM2_RC_INITIALIZE) { |
856 | dev_warn(dev, "Firmware has not started TPM\n"); | 824 | dev_warn(dev, "Firmware has not started TPM\n"); |
@@ -866,12 +834,6 @@ static int tpm_tis_init(struct device *dev, struct tpm_info *tpm_info, | |||
866 | goto out_err; | 834 | goto out_err; |
867 | } | 835 | } |
868 | } else { | 836 | } else { |
869 | if (tpm_get_timeouts(chip)) { | ||
870 | dev_err(dev, "Could not get TPM timeouts and durations\n"); | ||
871 | rc = -ENODEV; | ||
872 | goto out_err; | ||
873 | } | ||
874 | |||
875 | if (tpm_do_selftest(chip)) { | 837 | if (tpm_do_selftest(chip)) { |
876 | dev_err(dev, "TPM self test failed\n"); | 838 | dev_err(dev, "TPM self test failed\n"); |
877 | rc = -ENODEV; | 839 | rc = -ENODEV; |
diff --git a/fs/gfs2/glops.c b/fs/gfs2/glops.c index f348cfb6b69a..437fd73e381e 100644 --- a/fs/gfs2/glops.c +++ b/fs/gfs2/glops.c | |||
@@ -13,6 +13,7 @@ | |||
13 | #include <linux/gfs2_ondisk.h> | 13 | #include <linux/gfs2_ondisk.h> |
14 | #include <linux/bio.h> | 14 | #include <linux/bio.h> |
15 | #include <linux/posix_acl.h> | 15 | #include <linux/posix_acl.h> |
16 | #include <linux/security.h> | ||
16 | 17 | ||
17 | #include "gfs2.h" | 18 | #include "gfs2.h" |
18 | #include "incore.h" | 19 | #include "incore.h" |
@@ -262,6 +263,7 @@ static void inode_go_inval(struct gfs2_glock *gl, int flags) | |||
262 | if (ip) { | 263 | if (ip) { |
263 | set_bit(GIF_INVALID, &ip->i_flags); | 264 | set_bit(GIF_INVALID, &ip->i_flags); |
264 | forget_all_cached_acls(&ip->i_inode); | 265 | forget_all_cached_acls(&ip->i_inode); |
266 | security_inode_invalidate_secctx(&ip->i_inode); | ||
265 | gfs2_dir_hash_inval(ip); | 267 | gfs2_dir_hash_inval(ip); |
266 | } | 268 | } |
267 | } | 269 | } |
diff --git a/include/crypto/hash_info.h b/include/crypto/hash_info.h index e1e5a3e5dd1b..56f217d41f12 100644 --- a/include/crypto/hash_info.h +++ b/include/crypto/hash_info.h | |||
@@ -34,6 +34,9 @@ | |||
34 | #define TGR160_DIGEST_SIZE 20 | 34 | #define TGR160_DIGEST_SIZE 20 |
35 | #define TGR192_DIGEST_SIZE 24 | 35 | #define TGR192_DIGEST_SIZE 24 |
36 | 36 | ||
37 | /* not defined in include/crypto/ */ | ||
38 | #define SM3256_DIGEST_SIZE 32 | ||
39 | |||
37 | extern const char *const hash_algo_name[HASH_ALGO__LAST]; | 40 | extern const char *const hash_algo_name[HASH_ALGO__LAST]; |
38 | extern const int hash_digest_size[HASH_ALGO__LAST]; | 41 | extern const int hash_digest_size[HASH_ALGO__LAST]; |
39 | 42 | ||
diff --git a/include/keys/system_keyring.h b/include/keys/system_keyring.h index b20cd885c1fd..39fd38cfa8c9 100644 --- a/include/keys/system_keyring.h +++ b/include/keys/system_keyring.h | |||
@@ -35,4 +35,28 @@ extern int system_verify_data(const void *data, unsigned long len, | |||
35 | enum key_being_used_for usage); | 35 | enum key_being_used_for usage); |
36 | #endif | 36 | #endif |
37 | 37 | ||
38 | #ifdef CONFIG_IMA_MOK_KEYRING | ||
39 | extern struct key *ima_mok_keyring; | ||
40 | extern struct key *ima_blacklist_keyring; | ||
41 | |||
42 | static inline struct key *get_ima_mok_keyring(void) | ||
43 | { | ||
44 | return ima_mok_keyring; | ||
45 | } | ||
46 | static inline struct key *get_ima_blacklist_keyring(void) | ||
47 | { | ||
48 | return ima_blacklist_keyring; | ||
49 | } | ||
50 | #else | ||
51 | static inline struct key *get_ima_mok_keyring(void) | ||
52 | { | ||
53 | return NULL; | ||
54 | } | ||
55 | static inline struct key *get_ima_blacklist_keyring(void) | ||
56 | { | ||
57 | return NULL; | ||
58 | } | ||
59 | #endif /* CONFIG_IMA_MOK_KEYRING */ | ||
60 | |||
61 | |||
38 | #endif /* _KEYS_SYSTEM_KEYRING_H */ | 62 | #endif /* _KEYS_SYSTEM_KEYRING_H */ |
diff --git a/include/keys/trusted-type.h b/include/keys/trusted-type.h index f91ecd9d1bb1..42cf2d991bf4 100644 --- a/include/keys/trusted-type.h +++ b/include/keys/trusted-type.h | |||
@@ -18,6 +18,7 @@ | |||
18 | #define MAX_KEY_SIZE 128 | 18 | #define MAX_KEY_SIZE 128 |
19 | #define MAX_BLOB_SIZE 512 | 19 | #define MAX_BLOB_SIZE 512 |
20 | #define MAX_PCRINFO_SIZE 64 | 20 | #define MAX_PCRINFO_SIZE 64 |
21 | #define MAX_DIGEST_SIZE 64 | ||
21 | 22 | ||
22 | struct trusted_key_payload { | 23 | struct trusted_key_payload { |
23 | struct rcu_head rcu; | 24 | struct rcu_head rcu; |
@@ -36,6 +37,10 @@ struct trusted_key_options { | |||
36 | uint32_t pcrinfo_len; | 37 | uint32_t pcrinfo_len; |
37 | unsigned char pcrinfo[MAX_PCRINFO_SIZE]; | 38 | unsigned char pcrinfo[MAX_PCRINFO_SIZE]; |
38 | int pcrlock; | 39 | int pcrlock; |
40 | uint32_t hash; | ||
41 | uint32_t digest_len; | ||
42 | unsigned char policydigest[MAX_DIGEST_SIZE]; | ||
43 | uint32_t policyhandle; | ||
39 | }; | 44 | }; |
40 | 45 | ||
41 | extern struct key_type key_type_trusted; | 46 | extern struct key_type key_type_trusted; |
diff --git a/include/linux/audit.h b/include/linux/audit.h index 476bc1237ec2..b40ed5df5542 100644 --- a/include/linux/audit.h +++ b/include/linux/audit.h | |||
@@ -238,7 +238,7 @@ extern void __audit_getname(struct filename *name); | |||
238 | extern void __audit_inode(struct filename *name, const struct dentry *dentry, | 238 | extern void __audit_inode(struct filename *name, const struct dentry *dentry, |
239 | unsigned int flags); | 239 | unsigned int flags); |
240 | extern void __audit_file(const struct file *); | 240 | extern void __audit_file(const struct file *); |
241 | extern void __audit_inode_child(const struct inode *parent, | 241 | extern void __audit_inode_child(struct inode *parent, |
242 | const struct dentry *dentry, | 242 | const struct dentry *dentry, |
243 | const unsigned char type); | 243 | const unsigned char type); |
244 | extern void __audit_seccomp(unsigned long syscall, long signr, int code); | 244 | extern void __audit_seccomp(unsigned long syscall, long signr, int code); |
@@ -303,7 +303,7 @@ static inline void audit_inode_parent_hidden(struct filename *name, | |||
303 | __audit_inode(name, dentry, | 303 | __audit_inode(name, dentry, |
304 | AUDIT_INODE_PARENT | AUDIT_INODE_HIDDEN); | 304 | AUDIT_INODE_PARENT | AUDIT_INODE_HIDDEN); |
305 | } | 305 | } |
306 | static inline void audit_inode_child(const struct inode *parent, | 306 | static inline void audit_inode_child(struct inode *parent, |
307 | const struct dentry *dentry, | 307 | const struct dentry *dentry, |
308 | const unsigned char type) { | 308 | const unsigned char type) { |
309 | if (unlikely(!audit_dummy_context())) | 309 | if (unlikely(!audit_dummy_context())) |
@@ -463,7 +463,7 @@ static inline void __audit_inode(struct filename *name, | |||
463 | const struct dentry *dentry, | 463 | const struct dentry *dentry, |
464 | unsigned int flags) | 464 | unsigned int flags) |
465 | { } | 465 | { } |
466 | static inline void __audit_inode_child(const struct inode *parent, | 466 | static inline void __audit_inode_child(struct inode *parent, |
467 | const struct dentry *dentry, | 467 | const struct dentry *dentry, |
468 | const unsigned char type) | 468 | const unsigned char type) |
469 | { } | 469 | { } |
@@ -477,7 +477,7 @@ static inline void audit_file(struct file *file) | |||
477 | static inline void audit_inode_parent_hidden(struct filename *name, | 477 | static inline void audit_inode_parent_hidden(struct filename *name, |
478 | const struct dentry *dentry) | 478 | const struct dentry *dentry) |
479 | { } | 479 | { } |
480 | static inline void audit_inode_child(const struct inode *parent, | 480 | static inline void audit_inode_child(struct inode *parent, |
481 | const struct dentry *dentry, | 481 | const struct dentry *dentry, |
482 | const unsigned char type) | 482 | const unsigned char type) |
483 | { } | 483 | { } |
diff --git a/include/linux/capability.h b/include/linux/capability.h index af9f0b9e80e6..f314275d4e3f 100644 --- a/include/linux/capability.h +++ b/include/linux/capability.h | |||
@@ -145,24 +145,24 @@ static inline kernel_cap_t cap_invert(const kernel_cap_t c) | |||
145 | return dest; | 145 | return dest; |
146 | } | 146 | } |
147 | 147 | ||
148 | static inline int cap_isclear(const kernel_cap_t a) | 148 | static inline bool cap_isclear(const kernel_cap_t a) |
149 | { | 149 | { |
150 | unsigned __capi; | 150 | unsigned __capi; |
151 | CAP_FOR_EACH_U32(__capi) { | 151 | CAP_FOR_EACH_U32(__capi) { |
152 | if (a.cap[__capi] != 0) | 152 | if (a.cap[__capi] != 0) |
153 | return 0; | 153 | return false; |
154 | } | 154 | } |
155 | return 1; | 155 | return true; |
156 | } | 156 | } |
157 | 157 | ||
158 | /* | 158 | /* |
159 | * Check if "a" is a subset of "set". | 159 | * Check if "a" is a subset of "set". |
160 | * return 1 if ALL of the capabilities in "a" are also in "set" | 160 | * return true if ALL of the capabilities in "a" are also in "set" |
161 | * cap_issubset(0101, 1111) will return 1 | 161 | * cap_issubset(0101, 1111) will return true |
162 | * return 0 if ANY of the capabilities in "a" are not in "set" | 162 | * return false if ANY of the capabilities in "a" are not in "set" |
163 | * cap_issubset(1111, 0101) will return 0 | 163 | * cap_issubset(1111, 0101) will return false |
164 | */ | 164 | */ |
165 | static inline int cap_issubset(const kernel_cap_t a, const kernel_cap_t set) | 165 | static inline bool cap_issubset(const kernel_cap_t a, const kernel_cap_t set) |
166 | { | 166 | { |
167 | kernel_cap_t dest; | 167 | kernel_cap_t dest; |
168 | dest = cap_drop(a, set); | 168 | dest = cap_drop(a, set); |
@@ -171,12 +171,6 @@ static inline int cap_issubset(const kernel_cap_t a, const kernel_cap_t set) | |||
171 | 171 | ||
172 | /* Used to decide between falling back on the old suser() or fsuser(). */ | 172 | /* Used to decide between falling back on the old suser() or fsuser(). */ |
173 | 173 | ||
174 | static inline int cap_is_fs_cap(int cap) | ||
175 | { | ||
176 | const kernel_cap_t __cap_fs_set = CAP_FS_SET; | ||
177 | return !!(CAP_TO_MASK(cap) & __cap_fs_set.cap[CAP_TO_INDEX(cap)]); | ||
178 | } | ||
179 | |||
180 | static inline kernel_cap_t cap_drop_fs_set(const kernel_cap_t a) | 174 | static inline kernel_cap_t cap_drop_fs_set(const kernel_cap_t a) |
181 | { | 175 | { |
182 | const kernel_cap_t __cap_fs_set = CAP_FS_SET; | 176 | const kernel_cap_t __cap_fs_set = CAP_FS_SET; |
diff --git a/include/linux/evm.h b/include/linux/evm.h index 1fcb88ca88de..35ed9a8a403a 100644 --- a/include/linux/evm.h +++ b/include/linux/evm.h | |||
@@ -14,6 +14,7 @@ | |||
14 | struct integrity_iint_cache; | 14 | struct integrity_iint_cache; |
15 | 15 | ||
16 | #ifdef CONFIG_EVM | 16 | #ifdef CONFIG_EVM |
17 | extern int evm_set_key(void *key, size_t keylen); | ||
17 | extern enum integrity_status evm_verifyxattr(struct dentry *dentry, | 18 | extern enum integrity_status evm_verifyxattr(struct dentry *dentry, |
18 | const char *xattr_name, | 19 | const char *xattr_name, |
19 | void *xattr_value, | 20 | void *xattr_value, |
@@ -42,6 +43,12 @@ static inline int posix_xattr_acl(const char *xattrname) | |||
42 | } | 43 | } |
43 | #endif | 44 | #endif |
44 | #else | 45 | #else |
46 | |||
47 | static inline int evm_set_key(void *key, size_t keylen) | ||
48 | { | ||
49 | return -EOPNOTSUPP; | ||
50 | } | ||
51 | |||
45 | #ifdef CONFIG_INTEGRITY | 52 | #ifdef CONFIG_INTEGRITY |
46 | static inline enum integrity_status evm_verifyxattr(struct dentry *dentry, | 53 | static inline enum integrity_status evm_verifyxattr(struct dentry *dentry, |
47 | const char *xattr_name, | 54 | const char *xattr_name, |
diff --git a/include/linux/key.h b/include/linux/key.h index 66f705243985..7321ab8ef949 100644 --- a/include/linux/key.h +++ b/include/linux/key.h | |||
@@ -177,6 +177,7 @@ struct key { | |||
177 | #define KEY_FLAG_TRUSTED_ONLY 9 /* set if keyring only accepts links to trusted keys */ | 177 | #define KEY_FLAG_TRUSTED_ONLY 9 /* set if keyring only accepts links to trusted keys */ |
178 | #define KEY_FLAG_BUILTIN 10 /* set if key is builtin */ | 178 | #define KEY_FLAG_BUILTIN 10 /* set if key is builtin */ |
179 | #define KEY_FLAG_ROOT_CAN_INVAL 11 /* set if key can be invalidated by root without permission */ | 179 | #define KEY_FLAG_ROOT_CAN_INVAL 11 /* set if key can be invalidated by root without permission */ |
180 | #define KEY_FLAG_KEEP 12 /* set if key should not be removed */ | ||
180 | 181 | ||
181 | /* the key type and key description string | 182 | /* the key type and key description string |
182 | * - the desc is used to match a key against search criteria | 183 | * - the desc is used to match a key against search criteria |
diff --git a/include/linux/lsm_hooks.h b/include/linux/lsm_hooks.h index ec3a6bab29de..71969de4058c 100644 --- a/include/linux/lsm_hooks.h +++ b/include/linux/lsm_hooks.h | |||
@@ -1261,6 +1261,10 @@ | |||
1261 | * audit_rule_init. | 1261 | * audit_rule_init. |
1262 | * @rule contains the allocated rule | 1262 | * @rule contains the allocated rule |
1263 | * | 1263 | * |
1264 | * @inode_invalidate_secctx: | ||
1265 | * Notify the security module that it must revalidate the security context | ||
1266 | * of an inode. | ||
1267 | * | ||
1264 | * @inode_notifysecctx: | 1268 | * @inode_notifysecctx: |
1265 | * Notify the security module of what the security context of an inode | 1269 | * Notify the security module of what the security context of an inode |
1266 | * should be. Initializes the incore security context managed by the | 1270 | * should be. Initializes the incore security context managed by the |
@@ -1413,14 +1417,14 @@ union security_list_options { | |||
1413 | int (*inode_removexattr)(struct dentry *dentry, const char *name); | 1417 | int (*inode_removexattr)(struct dentry *dentry, const char *name); |
1414 | int (*inode_need_killpriv)(struct dentry *dentry); | 1418 | int (*inode_need_killpriv)(struct dentry *dentry); |
1415 | int (*inode_killpriv)(struct dentry *dentry); | 1419 | int (*inode_killpriv)(struct dentry *dentry); |
1416 | int (*inode_getsecurity)(const struct inode *inode, const char *name, | 1420 | int (*inode_getsecurity)(struct inode *inode, const char *name, |
1417 | void **buffer, bool alloc); | 1421 | void **buffer, bool alloc); |
1418 | int (*inode_setsecurity)(struct inode *inode, const char *name, | 1422 | int (*inode_setsecurity)(struct inode *inode, const char *name, |
1419 | const void *value, size_t size, | 1423 | const void *value, size_t size, |
1420 | int flags); | 1424 | int flags); |
1421 | int (*inode_listsecurity)(struct inode *inode, char *buffer, | 1425 | int (*inode_listsecurity)(struct inode *inode, char *buffer, |
1422 | size_t buffer_size); | 1426 | size_t buffer_size); |
1423 | void (*inode_getsecid)(const struct inode *inode, u32 *secid); | 1427 | void (*inode_getsecid)(struct inode *inode, u32 *secid); |
1424 | 1428 | ||
1425 | int (*file_permission)(struct file *file, int mask); | 1429 | int (*file_permission)(struct file *file, int mask); |
1426 | int (*file_alloc_security)(struct file *file); | 1430 | int (*file_alloc_security)(struct file *file); |
@@ -1516,6 +1520,7 @@ union security_list_options { | |||
1516 | int (*secctx_to_secid)(const char *secdata, u32 seclen, u32 *secid); | 1520 | int (*secctx_to_secid)(const char *secdata, u32 seclen, u32 *secid); |
1517 | void (*release_secctx)(char *secdata, u32 seclen); | 1521 | void (*release_secctx)(char *secdata, u32 seclen); |
1518 | 1522 | ||
1523 | void (*inode_invalidate_secctx)(struct inode *inode); | ||
1519 | int (*inode_notifysecctx)(struct inode *inode, void *ctx, u32 ctxlen); | 1524 | int (*inode_notifysecctx)(struct inode *inode, void *ctx, u32 ctxlen); |
1520 | int (*inode_setsecctx)(struct dentry *dentry, void *ctx, u32 ctxlen); | 1525 | int (*inode_setsecctx)(struct dentry *dentry, void *ctx, u32 ctxlen); |
1521 | int (*inode_getsecctx)(struct inode *inode, void **ctx, u32 *ctxlen); | 1526 | int (*inode_getsecctx)(struct inode *inode, void **ctx, u32 *ctxlen); |
@@ -1757,6 +1762,7 @@ struct security_hook_heads { | |||
1757 | struct list_head secid_to_secctx; | 1762 | struct list_head secid_to_secctx; |
1758 | struct list_head secctx_to_secid; | 1763 | struct list_head secctx_to_secid; |
1759 | struct list_head release_secctx; | 1764 | struct list_head release_secctx; |
1765 | struct list_head inode_invalidate_secctx; | ||
1760 | struct list_head inode_notifysecctx; | 1766 | struct list_head inode_notifysecctx; |
1761 | struct list_head inode_setsecctx; | 1767 | struct list_head inode_setsecctx; |
1762 | struct list_head inode_getsecctx; | 1768 | struct list_head inode_getsecctx; |
diff --git a/include/linux/security.h b/include/linux/security.h index 2f4c1f7aa7db..4824a4ccaf1c 100644 --- a/include/linux/security.h +++ b/include/linux/security.h | |||
@@ -270,10 +270,10 @@ int security_inode_listxattr(struct dentry *dentry); | |||
270 | int security_inode_removexattr(struct dentry *dentry, const char *name); | 270 | int security_inode_removexattr(struct dentry *dentry, const char *name); |
271 | int security_inode_need_killpriv(struct dentry *dentry); | 271 | int security_inode_need_killpriv(struct dentry *dentry); |
272 | int security_inode_killpriv(struct dentry *dentry); | 272 | int security_inode_killpriv(struct dentry *dentry); |
273 | int security_inode_getsecurity(const struct inode *inode, const char *name, void **buffer, bool alloc); | 273 | int security_inode_getsecurity(struct inode *inode, const char *name, void **buffer, bool alloc); |
274 | int security_inode_setsecurity(struct inode *inode, const char *name, const void *value, size_t size, int flags); | 274 | int security_inode_setsecurity(struct inode *inode, const char *name, const void *value, size_t size, int flags); |
275 | int security_inode_listsecurity(struct inode *inode, char *buffer, size_t buffer_size); | 275 | int security_inode_listsecurity(struct inode *inode, char *buffer, size_t buffer_size); |
276 | void security_inode_getsecid(const struct inode *inode, u32 *secid); | 276 | void security_inode_getsecid(struct inode *inode, u32 *secid); |
277 | int security_file_permission(struct file *file, int mask); | 277 | int security_file_permission(struct file *file, int mask); |
278 | int security_file_alloc(struct file *file); | 278 | int security_file_alloc(struct file *file); |
279 | void security_file_free(struct file *file); | 279 | void security_file_free(struct file *file); |
@@ -353,6 +353,7 @@ int security_secid_to_secctx(u32 secid, char **secdata, u32 *seclen); | |||
353 | int security_secctx_to_secid(const char *secdata, u32 seclen, u32 *secid); | 353 | int security_secctx_to_secid(const char *secdata, u32 seclen, u32 *secid); |
354 | void security_release_secctx(char *secdata, u32 seclen); | 354 | void security_release_secctx(char *secdata, u32 seclen); |
355 | 355 | ||
356 | void security_inode_invalidate_secctx(struct inode *inode); | ||
356 | int security_inode_notifysecctx(struct inode *inode, void *ctx, u32 ctxlen); | 357 | int security_inode_notifysecctx(struct inode *inode, void *ctx, u32 ctxlen); |
357 | int security_inode_setsecctx(struct dentry *dentry, void *ctx, u32 ctxlen); | 358 | int security_inode_setsecctx(struct dentry *dentry, void *ctx, u32 ctxlen); |
358 | int security_inode_getsecctx(struct inode *inode, void **ctx, u32 *ctxlen); | 359 | int security_inode_getsecctx(struct inode *inode, void **ctx, u32 *ctxlen); |
@@ -719,7 +720,7 @@ static inline int security_inode_killpriv(struct dentry *dentry) | |||
719 | return cap_inode_killpriv(dentry); | 720 | return cap_inode_killpriv(dentry); |
720 | } | 721 | } |
721 | 722 | ||
722 | static inline int security_inode_getsecurity(const struct inode *inode, const char *name, void **buffer, bool alloc) | 723 | static inline int security_inode_getsecurity(struct inode *inode, const char *name, void **buffer, bool alloc) |
723 | { | 724 | { |
724 | return -EOPNOTSUPP; | 725 | return -EOPNOTSUPP; |
725 | } | 726 | } |
@@ -734,7 +735,7 @@ static inline int security_inode_listsecurity(struct inode *inode, char *buffer, | |||
734 | return 0; | 735 | return 0; |
735 | } | 736 | } |
736 | 737 | ||
737 | static inline void security_inode_getsecid(const struct inode *inode, u32 *secid) | 738 | static inline void security_inode_getsecid(struct inode *inode, u32 *secid) |
738 | { | 739 | { |
739 | *secid = 0; | 740 | *secid = 0; |
740 | } | 741 | } |
@@ -1093,6 +1094,10 @@ static inline void security_release_secctx(char *secdata, u32 seclen) | |||
1093 | { | 1094 | { |
1094 | } | 1095 | } |
1095 | 1096 | ||
1097 | static inline void security_inode_invalidate_secctx(struct inode *inode) | ||
1098 | { | ||
1099 | } | ||
1100 | |||
1096 | static inline int security_inode_notifysecctx(struct inode *inode, void *ctx, u32 ctxlen) | 1101 | static inline int security_inode_notifysecctx(struct inode *inode, void *ctx, u32 ctxlen) |
1097 | { | 1102 | { |
1098 | return -EOPNOTSUPP; | 1103 | return -EOPNOTSUPP; |
diff --git a/include/uapi/linux/hash_info.h b/include/uapi/linux/hash_info.h index ca18c45f8304..ebf8fd885dd5 100644 --- a/include/uapi/linux/hash_info.h +++ b/include/uapi/linux/hash_info.h | |||
@@ -31,6 +31,7 @@ enum hash_algo { | |||
31 | HASH_ALGO_TGR_128, | 31 | HASH_ALGO_TGR_128, |
32 | HASH_ALGO_TGR_160, | 32 | HASH_ALGO_TGR_160, |
33 | HASH_ALGO_TGR_192, | 33 | HASH_ALGO_TGR_192, |
34 | HASH_ALGO_SM3_256, | ||
34 | HASH_ALGO__LAST | 35 | HASH_ALGO__LAST |
35 | }; | 36 | }; |
36 | 37 | ||
diff --git a/kernel/audit.c b/kernel/audit.c index d6dd95cc59e6..3a3e5deeda8d 100644 --- a/kernel/audit.c +++ b/kernel/audit.c | |||
@@ -1719,7 +1719,7 @@ static inline int audit_copy_fcaps(struct audit_names *name, | |||
1719 | 1719 | ||
1720 | /* Copy inode data into an audit_names. */ | 1720 | /* Copy inode data into an audit_names. */ |
1721 | void audit_copy_inode(struct audit_names *name, const struct dentry *dentry, | 1721 | void audit_copy_inode(struct audit_names *name, const struct dentry *dentry, |
1722 | const struct inode *inode) | 1722 | struct inode *inode) |
1723 | { | 1723 | { |
1724 | name->ino = inode->i_ino; | 1724 | name->ino = inode->i_ino; |
1725 | name->dev = inode->i_sb->s_dev; | 1725 | name->dev = inode->i_sb->s_dev; |
diff --git a/kernel/audit.h b/kernel/audit.h index de6cbb7cf547..cbbe6bb6496e 100644 --- a/kernel/audit.h +++ b/kernel/audit.h | |||
@@ -207,7 +207,7 @@ extern u32 audit_ever_enabled; | |||
207 | 207 | ||
208 | extern void audit_copy_inode(struct audit_names *name, | 208 | extern void audit_copy_inode(struct audit_names *name, |
209 | const struct dentry *dentry, | 209 | const struct dentry *dentry, |
210 | const struct inode *inode); | 210 | struct inode *inode); |
211 | extern void audit_log_cap(struct audit_buffer *ab, char *prefix, | 211 | extern void audit_log_cap(struct audit_buffer *ab, char *prefix, |
212 | kernel_cap_t *cap); | 212 | kernel_cap_t *cap); |
213 | extern void audit_log_name(struct audit_context *context, | 213 | extern void audit_log_name(struct audit_context *context, |
diff --git a/kernel/auditsc.c b/kernel/auditsc.c index b86cc04959de..195ffaee50b9 100644 --- a/kernel/auditsc.c +++ b/kernel/auditsc.c | |||
@@ -1754,7 +1754,7 @@ void __audit_inode(struct filename *name, const struct dentry *dentry, | |||
1754 | unsigned int flags) | 1754 | unsigned int flags) |
1755 | { | 1755 | { |
1756 | struct audit_context *context = current->audit_context; | 1756 | struct audit_context *context = current->audit_context; |
1757 | const struct inode *inode = d_backing_inode(dentry); | 1757 | struct inode *inode = d_backing_inode(dentry); |
1758 | struct audit_names *n; | 1758 | struct audit_names *n; |
1759 | bool parent = flags & AUDIT_INODE_PARENT; | 1759 | bool parent = flags & AUDIT_INODE_PARENT; |
1760 | 1760 | ||
@@ -1848,12 +1848,12 @@ void __audit_file(const struct file *file) | |||
1848 | * must be hooked prior, in order to capture the target inode during | 1848 | * must be hooked prior, in order to capture the target inode during |
1849 | * unsuccessful attempts. | 1849 | * unsuccessful attempts. |
1850 | */ | 1850 | */ |
1851 | void __audit_inode_child(const struct inode *parent, | 1851 | void __audit_inode_child(struct inode *parent, |
1852 | const struct dentry *dentry, | 1852 | const struct dentry *dentry, |
1853 | const unsigned char type) | 1853 | const unsigned char type) |
1854 | { | 1854 | { |
1855 | struct audit_context *context = current->audit_context; | 1855 | struct audit_context *context = current->audit_context; |
1856 | const struct inode *inode = d_backing_inode(dentry); | 1856 | struct inode *inode = d_backing_inode(dentry); |
1857 | const char *dname = dentry->d_name.name; | 1857 | const char *dname = dentry->d_name.name; |
1858 | struct audit_names *n, *found_parent = NULL, *found_child = NULL; | 1858 | struct audit_names *n, *found_parent = NULL, *found_child = NULL; |
1859 | 1859 | ||
diff --git a/security/integrity/Kconfig b/security/integrity/Kconfig index 73c457bf5a4a..21d756832b75 100644 --- a/security/integrity/Kconfig +++ b/security/integrity/Kconfig | |||
@@ -41,6 +41,17 @@ config INTEGRITY_ASYMMETRIC_KEYS | |||
41 | This option enables digital signature verification using | 41 | This option enables digital signature verification using |
42 | asymmetric keys. | 42 | asymmetric keys. |
43 | 43 | ||
44 | config INTEGRITY_TRUSTED_KEYRING | ||
45 | bool "Require all keys on the integrity keyrings be signed" | ||
46 | depends on SYSTEM_TRUSTED_KEYRING | ||
47 | depends on INTEGRITY_ASYMMETRIC_KEYS | ||
48 | select KEYS_DEBUG_PROC_KEYS | ||
49 | default y | ||
50 | help | ||
51 | This option requires that all keys added to the .ima and | ||
52 | .evm keyrings be signed by a key on the system trusted | ||
53 | keyring. | ||
54 | |||
44 | config INTEGRITY_AUDIT | 55 | config INTEGRITY_AUDIT |
45 | bool "Enables integrity auditing support " | 56 | bool "Enables integrity auditing support " |
46 | depends on AUDIT | 57 | depends on AUDIT |
diff --git a/security/integrity/digsig.c b/security/integrity/digsig.c index 5be9ffbe90ba..8ef15118cc78 100644 --- a/security/integrity/digsig.c +++ b/security/integrity/digsig.c | |||
@@ -24,15 +24,22 @@ | |||
24 | static struct key *keyring[INTEGRITY_KEYRING_MAX]; | 24 | static struct key *keyring[INTEGRITY_KEYRING_MAX]; |
25 | 25 | ||
26 | static const char *keyring_name[INTEGRITY_KEYRING_MAX] = { | 26 | static const char *keyring_name[INTEGRITY_KEYRING_MAX] = { |
27 | #ifndef CONFIG_INTEGRITY_TRUSTED_KEYRING | ||
27 | "_evm", | 28 | "_evm", |
28 | "_module", | ||
29 | #ifndef CONFIG_IMA_TRUSTED_KEYRING | ||
30 | "_ima", | 29 | "_ima", |
31 | #else | 30 | #else |
31 | ".evm", | ||
32 | ".ima", | 32 | ".ima", |
33 | #endif | 33 | #endif |
34 | "_module", | ||
34 | }; | 35 | }; |
35 | 36 | ||
37 | #ifdef CONFIG_INTEGRITY_TRUSTED_KEYRING | ||
38 | static bool init_keyring __initdata = true; | ||
39 | #else | ||
40 | static bool init_keyring __initdata; | ||
41 | #endif | ||
42 | |||
36 | int integrity_digsig_verify(const unsigned int id, const char *sig, int siglen, | 43 | int integrity_digsig_verify(const unsigned int id, const char *sig, int siglen, |
37 | const char *digest, int digestlen) | 44 | const char *digest, int digestlen) |
38 | { | 45 | { |
@@ -68,6 +75,9 @@ int __init integrity_init_keyring(const unsigned int id) | |||
68 | const struct cred *cred = current_cred(); | 75 | const struct cred *cred = current_cred(); |
69 | int err = 0; | 76 | int err = 0; |
70 | 77 | ||
78 | if (!init_keyring) | ||
79 | return 0; | ||
80 | |||
71 | keyring[id] = keyring_alloc(keyring_name[id], KUIDT_INIT(0), | 81 | keyring[id] = keyring_alloc(keyring_name[id], KUIDT_INIT(0), |
72 | KGIDT_INIT(0), cred, | 82 | KGIDT_INIT(0), cred, |
73 | ((KEY_POS_ALL & ~KEY_POS_SETATTR) | | 83 | ((KEY_POS_ALL & ~KEY_POS_SETATTR) | |
diff --git a/security/integrity/digsig_asymmetric.c b/security/integrity/digsig_asymmetric.c index 4fec1816a2b3..5ade2a7517a6 100644 --- a/security/integrity/digsig_asymmetric.c +++ b/security/integrity/digsig_asymmetric.c | |||
@@ -17,6 +17,7 @@ | |||
17 | #include <linux/key-type.h> | 17 | #include <linux/key-type.h> |
18 | #include <crypto/public_key.h> | 18 | #include <crypto/public_key.h> |
19 | #include <keys/asymmetric-type.h> | 19 | #include <keys/asymmetric-type.h> |
20 | #include <keys/system_keyring.h> | ||
20 | 21 | ||
21 | #include "integrity.h" | 22 | #include "integrity.h" |
22 | 23 | ||
@@ -32,9 +33,22 @@ static struct key *request_asymmetric_key(struct key *keyring, uint32_t keyid) | |||
32 | 33 | ||
33 | pr_debug("key search: \"%s\"\n", name); | 34 | pr_debug("key search: \"%s\"\n", name); |
34 | 35 | ||
36 | key = get_ima_blacklist_keyring(); | ||
37 | if (key) { | ||
38 | key_ref_t kref; | ||
39 | |||
40 | kref = keyring_search(make_key_ref(key, 1), | ||
41 | &key_type_asymmetric, name); | ||
42 | if (!IS_ERR(kref)) { | ||
43 | pr_err("Key '%s' is in ima_blacklist_keyring\n", name); | ||
44 | return ERR_PTR(-EKEYREJECTED); | ||
45 | } | ||
46 | } | ||
47 | |||
35 | if (keyring) { | 48 | if (keyring) { |
36 | /* search in specific keyring */ | 49 | /* search in specific keyring */ |
37 | key_ref_t kref; | 50 | key_ref_t kref; |
51 | |||
38 | kref = keyring_search(make_key_ref(keyring, 1), | 52 | kref = keyring_search(make_key_ref(keyring, 1), |
39 | &key_type_asymmetric, name); | 53 | &key_type_asymmetric, name); |
40 | if (IS_ERR(kref)) | 54 | if (IS_ERR(kref)) |
diff --git a/security/integrity/evm/Kconfig b/security/integrity/evm/Kconfig index bf19723cf117..e825e0ae78e7 100644 --- a/security/integrity/evm/Kconfig +++ b/security/integrity/evm/Kconfig | |||
@@ -42,3 +42,20 @@ config EVM_EXTRA_SMACK_XATTRS | |||
42 | additional info to the calculation, requires existing EVM | 42 | additional info to the calculation, requires existing EVM |
43 | labeled file systems to be relabeled. | 43 | labeled file systems to be relabeled. |
44 | 44 | ||
45 | config EVM_LOAD_X509 | ||
46 | bool "Load an X509 certificate onto the '.evm' trusted keyring" | ||
47 | depends on EVM && INTEGRITY_TRUSTED_KEYRING | ||
48 | default n | ||
49 | help | ||
50 | Load an X509 certificate onto the '.evm' trusted keyring. | ||
51 | |||
52 | This option enables X509 certificate loading from the kernel | ||
53 | onto the '.evm' trusted keyring. A public key can be used to | ||
54 | verify EVM integrity starting from the 'init' process. | ||
55 | |||
56 | config EVM_X509_PATH | ||
57 | string "EVM X509 certificate path" | ||
58 | depends on EVM_LOAD_X509 | ||
59 | default "/etc/keys/x509_evm.der" | ||
60 | help | ||
61 | This option defines X509 certificate path. | ||
diff --git a/security/integrity/evm/evm.h b/security/integrity/evm/evm.h index 88bfe77efa1c..f5f12727771a 100644 --- a/security/integrity/evm/evm.h +++ b/security/integrity/evm/evm.h | |||
@@ -21,6 +21,9 @@ | |||
21 | 21 | ||
22 | #include "../integrity.h" | 22 | #include "../integrity.h" |
23 | 23 | ||
24 | #define EVM_INIT_HMAC 0x0001 | ||
25 | #define EVM_INIT_X509 0x0002 | ||
26 | |||
24 | extern int evm_initialized; | 27 | extern int evm_initialized; |
25 | extern char *evm_hmac; | 28 | extern char *evm_hmac; |
26 | extern char *evm_hash; | 29 | extern char *evm_hash; |
diff --git a/security/integrity/evm/evm_crypto.c b/security/integrity/evm/evm_crypto.c index 461f8d891579..30b6b7d0429f 100644 --- a/security/integrity/evm/evm_crypto.c +++ b/security/integrity/evm/evm_crypto.c | |||
@@ -18,6 +18,7 @@ | |||
18 | #include <linux/module.h> | 18 | #include <linux/module.h> |
19 | #include <linux/crypto.h> | 19 | #include <linux/crypto.h> |
20 | #include <linux/xattr.h> | 20 | #include <linux/xattr.h> |
21 | #include <linux/evm.h> | ||
21 | #include <keys/encrypted-type.h> | 22 | #include <keys/encrypted-type.h> |
22 | #include <crypto/hash.h> | 23 | #include <crypto/hash.h> |
23 | #include "evm.h" | 24 | #include "evm.h" |
@@ -32,6 +33,44 @@ struct crypto_shash *hash_tfm; | |||
32 | 33 | ||
33 | static DEFINE_MUTEX(mutex); | 34 | static DEFINE_MUTEX(mutex); |
34 | 35 | ||
36 | #define EVM_SET_KEY_BUSY 0 | ||
37 | |||
38 | static unsigned long evm_set_key_flags; | ||
39 | |||
40 | /** | ||
41 | * evm_set_key() - set EVM HMAC key from the kernel | ||
42 | * @key: pointer to a buffer with the key data | ||
43 | * @size: length of the key data | ||
44 | * | ||
45 | * This function allows setting the EVM HMAC key from the kernel | ||
46 | * without using the "encrypted" key subsystem keys. It can be used | ||
47 | * by the crypto HW kernel module which has its own way of managing | ||
48 | * keys. | ||
49 | * | ||
50 | * key length should be between 32 and 128 bytes long | ||
51 | */ | ||
52 | int evm_set_key(void *key, size_t keylen) | ||
53 | { | ||
54 | int rc; | ||
55 | |||
56 | rc = -EBUSY; | ||
57 | if (test_and_set_bit(EVM_SET_KEY_BUSY, &evm_set_key_flags)) | ||
58 | goto busy; | ||
59 | rc = -EINVAL; | ||
60 | if (keylen > MAX_KEY_SIZE) | ||
61 | goto inval; | ||
62 | memcpy(evmkey, key, keylen); | ||
63 | evm_initialized |= EVM_INIT_HMAC; | ||
64 | pr_info("key initialized\n"); | ||
65 | return 0; | ||
66 | inval: | ||
67 | clear_bit(EVM_SET_KEY_BUSY, &evm_set_key_flags); | ||
68 | busy: | ||
69 | pr_err("key initialization failed\n"); | ||
70 | return rc; | ||
71 | } | ||
72 | EXPORT_SYMBOL_GPL(evm_set_key); | ||
73 | |||
35 | static struct shash_desc *init_desc(char type) | 74 | static struct shash_desc *init_desc(char type) |
36 | { | 75 | { |
37 | long rc; | 76 | long rc; |
@@ -40,6 +79,10 @@ static struct shash_desc *init_desc(char type) | |||
40 | struct shash_desc *desc; | 79 | struct shash_desc *desc; |
41 | 80 | ||
42 | if (type == EVM_XATTR_HMAC) { | 81 | if (type == EVM_XATTR_HMAC) { |
82 | if (!(evm_initialized & EVM_INIT_HMAC)) { | ||
83 | pr_err("HMAC key is not set\n"); | ||
84 | return ERR_PTR(-ENOKEY); | ||
85 | } | ||
43 | tfm = &hmac_tfm; | 86 | tfm = &hmac_tfm; |
44 | algo = evm_hmac; | 87 | algo = evm_hmac; |
45 | } else { | 88 | } else { |
@@ -240,7 +283,7 @@ int evm_init_key(void) | |||
240 | { | 283 | { |
241 | struct key *evm_key; | 284 | struct key *evm_key; |
242 | struct encrypted_key_payload *ekp; | 285 | struct encrypted_key_payload *ekp; |
243 | int rc = 0; | 286 | int rc; |
244 | 287 | ||
245 | evm_key = request_key(&key_type_encrypted, EVMKEY, NULL); | 288 | evm_key = request_key(&key_type_encrypted, EVMKEY, NULL); |
246 | if (IS_ERR(evm_key)) | 289 | if (IS_ERR(evm_key)) |
@@ -248,12 +291,9 @@ int evm_init_key(void) | |||
248 | 291 | ||
249 | down_read(&evm_key->sem); | 292 | down_read(&evm_key->sem); |
250 | ekp = evm_key->payload.data[0]; | 293 | ekp = evm_key->payload.data[0]; |
251 | if (ekp->decrypted_datalen > MAX_KEY_SIZE) { | 294 | |
252 | rc = -EINVAL; | 295 | rc = evm_set_key(ekp->decrypted_data, ekp->decrypted_datalen); |
253 | goto out; | 296 | |
254 | } | ||
255 | memcpy(evmkey, ekp->decrypted_data, ekp->decrypted_datalen); | ||
256 | out: | ||
257 | /* burn the original key contents */ | 297 | /* burn the original key contents */ |
258 | memset(ekp->decrypted_data, 0, ekp->decrypted_datalen); | 298 | memset(ekp->decrypted_data, 0, ekp->decrypted_datalen); |
259 | up_read(&evm_key->sem); | 299 | up_read(&evm_key->sem); |
diff --git a/security/integrity/evm/evm_main.c b/security/integrity/evm/evm_main.c index 1334e02ae8f4..f7160253f17f 100644 --- a/security/integrity/evm/evm_main.c +++ b/security/integrity/evm/evm_main.c | |||
@@ -358,6 +358,15 @@ int evm_inode_removexattr(struct dentry *dentry, const char *xattr_name) | |||
358 | return evm_protect_xattr(dentry, xattr_name, NULL, 0); | 358 | return evm_protect_xattr(dentry, xattr_name, NULL, 0); |
359 | } | 359 | } |
360 | 360 | ||
361 | static void evm_reset_status(struct inode *inode) | ||
362 | { | ||
363 | struct integrity_iint_cache *iint; | ||
364 | |||
365 | iint = integrity_iint_find(inode); | ||
366 | if (iint) | ||
367 | iint->evm_status = INTEGRITY_UNKNOWN; | ||
368 | } | ||
369 | |||
361 | /** | 370 | /** |
362 | * evm_inode_post_setxattr - update 'security.evm' to reflect the changes | 371 | * evm_inode_post_setxattr - update 'security.evm' to reflect the changes |
363 | * @dentry: pointer to the affected dentry | 372 | * @dentry: pointer to the affected dentry |
@@ -378,6 +387,8 @@ void evm_inode_post_setxattr(struct dentry *dentry, const char *xattr_name, | |||
378 | && !posix_xattr_acl(xattr_name))) | 387 | && !posix_xattr_acl(xattr_name))) |
379 | return; | 388 | return; |
380 | 389 | ||
390 | evm_reset_status(dentry->d_inode); | ||
391 | |||
381 | evm_update_evmxattr(dentry, xattr_name, xattr_value, xattr_value_len); | 392 | evm_update_evmxattr(dentry, xattr_name, xattr_value, xattr_value_len); |
382 | } | 393 | } |
383 | 394 | ||
@@ -396,6 +407,8 @@ void evm_inode_post_removexattr(struct dentry *dentry, const char *xattr_name) | |||
396 | if (!evm_initialized || !evm_protected_xattr(xattr_name)) | 407 | if (!evm_initialized || !evm_protected_xattr(xattr_name)) |
397 | return; | 408 | return; |
398 | 409 | ||
410 | evm_reset_status(dentry->d_inode); | ||
411 | |||
399 | evm_update_evmxattr(dentry, xattr_name, NULL, 0); | 412 | evm_update_evmxattr(dentry, xattr_name, NULL, 0); |
400 | } | 413 | } |
401 | 414 | ||
@@ -472,21 +485,34 @@ out: | |||
472 | } | 485 | } |
473 | EXPORT_SYMBOL_GPL(evm_inode_init_security); | 486 | EXPORT_SYMBOL_GPL(evm_inode_init_security); |
474 | 487 | ||
488 | #ifdef CONFIG_EVM_LOAD_X509 | ||
489 | void __init evm_load_x509(void) | ||
490 | { | ||
491 | int rc; | ||
492 | |||
493 | rc = integrity_load_x509(INTEGRITY_KEYRING_EVM, CONFIG_EVM_X509_PATH); | ||
494 | if (!rc) | ||
495 | evm_initialized |= EVM_INIT_X509; | ||
496 | } | ||
497 | #endif | ||
498 | |||
475 | static int __init init_evm(void) | 499 | static int __init init_evm(void) |
476 | { | 500 | { |
477 | int error; | 501 | int error; |
478 | 502 | ||
479 | evm_init_config(); | 503 | evm_init_config(); |
480 | 504 | ||
505 | error = integrity_init_keyring(INTEGRITY_KEYRING_EVM); | ||
506 | if (error) | ||
507 | return error; | ||
508 | |||
481 | error = evm_init_secfs(); | 509 | error = evm_init_secfs(); |
482 | if (error < 0) { | 510 | if (error < 0) { |
483 | pr_info("Error registering secfs\n"); | 511 | pr_info("Error registering secfs\n"); |
484 | goto err; | 512 | return error; |
485 | } | 513 | } |
486 | 514 | ||
487 | return 0; | 515 | return 0; |
488 | err: | ||
489 | return error; | ||
490 | } | 516 | } |
491 | 517 | ||
492 | /* | 518 | /* |
diff --git a/security/integrity/evm/evm_secfs.c b/security/integrity/evm/evm_secfs.c index cf12a04717d3..c8dccd54d501 100644 --- a/security/integrity/evm/evm_secfs.c +++ b/security/integrity/evm/evm_secfs.c | |||
@@ -62,9 +62,9 @@ static ssize_t evm_write_key(struct file *file, const char __user *buf, | |||
62 | size_t count, loff_t *ppos) | 62 | size_t count, loff_t *ppos) |
63 | { | 63 | { |
64 | char temp[80]; | 64 | char temp[80]; |
65 | int i, error; | 65 | int i; |
66 | 66 | ||
67 | if (!capable(CAP_SYS_ADMIN) || evm_initialized) | 67 | if (!capable(CAP_SYS_ADMIN) || (evm_initialized & EVM_INIT_HMAC)) |
68 | return -EPERM; | 68 | return -EPERM; |
69 | 69 | ||
70 | if (count >= sizeof(temp) || count == 0) | 70 | if (count >= sizeof(temp) || count == 0) |
@@ -78,12 +78,8 @@ static ssize_t evm_write_key(struct file *file, const char __user *buf, | |||
78 | if ((sscanf(temp, "%d", &i) != 1) || (i != 1)) | 78 | if ((sscanf(temp, "%d", &i) != 1) || (i != 1)) |
79 | return -EINVAL; | 79 | return -EINVAL; |
80 | 80 | ||
81 | error = evm_init_key(); | 81 | evm_init_key(); |
82 | if (!error) { | 82 | |
83 | evm_initialized = 1; | ||
84 | pr_info("initialized\n"); | ||
85 | } else | ||
86 | pr_err("initialization failed\n"); | ||
87 | return count; | 83 | return count; |
88 | } | 84 | } |
89 | 85 | ||
diff --git a/security/integrity/iint.c b/security/integrity/iint.c index c2e3ccd4b510..8f1ab37f2897 100644 --- a/security/integrity/iint.c +++ b/security/integrity/iint.c | |||
@@ -255,4 +255,5 @@ out: | |||
255 | void __init integrity_load_keys(void) | 255 | void __init integrity_load_keys(void) |
256 | { | 256 | { |
257 | ima_load_x509(); | 257 | ima_load_x509(); |
258 | evm_load_x509(); | ||
258 | } | 259 | } |
diff --git a/security/integrity/ima/Kconfig b/security/integrity/ima/Kconfig index df303346029b..e54a8a8dae94 100644 --- a/security/integrity/ima/Kconfig +++ b/security/integrity/ima/Kconfig | |||
@@ -107,6 +107,27 @@ config IMA_DEFAULT_HASH | |||
107 | default "sha512" if IMA_DEFAULT_HASH_SHA512 | 107 | default "sha512" if IMA_DEFAULT_HASH_SHA512 |
108 | default "wp512" if IMA_DEFAULT_HASH_WP512 | 108 | default "wp512" if IMA_DEFAULT_HASH_WP512 |
109 | 109 | ||
110 | config IMA_WRITE_POLICY | ||
111 | bool "Enable multiple writes to the IMA policy" | ||
112 | depends on IMA | ||
113 | default n | ||
114 | help | ||
115 | IMA policy can now be updated multiple times. The new rules get | ||
116 | appended to the original policy. Have in mind that the rules are | ||
117 | scanned in FIFO order so be careful when you design and add new ones. | ||
118 | |||
119 | If unsure, say N. | ||
120 | |||
121 | config IMA_READ_POLICY | ||
122 | bool "Enable reading back the current IMA policy" | ||
123 | depends on IMA | ||
124 | default y if IMA_WRITE_POLICY | ||
125 | default n if !IMA_WRITE_POLICY | ||
126 | help | ||
127 | It is often useful to be able to read back the IMA policy. It is | ||
128 | even more important after introducing CONFIG_IMA_WRITE_POLICY. | ||
129 | This option allows the root user to see the current policy rules. | ||
130 | |||
110 | config IMA_APPRAISE | 131 | config IMA_APPRAISE |
111 | bool "Appraise integrity measurements" | 132 | bool "Appraise integrity measurements" |
112 | depends on IMA | 133 | depends on IMA |
@@ -123,14 +144,35 @@ config IMA_APPRAISE | |||
123 | If unsure, say N. | 144 | If unsure, say N. |
124 | 145 | ||
125 | config IMA_TRUSTED_KEYRING | 146 | config IMA_TRUSTED_KEYRING |
126 | bool "Require all keys on the .ima keyring be signed" | 147 | bool "Require all keys on the .ima keyring be signed (deprecated)" |
127 | depends on IMA_APPRAISE && SYSTEM_TRUSTED_KEYRING | 148 | depends on IMA_APPRAISE && SYSTEM_TRUSTED_KEYRING |
128 | depends on INTEGRITY_ASYMMETRIC_KEYS | 149 | depends on INTEGRITY_ASYMMETRIC_KEYS |
150 | select INTEGRITY_TRUSTED_KEYRING | ||
129 | default y | 151 | default y |
130 | help | 152 | help |
131 | This option requires that all keys added to the .ima | 153 | This option requires that all keys added to the .ima |
132 | keyring be signed by a key on the system trusted keyring. | 154 | keyring be signed by a key on the system trusted keyring. |
133 | 155 | ||
156 | This option is deprecated in favor of INTEGRITY_TRUSTED_KEYRING | ||
157 | |||
158 | config IMA_MOK_KEYRING | ||
159 | bool "Create IMA machine owner keys (MOK) and blacklist keyrings" | ||
160 | depends on SYSTEM_TRUSTED_KEYRING | ||
161 | depends on IMA_TRUSTED_KEYRING | ||
162 | default n | ||
163 | help | ||
164 | This option creates IMA MOK and blacklist keyrings. IMA MOK is an | ||
165 | intermediate keyring that sits between .system and .ima keyrings, | ||
166 | effectively forming a simple CA hierarchy. To successfully import a | ||
167 | key into .ima_mok it must be signed by a key which CA is in .system | ||
168 | keyring. On turn any key that needs to go in .ima keyring must be | ||
169 | signed by CA in either .system or .ima_mok keyrings. IMA MOK is empty | ||
170 | at kernel boot. | ||
171 | |||
172 | IMA blacklist keyring contains all revoked IMA keys. It is consulted | ||
173 | before any other keyring. If the search is successful the requested | ||
174 | operation is rejected and error is returned to the caller. | ||
175 | |||
134 | config IMA_LOAD_X509 | 176 | config IMA_LOAD_X509 |
135 | bool "Load X509 certificate onto the '.ima' trusted keyring" | 177 | bool "Load X509 certificate onto the '.ima' trusted keyring" |
136 | depends on IMA_TRUSTED_KEYRING | 178 | depends on IMA_TRUSTED_KEYRING |
diff --git a/security/integrity/ima/Makefile b/security/integrity/ima/Makefile index d79263d2fdbf..a8539f9e060f 100644 --- a/security/integrity/ima/Makefile +++ b/security/integrity/ima/Makefile | |||
@@ -8,3 +8,4 @@ obj-$(CONFIG_IMA) += ima.o | |||
8 | ima-y := ima_fs.o ima_queue.o ima_init.o ima_main.o ima_crypto.o ima_api.o \ | 8 | ima-y := ima_fs.o ima_queue.o ima_init.o ima_main.o ima_crypto.o ima_api.o \ |
9 | ima_policy.o ima_template.o ima_template_lib.o | 9 | ima_policy.o ima_template.o ima_template_lib.o |
10 | ima-$(CONFIG_IMA_APPRAISE) += ima_appraise.o | 10 | ima-$(CONFIG_IMA_APPRAISE) += ima_appraise.o |
11 | obj-$(CONFIG_IMA_MOK_KEYRING) += ima_mok.o | ||
diff --git a/security/integrity/ima/ima.h b/security/integrity/ima/ima.h index e2a60c30df44..585af61ed399 100644 --- a/security/integrity/ima/ima.h +++ b/security/integrity/ima/ima.h | |||
@@ -166,6 +166,11 @@ void ima_update_policy(void); | |||
166 | void ima_update_policy_flag(void); | 166 | void ima_update_policy_flag(void); |
167 | ssize_t ima_parse_add_rule(char *); | 167 | ssize_t ima_parse_add_rule(char *); |
168 | void ima_delete_rules(void); | 168 | void ima_delete_rules(void); |
169 | int ima_check_policy(void); | ||
170 | void *ima_policy_start(struct seq_file *m, loff_t *pos); | ||
171 | void *ima_policy_next(struct seq_file *m, void *v, loff_t *pos); | ||
172 | void ima_policy_stop(struct seq_file *m, void *v); | ||
173 | int ima_policy_show(struct seq_file *m, void *v); | ||
169 | 174 | ||
170 | /* Appraise integrity measurements */ | 175 | /* Appraise integrity measurements */ |
171 | #define IMA_APPRAISE_ENFORCE 0x01 | 176 | #define IMA_APPRAISE_ENFORCE 0x01 |
@@ -250,17 +255,12 @@ static inline int security_filter_rule_match(u32 secid, u32 field, u32 op, | |||
250 | { | 255 | { |
251 | return -EINVAL; | 256 | return -EINVAL; |
252 | } | 257 | } |
253 | #endif /* CONFIG_IMA_LSM_RULES */ | 258 | #endif /* CONFIG_IMA_TRUSTED_KEYRING */ |
254 | 259 | ||
255 | #ifdef CONFIG_IMA_TRUSTED_KEYRING | 260 | #ifdef CONFIG_IMA_READ_POLICY |
256 | static inline int ima_init_keyring(const unsigned int id) | 261 | #define POLICY_FILE_FLAGS (S_IWUSR | S_IRUSR) |
257 | { | ||
258 | return integrity_init_keyring(id); | ||
259 | } | ||
260 | #else | 262 | #else |
261 | static inline int ima_init_keyring(const unsigned int id) | 263 | #define POLICY_FILE_FLAGS S_IWUSR |
262 | { | 264 | #endif /* CONFIG_IMA_WRITE_POLICY */ |
263 | return 0; | 265 | |
264 | } | 266 | #endif /* __LINUX_IMA_H */ |
265 | #endif /* CONFIG_IMA_TRUSTED_KEYRING */ | ||
266 | #endif | ||
diff --git a/security/integrity/ima/ima_fs.c b/security/integrity/ima/ima_fs.c index 816d175da79a..f355231997b4 100644 --- a/security/integrity/ima/ima_fs.c +++ b/security/integrity/ima/ima_fs.c | |||
@@ -25,6 +25,8 @@ | |||
25 | 25 | ||
26 | #include "ima.h" | 26 | #include "ima.h" |
27 | 27 | ||
28 | static DEFINE_MUTEX(ima_write_mutex); | ||
29 | |||
28 | static int valid_policy = 1; | 30 | static int valid_policy = 1; |
29 | #define TMPBUFLEN 12 | 31 | #define TMPBUFLEN 12 |
30 | static ssize_t ima_show_htable_value(char __user *buf, size_t count, | 32 | static ssize_t ima_show_htable_value(char __user *buf, size_t count, |
@@ -259,7 +261,7 @@ static const struct file_operations ima_ascii_measurements_ops = { | |||
259 | static ssize_t ima_write_policy(struct file *file, const char __user *buf, | 261 | static ssize_t ima_write_policy(struct file *file, const char __user *buf, |
260 | size_t datalen, loff_t *ppos) | 262 | size_t datalen, loff_t *ppos) |
261 | { | 263 | { |
262 | char *data = NULL; | 264 | char *data; |
263 | ssize_t result; | 265 | ssize_t result; |
264 | 266 | ||
265 | if (datalen >= PAGE_SIZE) | 267 | if (datalen >= PAGE_SIZE) |
@@ -279,13 +281,20 @@ static ssize_t ima_write_policy(struct file *file, const char __user *buf, | |||
279 | 281 | ||
280 | result = -EFAULT; | 282 | result = -EFAULT; |
281 | if (copy_from_user(data, buf, datalen)) | 283 | if (copy_from_user(data, buf, datalen)) |
282 | goto out; | 284 | goto out_free; |
283 | 285 | ||
286 | result = mutex_lock_interruptible(&ima_write_mutex); | ||
287 | if (result < 0) | ||
288 | goto out_free; | ||
284 | result = ima_parse_add_rule(data); | 289 | result = ima_parse_add_rule(data); |
290 | mutex_unlock(&ima_write_mutex); | ||
291 | |||
292 | out_free: | ||
293 | kfree(data); | ||
285 | out: | 294 | out: |
286 | if (result < 0) | 295 | if (result < 0) |
287 | valid_policy = 0; | 296 | valid_policy = 0; |
288 | kfree(data); | 297 | |
289 | return result; | 298 | return result; |
290 | } | 299 | } |
291 | 300 | ||
@@ -302,14 +311,31 @@ enum ima_fs_flags { | |||
302 | 311 | ||
303 | static unsigned long ima_fs_flags; | 312 | static unsigned long ima_fs_flags; |
304 | 313 | ||
314 | #ifdef CONFIG_IMA_READ_POLICY | ||
315 | static const struct seq_operations ima_policy_seqops = { | ||
316 | .start = ima_policy_start, | ||
317 | .next = ima_policy_next, | ||
318 | .stop = ima_policy_stop, | ||
319 | .show = ima_policy_show, | ||
320 | }; | ||
321 | #endif | ||
322 | |||
305 | /* | 323 | /* |
306 | * ima_open_policy: sequentialize access to the policy file | 324 | * ima_open_policy: sequentialize access to the policy file |
307 | */ | 325 | */ |
308 | static int ima_open_policy(struct inode *inode, struct file *filp) | 326 | static int ima_open_policy(struct inode *inode, struct file *filp) |
309 | { | 327 | { |
310 | /* No point in being allowed to open it if you aren't going to write */ | 328 | if (!(filp->f_flags & O_WRONLY)) { |
311 | if (!(filp->f_flags & O_WRONLY)) | 329 | #ifndef CONFIG_IMA_READ_POLICY |
312 | return -EACCES; | 330 | return -EACCES; |
331 | #else | ||
332 | if ((filp->f_flags & O_ACCMODE) != O_RDONLY) | ||
333 | return -EACCES; | ||
334 | if (!capable(CAP_SYS_ADMIN)) | ||
335 | return -EPERM; | ||
336 | return seq_open(filp, &ima_policy_seqops); | ||
337 | #endif | ||
338 | } | ||
313 | if (test_and_set_bit(IMA_FS_BUSY, &ima_fs_flags)) | 339 | if (test_and_set_bit(IMA_FS_BUSY, &ima_fs_flags)) |
314 | return -EBUSY; | 340 | return -EBUSY; |
315 | return 0; | 341 | return 0; |
@@ -326,6 +352,14 @@ static int ima_release_policy(struct inode *inode, struct file *file) | |||
326 | { | 352 | { |
327 | const char *cause = valid_policy ? "completed" : "failed"; | 353 | const char *cause = valid_policy ? "completed" : "failed"; |
328 | 354 | ||
355 | if ((file->f_flags & O_ACCMODE) == O_RDONLY) | ||
356 | return 0; | ||
357 | |||
358 | if (valid_policy && ima_check_policy() < 0) { | ||
359 | cause = "failed"; | ||
360 | valid_policy = 0; | ||
361 | } | ||
362 | |||
329 | pr_info("IMA: policy update %s\n", cause); | 363 | pr_info("IMA: policy update %s\n", cause); |
330 | integrity_audit_msg(AUDIT_INTEGRITY_STATUS, NULL, NULL, | 364 | integrity_audit_msg(AUDIT_INTEGRITY_STATUS, NULL, NULL, |
331 | "policy_update", cause, !valid_policy, 0); | 365 | "policy_update", cause, !valid_policy, 0); |
@@ -336,15 +370,21 @@ static int ima_release_policy(struct inode *inode, struct file *file) | |||
336 | clear_bit(IMA_FS_BUSY, &ima_fs_flags); | 370 | clear_bit(IMA_FS_BUSY, &ima_fs_flags); |
337 | return 0; | 371 | return 0; |
338 | } | 372 | } |
373 | |||
339 | ima_update_policy(); | 374 | ima_update_policy(); |
375 | #ifndef CONFIG_IMA_WRITE_POLICY | ||
340 | securityfs_remove(ima_policy); | 376 | securityfs_remove(ima_policy); |
341 | ima_policy = NULL; | 377 | ima_policy = NULL; |
378 | #else | ||
379 | clear_bit(IMA_FS_BUSY, &ima_fs_flags); | ||
380 | #endif | ||
342 | return 0; | 381 | return 0; |
343 | } | 382 | } |
344 | 383 | ||
345 | static const struct file_operations ima_measure_policy_ops = { | 384 | static const struct file_operations ima_measure_policy_ops = { |
346 | .open = ima_open_policy, | 385 | .open = ima_open_policy, |
347 | .write = ima_write_policy, | 386 | .write = ima_write_policy, |
387 | .read = seq_read, | ||
348 | .release = ima_release_policy, | 388 | .release = ima_release_policy, |
349 | .llseek = generic_file_llseek, | 389 | .llseek = generic_file_llseek, |
350 | }; | 390 | }; |
@@ -382,8 +422,7 @@ int __init ima_fs_init(void) | |||
382 | if (IS_ERR(violations)) | 422 | if (IS_ERR(violations)) |
383 | goto out; | 423 | goto out; |
384 | 424 | ||
385 | ima_policy = securityfs_create_file("policy", | 425 | ima_policy = securityfs_create_file("policy", POLICY_FILE_FLAGS, |
386 | S_IWUSR, | ||
387 | ima_dir, NULL, | 426 | ima_dir, NULL, |
388 | &ima_measure_policy_ops); | 427 | &ima_measure_policy_ops); |
389 | if (IS_ERR(ima_policy)) | 428 | if (IS_ERR(ima_policy)) |
diff --git a/security/integrity/ima/ima_init.c b/security/integrity/ima/ima_init.c index e600cadd231c..bd79f254d204 100644 --- a/security/integrity/ima/ima_init.c +++ b/security/integrity/ima/ima_init.c | |||
@@ -116,7 +116,7 @@ int __init ima_init(void) | |||
116 | if (!ima_used_chip) | 116 | if (!ima_used_chip) |
117 | pr_info("No TPM chip found, activating TPM-bypass!\n"); | 117 | pr_info("No TPM chip found, activating TPM-bypass!\n"); |
118 | 118 | ||
119 | rc = ima_init_keyring(INTEGRITY_KEYRING_IMA); | 119 | rc = integrity_init_keyring(INTEGRITY_KEYRING_IMA); |
120 | if (rc) | 120 | if (rc) |
121 | return rc; | 121 | return rc; |
122 | 122 | ||
diff --git a/security/integrity/ima/ima_mok.c b/security/integrity/ima/ima_mok.c new file mode 100644 index 000000000000..676885e4320e --- /dev/null +++ b/security/integrity/ima/ima_mok.c | |||
@@ -0,0 +1,55 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2015 Juniper Networks, Inc. | ||
3 | * | ||
4 | * Author: | ||
5 | * Petko Manolov <petko.manolov@konsulko.com> | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or | ||
8 | * modify it under the terms of the GNU General Public License as | ||
9 | * published by the Free Software Foundation, version 2 of the | ||
10 | * License. | ||
11 | * | ||
12 | */ | ||
13 | |||
14 | #include <linux/export.h> | ||
15 | #include <linux/kernel.h> | ||
16 | #include <linux/sched.h> | ||
17 | #include <linux/cred.h> | ||
18 | #include <linux/err.h> | ||
19 | #include <linux/init.h> | ||
20 | #include <keys/asymmetric-type.h> | ||
21 | |||
22 | |||
23 | struct key *ima_mok_keyring; | ||
24 | struct key *ima_blacklist_keyring; | ||
25 | |||
26 | /* | ||
27 | * Allocate the IMA MOK and blacklist keyrings | ||
28 | */ | ||
29 | __init int ima_mok_init(void) | ||
30 | { | ||
31 | pr_notice("Allocating IMA MOK and blacklist keyrings.\n"); | ||
32 | |||
33 | ima_mok_keyring = keyring_alloc(".ima_mok", | ||
34 | KUIDT_INIT(0), KGIDT_INIT(0), current_cred(), | ||
35 | (KEY_POS_ALL & ~KEY_POS_SETATTR) | | ||
36 | KEY_USR_VIEW | KEY_USR_READ | | ||
37 | KEY_USR_WRITE | KEY_USR_SEARCH, | ||
38 | KEY_ALLOC_NOT_IN_QUOTA, NULL); | ||
39 | |||
40 | ima_blacklist_keyring = keyring_alloc(".ima_blacklist", | ||
41 | KUIDT_INIT(0), KGIDT_INIT(0), current_cred(), | ||
42 | (KEY_POS_ALL & ~KEY_POS_SETATTR) | | ||
43 | KEY_USR_VIEW | KEY_USR_READ | | ||
44 | KEY_USR_WRITE | KEY_USR_SEARCH, | ||
45 | KEY_ALLOC_NOT_IN_QUOTA, NULL); | ||
46 | |||
47 | if (IS_ERR(ima_mok_keyring) || IS_ERR(ima_blacklist_keyring)) | ||
48 | panic("Can't allocate IMA MOK or blacklist keyrings."); | ||
49 | set_bit(KEY_FLAG_TRUSTED_ONLY, &ima_mok_keyring->flags); | ||
50 | |||
51 | set_bit(KEY_FLAG_TRUSTED_ONLY, &ima_blacklist_keyring->flags); | ||
52 | set_bit(KEY_FLAG_KEEP, &ima_blacklist_keyring->flags); | ||
53 | return 0; | ||
54 | } | ||
55 | device_initcall(ima_mok_init); | ||
diff --git a/security/integrity/ima/ima_policy.c b/security/integrity/ima/ima_policy.c index 3997e206f82d..0a3b781f18e5 100644 --- a/security/integrity/ima/ima_policy.c +++ b/security/integrity/ima/ima_policy.c | |||
@@ -16,7 +16,9 @@ | |||
16 | #include <linux/magic.h> | 16 | #include <linux/magic.h> |
17 | #include <linux/parser.h> | 17 | #include <linux/parser.h> |
18 | #include <linux/slab.h> | 18 | #include <linux/slab.h> |
19 | #include <linux/rculist.h> | ||
19 | #include <linux/genhd.h> | 20 | #include <linux/genhd.h> |
21 | #include <linux/seq_file.h> | ||
20 | 22 | ||
21 | #include "ima.h" | 23 | #include "ima.h" |
22 | 24 | ||
@@ -38,6 +40,7 @@ | |||
38 | #define AUDIT 0x0040 | 40 | #define AUDIT 0x0040 |
39 | 41 | ||
40 | int ima_policy_flag; | 42 | int ima_policy_flag; |
43 | static int temp_ima_appraise; | ||
41 | 44 | ||
42 | #define MAX_LSM_RULES 6 | 45 | #define MAX_LSM_RULES 6 |
43 | enum lsm_rule_types { LSM_OBJ_USER, LSM_OBJ_ROLE, LSM_OBJ_TYPE, | 46 | enum lsm_rule_types { LSM_OBJ_USER, LSM_OBJ_ROLE, LSM_OBJ_TYPE, |
@@ -135,11 +138,11 @@ static struct ima_rule_entry default_appraise_rules[] = { | |||
135 | 138 | ||
136 | static LIST_HEAD(ima_default_rules); | 139 | static LIST_HEAD(ima_default_rules); |
137 | static LIST_HEAD(ima_policy_rules); | 140 | static LIST_HEAD(ima_policy_rules); |
141 | static LIST_HEAD(ima_temp_rules); | ||
138 | static struct list_head *ima_rules; | 142 | static struct list_head *ima_rules; |
139 | 143 | ||
140 | static DEFINE_MUTEX(ima_rules_mutex); | ||
141 | |||
142 | static int ima_policy __initdata; | 144 | static int ima_policy __initdata; |
145 | |||
143 | static int __init default_measure_policy_setup(char *str) | 146 | static int __init default_measure_policy_setup(char *str) |
144 | { | 147 | { |
145 | if (ima_policy) | 148 | if (ima_policy) |
@@ -171,21 +174,18 @@ static int __init default_appraise_policy_setup(char *str) | |||
171 | __setup("ima_appraise_tcb", default_appraise_policy_setup); | 174 | __setup("ima_appraise_tcb", default_appraise_policy_setup); |
172 | 175 | ||
173 | /* | 176 | /* |
174 | * Although the IMA policy does not change, the LSM policy can be | 177 | * The LSM policy can be reloaded, leaving the IMA LSM based rules referring |
175 | * reloaded, leaving the IMA LSM based rules referring to the old, | 178 | * to the old, stale LSM policy. Update the IMA LSM based rules to reflect |
176 | * stale LSM policy. | 179 | * the reloaded LSM policy. We assume the rules still exist; and BUG_ON() if |
177 | * | 180 | * they don't. |
178 | * Update the IMA LSM based rules to reflect the reloaded LSM policy. | ||
179 | * We assume the rules still exist; and BUG_ON() if they don't. | ||
180 | */ | 181 | */ |
181 | static void ima_lsm_update_rules(void) | 182 | static void ima_lsm_update_rules(void) |
182 | { | 183 | { |
183 | struct ima_rule_entry *entry, *tmp; | 184 | struct ima_rule_entry *entry; |
184 | int result; | 185 | int result; |
185 | int i; | 186 | int i; |
186 | 187 | ||
187 | mutex_lock(&ima_rules_mutex); | 188 | list_for_each_entry(entry, &ima_policy_rules, list) { |
188 | list_for_each_entry_safe(entry, tmp, &ima_policy_rules, list) { | ||
189 | for (i = 0; i < MAX_LSM_RULES; i++) { | 189 | for (i = 0; i < MAX_LSM_RULES; i++) { |
190 | if (!entry->lsm[i].rule) | 190 | if (!entry->lsm[i].rule) |
191 | continue; | 191 | continue; |
@@ -196,7 +196,6 @@ static void ima_lsm_update_rules(void) | |||
196 | BUG_ON(!entry->lsm[i].rule); | 196 | BUG_ON(!entry->lsm[i].rule); |
197 | } | 197 | } |
198 | } | 198 | } |
199 | mutex_unlock(&ima_rules_mutex); | ||
200 | } | 199 | } |
201 | 200 | ||
202 | /** | 201 | /** |
@@ -319,9 +318,9 @@ static int get_subaction(struct ima_rule_entry *rule, int func) | |||
319 | * Measure decision based on func/mask/fsmagic and LSM(subj/obj/type) | 318 | * Measure decision based on func/mask/fsmagic and LSM(subj/obj/type) |
320 | * conditions. | 319 | * conditions. |
321 | * | 320 | * |
322 | * (There is no need for locking when walking the policy list, | 321 | * Since the IMA policy may be updated multiple times we need to lock the |
323 | * as elements in the list are never deleted, nor does the list | 322 | * list when walking it. Reads are many orders of magnitude more numerous |
324 | * change.) | 323 | * than writes so ima_match_policy() is classical RCU candidate. |
325 | */ | 324 | */ |
326 | int ima_match_policy(struct inode *inode, enum ima_hooks func, int mask, | 325 | int ima_match_policy(struct inode *inode, enum ima_hooks func, int mask, |
327 | int flags) | 326 | int flags) |
@@ -329,7 +328,8 @@ int ima_match_policy(struct inode *inode, enum ima_hooks func, int mask, | |||
329 | struct ima_rule_entry *entry; | 328 | struct ima_rule_entry *entry; |
330 | int action = 0, actmask = flags | (flags << 1); | 329 | int action = 0, actmask = flags | (flags << 1); |
331 | 330 | ||
332 | list_for_each_entry(entry, ima_rules, list) { | 331 | rcu_read_lock(); |
332 | list_for_each_entry_rcu(entry, ima_rules, list) { | ||
333 | 333 | ||
334 | if (!(entry->action & actmask)) | 334 | if (!(entry->action & actmask)) |
335 | continue; | 335 | continue; |
@@ -351,6 +351,7 @@ int ima_match_policy(struct inode *inode, enum ima_hooks func, int mask, | |||
351 | if (!actmask) | 351 | if (!actmask) |
352 | break; | 352 | break; |
353 | } | 353 | } |
354 | rcu_read_unlock(); | ||
354 | 355 | ||
355 | return action; | 356 | return action; |
356 | } | 357 | } |
@@ -365,12 +366,12 @@ void ima_update_policy_flag(void) | |||
365 | { | 366 | { |
366 | struct ima_rule_entry *entry; | 367 | struct ima_rule_entry *entry; |
367 | 368 | ||
368 | ima_policy_flag = 0; | ||
369 | list_for_each_entry(entry, ima_rules, list) { | 369 | list_for_each_entry(entry, ima_rules, list) { |
370 | if (entry->action & IMA_DO_MASK) | 370 | if (entry->action & IMA_DO_MASK) |
371 | ima_policy_flag |= entry->action; | 371 | ima_policy_flag |= entry->action; |
372 | } | 372 | } |
373 | 373 | ||
374 | ima_appraise |= temp_ima_appraise; | ||
374 | if (!ima_appraise) | 375 | if (!ima_appraise) |
375 | ima_policy_flag &= ~IMA_APPRAISE; | 376 | ima_policy_flag &= ~IMA_APPRAISE; |
376 | } | 377 | } |
@@ -415,16 +416,48 @@ void __init ima_init_policy(void) | |||
415 | ima_rules = &ima_default_rules; | 416 | ima_rules = &ima_default_rules; |
416 | } | 417 | } |
417 | 418 | ||
419 | /* Make sure we have a valid policy, at least containing some rules. */ | ||
420 | int ima_check_policy() | ||
421 | { | ||
422 | if (list_empty(&ima_temp_rules)) | ||
423 | return -EINVAL; | ||
424 | return 0; | ||
425 | } | ||
426 | |||
418 | /** | 427 | /** |
419 | * ima_update_policy - update default_rules with new measure rules | 428 | * ima_update_policy - update default_rules with new measure rules |
420 | * | 429 | * |
421 | * Called on file .release to update the default rules with a complete new | 430 | * Called on file .release to update the default rules with a complete new |
422 | * policy. Once updated, the policy is locked, no additional rules can be | 431 | * policy. What we do here is to splice ima_policy_rules and ima_temp_rules so |
423 | * added to the policy. | 432 | * they make a queue. The policy may be updated multiple times and this is the |
433 | * RCU updater. | ||
434 | * | ||
435 | * Policy rules are never deleted so ima_policy_flag gets zeroed only once when | ||
436 | * we switch from the default policy to user defined. | ||
424 | */ | 437 | */ |
425 | void ima_update_policy(void) | 438 | void ima_update_policy(void) |
426 | { | 439 | { |
427 | ima_rules = &ima_policy_rules; | 440 | struct list_head *first, *last, *policy; |
441 | |||
442 | /* append current policy with the new rules */ | ||
443 | first = (&ima_temp_rules)->next; | ||
444 | last = (&ima_temp_rules)->prev; | ||
445 | policy = &ima_policy_rules; | ||
446 | |||
447 | synchronize_rcu(); | ||
448 | |||
449 | last->next = policy; | ||
450 | rcu_assign_pointer(list_next_rcu(policy->prev), first); | ||
451 | first->prev = policy->prev; | ||
452 | policy->prev = last; | ||
453 | |||
454 | /* prepare for the next policy rules addition */ | ||
455 | INIT_LIST_HEAD(&ima_temp_rules); | ||
456 | |||
457 | if (ima_rules != policy) { | ||
458 | ima_policy_flag = 0; | ||
459 | ima_rules = policy; | ||
460 | } | ||
428 | ima_update_policy_flag(); | 461 | ima_update_policy_flag(); |
429 | } | 462 | } |
430 | 463 | ||
@@ -436,8 +469,8 @@ enum { | |||
436 | Opt_obj_user, Opt_obj_role, Opt_obj_type, | 469 | Opt_obj_user, Opt_obj_role, Opt_obj_type, |
437 | Opt_subj_user, Opt_subj_role, Opt_subj_type, | 470 | Opt_subj_user, Opt_subj_role, Opt_subj_type, |
438 | Opt_func, Opt_mask, Opt_fsmagic, | 471 | Opt_func, Opt_mask, Opt_fsmagic, |
439 | Opt_uid, Opt_euid, Opt_fowner, | 472 | Opt_fsuuid, Opt_uid, Opt_euid, Opt_fowner, |
440 | Opt_appraise_type, Opt_fsuuid, Opt_permit_directio | 473 | Opt_appraise_type, Opt_permit_directio |
441 | }; | 474 | }; |
442 | 475 | ||
443 | static match_table_t policy_tokens = { | 476 | static match_table_t policy_tokens = { |
@@ -734,9 +767,9 @@ static int ima_parse_rule(char *rule, struct ima_rule_entry *entry) | |||
734 | if (!result && (entry->action == UNKNOWN)) | 767 | if (!result && (entry->action == UNKNOWN)) |
735 | result = -EINVAL; | 768 | result = -EINVAL; |
736 | else if (entry->func == MODULE_CHECK) | 769 | else if (entry->func == MODULE_CHECK) |
737 | ima_appraise |= IMA_APPRAISE_MODULES; | 770 | temp_ima_appraise |= IMA_APPRAISE_MODULES; |
738 | else if (entry->func == FIRMWARE_CHECK) | 771 | else if (entry->func == FIRMWARE_CHECK) |
739 | ima_appraise |= IMA_APPRAISE_FIRMWARE; | 772 | temp_ima_appraise |= IMA_APPRAISE_FIRMWARE; |
740 | audit_log_format(ab, "res=%d", !result); | 773 | audit_log_format(ab, "res=%d", !result); |
741 | audit_log_end(ab); | 774 | audit_log_end(ab); |
742 | return result; | 775 | return result; |
@@ -746,7 +779,7 @@ static int ima_parse_rule(char *rule, struct ima_rule_entry *entry) | |||
746 | * ima_parse_add_rule - add a rule to ima_policy_rules | 779 | * ima_parse_add_rule - add a rule to ima_policy_rules |
747 | * @rule - ima measurement policy rule | 780 | * @rule - ima measurement policy rule |
748 | * | 781 | * |
749 | * Uses a mutex to protect the policy list from multiple concurrent writers. | 782 | * Avoid locking by allowing just one writer at a time in ima_write_policy() |
750 | * Returns the length of the rule parsed, an error code on failure | 783 | * Returns the length of the rule parsed, an error code on failure |
751 | */ | 784 | */ |
752 | ssize_t ima_parse_add_rule(char *rule) | 785 | ssize_t ima_parse_add_rule(char *rule) |
@@ -782,26 +815,230 @@ ssize_t ima_parse_add_rule(char *rule) | |||
782 | return result; | 815 | return result; |
783 | } | 816 | } |
784 | 817 | ||
785 | mutex_lock(&ima_rules_mutex); | 818 | list_add_tail(&entry->list, &ima_temp_rules); |
786 | list_add_tail(&entry->list, &ima_policy_rules); | ||
787 | mutex_unlock(&ima_rules_mutex); | ||
788 | 819 | ||
789 | return len; | 820 | return len; |
790 | } | 821 | } |
791 | 822 | ||
792 | /* ima_delete_rules called to cleanup invalid policy */ | 823 | /** |
824 | * ima_delete_rules() called to cleanup invalid in-flight policy. | ||
825 | * We don't need locking as we operate on the temp list, which is | ||
826 | * different from the active one. There is also only one user of | ||
827 | * ima_delete_rules() at a time. | ||
828 | */ | ||
793 | void ima_delete_rules(void) | 829 | void ima_delete_rules(void) |
794 | { | 830 | { |
795 | struct ima_rule_entry *entry, *tmp; | 831 | struct ima_rule_entry *entry, *tmp; |
796 | int i; | 832 | int i; |
797 | 833 | ||
798 | mutex_lock(&ima_rules_mutex); | 834 | temp_ima_appraise = 0; |
799 | list_for_each_entry_safe(entry, tmp, &ima_policy_rules, list) { | 835 | list_for_each_entry_safe(entry, tmp, &ima_temp_rules, list) { |
800 | for (i = 0; i < MAX_LSM_RULES; i++) | 836 | for (i = 0; i < MAX_LSM_RULES; i++) |
801 | kfree(entry->lsm[i].args_p); | 837 | kfree(entry->lsm[i].args_p); |
802 | 838 | ||
803 | list_del(&entry->list); | 839 | list_del(&entry->list); |
804 | kfree(entry); | 840 | kfree(entry); |
805 | } | 841 | } |
806 | mutex_unlock(&ima_rules_mutex); | ||
807 | } | 842 | } |
843 | |||
844 | #ifdef CONFIG_IMA_READ_POLICY | ||
845 | enum { | ||
846 | mask_exec = 0, mask_write, mask_read, mask_append | ||
847 | }; | ||
848 | |||
849 | static char *mask_tokens[] = { | ||
850 | "MAY_EXEC", | ||
851 | "MAY_WRITE", | ||
852 | "MAY_READ", | ||
853 | "MAY_APPEND" | ||
854 | }; | ||
855 | |||
856 | enum { | ||
857 | func_file = 0, func_mmap, func_bprm, | ||
858 | func_module, func_firmware, func_post | ||
859 | }; | ||
860 | |||
861 | static char *func_tokens[] = { | ||
862 | "FILE_CHECK", | ||
863 | "MMAP_CHECK", | ||
864 | "BPRM_CHECK", | ||
865 | "MODULE_CHECK", | ||
866 | "FIRMWARE_CHECK", | ||
867 | "POST_SETATTR" | ||
868 | }; | ||
869 | |||
870 | void *ima_policy_start(struct seq_file *m, loff_t *pos) | ||
871 | { | ||
872 | loff_t l = *pos; | ||
873 | struct ima_rule_entry *entry; | ||
874 | |||
875 | rcu_read_lock(); | ||
876 | list_for_each_entry_rcu(entry, ima_rules, list) { | ||
877 | if (!l--) { | ||
878 | rcu_read_unlock(); | ||
879 | return entry; | ||
880 | } | ||
881 | } | ||
882 | rcu_read_unlock(); | ||
883 | return NULL; | ||
884 | } | ||
885 | |||
886 | void *ima_policy_next(struct seq_file *m, void *v, loff_t *pos) | ||
887 | { | ||
888 | struct ima_rule_entry *entry = v; | ||
889 | |||
890 | rcu_read_lock(); | ||
891 | entry = list_entry_rcu(entry->list.next, struct ima_rule_entry, list); | ||
892 | rcu_read_unlock(); | ||
893 | (*pos)++; | ||
894 | |||
895 | return (&entry->list == ima_rules) ? NULL : entry; | ||
896 | } | ||
897 | |||
898 | void ima_policy_stop(struct seq_file *m, void *v) | ||
899 | { | ||
900 | } | ||
901 | |||
902 | #define pt(token) policy_tokens[token + Opt_err].pattern | ||
903 | #define mt(token) mask_tokens[token] | ||
904 | #define ft(token) func_tokens[token] | ||
905 | |||
906 | int ima_policy_show(struct seq_file *m, void *v) | ||
907 | { | ||
908 | struct ima_rule_entry *entry = v; | ||
909 | int i = 0; | ||
910 | char tbuf[64] = {0,}; | ||
911 | |||
912 | rcu_read_lock(); | ||
913 | |||
914 | if (entry->action & MEASURE) | ||
915 | seq_puts(m, pt(Opt_measure)); | ||
916 | if (entry->action & DONT_MEASURE) | ||
917 | seq_puts(m, pt(Opt_dont_measure)); | ||
918 | if (entry->action & APPRAISE) | ||
919 | seq_puts(m, pt(Opt_appraise)); | ||
920 | if (entry->action & DONT_APPRAISE) | ||
921 | seq_puts(m, pt(Opt_dont_appraise)); | ||
922 | if (entry->action & AUDIT) | ||
923 | seq_puts(m, pt(Opt_audit)); | ||
924 | |||
925 | seq_puts(m, " "); | ||
926 | |||
927 | if (entry->flags & IMA_FUNC) { | ||
928 | switch (entry->func) { | ||
929 | case FILE_CHECK: | ||
930 | seq_printf(m, pt(Opt_func), ft(func_file)); | ||
931 | break; | ||
932 | case MMAP_CHECK: | ||
933 | seq_printf(m, pt(Opt_func), ft(func_mmap)); | ||
934 | break; | ||
935 | case BPRM_CHECK: | ||
936 | seq_printf(m, pt(Opt_func), ft(func_bprm)); | ||
937 | break; | ||
938 | case MODULE_CHECK: | ||
939 | seq_printf(m, pt(Opt_func), ft(func_module)); | ||
940 | break; | ||
941 | case FIRMWARE_CHECK: | ||
942 | seq_printf(m, pt(Opt_func), ft(func_firmware)); | ||
943 | break; | ||
944 | case POST_SETATTR: | ||
945 | seq_printf(m, pt(Opt_func), ft(func_post)); | ||
946 | break; | ||
947 | default: | ||
948 | snprintf(tbuf, sizeof(tbuf), "%d", entry->func); | ||
949 | seq_printf(m, pt(Opt_func), tbuf); | ||
950 | break; | ||
951 | } | ||
952 | seq_puts(m, " "); | ||
953 | } | ||
954 | |||
955 | if (entry->flags & IMA_MASK) { | ||
956 | if (entry->mask & MAY_EXEC) | ||
957 | seq_printf(m, pt(Opt_mask), mt(mask_exec)); | ||
958 | if (entry->mask & MAY_WRITE) | ||
959 | seq_printf(m, pt(Opt_mask), mt(mask_write)); | ||
960 | if (entry->mask & MAY_READ) | ||
961 | seq_printf(m, pt(Opt_mask), mt(mask_read)); | ||
962 | if (entry->mask & MAY_APPEND) | ||
963 | seq_printf(m, pt(Opt_mask), mt(mask_append)); | ||
964 | seq_puts(m, " "); | ||
965 | } | ||
966 | |||
967 | if (entry->flags & IMA_FSMAGIC) { | ||
968 | snprintf(tbuf, sizeof(tbuf), "0x%lx", entry->fsmagic); | ||
969 | seq_printf(m, pt(Opt_fsmagic), tbuf); | ||
970 | seq_puts(m, " "); | ||
971 | } | ||
972 | |||
973 | if (entry->flags & IMA_FSUUID) { | ||
974 | seq_puts(m, "fsuuid="); | ||
975 | for (i = 0; i < ARRAY_SIZE(entry->fsuuid); ++i) { | ||
976 | switch (i) { | ||
977 | case 4: | ||
978 | case 6: | ||
979 | case 8: | ||
980 | case 10: | ||
981 | seq_puts(m, "-"); | ||
982 | } | ||
983 | seq_printf(m, "%x", entry->fsuuid[i]); | ||
984 | } | ||
985 | seq_puts(m, " "); | ||
986 | } | ||
987 | |||
988 | if (entry->flags & IMA_UID) { | ||
989 | snprintf(tbuf, sizeof(tbuf), "%d", __kuid_val(entry->uid)); | ||
990 | seq_printf(m, pt(Opt_uid), tbuf); | ||
991 | seq_puts(m, " "); | ||
992 | } | ||
993 | |||
994 | if (entry->flags & IMA_EUID) { | ||
995 | snprintf(tbuf, sizeof(tbuf), "%d", __kuid_val(entry->uid)); | ||
996 | seq_printf(m, pt(Opt_euid), tbuf); | ||
997 | seq_puts(m, " "); | ||
998 | } | ||
999 | |||
1000 | if (entry->flags & IMA_FOWNER) { | ||
1001 | snprintf(tbuf, sizeof(tbuf), "%d", __kuid_val(entry->fowner)); | ||
1002 | seq_printf(m, pt(Opt_fowner), tbuf); | ||
1003 | seq_puts(m, " "); | ||
1004 | } | ||
1005 | |||
1006 | for (i = 0; i < MAX_LSM_RULES; i++) { | ||
1007 | if (entry->lsm[i].rule) { | ||
1008 | switch (i) { | ||
1009 | case LSM_OBJ_USER: | ||
1010 | seq_printf(m, pt(Opt_obj_user), | ||
1011 | (char *)entry->lsm[i].args_p); | ||
1012 | break; | ||
1013 | case LSM_OBJ_ROLE: | ||
1014 | seq_printf(m, pt(Opt_obj_role), | ||
1015 | (char *)entry->lsm[i].args_p); | ||
1016 | break; | ||
1017 | case LSM_OBJ_TYPE: | ||
1018 | seq_printf(m, pt(Opt_obj_type), | ||
1019 | (char *)entry->lsm[i].args_p); | ||
1020 | break; | ||
1021 | case LSM_SUBJ_USER: | ||
1022 | seq_printf(m, pt(Opt_subj_user), | ||
1023 | (char *)entry->lsm[i].args_p); | ||
1024 | break; | ||
1025 | case LSM_SUBJ_ROLE: | ||
1026 | seq_printf(m, pt(Opt_subj_role), | ||
1027 | (char *)entry->lsm[i].args_p); | ||
1028 | break; | ||
1029 | case LSM_SUBJ_TYPE: | ||
1030 | seq_printf(m, pt(Opt_subj_type), | ||
1031 | (char *)entry->lsm[i].args_p); | ||
1032 | break; | ||
1033 | } | ||
1034 | } | ||
1035 | } | ||
1036 | if (entry->flags & IMA_DIGSIG_REQUIRED) | ||
1037 | seq_puts(m, "appraise_type=imasig "); | ||
1038 | if (entry->flags & IMA_PERMIT_DIRECTIO) | ||
1039 | seq_puts(m, "permit_directio "); | ||
1040 | rcu_read_unlock(); | ||
1041 | seq_puts(m, "\n"); | ||
1042 | return 0; | ||
1043 | } | ||
1044 | #endif /* CONFIG_IMA_READ_POLICY */ | ||
diff --git a/security/integrity/integrity.h b/security/integrity/integrity.h index 9c6168709d3b..5efe2ecc538d 100644 --- a/security/integrity/integrity.h +++ b/security/integrity/integrity.h | |||
@@ -125,8 +125,8 @@ int integrity_kernel_read(struct file *file, loff_t offset, | |||
125 | int __init integrity_read_file(const char *path, char **data); | 125 | int __init integrity_read_file(const char *path, char **data); |
126 | 126 | ||
127 | #define INTEGRITY_KEYRING_EVM 0 | 127 | #define INTEGRITY_KEYRING_EVM 0 |
128 | #define INTEGRITY_KEYRING_MODULE 1 | 128 | #define INTEGRITY_KEYRING_IMA 1 |
129 | #define INTEGRITY_KEYRING_IMA 2 | 129 | #define INTEGRITY_KEYRING_MODULE 2 |
130 | #define INTEGRITY_KEYRING_MAX 3 | 130 | #define INTEGRITY_KEYRING_MAX 3 |
131 | 131 | ||
132 | #ifdef CONFIG_INTEGRITY_SIGNATURE | 132 | #ifdef CONFIG_INTEGRITY_SIGNATURE |
@@ -149,7 +149,6 @@ static inline int integrity_init_keyring(const unsigned int id) | |||
149 | { | 149 | { |
150 | return 0; | 150 | return 0; |
151 | } | 151 | } |
152 | |||
153 | #endif /* CONFIG_INTEGRITY_SIGNATURE */ | 152 | #endif /* CONFIG_INTEGRITY_SIGNATURE */ |
154 | 153 | ||
155 | #ifdef CONFIG_INTEGRITY_ASYMMETRIC_KEYS | 154 | #ifdef CONFIG_INTEGRITY_ASYMMETRIC_KEYS |
@@ -171,6 +170,14 @@ static inline void ima_load_x509(void) | |||
171 | } | 170 | } |
172 | #endif | 171 | #endif |
173 | 172 | ||
173 | #ifdef CONFIG_EVM_LOAD_X509 | ||
174 | void __init evm_load_x509(void); | ||
175 | #else | ||
176 | static inline void evm_load_x509(void) | ||
177 | { | ||
178 | } | ||
179 | #endif | ||
180 | |||
174 | #ifdef CONFIG_INTEGRITY_AUDIT | 181 | #ifdef CONFIG_INTEGRITY_AUDIT |
175 | /* declarations */ | 182 | /* declarations */ |
176 | void integrity_audit_msg(int audit_msgno, struct inode *inode, | 183 | void integrity_audit_msg(int audit_msgno, struct inode *inode, |
diff --git a/security/keys/Kconfig b/security/keys/Kconfig index 72483b8f1be5..fe4d74e126a7 100644 --- a/security/keys/Kconfig +++ b/security/keys/Kconfig | |||
@@ -54,6 +54,7 @@ config TRUSTED_KEYS | |||
54 | select CRYPTO | 54 | select CRYPTO |
55 | select CRYPTO_HMAC | 55 | select CRYPTO_HMAC |
56 | select CRYPTO_SHA1 | 56 | select CRYPTO_SHA1 |
57 | select CRYPTO_HASH_INFO | ||
57 | help | 58 | help |
58 | This option provides support for creating, sealing, and unsealing | 59 | This option provides support for creating, sealing, and unsealing |
59 | keys in the kernel. Trusted keys are random number symmetric keys, | 60 | keys in the kernel. Trusted keys are random number symmetric keys, |
diff --git a/security/keys/key.c b/security/keys/key.c index ab7997ded725..07a87311055c 100644 --- a/security/keys/key.c +++ b/security/keys/key.c | |||
@@ -429,8 +429,11 @@ static int __key_instantiate_and_link(struct key *key, | |||
429 | awaken = 1; | 429 | awaken = 1; |
430 | 430 | ||
431 | /* and link it into the destination keyring */ | 431 | /* and link it into the destination keyring */ |
432 | if (keyring) | 432 | if (keyring) { |
433 | set_bit(KEY_FLAG_KEEP, &key->flags); | ||
434 | |||
433 | __key_link(key, _edit); | 435 | __key_link(key, _edit); |
436 | } | ||
434 | 437 | ||
435 | /* disable the authorisation key */ | 438 | /* disable the authorisation key */ |
436 | if (authkey) | 439 | if (authkey) |
diff --git a/security/keys/keyctl.c b/security/keys/keyctl.c index 1c3872aeed14..ed73c6c1c326 100644 --- a/security/keys/keyctl.c +++ b/security/keys/keyctl.c | |||
@@ -358,11 +358,14 @@ error: | |||
358 | * and any links to the key will be automatically garbage collected after a | 358 | * and any links to the key will be automatically garbage collected after a |
359 | * certain amount of time (/proc/sys/kernel/keys/gc_delay). | 359 | * certain amount of time (/proc/sys/kernel/keys/gc_delay). |
360 | * | 360 | * |
361 | * Keys with KEY_FLAG_KEEP set should not be revoked. | ||
362 | * | ||
361 | * If successful, 0 is returned. | 363 | * If successful, 0 is returned. |
362 | */ | 364 | */ |
363 | long keyctl_revoke_key(key_serial_t id) | 365 | long keyctl_revoke_key(key_serial_t id) |
364 | { | 366 | { |
365 | key_ref_t key_ref; | 367 | key_ref_t key_ref; |
368 | struct key *key; | ||
366 | long ret; | 369 | long ret; |
367 | 370 | ||
368 | key_ref = lookup_user_key(id, 0, KEY_NEED_WRITE); | 371 | key_ref = lookup_user_key(id, 0, KEY_NEED_WRITE); |
@@ -377,8 +380,12 @@ long keyctl_revoke_key(key_serial_t id) | |||
377 | } | 380 | } |
378 | } | 381 | } |
379 | 382 | ||
380 | key_revoke(key_ref_to_ptr(key_ref)); | 383 | key = key_ref_to_ptr(key_ref); |
381 | ret = 0; | 384 | ret = 0; |
385 | if (test_bit(KEY_FLAG_KEEP, &key->flags)) | ||
386 | ret = -EPERM; | ||
387 | else | ||
388 | key_revoke(key); | ||
382 | 389 | ||
383 | key_ref_put(key_ref); | 390 | key_ref_put(key_ref); |
384 | error: | 391 | error: |
@@ -392,11 +399,14 @@ error: | |||
392 | * The key and any links to the key will be automatically garbage collected | 399 | * The key and any links to the key will be automatically garbage collected |
393 | * immediately. | 400 | * immediately. |
394 | * | 401 | * |
402 | * Keys with KEY_FLAG_KEEP set should not be invalidated. | ||
403 | * | ||
395 | * If successful, 0 is returned. | 404 | * If successful, 0 is returned. |
396 | */ | 405 | */ |
397 | long keyctl_invalidate_key(key_serial_t id) | 406 | long keyctl_invalidate_key(key_serial_t id) |
398 | { | 407 | { |
399 | key_ref_t key_ref; | 408 | key_ref_t key_ref; |
409 | struct key *key; | ||
400 | long ret; | 410 | long ret; |
401 | 411 | ||
402 | kenter("%d", id); | 412 | kenter("%d", id); |
@@ -420,8 +430,12 @@ long keyctl_invalidate_key(key_serial_t id) | |||
420 | } | 430 | } |
421 | 431 | ||
422 | invalidate: | 432 | invalidate: |
423 | key_invalidate(key_ref_to_ptr(key_ref)); | 433 | key = key_ref_to_ptr(key_ref); |
424 | ret = 0; | 434 | ret = 0; |
435 | if (test_bit(KEY_FLAG_KEEP, &key->flags)) | ||
436 | ret = -EPERM; | ||
437 | else | ||
438 | key_invalidate(key); | ||
425 | error_put: | 439 | error_put: |
426 | key_ref_put(key_ref); | 440 | key_ref_put(key_ref); |
427 | error: | 441 | error: |
@@ -433,12 +447,13 @@ error: | |||
433 | * Clear the specified keyring, creating an empty process keyring if one of the | 447 | * Clear the specified keyring, creating an empty process keyring if one of the |
434 | * special keyring IDs is used. | 448 | * special keyring IDs is used. |
435 | * | 449 | * |
436 | * The keyring must grant the caller Write permission for this to work. If | 450 | * The keyring must grant the caller Write permission and not have |
437 | * successful, 0 will be returned. | 451 | * KEY_FLAG_KEEP set for this to work. If successful, 0 will be returned. |
438 | */ | 452 | */ |
439 | long keyctl_keyring_clear(key_serial_t ringid) | 453 | long keyctl_keyring_clear(key_serial_t ringid) |
440 | { | 454 | { |
441 | key_ref_t keyring_ref; | 455 | key_ref_t keyring_ref; |
456 | struct key *keyring; | ||
442 | long ret; | 457 | long ret; |
443 | 458 | ||
444 | keyring_ref = lookup_user_key(ringid, KEY_LOOKUP_CREATE, KEY_NEED_WRITE); | 459 | keyring_ref = lookup_user_key(ringid, KEY_LOOKUP_CREATE, KEY_NEED_WRITE); |
@@ -460,7 +475,11 @@ long keyctl_keyring_clear(key_serial_t ringid) | |||
460 | } | 475 | } |
461 | 476 | ||
462 | clear: | 477 | clear: |
463 | ret = keyring_clear(key_ref_to_ptr(keyring_ref)); | 478 | keyring = key_ref_to_ptr(keyring_ref); |
479 | if (test_bit(KEY_FLAG_KEEP, &keyring->flags)) | ||
480 | ret = -EPERM; | ||
481 | else | ||
482 | ret = keyring_clear(keyring); | ||
464 | error_put: | 483 | error_put: |
465 | key_ref_put(keyring_ref); | 484 | key_ref_put(keyring_ref); |
466 | error: | 485 | error: |
@@ -511,11 +530,14 @@ error: | |||
511 | * itself need not grant the caller anything. If the last link to a key is | 530 | * itself need not grant the caller anything. If the last link to a key is |
512 | * removed then that key will be scheduled for destruction. | 531 | * removed then that key will be scheduled for destruction. |
513 | * | 532 | * |
533 | * Keys or keyrings with KEY_FLAG_KEEP set should not be unlinked. | ||
534 | * | ||
514 | * If successful, 0 will be returned. | 535 | * If successful, 0 will be returned. |
515 | */ | 536 | */ |
516 | long keyctl_keyring_unlink(key_serial_t id, key_serial_t ringid) | 537 | long keyctl_keyring_unlink(key_serial_t id, key_serial_t ringid) |
517 | { | 538 | { |
518 | key_ref_t keyring_ref, key_ref; | 539 | key_ref_t keyring_ref, key_ref; |
540 | struct key *keyring, *key; | ||
519 | long ret; | 541 | long ret; |
520 | 542 | ||
521 | keyring_ref = lookup_user_key(ringid, 0, KEY_NEED_WRITE); | 543 | keyring_ref = lookup_user_key(ringid, 0, KEY_NEED_WRITE); |
@@ -530,7 +552,13 @@ long keyctl_keyring_unlink(key_serial_t id, key_serial_t ringid) | |||
530 | goto error2; | 552 | goto error2; |
531 | } | 553 | } |
532 | 554 | ||
533 | ret = key_unlink(key_ref_to_ptr(keyring_ref), key_ref_to_ptr(key_ref)); | 555 | keyring = key_ref_to_ptr(keyring_ref); |
556 | key = key_ref_to_ptr(key_ref); | ||
557 | if (test_bit(KEY_FLAG_KEEP, &keyring->flags) && | ||
558 | test_bit(KEY_FLAG_KEEP, &key->flags)) | ||
559 | ret = -EPERM; | ||
560 | else | ||
561 | ret = key_unlink(keyring, key); | ||
534 | 562 | ||
535 | key_ref_put(key_ref); | 563 | key_ref_put(key_ref); |
536 | error2: | 564 | error2: |
@@ -1289,6 +1317,8 @@ error: | |||
1289 | * the current time. The key and any links to the key will be automatically | 1317 | * the current time. The key and any links to the key will be automatically |
1290 | * garbage collected after the timeout expires. | 1318 | * garbage collected after the timeout expires. |
1291 | * | 1319 | * |
1320 | * Keys with KEY_FLAG_KEEP set should not be timed out. | ||
1321 | * | ||
1292 | * If successful, 0 is returned. | 1322 | * If successful, 0 is returned. |
1293 | */ | 1323 | */ |
1294 | long keyctl_set_timeout(key_serial_t id, unsigned timeout) | 1324 | long keyctl_set_timeout(key_serial_t id, unsigned timeout) |
@@ -1320,10 +1350,13 @@ long keyctl_set_timeout(key_serial_t id, unsigned timeout) | |||
1320 | 1350 | ||
1321 | okay: | 1351 | okay: |
1322 | key = key_ref_to_ptr(key_ref); | 1352 | key = key_ref_to_ptr(key_ref); |
1323 | key_set_timeout(key, timeout); | 1353 | ret = 0; |
1354 | if (test_bit(KEY_FLAG_KEEP, &key->flags)) | ||
1355 | ret = -EPERM; | ||
1356 | else | ||
1357 | key_set_timeout(key, timeout); | ||
1324 | key_put(key); | 1358 | key_put(key); |
1325 | 1359 | ||
1326 | ret = 0; | ||
1327 | error: | 1360 | error: |
1328 | return ret; | 1361 | return ret; |
1329 | } | 1362 | } |
diff --git a/security/keys/trusted.c b/security/keys/trusted.c index 16dec53184b6..0dcab20cdacd 100644 --- a/security/keys/trusted.c +++ b/security/keys/trusted.c | |||
@@ -11,6 +11,7 @@ | |||
11 | * See Documentation/security/keys-trusted-encrypted.txt | 11 | * See Documentation/security/keys-trusted-encrypted.txt |
12 | */ | 12 | */ |
13 | 13 | ||
14 | #include <crypto/hash_info.h> | ||
14 | #include <linux/uaccess.h> | 15 | #include <linux/uaccess.h> |
15 | #include <linux/module.h> | 16 | #include <linux/module.h> |
16 | #include <linux/init.h> | 17 | #include <linux/init.h> |
@@ -710,7 +711,10 @@ enum { | |||
710 | Opt_err = -1, | 711 | Opt_err = -1, |
711 | Opt_new, Opt_load, Opt_update, | 712 | Opt_new, Opt_load, Opt_update, |
712 | Opt_keyhandle, Opt_keyauth, Opt_blobauth, | 713 | Opt_keyhandle, Opt_keyauth, Opt_blobauth, |
713 | Opt_pcrinfo, Opt_pcrlock, Opt_migratable | 714 | Opt_pcrinfo, Opt_pcrlock, Opt_migratable, |
715 | Opt_hash, | ||
716 | Opt_policydigest, | ||
717 | Opt_policyhandle, | ||
714 | }; | 718 | }; |
715 | 719 | ||
716 | static const match_table_t key_tokens = { | 720 | static const match_table_t key_tokens = { |
@@ -723,6 +727,9 @@ static const match_table_t key_tokens = { | |||
723 | {Opt_pcrinfo, "pcrinfo=%s"}, | 727 | {Opt_pcrinfo, "pcrinfo=%s"}, |
724 | {Opt_pcrlock, "pcrlock=%s"}, | 728 | {Opt_pcrlock, "pcrlock=%s"}, |
725 | {Opt_migratable, "migratable=%s"}, | 729 | {Opt_migratable, "migratable=%s"}, |
730 | {Opt_hash, "hash=%s"}, | ||
731 | {Opt_policydigest, "policydigest=%s"}, | ||
732 | {Opt_policyhandle, "policyhandle=%s"}, | ||
726 | {Opt_err, NULL} | 733 | {Opt_err, NULL} |
727 | }; | 734 | }; |
728 | 735 | ||
@@ -736,11 +743,23 @@ static int getoptions(char *c, struct trusted_key_payload *pay, | |||
736 | int res; | 743 | int res; |
737 | unsigned long handle; | 744 | unsigned long handle; |
738 | unsigned long lock; | 745 | unsigned long lock; |
746 | unsigned long token_mask = 0; | ||
747 | int i; | ||
748 | int tpm2; | ||
749 | |||
750 | tpm2 = tpm_is_tpm2(TPM_ANY_NUM); | ||
751 | if (tpm2 < 0) | ||
752 | return tpm2; | ||
753 | |||
754 | opt->hash = tpm2 ? HASH_ALGO_SHA256 : HASH_ALGO_SHA1; | ||
755 | opt->digest_len = hash_digest_size[opt->hash]; | ||
739 | 756 | ||
740 | while ((p = strsep(&c, " \t"))) { | 757 | while ((p = strsep(&c, " \t"))) { |
741 | if (*p == '\0' || *p == ' ' || *p == '\t') | 758 | if (*p == '\0' || *p == ' ' || *p == '\t') |
742 | continue; | 759 | continue; |
743 | token = match_token(p, key_tokens, args); | 760 | token = match_token(p, key_tokens, args); |
761 | if (test_and_set_bit(token, &token_mask)) | ||
762 | return -EINVAL; | ||
744 | 763 | ||
745 | switch (token) { | 764 | switch (token) { |
746 | case Opt_pcrinfo: | 765 | case Opt_pcrinfo: |
@@ -787,6 +806,41 @@ static int getoptions(char *c, struct trusted_key_payload *pay, | |||
787 | return -EINVAL; | 806 | return -EINVAL; |
788 | opt->pcrlock = lock; | 807 | opt->pcrlock = lock; |
789 | break; | 808 | break; |
809 | case Opt_hash: | ||
810 | if (test_bit(Opt_policydigest, &token_mask)) | ||
811 | return -EINVAL; | ||
812 | for (i = 0; i < HASH_ALGO__LAST; i++) { | ||
813 | if (!strcmp(args[0].from, hash_algo_name[i])) { | ||
814 | opt->hash = i; | ||
815 | opt->digest_len = | ||
816 | hash_digest_size[opt->hash]; | ||
817 | break; | ||
818 | } | ||
819 | } | ||
820 | if (i == HASH_ALGO__LAST) | ||
821 | return -EINVAL; | ||
822 | if (!tpm2 && i != HASH_ALGO_SHA1) { | ||
823 | pr_info("trusted_key: TPM 1.x only supports SHA-1.\n"); | ||
824 | return -EINVAL; | ||
825 | } | ||
826 | break; | ||
827 | case Opt_policydigest: | ||
828 | if (!tpm2 || | ||
829 | strlen(args[0].from) != (2 * opt->digest_len)) | ||
830 | return -EINVAL; | ||
831 | res = hex2bin(opt->policydigest, args[0].from, | ||
832 | opt->digest_len); | ||
833 | if (res < 0) | ||
834 | return -EINVAL; | ||
835 | break; | ||
836 | case Opt_policyhandle: | ||
837 | if (!tpm2) | ||
838 | return -EINVAL; | ||
839 | res = kstrtoul(args[0].from, 16, &handle); | ||
840 | if (res < 0) | ||
841 | return -EINVAL; | ||
842 | opt->policyhandle = handle; | ||
843 | break; | ||
790 | default: | 844 | default: |
791 | return -EINVAL; | 845 | return -EINVAL; |
792 | } | 846 | } |
diff --git a/security/security.c b/security/security.c index 46f405ce6b0f..e8ffd92ae2eb 100644 --- a/security/security.c +++ b/security/security.c | |||
@@ -697,7 +697,7 @@ int security_inode_killpriv(struct dentry *dentry) | |||
697 | return call_int_hook(inode_killpriv, 0, dentry); | 697 | return call_int_hook(inode_killpriv, 0, dentry); |
698 | } | 698 | } |
699 | 699 | ||
700 | int security_inode_getsecurity(const struct inode *inode, const char *name, void **buffer, bool alloc) | 700 | int security_inode_getsecurity(struct inode *inode, const char *name, void **buffer, bool alloc) |
701 | { | 701 | { |
702 | if (unlikely(IS_PRIVATE(inode))) | 702 | if (unlikely(IS_PRIVATE(inode))) |
703 | return -EOPNOTSUPP; | 703 | return -EOPNOTSUPP; |
@@ -721,7 +721,7 @@ int security_inode_listsecurity(struct inode *inode, char *buffer, size_t buffer | |||
721 | } | 721 | } |
722 | EXPORT_SYMBOL(security_inode_listsecurity); | 722 | EXPORT_SYMBOL(security_inode_listsecurity); |
723 | 723 | ||
724 | void security_inode_getsecid(const struct inode *inode, u32 *secid) | 724 | void security_inode_getsecid(struct inode *inode, u32 *secid) |
725 | { | 725 | { |
726 | call_void_hook(inode_getsecid, inode, secid); | 726 | call_void_hook(inode_getsecid, inode, secid); |
727 | } | 727 | } |
@@ -1161,6 +1161,12 @@ void security_release_secctx(char *secdata, u32 seclen) | |||
1161 | } | 1161 | } |
1162 | EXPORT_SYMBOL(security_release_secctx); | 1162 | EXPORT_SYMBOL(security_release_secctx); |
1163 | 1163 | ||
1164 | void security_inode_invalidate_secctx(struct inode *inode) | ||
1165 | { | ||
1166 | call_void_hook(inode_invalidate_secctx, inode); | ||
1167 | } | ||
1168 | EXPORT_SYMBOL(security_inode_invalidate_secctx); | ||
1169 | |||
1164 | int security_inode_notifysecctx(struct inode *inode, void *ctx, u32 ctxlen) | 1170 | int security_inode_notifysecctx(struct inode *inode, void *ctx, u32 ctxlen) |
1165 | { | 1171 | { |
1166 | return call_int_hook(inode_notifysecctx, 0, inode, ctx, ctxlen); | 1172 | return call_int_hook(inode_notifysecctx, 0, inode, ctx, ctxlen); |
@@ -1763,6 +1769,8 @@ struct security_hook_heads security_hook_heads = { | |||
1763 | LIST_HEAD_INIT(security_hook_heads.secctx_to_secid), | 1769 | LIST_HEAD_INIT(security_hook_heads.secctx_to_secid), |
1764 | .release_secctx = | 1770 | .release_secctx = |
1765 | LIST_HEAD_INIT(security_hook_heads.release_secctx), | 1771 | LIST_HEAD_INIT(security_hook_heads.release_secctx), |
1772 | .inode_invalidate_secctx = | ||
1773 | LIST_HEAD_INIT(security_hook_heads.inode_invalidate_secctx), | ||
1766 | .inode_notifysecctx = | 1774 | .inode_notifysecctx = |
1767 | LIST_HEAD_INIT(security_hook_heads.inode_notifysecctx), | 1775 | LIST_HEAD_INIT(security_hook_heads.inode_notifysecctx), |
1768 | .inode_setsecctx = | 1776 | .inode_setsecctx = |
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c index d0cfaa9f19d0..f8110cfd80ff 100644 --- a/security/selinux/hooks.c +++ b/security/selinux/hooks.c | |||
@@ -242,6 +242,72 @@ static int inode_alloc_security(struct inode *inode) | |||
242 | return 0; | 242 | return 0; |
243 | } | 243 | } |
244 | 244 | ||
245 | static int inode_doinit_with_dentry(struct inode *inode, struct dentry *opt_dentry); | ||
246 | |||
247 | /* | ||
248 | * Try reloading inode security labels that have been marked as invalid. The | ||
249 | * @may_sleep parameter indicates when sleeping and thus reloading labels is | ||
250 | * allowed; when set to false, returns ERR_PTR(-ECHILD) when the label is | ||
251 | * invalid. The @opt_dentry parameter should be set to a dentry of the inode; | ||
252 | * when no dentry is available, set it to NULL instead. | ||
253 | */ | ||
254 | static int __inode_security_revalidate(struct inode *inode, | ||
255 | struct dentry *opt_dentry, | ||
256 | bool may_sleep) | ||
257 | { | ||
258 | struct inode_security_struct *isec = inode->i_security; | ||
259 | |||
260 | might_sleep_if(may_sleep); | ||
261 | |||
262 | if (isec->initialized == LABEL_INVALID) { | ||
263 | if (!may_sleep) | ||
264 | return -ECHILD; | ||
265 | |||
266 | /* | ||
267 | * Try reloading the inode security label. This will fail if | ||
268 | * @opt_dentry is NULL and no dentry for this inode can be | ||
269 | * found; in that case, continue using the old label. | ||
270 | */ | ||
271 | inode_doinit_with_dentry(inode, opt_dentry); | ||
272 | } | ||
273 | return 0; | ||
274 | } | ||
275 | |||
276 | static struct inode_security_struct *inode_security_novalidate(struct inode *inode) | ||
277 | { | ||
278 | return inode->i_security; | ||
279 | } | ||
280 | |||
281 | static struct inode_security_struct *inode_security_rcu(struct inode *inode, bool rcu) | ||
282 | { | ||
283 | int error; | ||
284 | |||
285 | error = __inode_security_revalidate(inode, NULL, !rcu); | ||
286 | if (error) | ||
287 | return ERR_PTR(error); | ||
288 | return inode->i_security; | ||
289 | } | ||
290 | |||
291 | /* | ||
292 | * Get the security label of an inode. | ||
293 | */ | ||
294 | static struct inode_security_struct *inode_security(struct inode *inode) | ||
295 | { | ||
296 | __inode_security_revalidate(inode, NULL, true); | ||
297 | return inode->i_security; | ||
298 | } | ||
299 | |||
300 | /* | ||
301 | * Get the security label of a dentry's backing inode. | ||
302 | */ | ||
303 | static struct inode_security_struct *backing_inode_security(struct dentry *dentry) | ||
304 | { | ||
305 | struct inode *inode = d_backing_inode(dentry); | ||
306 | |||
307 | __inode_security_revalidate(inode, dentry, true); | ||
308 | return inode->i_security; | ||
309 | } | ||
310 | |||
245 | static void inode_free_rcu(struct rcu_head *head) | 311 | static void inode_free_rcu(struct rcu_head *head) |
246 | { | 312 | { |
247 | struct inode_security_struct *isec; | 313 | struct inode_security_struct *isec; |
@@ -345,8 +411,6 @@ static const char *labeling_behaviors[7] = { | |||
345 | "uses native labeling", | 411 | "uses native labeling", |
346 | }; | 412 | }; |
347 | 413 | ||
348 | static int inode_doinit_with_dentry(struct inode *inode, struct dentry *opt_dentry); | ||
349 | |||
350 | static inline int inode_doinit(struct inode *inode) | 414 | static inline int inode_doinit(struct inode *inode) |
351 | { | 415 | { |
352 | return inode_doinit_with_dentry(inode, NULL); | 416 | return inode_doinit_with_dentry(inode, NULL); |
@@ -565,8 +629,8 @@ static int selinux_get_mnt_opts(const struct super_block *sb, | |||
565 | opts->mnt_opts_flags[i++] = DEFCONTEXT_MNT; | 629 | opts->mnt_opts_flags[i++] = DEFCONTEXT_MNT; |
566 | } | 630 | } |
567 | if (sbsec->flags & ROOTCONTEXT_MNT) { | 631 | if (sbsec->flags & ROOTCONTEXT_MNT) { |
568 | struct inode *root = d_backing_inode(sbsec->sb->s_root); | 632 | struct dentry *root = sbsec->sb->s_root; |
569 | struct inode_security_struct *isec = root->i_security; | 633 | struct inode_security_struct *isec = backing_inode_security(root); |
570 | 634 | ||
571 | rc = security_sid_to_context(isec->sid, &context, &len); | 635 | rc = security_sid_to_context(isec->sid, &context, &len); |
572 | if (rc) | 636 | if (rc) |
@@ -621,8 +685,8 @@ static int selinux_set_mnt_opts(struct super_block *sb, | |||
621 | int rc = 0, i; | 685 | int rc = 0, i; |
622 | struct superblock_security_struct *sbsec = sb->s_security; | 686 | struct superblock_security_struct *sbsec = sb->s_security; |
623 | const char *name = sb->s_type->name; | 687 | const char *name = sb->s_type->name; |
624 | struct inode *inode = d_backing_inode(sbsec->sb->s_root); | 688 | struct dentry *root = sbsec->sb->s_root; |
625 | struct inode_security_struct *root_isec = inode->i_security; | 689 | struct inode_security_struct *root_isec = backing_inode_security(root); |
626 | u32 fscontext_sid = 0, context_sid = 0, rootcontext_sid = 0; | 690 | u32 fscontext_sid = 0, context_sid = 0, rootcontext_sid = 0; |
627 | u32 defcontext_sid = 0; | 691 | u32 defcontext_sid = 0; |
628 | char **mount_options = opts->mnt_opts; | 692 | char **mount_options = opts->mnt_opts; |
@@ -802,7 +866,7 @@ static int selinux_set_mnt_opts(struct super_block *sb, | |||
802 | goto out; | 866 | goto out; |
803 | 867 | ||
804 | root_isec->sid = rootcontext_sid; | 868 | root_isec->sid = rootcontext_sid; |
805 | root_isec->initialized = 1; | 869 | root_isec->initialized = LABEL_INITIALIZED; |
806 | } | 870 | } |
807 | 871 | ||
808 | if (defcontext_sid) { | 872 | if (defcontext_sid) { |
@@ -852,8 +916,8 @@ static int selinux_cmp_sb_context(const struct super_block *oldsb, | |||
852 | if ((oldflags & DEFCONTEXT_MNT) && old->def_sid != new->def_sid) | 916 | if ((oldflags & DEFCONTEXT_MNT) && old->def_sid != new->def_sid) |
853 | goto mismatch; | 917 | goto mismatch; |
854 | if (oldflags & ROOTCONTEXT_MNT) { | 918 | if (oldflags & ROOTCONTEXT_MNT) { |
855 | struct inode_security_struct *oldroot = d_backing_inode(oldsb->s_root)->i_security; | 919 | struct inode_security_struct *oldroot = backing_inode_security(oldsb->s_root); |
856 | struct inode_security_struct *newroot = d_backing_inode(newsb->s_root)->i_security; | 920 | struct inode_security_struct *newroot = backing_inode_security(newsb->s_root); |
857 | if (oldroot->sid != newroot->sid) | 921 | if (oldroot->sid != newroot->sid) |
858 | goto mismatch; | 922 | goto mismatch; |
859 | } | 923 | } |
@@ -903,17 +967,14 @@ static int selinux_sb_clone_mnt_opts(const struct super_block *oldsb, | |||
903 | if (!set_fscontext) | 967 | if (!set_fscontext) |
904 | newsbsec->sid = sid; | 968 | newsbsec->sid = sid; |
905 | if (!set_rootcontext) { | 969 | if (!set_rootcontext) { |
906 | struct inode *newinode = d_backing_inode(newsb->s_root); | 970 | struct inode_security_struct *newisec = backing_inode_security(newsb->s_root); |
907 | struct inode_security_struct *newisec = newinode->i_security; | ||
908 | newisec->sid = sid; | 971 | newisec->sid = sid; |
909 | } | 972 | } |
910 | newsbsec->mntpoint_sid = sid; | 973 | newsbsec->mntpoint_sid = sid; |
911 | } | 974 | } |
912 | if (set_rootcontext) { | 975 | if (set_rootcontext) { |
913 | const struct inode *oldinode = d_backing_inode(oldsb->s_root); | 976 | const struct inode_security_struct *oldisec = backing_inode_security(oldsb->s_root); |
914 | const struct inode_security_struct *oldisec = oldinode->i_security; | 977 | struct inode_security_struct *newisec = backing_inode_security(newsb->s_root); |
915 | struct inode *newinode = d_backing_inode(newsb->s_root); | ||
916 | struct inode_security_struct *newisec = newinode->i_security; | ||
917 | 978 | ||
918 | newisec->sid = oldisec->sid; | 979 | newisec->sid = oldisec->sid; |
919 | } | 980 | } |
@@ -1293,11 +1354,11 @@ static int inode_doinit_with_dentry(struct inode *inode, struct dentry *opt_dent | |||
1293 | unsigned len = 0; | 1354 | unsigned len = 0; |
1294 | int rc = 0; | 1355 | int rc = 0; |
1295 | 1356 | ||
1296 | if (isec->initialized) | 1357 | if (isec->initialized == LABEL_INITIALIZED) |
1297 | goto out; | 1358 | goto out; |
1298 | 1359 | ||
1299 | mutex_lock(&isec->lock); | 1360 | mutex_lock(&isec->lock); |
1300 | if (isec->initialized) | 1361 | if (isec->initialized == LABEL_INITIALIZED) |
1301 | goto out_unlock; | 1362 | goto out_unlock; |
1302 | 1363 | ||
1303 | sbsec = inode->i_sb->s_security; | 1364 | sbsec = inode->i_sb->s_security; |
@@ -1469,7 +1530,7 @@ static int inode_doinit_with_dentry(struct inode *inode, struct dentry *opt_dent | |||
1469 | break; | 1530 | break; |
1470 | } | 1531 | } |
1471 | 1532 | ||
1472 | isec->initialized = 1; | 1533 | isec->initialized = LABEL_INITIALIZED; |
1473 | 1534 | ||
1474 | out_unlock: | 1535 | out_unlock: |
1475 | mutex_unlock(&isec->lock); | 1536 | mutex_unlock(&isec->lock); |
@@ -1640,6 +1701,7 @@ static inline int dentry_has_perm(const struct cred *cred, | |||
1640 | 1701 | ||
1641 | ad.type = LSM_AUDIT_DATA_DENTRY; | 1702 | ad.type = LSM_AUDIT_DATA_DENTRY; |
1642 | ad.u.dentry = dentry; | 1703 | ad.u.dentry = dentry; |
1704 | __inode_security_revalidate(inode, dentry, true); | ||
1643 | return inode_has_perm(cred, inode, av, &ad); | 1705 | return inode_has_perm(cred, inode, av, &ad); |
1644 | } | 1706 | } |
1645 | 1707 | ||
@@ -1655,6 +1717,7 @@ static inline int path_has_perm(const struct cred *cred, | |||
1655 | 1717 | ||
1656 | ad.type = LSM_AUDIT_DATA_PATH; | 1718 | ad.type = LSM_AUDIT_DATA_PATH; |
1657 | ad.u.path = *path; | 1719 | ad.u.path = *path; |
1720 | __inode_security_revalidate(inode, path->dentry, true); | ||
1658 | return inode_has_perm(cred, inode, av, &ad); | 1721 | return inode_has_perm(cred, inode, av, &ad); |
1659 | } | 1722 | } |
1660 | 1723 | ||
@@ -1712,13 +1775,13 @@ out: | |||
1712 | /* | 1775 | /* |
1713 | * Determine the label for an inode that might be unioned. | 1776 | * Determine the label for an inode that might be unioned. |
1714 | */ | 1777 | */ |
1715 | static int selinux_determine_inode_label(const struct inode *dir, | 1778 | static int selinux_determine_inode_label(struct inode *dir, |
1716 | const struct qstr *name, | 1779 | const struct qstr *name, |
1717 | u16 tclass, | 1780 | u16 tclass, |
1718 | u32 *_new_isid) | 1781 | u32 *_new_isid) |
1719 | { | 1782 | { |
1720 | const struct superblock_security_struct *sbsec = dir->i_sb->s_security; | 1783 | const struct superblock_security_struct *sbsec = dir->i_sb->s_security; |
1721 | const struct inode_security_struct *dsec = dir->i_security; | 1784 | const struct inode_security_struct *dsec = inode_security(dir); |
1722 | const struct task_security_struct *tsec = current_security(); | 1785 | const struct task_security_struct *tsec = current_security(); |
1723 | 1786 | ||
1724 | if ((sbsec->flags & SE_SBINITIALIZED) && | 1787 | if ((sbsec->flags & SE_SBINITIALIZED) && |
@@ -1747,7 +1810,7 @@ static int may_create(struct inode *dir, | |||
1747 | struct common_audit_data ad; | 1810 | struct common_audit_data ad; |
1748 | int rc; | 1811 | int rc; |
1749 | 1812 | ||
1750 | dsec = dir->i_security; | 1813 | dsec = inode_security(dir); |
1751 | sbsec = dir->i_sb->s_security; | 1814 | sbsec = dir->i_sb->s_security; |
1752 | 1815 | ||
1753 | sid = tsec->sid; | 1816 | sid = tsec->sid; |
@@ -1800,8 +1863,8 @@ static int may_link(struct inode *dir, | |||
1800 | u32 av; | 1863 | u32 av; |
1801 | int rc; | 1864 | int rc; |
1802 | 1865 | ||
1803 | dsec = dir->i_security; | 1866 | dsec = inode_security(dir); |
1804 | isec = d_backing_inode(dentry)->i_security; | 1867 | isec = backing_inode_security(dentry); |
1805 | 1868 | ||
1806 | ad.type = LSM_AUDIT_DATA_DENTRY; | 1869 | ad.type = LSM_AUDIT_DATA_DENTRY; |
1807 | ad.u.dentry = dentry; | 1870 | ad.u.dentry = dentry; |
@@ -1844,10 +1907,10 @@ static inline int may_rename(struct inode *old_dir, | |||
1844 | int old_is_dir, new_is_dir; | 1907 | int old_is_dir, new_is_dir; |
1845 | int rc; | 1908 | int rc; |
1846 | 1909 | ||
1847 | old_dsec = old_dir->i_security; | 1910 | old_dsec = inode_security(old_dir); |
1848 | old_isec = d_backing_inode(old_dentry)->i_security; | 1911 | old_isec = backing_inode_security(old_dentry); |
1849 | old_is_dir = d_is_dir(old_dentry); | 1912 | old_is_dir = d_is_dir(old_dentry); |
1850 | new_dsec = new_dir->i_security; | 1913 | new_dsec = inode_security(new_dir); |
1851 | 1914 | ||
1852 | ad.type = LSM_AUDIT_DATA_DENTRY; | 1915 | ad.type = LSM_AUDIT_DATA_DENTRY; |
1853 | 1916 | ||
@@ -1875,7 +1938,7 @@ static inline int may_rename(struct inode *old_dir, | |||
1875 | if (rc) | 1938 | if (rc) |
1876 | return rc; | 1939 | return rc; |
1877 | if (d_is_positive(new_dentry)) { | 1940 | if (d_is_positive(new_dentry)) { |
1878 | new_isec = d_backing_inode(new_dentry)->i_security; | 1941 | new_isec = backing_inode_security(new_dentry); |
1879 | new_is_dir = d_is_dir(new_dentry); | 1942 | new_is_dir = d_is_dir(new_dentry); |
1880 | rc = avc_has_perm(sid, new_isec->sid, | 1943 | rc = avc_has_perm(sid, new_isec->sid, |
1881 | new_isec->sclass, | 1944 | new_isec->sclass, |
@@ -2011,8 +2074,8 @@ static int selinux_binder_transfer_file(struct task_struct *from, | |||
2011 | { | 2074 | { |
2012 | u32 sid = task_sid(to); | 2075 | u32 sid = task_sid(to); |
2013 | struct file_security_struct *fsec = file->f_security; | 2076 | struct file_security_struct *fsec = file->f_security; |
2014 | struct inode *inode = d_backing_inode(file->f_path.dentry); | 2077 | struct dentry *dentry = file->f_path.dentry; |
2015 | struct inode_security_struct *isec = inode->i_security; | 2078 | struct inode_security_struct *isec = backing_inode_security(dentry); |
2016 | struct common_audit_data ad; | 2079 | struct common_audit_data ad; |
2017 | int rc; | 2080 | int rc; |
2018 | 2081 | ||
@@ -2028,7 +2091,7 @@ static int selinux_binder_transfer_file(struct task_struct *from, | |||
2028 | return rc; | 2091 | return rc; |
2029 | } | 2092 | } |
2030 | 2093 | ||
2031 | if (unlikely(IS_PRIVATE(inode))) | 2094 | if (unlikely(IS_PRIVATE(d_backing_inode(dentry)))) |
2032 | return 0; | 2095 | return 0; |
2033 | 2096 | ||
2034 | return avc_has_perm(sid, isec->sid, isec->sclass, file_to_av(file), | 2097 | return avc_has_perm(sid, isec->sid, isec->sclass, file_to_av(file), |
@@ -2217,7 +2280,7 @@ static int selinux_bprm_set_creds(struct linux_binprm *bprm) | |||
2217 | 2280 | ||
2218 | old_tsec = current_security(); | 2281 | old_tsec = current_security(); |
2219 | new_tsec = bprm->cred->security; | 2282 | new_tsec = bprm->cred->security; |
2220 | isec = inode->i_security; | 2283 | isec = inode_security(inode); |
2221 | 2284 | ||
2222 | /* Default to the current task SID. */ | 2285 | /* Default to the current task SID. */ |
2223 | new_tsec->sid = old_tsec->sid; | 2286 | new_tsec->sid = old_tsec->sid; |
@@ -2639,7 +2702,7 @@ static int selinux_sb_remount(struct super_block *sb, void *data) | |||
2639 | break; | 2702 | break; |
2640 | case ROOTCONTEXT_MNT: { | 2703 | case ROOTCONTEXT_MNT: { |
2641 | struct inode_security_struct *root_isec; | 2704 | struct inode_security_struct *root_isec; |
2642 | root_isec = d_backing_inode(sb->s_root)->i_security; | 2705 | root_isec = backing_inode_security(sb->s_root); |
2643 | 2706 | ||
2644 | if (bad_option(sbsec, ROOTCONTEXT_MNT, root_isec->sid, sid)) | 2707 | if (bad_option(sbsec, ROOTCONTEXT_MNT, root_isec->sid, sid)) |
2645 | goto out_bad_option; | 2708 | goto out_bad_option; |
@@ -2753,13 +2816,11 @@ static int selinux_inode_init_security(struct inode *inode, struct inode *dir, | |||
2753 | void **value, size_t *len) | 2816 | void **value, size_t *len) |
2754 | { | 2817 | { |
2755 | const struct task_security_struct *tsec = current_security(); | 2818 | const struct task_security_struct *tsec = current_security(); |
2756 | struct inode_security_struct *dsec; | ||
2757 | struct superblock_security_struct *sbsec; | 2819 | struct superblock_security_struct *sbsec; |
2758 | u32 sid, newsid, clen; | 2820 | u32 sid, newsid, clen; |
2759 | int rc; | 2821 | int rc; |
2760 | char *context; | 2822 | char *context; |
2761 | 2823 | ||
2762 | dsec = dir->i_security; | ||
2763 | sbsec = dir->i_sb->s_security; | 2824 | sbsec = dir->i_sb->s_security; |
2764 | 2825 | ||
2765 | sid = tsec->sid; | 2826 | sid = tsec->sid; |
@@ -2777,7 +2838,7 @@ static int selinux_inode_init_security(struct inode *inode, struct inode *dir, | |||
2777 | struct inode_security_struct *isec = inode->i_security; | 2838 | struct inode_security_struct *isec = inode->i_security; |
2778 | isec->sclass = inode_mode_to_security_class(inode->i_mode); | 2839 | isec->sclass = inode_mode_to_security_class(inode->i_mode); |
2779 | isec->sid = newsid; | 2840 | isec->sid = newsid; |
2780 | isec->initialized = 1; | 2841 | isec->initialized = LABEL_INITIALIZED; |
2781 | } | 2842 | } |
2782 | 2843 | ||
2783 | if (!ss_initialized || !(sbsec->flags & SBLABEL_MNT)) | 2844 | if (!ss_initialized || !(sbsec->flags & SBLABEL_MNT)) |
@@ -2858,7 +2919,9 @@ static int selinux_inode_follow_link(struct dentry *dentry, struct inode *inode, | |||
2858 | ad.type = LSM_AUDIT_DATA_DENTRY; | 2919 | ad.type = LSM_AUDIT_DATA_DENTRY; |
2859 | ad.u.dentry = dentry; | 2920 | ad.u.dentry = dentry; |
2860 | sid = cred_sid(cred); | 2921 | sid = cred_sid(cred); |
2861 | isec = inode->i_security; | 2922 | isec = inode_security_rcu(inode, rcu); |
2923 | if (IS_ERR(isec)) | ||
2924 | return PTR_ERR(isec); | ||
2862 | 2925 | ||
2863 | return avc_has_perm_flags(sid, isec->sid, isec->sclass, FILE__READ, &ad, | 2926 | return avc_has_perm_flags(sid, isec->sid, isec->sclass, FILE__READ, &ad, |
2864 | rcu ? MAY_NOT_BLOCK : 0); | 2927 | rcu ? MAY_NOT_BLOCK : 0); |
@@ -2910,7 +2973,9 @@ static int selinux_inode_permission(struct inode *inode, int mask) | |||
2910 | perms = file_mask_to_av(inode->i_mode, mask); | 2973 | perms = file_mask_to_av(inode->i_mode, mask); |
2911 | 2974 | ||
2912 | sid = cred_sid(cred); | 2975 | sid = cred_sid(cred); |
2913 | isec = inode->i_security; | 2976 | isec = inode_security_rcu(inode, flags & MAY_NOT_BLOCK); |
2977 | if (IS_ERR(isec)) | ||
2978 | return PTR_ERR(isec); | ||
2914 | 2979 | ||
2915 | rc = avc_has_perm_noaudit(sid, isec->sid, isec->sclass, perms, 0, &avd); | 2980 | rc = avc_has_perm_noaudit(sid, isec->sid, isec->sclass, perms, 0, &avd); |
2916 | audited = avc_audit_required(perms, &avd, rc, | 2981 | audited = avc_audit_required(perms, &avd, rc, |
@@ -2980,7 +3045,7 @@ static int selinux_inode_setxattr(struct dentry *dentry, const char *name, | |||
2980 | const void *value, size_t size, int flags) | 3045 | const void *value, size_t size, int flags) |
2981 | { | 3046 | { |
2982 | struct inode *inode = d_backing_inode(dentry); | 3047 | struct inode *inode = d_backing_inode(dentry); |
2983 | struct inode_security_struct *isec = inode->i_security; | 3048 | struct inode_security_struct *isec = backing_inode_security(dentry); |
2984 | struct superblock_security_struct *sbsec; | 3049 | struct superblock_security_struct *sbsec; |
2985 | struct common_audit_data ad; | 3050 | struct common_audit_data ad; |
2986 | u32 newsid, sid = current_sid(); | 3051 | u32 newsid, sid = current_sid(); |
@@ -3057,7 +3122,7 @@ static void selinux_inode_post_setxattr(struct dentry *dentry, const char *name, | |||
3057 | int flags) | 3122 | int flags) |
3058 | { | 3123 | { |
3059 | struct inode *inode = d_backing_inode(dentry); | 3124 | struct inode *inode = d_backing_inode(dentry); |
3060 | struct inode_security_struct *isec = inode->i_security; | 3125 | struct inode_security_struct *isec = backing_inode_security(dentry); |
3061 | u32 newsid; | 3126 | u32 newsid; |
3062 | int rc; | 3127 | int rc; |
3063 | 3128 | ||
@@ -3076,7 +3141,7 @@ static void selinux_inode_post_setxattr(struct dentry *dentry, const char *name, | |||
3076 | 3141 | ||
3077 | isec->sclass = inode_mode_to_security_class(inode->i_mode); | 3142 | isec->sclass = inode_mode_to_security_class(inode->i_mode); |
3078 | isec->sid = newsid; | 3143 | isec->sid = newsid; |
3079 | isec->initialized = 1; | 3144 | isec->initialized = LABEL_INITIALIZED; |
3080 | 3145 | ||
3081 | return; | 3146 | return; |
3082 | } | 3147 | } |
@@ -3110,12 +3175,12 @@ static int selinux_inode_removexattr(struct dentry *dentry, const char *name) | |||
3110 | * | 3175 | * |
3111 | * Permission check is handled by selinux_inode_getxattr hook. | 3176 | * Permission check is handled by selinux_inode_getxattr hook. |
3112 | */ | 3177 | */ |
3113 | static int selinux_inode_getsecurity(const struct inode *inode, const char *name, void **buffer, bool alloc) | 3178 | static int selinux_inode_getsecurity(struct inode *inode, const char *name, void **buffer, bool alloc) |
3114 | { | 3179 | { |
3115 | u32 size; | 3180 | u32 size; |
3116 | int error; | 3181 | int error; |
3117 | char *context = NULL; | 3182 | char *context = NULL; |
3118 | struct inode_security_struct *isec = inode->i_security; | 3183 | struct inode_security_struct *isec = inode_security(inode); |
3119 | 3184 | ||
3120 | if (strcmp(name, XATTR_SELINUX_SUFFIX)) | 3185 | if (strcmp(name, XATTR_SELINUX_SUFFIX)) |
3121 | return -EOPNOTSUPP; | 3186 | return -EOPNOTSUPP; |
@@ -3154,7 +3219,7 @@ out_nofree: | |||
3154 | static int selinux_inode_setsecurity(struct inode *inode, const char *name, | 3219 | static int selinux_inode_setsecurity(struct inode *inode, const char *name, |
3155 | const void *value, size_t size, int flags) | 3220 | const void *value, size_t size, int flags) |
3156 | { | 3221 | { |
3157 | struct inode_security_struct *isec = inode->i_security; | 3222 | struct inode_security_struct *isec = inode_security(inode); |
3158 | u32 newsid; | 3223 | u32 newsid; |
3159 | int rc; | 3224 | int rc; |
3160 | 3225 | ||
@@ -3170,7 +3235,7 @@ static int selinux_inode_setsecurity(struct inode *inode, const char *name, | |||
3170 | 3235 | ||
3171 | isec->sclass = inode_mode_to_security_class(inode->i_mode); | 3236 | isec->sclass = inode_mode_to_security_class(inode->i_mode); |
3172 | isec->sid = newsid; | 3237 | isec->sid = newsid; |
3173 | isec->initialized = 1; | 3238 | isec->initialized = LABEL_INITIALIZED; |
3174 | return 0; | 3239 | return 0; |
3175 | } | 3240 | } |
3176 | 3241 | ||
@@ -3182,9 +3247,9 @@ static int selinux_inode_listsecurity(struct inode *inode, char *buffer, size_t | |||
3182 | return len; | 3247 | return len; |
3183 | } | 3248 | } |
3184 | 3249 | ||
3185 | static void selinux_inode_getsecid(const struct inode *inode, u32 *secid) | 3250 | static void selinux_inode_getsecid(struct inode *inode, u32 *secid) |
3186 | { | 3251 | { |
3187 | struct inode_security_struct *isec = inode->i_security; | 3252 | struct inode_security_struct *isec = inode_security(inode); |
3188 | *secid = isec->sid; | 3253 | *secid = isec->sid; |
3189 | } | 3254 | } |
3190 | 3255 | ||
@@ -3207,13 +3272,14 @@ static int selinux_file_permission(struct file *file, int mask) | |||
3207 | { | 3272 | { |
3208 | struct inode *inode = file_inode(file); | 3273 | struct inode *inode = file_inode(file); |
3209 | struct file_security_struct *fsec = file->f_security; | 3274 | struct file_security_struct *fsec = file->f_security; |
3210 | struct inode_security_struct *isec = inode->i_security; | 3275 | struct inode_security_struct *isec; |
3211 | u32 sid = current_sid(); | 3276 | u32 sid = current_sid(); |
3212 | 3277 | ||
3213 | if (!mask) | 3278 | if (!mask) |
3214 | /* No permission to check. Existence test. */ | 3279 | /* No permission to check. Existence test. */ |
3215 | return 0; | 3280 | return 0; |
3216 | 3281 | ||
3282 | isec = inode_security(inode); | ||
3217 | if (sid == fsec->sid && fsec->isid == isec->sid && | 3283 | if (sid == fsec->sid && fsec->isid == isec->sid && |
3218 | fsec->pseqno == avc_policy_seqno()) | 3284 | fsec->pseqno == avc_policy_seqno()) |
3219 | /* No change since file_open check. */ | 3285 | /* No change since file_open check. */ |
@@ -3242,7 +3308,7 @@ static int ioctl_has_perm(const struct cred *cred, struct file *file, | |||
3242 | struct common_audit_data ad; | 3308 | struct common_audit_data ad; |
3243 | struct file_security_struct *fsec = file->f_security; | 3309 | struct file_security_struct *fsec = file->f_security; |
3244 | struct inode *inode = file_inode(file); | 3310 | struct inode *inode = file_inode(file); |
3245 | struct inode_security_struct *isec = inode->i_security; | 3311 | struct inode_security_struct *isec = inode_security(inode); |
3246 | struct lsm_ioctlop_audit ioctl; | 3312 | struct lsm_ioctlop_audit ioctl; |
3247 | u32 ssid = cred_sid(cred); | 3313 | u32 ssid = cred_sid(cred); |
3248 | int rc; | 3314 | int rc; |
@@ -3506,7 +3572,7 @@ static int selinux_file_open(struct file *file, const struct cred *cred) | |||
3506 | struct inode_security_struct *isec; | 3572 | struct inode_security_struct *isec; |
3507 | 3573 | ||
3508 | fsec = file->f_security; | 3574 | fsec = file->f_security; |
3509 | isec = file_inode(file)->i_security; | 3575 | isec = inode_security(file_inode(file)); |
3510 | /* | 3576 | /* |
3511 | * Save inode label and policy sequence number | 3577 | * Save inode label and policy sequence number |
3512 | * at open-time so that selinux_file_permission | 3578 | * at open-time so that selinux_file_permission |
@@ -3624,7 +3690,7 @@ static int selinux_kernel_act_as(struct cred *new, u32 secid) | |||
3624 | */ | 3690 | */ |
3625 | static int selinux_kernel_create_files_as(struct cred *new, struct inode *inode) | 3691 | static int selinux_kernel_create_files_as(struct cred *new, struct inode *inode) |
3626 | { | 3692 | { |
3627 | struct inode_security_struct *isec = inode->i_security; | 3693 | struct inode_security_struct *isec = inode_security(inode); |
3628 | struct task_security_struct *tsec = new->security; | 3694 | struct task_security_struct *tsec = new->security; |
3629 | u32 sid = current_sid(); | 3695 | u32 sid = current_sid(); |
3630 | int ret; | 3696 | int ret; |
@@ -3748,7 +3814,7 @@ static void selinux_task_to_inode(struct task_struct *p, | |||
3748 | u32 sid = task_sid(p); | 3814 | u32 sid = task_sid(p); |
3749 | 3815 | ||
3750 | isec->sid = sid; | 3816 | isec->sid = sid; |
3751 | isec->initialized = 1; | 3817 | isec->initialized = LABEL_INITIALIZED; |
3752 | } | 3818 | } |
3753 | 3819 | ||
3754 | /* Returns error only if unable to parse addresses */ | 3820 | /* Returns error only if unable to parse addresses */ |
@@ -4065,7 +4131,7 @@ static int selinux_socket_post_create(struct socket *sock, int family, | |||
4065 | int type, int protocol, int kern) | 4131 | int type, int protocol, int kern) |
4066 | { | 4132 | { |
4067 | const struct task_security_struct *tsec = current_security(); | 4133 | const struct task_security_struct *tsec = current_security(); |
4068 | struct inode_security_struct *isec = SOCK_INODE(sock)->i_security; | 4134 | struct inode_security_struct *isec = inode_security_novalidate(SOCK_INODE(sock)); |
4069 | struct sk_security_struct *sksec; | 4135 | struct sk_security_struct *sksec; |
4070 | int err = 0; | 4136 | int err = 0; |
4071 | 4137 | ||
@@ -4079,7 +4145,7 @@ static int selinux_socket_post_create(struct socket *sock, int family, | |||
4079 | return err; | 4145 | return err; |
4080 | } | 4146 | } |
4081 | 4147 | ||
4082 | isec->initialized = 1; | 4148 | isec->initialized = LABEL_INITIALIZED; |
4083 | 4149 | ||
4084 | if (sock->sk) { | 4150 | if (sock->sk) { |
4085 | sksec = sock->sk->sk_security; | 4151 | sksec = sock->sk->sk_security; |
@@ -4265,12 +4331,12 @@ static int selinux_socket_accept(struct socket *sock, struct socket *newsock) | |||
4265 | if (err) | 4331 | if (err) |
4266 | return err; | 4332 | return err; |
4267 | 4333 | ||
4268 | newisec = SOCK_INODE(newsock)->i_security; | 4334 | newisec = inode_security_novalidate(SOCK_INODE(newsock)); |
4269 | 4335 | ||
4270 | isec = SOCK_INODE(sock)->i_security; | 4336 | isec = inode_security_novalidate(SOCK_INODE(sock)); |
4271 | newisec->sclass = isec->sclass; | 4337 | newisec->sclass = isec->sclass; |
4272 | newisec->sid = isec->sid; | 4338 | newisec->sid = isec->sid; |
4273 | newisec->initialized = 1; | 4339 | newisec->initialized = LABEL_INITIALIZED; |
4274 | 4340 | ||
4275 | return 0; | 4341 | return 0; |
4276 | } | 4342 | } |
@@ -4605,7 +4671,8 @@ static void selinux_sk_getsecid(struct sock *sk, u32 *secid) | |||
4605 | 4671 | ||
4606 | static void selinux_sock_graft(struct sock *sk, struct socket *parent) | 4672 | static void selinux_sock_graft(struct sock *sk, struct socket *parent) |
4607 | { | 4673 | { |
4608 | struct inode_security_struct *isec = SOCK_INODE(parent)->i_security; | 4674 | struct inode_security_struct *isec = |
4675 | inode_security_novalidate(SOCK_INODE(parent)); | ||
4609 | struct sk_security_struct *sksec = sk->sk_security; | 4676 | struct sk_security_struct *sksec = sk->sk_security; |
4610 | 4677 | ||
4611 | if (sk->sk_family == PF_INET || sk->sk_family == PF_INET6 || | 4678 | if (sk->sk_family == PF_INET || sk->sk_family == PF_INET6 || |
@@ -4785,11 +4852,12 @@ static int selinux_nlmsg_perm(struct sock *sk, struct sk_buff *skb) | |||
4785 | err = selinux_nlmsg_lookup(sksec->sclass, nlh->nlmsg_type, &perm); | 4852 | err = selinux_nlmsg_lookup(sksec->sclass, nlh->nlmsg_type, &perm); |
4786 | if (err) { | 4853 | if (err) { |
4787 | if (err == -EINVAL) { | 4854 | if (err == -EINVAL) { |
4788 | printk(KERN_WARNING | 4855 | pr_warn_ratelimited("SELinux: unrecognized netlink" |
4789 | "SELinux: unrecognized netlink message:" | 4856 | " message: protocol=%hu nlmsg_type=%hu sclass=%s" |
4790 | " protocol=%hu nlmsg_type=%hu sclass=%s\n", | 4857 | " pig=%d comm=%s\n", |
4791 | sk->sk_protocol, nlh->nlmsg_type, | 4858 | sk->sk_protocol, nlh->nlmsg_type, |
4792 | secclass_map[sksec->sclass - 1].name); | 4859 | secclass_map[sksec->sclass - 1].name, |
4860 | task_pid_nr(current), current->comm); | ||
4793 | if (!selinux_enforcing || security_get_allow_unknown()) | 4861 | if (!selinux_enforcing || security_get_allow_unknown()) |
4794 | err = 0; | 4862 | err = 0; |
4795 | } | 4863 | } |
@@ -5762,6 +5830,15 @@ static void selinux_release_secctx(char *secdata, u32 seclen) | |||
5762 | kfree(secdata); | 5830 | kfree(secdata); |
5763 | } | 5831 | } |
5764 | 5832 | ||
5833 | static void selinux_inode_invalidate_secctx(struct inode *inode) | ||
5834 | { | ||
5835 | struct inode_security_struct *isec = inode->i_security; | ||
5836 | |||
5837 | mutex_lock(&isec->lock); | ||
5838 | isec->initialized = LABEL_INVALID; | ||
5839 | mutex_unlock(&isec->lock); | ||
5840 | } | ||
5841 | |||
5765 | /* | 5842 | /* |
5766 | * called with inode->i_mutex locked | 5843 | * called with inode->i_mutex locked |
5767 | */ | 5844 | */ |
@@ -5993,6 +6070,7 @@ static struct security_hook_list selinux_hooks[] = { | |||
5993 | LSM_HOOK_INIT(secid_to_secctx, selinux_secid_to_secctx), | 6070 | LSM_HOOK_INIT(secid_to_secctx, selinux_secid_to_secctx), |
5994 | LSM_HOOK_INIT(secctx_to_secid, selinux_secctx_to_secid), | 6071 | LSM_HOOK_INIT(secctx_to_secid, selinux_secctx_to_secid), |
5995 | LSM_HOOK_INIT(release_secctx, selinux_release_secctx), | 6072 | LSM_HOOK_INIT(release_secctx, selinux_release_secctx), |
6073 | LSM_HOOK_INIT(inode_invalidate_secctx, selinux_inode_invalidate_secctx), | ||
5996 | LSM_HOOK_INIT(inode_notifysecctx, selinux_inode_notifysecctx), | 6074 | LSM_HOOK_INIT(inode_notifysecctx, selinux_inode_notifysecctx), |
5997 | LSM_HOOK_INIT(inode_setsecctx, selinux_inode_setsecctx), | 6075 | LSM_HOOK_INIT(inode_setsecctx, selinux_inode_setsecctx), |
5998 | LSM_HOOK_INIT(inode_getsecctx, selinux_inode_getsecctx), | 6076 | LSM_HOOK_INIT(inode_getsecctx, selinux_inode_getsecctx), |
diff --git a/security/selinux/include/classmap.h b/security/selinux/include/classmap.h index 5a4eef59aeff..ef83c4b85a33 100644 --- a/security/selinux/include/classmap.h +++ b/security/selinux/include/classmap.h | |||
@@ -21,7 +21,7 @@ struct security_class_mapping secclass_map[] = { | |||
21 | { "compute_av", "compute_create", "compute_member", | 21 | { "compute_av", "compute_create", "compute_member", |
22 | "check_context", "load_policy", "compute_relabel", | 22 | "check_context", "load_policy", "compute_relabel", |
23 | "compute_user", "setenforce", "setbool", "setsecparam", | 23 | "compute_user", "setenforce", "setbool", "setsecparam", |
24 | "setcheckreqprot", "read_policy", NULL } }, | 24 | "setcheckreqprot", "read_policy", "validate_trans", NULL } }, |
25 | { "process", | 25 | { "process", |
26 | { "fork", "transition", "sigchld", "sigkill", | 26 | { "fork", "transition", "sigchld", "sigkill", |
27 | "sigstop", "signull", "signal", "ptrace", "getsched", "setsched", | 27 | "sigstop", "signull", "signal", "ptrace", "getsched", "setsched", |
diff --git a/security/selinux/include/objsec.h b/security/selinux/include/objsec.h index 81fa718d5cb3..a2ae05414ba1 100644 --- a/security/selinux/include/objsec.h +++ b/security/selinux/include/objsec.h | |||
@@ -37,6 +37,12 @@ struct task_security_struct { | |||
37 | u32 sockcreate_sid; /* fscreate SID */ | 37 | u32 sockcreate_sid; /* fscreate SID */ |
38 | }; | 38 | }; |
39 | 39 | ||
40 | enum label_initialized { | ||
41 | LABEL_MISSING, /* not initialized */ | ||
42 | LABEL_INITIALIZED, /* inizialized */ | ||
43 | LABEL_INVALID /* invalid */ | ||
44 | }; | ||
45 | |||
40 | struct inode_security_struct { | 46 | struct inode_security_struct { |
41 | struct inode *inode; /* back pointer to inode object */ | 47 | struct inode *inode; /* back pointer to inode object */ |
42 | union { | 48 | union { |
diff --git a/security/selinux/include/security.h b/security/selinux/include/security.h index 223e9fd15d66..38feb55d531a 100644 --- a/security/selinux/include/security.h +++ b/security/selinux/include/security.h | |||
@@ -187,6 +187,9 @@ int security_node_sid(u16 domain, void *addr, u32 addrlen, | |||
187 | int security_validate_transition(u32 oldsid, u32 newsid, u32 tasksid, | 187 | int security_validate_transition(u32 oldsid, u32 newsid, u32 tasksid, |
188 | u16 tclass); | 188 | u16 tclass); |
189 | 189 | ||
190 | int security_validate_transition_user(u32 oldsid, u32 newsid, u32 tasksid, | ||
191 | u16 tclass); | ||
192 | |||
190 | int security_bounded_transition(u32 oldsid, u32 newsid); | 193 | int security_bounded_transition(u32 oldsid, u32 newsid); |
191 | 194 | ||
192 | int security_sid_mls_copy(u32 sid, u32 mls_sid, u32 *new_sid); | 195 | int security_sid_mls_copy(u32 sid, u32 mls_sid, u32 *new_sid); |
diff --git a/security/selinux/selinuxfs.c b/security/selinux/selinuxfs.c index 73c60baa90a4..732c1c77dccd 100644 --- a/security/selinux/selinuxfs.c +++ b/security/selinux/selinuxfs.c | |||
@@ -116,6 +116,7 @@ enum sel_inos { | |||
116 | SEL_DENY_UNKNOWN, /* export unknown deny handling to userspace */ | 116 | SEL_DENY_UNKNOWN, /* export unknown deny handling to userspace */ |
117 | SEL_STATUS, /* export current status using mmap() */ | 117 | SEL_STATUS, /* export current status using mmap() */ |
118 | SEL_POLICY, /* allow userspace to read the in kernel policy */ | 118 | SEL_POLICY, /* allow userspace to read the in kernel policy */ |
119 | SEL_VALIDATE_TRANS, /* compute validatetrans decision */ | ||
119 | SEL_INO_NEXT, /* The next inode number to use */ | 120 | SEL_INO_NEXT, /* The next inode number to use */ |
120 | }; | 121 | }; |
121 | 122 | ||
@@ -632,6 +633,83 @@ static const struct file_operations sel_checkreqprot_ops = { | |||
632 | .llseek = generic_file_llseek, | 633 | .llseek = generic_file_llseek, |
633 | }; | 634 | }; |
634 | 635 | ||
636 | static ssize_t sel_write_validatetrans(struct file *file, | ||
637 | const char __user *buf, | ||
638 | size_t count, loff_t *ppos) | ||
639 | { | ||
640 | char *oldcon = NULL, *newcon = NULL, *taskcon = NULL; | ||
641 | char *req = NULL; | ||
642 | u32 osid, nsid, tsid; | ||
643 | u16 tclass; | ||
644 | int rc; | ||
645 | |||
646 | rc = task_has_security(current, SECURITY__VALIDATE_TRANS); | ||
647 | if (rc) | ||
648 | goto out; | ||
649 | |||
650 | rc = -ENOMEM; | ||
651 | if (count >= PAGE_SIZE) | ||
652 | goto out; | ||
653 | |||
654 | /* No partial writes. */ | ||
655 | rc = -EINVAL; | ||
656 | if (*ppos != 0) | ||
657 | goto out; | ||
658 | |||
659 | rc = -ENOMEM; | ||
660 | req = kzalloc(count + 1, GFP_KERNEL); | ||
661 | if (!req) | ||
662 | goto out; | ||
663 | |||
664 | rc = -EFAULT; | ||
665 | if (copy_from_user(req, buf, count)) | ||
666 | goto out; | ||
667 | |||
668 | rc = -ENOMEM; | ||
669 | oldcon = kzalloc(count + 1, GFP_KERNEL); | ||
670 | if (!oldcon) | ||
671 | goto out; | ||
672 | |||
673 | newcon = kzalloc(count + 1, GFP_KERNEL); | ||
674 | if (!newcon) | ||
675 | goto out; | ||
676 | |||
677 | taskcon = kzalloc(count + 1, GFP_KERNEL); | ||
678 | if (!taskcon) | ||
679 | goto out; | ||
680 | |||
681 | rc = -EINVAL; | ||
682 | if (sscanf(req, "%s %s %hu %s", oldcon, newcon, &tclass, taskcon) != 4) | ||
683 | goto out; | ||
684 | |||
685 | rc = security_context_str_to_sid(oldcon, &osid, GFP_KERNEL); | ||
686 | if (rc) | ||
687 | goto out; | ||
688 | |||
689 | rc = security_context_str_to_sid(newcon, &nsid, GFP_KERNEL); | ||
690 | if (rc) | ||
691 | goto out; | ||
692 | |||
693 | rc = security_context_str_to_sid(taskcon, &tsid, GFP_KERNEL); | ||
694 | if (rc) | ||
695 | goto out; | ||
696 | |||
697 | rc = security_validate_transition_user(osid, nsid, tsid, tclass); | ||
698 | if (!rc) | ||
699 | rc = count; | ||
700 | out: | ||
701 | kfree(req); | ||
702 | kfree(oldcon); | ||
703 | kfree(newcon); | ||
704 | kfree(taskcon); | ||
705 | return rc; | ||
706 | } | ||
707 | |||
708 | static const struct file_operations sel_transition_ops = { | ||
709 | .write = sel_write_validatetrans, | ||
710 | .llseek = generic_file_llseek, | ||
711 | }; | ||
712 | |||
635 | /* | 713 | /* |
636 | * Remaining nodes use transaction based IO methods like nfsd/nfsctl.c | 714 | * Remaining nodes use transaction based IO methods like nfsd/nfsctl.c |
637 | */ | 715 | */ |
@@ -1727,6 +1805,8 @@ static int sel_fill_super(struct super_block *sb, void *data, int silent) | |||
1727 | [SEL_DENY_UNKNOWN] = {"deny_unknown", &sel_handle_unknown_ops, S_IRUGO}, | 1805 | [SEL_DENY_UNKNOWN] = {"deny_unknown", &sel_handle_unknown_ops, S_IRUGO}, |
1728 | [SEL_STATUS] = {"status", &sel_handle_status_ops, S_IRUGO}, | 1806 | [SEL_STATUS] = {"status", &sel_handle_status_ops, S_IRUGO}, |
1729 | [SEL_POLICY] = {"policy", &sel_policy_ops, S_IRUGO}, | 1807 | [SEL_POLICY] = {"policy", &sel_policy_ops, S_IRUGO}, |
1808 | [SEL_VALIDATE_TRANS] = {"validatetrans", &sel_transition_ops, | ||
1809 | S_IWUGO}, | ||
1730 | /* last one */ {""} | 1810 | /* last one */ {""} |
1731 | }; | 1811 | }; |
1732 | ret = simple_fill_super(sb, SELINUX_MAGIC, selinux_files); | 1812 | ret = simple_fill_super(sb, SELINUX_MAGIC, selinux_files); |
diff --git a/security/selinux/ss/services.c b/security/selinux/ss/services.c index ebb5eb3c318c..ebda97333f1b 100644 --- a/security/selinux/ss/services.c +++ b/security/selinux/ss/services.c | |||
@@ -778,8 +778,8 @@ out: | |||
778 | return -EPERM; | 778 | return -EPERM; |
779 | } | 779 | } |
780 | 780 | ||
781 | int security_validate_transition(u32 oldsid, u32 newsid, u32 tasksid, | 781 | static int security_compute_validatetrans(u32 oldsid, u32 newsid, u32 tasksid, |
782 | u16 orig_tclass) | 782 | u16 orig_tclass, bool user) |
783 | { | 783 | { |
784 | struct context *ocontext; | 784 | struct context *ocontext; |
785 | struct context *ncontext; | 785 | struct context *ncontext; |
@@ -794,11 +794,12 @@ int security_validate_transition(u32 oldsid, u32 newsid, u32 tasksid, | |||
794 | 794 | ||
795 | read_lock(&policy_rwlock); | 795 | read_lock(&policy_rwlock); |
796 | 796 | ||
797 | tclass = unmap_class(orig_tclass); | 797 | if (!user) |
798 | tclass = unmap_class(orig_tclass); | ||
799 | else | ||
800 | tclass = orig_tclass; | ||
798 | 801 | ||
799 | if (!tclass || tclass > policydb.p_classes.nprim) { | 802 | if (!tclass || tclass > policydb.p_classes.nprim) { |
800 | printk(KERN_ERR "SELinux: %s: unrecognized class %d\n", | ||
801 | __func__, tclass); | ||
802 | rc = -EINVAL; | 803 | rc = -EINVAL; |
803 | goto out; | 804 | goto out; |
804 | } | 805 | } |
@@ -832,8 +833,13 @@ int security_validate_transition(u32 oldsid, u32 newsid, u32 tasksid, | |||
832 | while (constraint) { | 833 | while (constraint) { |
833 | if (!constraint_expr_eval(ocontext, ncontext, tcontext, | 834 | if (!constraint_expr_eval(ocontext, ncontext, tcontext, |
834 | constraint->expr)) { | 835 | constraint->expr)) { |
835 | rc = security_validtrans_handle_fail(ocontext, ncontext, | 836 | if (user) |
836 | tcontext, tclass); | 837 | rc = -EPERM; |
838 | else | ||
839 | rc = security_validtrans_handle_fail(ocontext, | ||
840 | ncontext, | ||
841 | tcontext, | ||
842 | tclass); | ||
837 | goto out; | 843 | goto out; |
838 | } | 844 | } |
839 | constraint = constraint->next; | 845 | constraint = constraint->next; |
@@ -844,6 +850,20 @@ out: | |||
844 | return rc; | 850 | return rc; |
845 | } | 851 | } |
846 | 852 | ||
853 | int security_validate_transition_user(u32 oldsid, u32 newsid, u32 tasksid, | ||
854 | u16 tclass) | ||
855 | { | ||
856 | return security_compute_validatetrans(oldsid, newsid, tasksid, | ||
857 | tclass, true); | ||
858 | } | ||
859 | |||
860 | int security_validate_transition(u32 oldsid, u32 newsid, u32 tasksid, | ||
861 | u16 orig_tclass) | ||
862 | { | ||
863 | return security_compute_validatetrans(oldsid, newsid, tasksid, | ||
864 | orig_tclass, false); | ||
865 | } | ||
866 | |||
847 | /* | 867 | /* |
848 | * security_bounded_transition - check whether the given | 868 | * security_bounded_transition - check whether the given |
849 | * transition is directed to bounded, or not. | 869 | * transition is directed to bounded, or not. |
diff --git a/security/smack/smack_lsm.c b/security/smack/smack_lsm.c index 37fdd5416a64..8d85435a45d7 100644 --- a/security/smack/smack_lsm.c +++ b/security/smack/smack_lsm.c | |||
@@ -1465,7 +1465,7 @@ static int smack_inode_removexattr(struct dentry *dentry, const char *name) | |||
1465 | * | 1465 | * |
1466 | * Returns the size of the attribute or an error code | 1466 | * Returns the size of the attribute or an error code |
1467 | */ | 1467 | */ |
1468 | static int smack_inode_getsecurity(const struct inode *inode, | 1468 | static int smack_inode_getsecurity(struct inode *inode, |
1469 | const char *name, void **buffer, | 1469 | const char *name, void **buffer, |
1470 | bool alloc) | 1470 | bool alloc) |
1471 | { | 1471 | { |
@@ -1536,7 +1536,7 @@ static int smack_inode_listsecurity(struct inode *inode, char *buffer, | |||
1536 | * @inode: inode to extract the info from | 1536 | * @inode: inode to extract the info from |
1537 | * @secid: where result will be saved | 1537 | * @secid: where result will be saved |
1538 | */ | 1538 | */ |
1539 | static void smack_inode_getsecid(const struct inode *inode, u32 *secid) | 1539 | static void smack_inode_getsecid(struct inode *inode, u32 *secid) |
1540 | { | 1540 | { |
1541 | struct inode_smack *isp = inode->i_security; | 1541 | struct inode_smack *isp = inode->i_security; |
1542 | 1542 | ||
@@ -1858,12 +1858,34 @@ static int smack_file_receive(struct file *file) | |||
1858 | int may = 0; | 1858 | int may = 0; |
1859 | struct smk_audit_info ad; | 1859 | struct smk_audit_info ad; |
1860 | struct inode *inode = file_inode(file); | 1860 | struct inode *inode = file_inode(file); |
1861 | struct socket *sock; | ||
1862 | struct task_smack *tsp; | ||
1863 | struct socket_smack *ssp; | ||
1861 | 1864 | ||
1862 | if (unlikely(IS_PRIVATE(inode))) | 1865 | if (unlikely(IS_PRIVATE(inode))) |
1863 | return 0; | 1866 | return 0; |
1864 | 1867 | ||
1865 | smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_PATH); | 1868 | smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_PATH); |
1866 | smk_ad_setfield_u_fs_path(&ad, file->f_path); | 1869 | smk_ad_setfield_u_fs_path(&ad, file->f_path); |
1870 | |||
1871 | if (S_ISSOCK(inode->i_mode)) { | ||
1872 | sock = SOCKET_I(inode); | ||
1873 | ssp = sock->sk->sk_security; | ||
1874 | tsp = current_security(); | ||
1875 | /* | ||
1876 | * If the receiving process can't write to the | ||
1877 | * passed socket or if the passed socket can't | ||
1878 | * write to the receiving process don't accept | ||
1879 | * the passed socket. | ||
1880 | */ | ||
1881 | rc = smk_access(tsp->smk_task, ssp->smk_out, MAY_WRITE, &ad); | ||
1882 | rc = smk_bu_file(file, may, rc); | ||
1883 | if (rc < 0) | ||
1884 | return rc; | ||
1885 | rc = smk_access(ssp->smk_in, tsp->smk_task, MAY_WRITE, &ad); | ||
1886 | rc = smk_bu_file(file, may, rc); | ||
1887 | return rc; | ||
1888 | } | ||
1867 | /* | 1889 | /* |
1868 | * This code relies on bitmasks. | 1890 | * This code relies on bitmasks. |
1869 | */ | 1891 | */ |
@@ -3756,7 +3778,7 @@ static int smack_socket_sendmsg(struct socket *sock, struct msghdr *msg, | |||
3756 | if (sip == NULL) | 3778 | if (sip == NULL) |
3757 | return 0; | 3779 | return 0; |
3758 | 3780 | ||
3759 | switch (sip->sin_family) { | 3781 | switch (sock->sk->sk_family) { |
3760 | case AF_INET: | 3782 | case AF_INET: |
3761 | rc = smack_netlabel_send(sock->sk, sip); | 3783 | rc = smack_netlabel_send(sock->sk, sip); |
3762 | break; | 3784 | break; |