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

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

Pull general security subsystem updates from James Morris:
"TPM (from Jarkko):
- essential clean up for tpm_crb so that ARM64 and x86 versions do
not distract each other as much as before

- /dev/tpm0 rejects now too short writes (shorter buffer than
specified in the command header

- use DMA-safe buffer in tpm_tis_spi

- otherwise mostly minor fixes.

Smack:
- base support for overlafs

Capabilities:
- BPRM_FCAPS fixes, from Richard Guy Briggs:

The audit subsystem is adding a BPRM_FCAPS record when auditing
setuid application execution (SYSCALL execve). This is not expected
as it was supposed to be limited to when the file system actually
had capabilities in an extended attribute. It lists all
capabilities making the event really ugly to parse what is
happening. The PATH record correctly records the setuid bit and
owner. Suppress the BPRM_FCAPS record on set*id.

TOMOYO:
- Y2038 timestamping fixes"

* 'next-general' of git://git.kernel.org/pub/scm/linux/kernel/git/jmorris/linux-security: (28 commits)
MAINTAINERS: update the IMA, EVM, trusted-keys, encrypted-keys entries
Smack: Base support for overlayfs
MAINTAINERS: remove David Safford as maintainer for encrypted+trusted keys
tomoyo: fix timestamping for y2038
capabilities: audit log other surprising conditions
capabilities: fix logic for effective root or real root
capabilities: invert logic for clarity
capabilities: remove a layer of conditional logic
capabilities: move audit log decision to function
capabilities: use intuitive names for id changes
capabilities: use root_priveleged inline to clarify logic
capabilities: rename has_cap to has_fcap
capabilities: intuitive names for cap gain status
capabilities: factor out cap_bprm_set_creds privileged root
tpm, tpm_tis: use ARRAY_SIZE() to define TPM_HID_USR_IDX
tpm: fix duplicate inline declaration specifier
tpm: fix type of a local variables in tpm_tis_spi.c
tpm: fix type of a local variable in tpm2_map_command()
tpm: fix type of a local variable in tpm2_get_cc_attrs_tbl()
tpm-dev-common: Reject too short writes
...

+383 -277
+4 -9
MAINTAINERS
··· 5219 5219 5220 5220 Extended Verification Module (EVM) 5221 5221 M: Mimi Zohar <zohar@linux.vnet.ibm.com> 5222 - L: linux-ima-devel@lists.sourceforge.net 5223 - L: linux-security-module@vger.kernel.org 5222 + L: linux-integrity@vger.kernel.org 5224 5223 S: Supported 5225 5224 F: security/integrity/evm/ 5226 5225 ··· 6846 6847 INTEGRITY MEASUREMENT ARCHITECTURE (IMA) 6847 6848 M: Mimi Zohar <zohar@linux.vnet.ibm.com> 6848 6849 M: Dmitry Kasatkin <dmitry.kasatkin@gmail.com> 6849 - L: linux-ima-devel@lists.sourceforge.net 6850 - L: linux-ima-user@lists.sourceforge.net 6851 - L: linux-security-module@vger.kernel.org 6850 + L: linux-integrity@vger.kernel.org 6852 6851 T: git git://git.kernel.org/pub/scm/linux/kernel/git/zohar/linux-integrity.git 6853 6852 S: Supported 6854 6853 F: security/integrity/ima/ ··· 7629 7632 7630 7633 KEYS-ENCRYPTED 7631 7634 M: Mimi Zohar <zohar@linux.vnet.ibm.com> 7632 - M: David Safford <safford@us.ibm.com> 7633 - L: linux-security-module@vger.kernel.org 7635 + L: linux-integrity@vger.kernel.org 7634 7636 L: keyrings@vger.kernel.org 7635 7637 S: Supported 7636 7638 F: Documentation/security/keys/trusted-encrypted.rst ··· 7637 7641 F: security/keys/encrypted-keys/ 7638 7642 7639 7643 KEYS-TRUSTED 7640 - M: David Safford <safford@us.ibm.com> 7641 7644 M: Mimi Zohar <zohar@linux.vnet.ibm.com> 7642 - L: linux-security-module@vger.kernel.org 7645 + L: linux-integrity@vger.kernel.org 7643 7646 L: keyrings@vger.kernel.org 7644 7647 S: Supported 7645 7648 F: Documentation/security/keys/trusted-encrypted.rst
+6
drivers/char/tpm/tpm-dev-common.c
··· 110 110 return -EFAULT; 111 111 } 112 112 113 + if (in_size < 6 || 114 + in_size < be32_to_cpu(*((__be32 *) (priv->data_buffer + 2)))) { 115 + mutex_unlock(&priv->buffer_mutex); 116 + return -EINVAL; 117 + } 118 + 113 119 /* atomic tpm command send and result receive. We only hold the ops 114 120 * lock during this period so that the tpm can be unregistered even if 115 121 * the char dev is held open.
+46 -37
drivers/char/tpm/tpm-sysfs.c
··· 20 20 #include <linux/device.h> 21 21 #include "tpm.h" 22 22 23 - #define READ_PUBEK_RESULT_SIZE 314 23 + struct tpm_readpubek_out { 24 + u8 algorithm[4]; 25 + u8 encscheme[2]; 26 + u8 sigscheme[2]; 27 + __be32 paramsize; 28 + u8 parameters[12]; 29 + __be32 keysize; 30 + u8 modulus[256]; 31 + u8 checksum[20]; 32 + } __packed; 33 + 24 34 #define READ_PUBEK_RESULT_MIN_BODY_SIZE (28 + 256) 25 35 #define TPM_ORD_READPUBEK 124 26 - static const struct tpm_input_header tpm_readpubek_header = { 27 - .tag = cpu_to_be16(TPM_TAG_RQU_COMMAND), 28 - .length = cpu_to_be32(30), 29 - .ordinal = cpu_to_be32(TPM_ORD_READPUBEK) 30 - }; 36 + 31 37 static ssize_t pubek_show(struct device *dev, struct device_attribute *attr, 32 38 char *buf) 33 39 { 34 - u8 *data; 35 - struct tpm_cmd_t tpm_cmd; 36 - ssize_t err; 37 - int i, rc; 40 + struct tpm_buf tpm_buf; 41 + struct tpm_readpubek_out *out; 42 + ssize_t rc; 43 + int i; 38 44 char *str = buf; 39 45 struct tpm_chip *chip = to_tpm_chip(dev); 46 + char anti_replay[20]; 40 47 41 - memset(&tpm_cmd, 0, sizeof(tpm_cmd)); 48 + memset(&anti_replay, 0, sizeof(anti_replay)); 42 49 43 - tpm_cmd.header.in = tpm_readpubek_header; 44 - err = tpm_transmit_cmd(chip, NULL, &tpm_cmd, READ_PUBEK_RESULT_SIZE, 45 - READ_PUBEK_RESULT_MIN_BODY_SIZE, 0, 46 - "attempting to read the PUBEK"); 47 - if (err) 48 - goto out; 50 + rc = tpm_buf_init(&tpm_buf, TPM_TAG_RQU_COMMAND, TPM_ORD_READPUBEK); 51 + if (rc) 52 + return rc; 49 53 50 - /* 51 - ignore header 10 bytes 52 - algorithm 32 bits (1 == RSA ) 53 - encscheme 16 bits 54 - sigscheme 16 bits 55 - parameters (RSA 12->bytes: keybit, #primes, expbit) 56 - keylenbytes 32 bits 57 - 256 byte modulus 58 - ignore checksum 20 bytes 59 - */ 60 - data = tpm_cmd.params.readpubek_out_buffer; 54 + tpm_buf_append(&tpm_buf, anti_replay, sizeof(anti_replay)); 55 + 56 + rc = tpm_transmit_cmd(chip, NULL, tpm_buf.data, PAGE_SIZE, 57 + READ_PUBEK_RESULT_MIN_BODY_SIZE, 0, 58 + "attempting to read the PUBEK"); 59 + if (rc) { 60 + tpm_buf_destroy(&tpm_buf); 61 + return 0; 62 + } 63 + 64 + out = (struct tpm_readpubek_out *)&tpm_buf.data[10]; 61 65 str += 62 66 sprintf(str, 63 67 "Algorithm: %02X %02X %02X %02X\n" ··· 72 68 "%02X %02X %02X %02X\n" 73 69 "Modulus length: %d\n" 74 70 "Modulus:\n", 75 - data[0], data[1], data[2], data[3], 76 - data[4], data[5], 77 - data[6], data[7], 78 - data[12], data[13], data[14], data[15], 79 - data[16], data[17], data[18], data[19], 80 - data[20], data[21], data[22], data[23], 81 - be32_to_cpu(*((__be32 *) (data + 24)))); 71 + out->algorithm[0], out->algorithm[1], out->algorithm[2], 72 + out->algorithm[3], 73 + out->encscheme[0], out->encscheme[1], 74 + out->sigscheme[0], out->sigscheme[1], 75 + out->parameters[0], out->parameters[1], 76 + out->parameters[2], out->parameters[3], 77 + out->parameters[4], out->parameters[5], 78 + out->parameters[6], out->parameters[7], 79 + out->parameters[8], out->parameters[9], 80 + out->parameters[10], out->parameters[11], 81 + be32_to_cpu(out->keysize)); 82 82 83 83 for (i = 0; i < 256; i++) { 84 - str += sprintf(str, "%02X ", data[i + 28]); 84 + str += sprintf(str, "%02X ", out->modulus[i]); 85 85 if ((i + 1) % 16 == 0) 86 86 str += sprintf(str, "\n"); 87 87 } 88 - out: 88 + 89 89 rc = str - buf; 90 + tpm_buf_destroy(&tpm_buf); 90 91 return rc; 91 92 } 92 93 static DEVICE_ATTR_RO(pubek);
+1 -14
drivers/char/tpm/tpm.h
··· 345 345 TPM_CAP_PROP_TIS_DURATION = 0x120, 346 346 }; 347 347 348 - struct tpm_readpubek_params_out { 349 - u8 algorithm[4]; 350 - u8 encscheme[2]; 351 - u8 sigscheme[2]; 352 - __be32 paramsize; 353 - u8 parameters[12]; /*assuming RSA*/ 354 - __be32 keysize; 355 - u8 modulus[256]; 356 - u8 checksum[20]; 357 - } __packed; 358 - 359 348 typedef union { 360 349 struct tpm_input_header in; 361 350 struct tpm_output_header out; ··· 374 385 } __packed; 375 386 376 387 typedef union { 377 - struct tpm_readpubek_params_out readpubek_out; 378 - u8 readpubek_out_buffer[sizeof(struct tpm_readpubek_params_out)]; 379 388 struct tpm_pcrread_in pcrread_in; 380 389 struct tpm_pcrread_out pcrread_out; 381 390 struct tpm_getrandom_in getrandom_in; ··· 544 557 } 545 558 #endif 546 559 547 - static inline inline u32 tpm2_rc_value(u32 rc) 560 + static inline u32 tpm2_rc_value(u32 rc) 548 561 { 549 562 return (rc & BIT(7)) ? rc & 0xff : rc; 550 563 }
+22 -51
drivers/char/tpm/tpm2-cmd.c
··· 834 834 }; 835 835 836 836 /** 837 - * tpm2_continue_selftest() - start a self test 838 - * 839 - * @chip: TPM chip to use 840 - * @full: test all commands instead of testing only those that were not 841 - * previously tested. 842 - * 843 - * Return: Same as with tpm_transmit_cmd with exception of RC_TESTING. 844 - */ 845 - static int tpm2_start_selftest(struct tpm_chip *chip, bool full) 846 - { 847 - int rc; 848 - struct tpm2_cmd cmd; 849 - 850 - cmd.header.in = tpm2_selftest_header; 851 - cmd.params.selftest_in.full_test = full; 852 - 853 - rc = tpm_transmit_cmd(chip, NULL, &cmd, TPM2_SELF_TEST_IN_SIZE, 0, 0, 854 - "continue selftest"); 855 - 856 - /* At least some prototype chips seem to give RC_TESTING error 857 - * immediately. This is a workaround for that. 858 - */ 859 - if (rc == TPM2_RC_TESTING) { 860 - dev_warn(&chip->dev, "Got RC_TESTING, ignoring\n"); 861 - rc = 0; 862 - } 863 - 864 - return rc; 865 - } 866 - 867 - /** 868 - * tpm2_do_selftest() - run a full self test 837 + * tpm2_do_selftest() - ensure that all self tests have passed 869 838 * 870 839 * @chip: TPM chip to use 871 840 * 872 841 * Return: Same as with tpm_transmit_cmd. 873 842 * 874 - * During the self test TPM2 commands return with the error code RC_TESTING. 875 - * Waiting is done by issuing PCR read until it executes successfully. 843 + * The TPM can either run all self tests synchronously and then return 844 + * RC_SUCCESS once all tests were successful. Or it can choose to run the tests 845 + * asynchronously and return RC_TESTING immediately while the self tests still 846 + * execute in the background. This function handles both cases and waits until 847 + * all tests have completed. 876 848 */ 877 849 static int tpm2_do_selftest(struct tpm_chip *chip) 878 850 { 879 851 int rc; 880 - unsigned int loops; 881 - unsigned int delay_msec = 100; 882 - unsigned long duration; 883 - int i; 852 + unsigned int delay_msec = 20; 853 + long duration; 854 + struct tpm2_cmd cmd; 884 855 885 - duration = tpm2_calc_ordinal_duration(chip, TPM2_CC_SELF_TEST); 856 + duration = jiffies_to_msecs( 857 + tpm2_calc_ordinal_duration(chip, TPM2_CC_SELF_TEST)); 886 858 887 - loops = jiffies_to_msecs(duration) / delay_msec; 859 + while (duration > 0) { 860 + cmd.header.in = tpm2_selftest_header; 861 + cmd.params.selftest_in.full_test = 0; 888 862 889 - rc = tpm2_start_selftest(chip, true); 890 - if (rc) 891 - return rc; 892 - 893 - for (i = 0; i < loops; i++) { 894 - /* Attempt to read a PCR value */ 895 - rc = tpm2_pcr_read(chip, 0, NULL); 896 - if (rc < 0) 897 - break; 863 + rc = tpm_transmit_cmd(chip, NULL, &cmd, TPM2_SELF_TEST_IN_SIZE, 864 + 0, 0, "continue selftest"); 898 865 899 866 if (rc != TPM2_RC_TESTING) 900 867 break; 901 868 902 869 tpm_msleep(delay_msec); 870 + duration -= delay_msec; 871 + 872 + /* wait longer the next round */ 873 + delay_msec *= 2; 903 874 } 904 875 905 876 return rc; ··· 980 1009 { 981 1010 struct tpm_buf buf; 982 1011 u32 nr_commands; 983 - u32 *attrs; 1012 + __be32 *attrs; 984 1013 u32 cc; 985 1014 int i; 986 1015 int rc; ··· 1020 1049 1021 1050 chip->nr_commands = nr_commands; 1022 1051 1023 - attrs = (u32 *)&buf.data[TPM_HEADER_SIZE + 9]; 1052 + attrs = (__be32 *)&buf.data[TPM_HEADER_SIZE + 9]; 1024 1053 for (i = 0; i < nr_commands; i++, attrs++) { 1025 1054 chip->cc_attrs_tbl[i] = be32_to_cpup(attrs); 1026 1055 cc = chip->cc_attrs_tbl[i] & 0xFFFF;
+2 -2
drivers/char/tpm/tpm2-space.c
··· 242 242 struct tpm_space *space = &chip->work_space; 243 243 unsigned int nr_handles; 244 244 u32 attrs; 245 - u32 *handle; 245 + __be32 *handle; 246 246 int i; 247 247 248 248 i = tpm2_find_cc(chip, cc); ··· 252 252 attrs = chip->cc_attrs_tbl[i]; 253 253 nr_handles = (attrs >> TPM2_CC_ATTR_CHANDLES) & GENMASK(2, 0); 254 254 255 - handle = (u32 *)&cmd[TPM_HEADER_SIZE]; 255 + handle = (__be32 *)&cmd[TPM_HEADER_SIZE]; 256 256 for (i = 0; i < nr_handles; i++, handle++) { 257 257 if ((be32_to_cpu(*handle) & 0xFF000000) == TPM2_HT_TRANSIENT) { 258 258 if (!tpm2_map_to_phandle(space, handle))
+29 -30
drivers/char/tpm/tpm_crb.c
··· 92 92 CRB_DRV_STS_COMPLETE = BIT(0), 93 93 }; 94 94 95 - enum crb_flags { 96 - CRB_FL_ACPI_START = BIT(0), 97 - CRB_FL_CRB_START = BIT(1), 98 - CRB_FL_CRB_SMC_START = BIT(2), 99 - }; 100 - 101 95 struct crb_priv { 102 - unsigned int flags; 96 + u32 sm; 97 + const char *hid; 103 98 void __iomem *iobase; 104 99 struct crb_regs_head __iomem *regs_h; 105 100 struct crb_regs_tail __iomem *regs_t; ··· 123 128 * Anyhow, we do not wait here as a consequent CMD_READY request 124 129 * will be handled correctly even if idle was not completed. 125 130 * 126 - * The function does nothing for devices with ACPI-start method. 131 + * The function does nothing for devices with ACPI-start method 132 + * or SMC-start method. 127 133 * 128 134 * Return: 0 always 129 135 */ 130 136 static int __maybe_unused crb_go_idle(struct device *dev, struct crb_priv *priv) 131 137 { 132 - if ((priv->flags & CRB_FL_ACPI_START) || 133 - (priv->flags & CRB_FL_CRB_SMC_START)) 138 + if ((priv->sm == ACPI_TPM2_START_METHOD) || 139 + (priv->sm == ACPI_TPM2_COMMAND_BUFFER_WITH_START_METHOD) || 140 + (priv->sm == ACPI_TPM2_COMMAND_BUFFER_WITH_ARM_SMC)) 134 141 return 0; 135 142 136 143 iowrite32(CRB_CTRL_REQ_GO_IDLE, &priv->regs_t->ctrl_req); ··· 171 174 * The device should respond within TIMEOUT_C. 172 175 * 173 176 * The function does nothing for devices with ACPI-start method 177 + * or SMC-start method. 174 178 * 175 179 * Return: 0 on success -ETIME on timeout; 176 180 */ 177 181 static int __maybe_unused crb_cmd_ready(struct device *dev, 178 182 struct crb_priv *priv) 179 183 { 180 - if ((priv->flags & CRB_FL_ACPI_START) || 181 - (priv->flags & CRB_FL_CRB_SMC_START)) 184 + if ((priv->sm == ACPI_TPM2_START_METHOD) || 185 + (priv->sm == ACPI_TPM2_COMMAND_BUFFER_WITH_START_METHOD) || 186 + (priv->sm == ACPI_TPM2_COMMAND_BUFFER_WITH_ARM_SMC)) 182 187 return 0; 183 188 184 189 iowrite32(CRB_CTRL_REQ_CMD_READY, &priv->regs_t->ctrl_req); ··· 324 325 /* Make sure that cmd is populated before issuing start. */ 325 326 wmb(); 326 327 327 - if (priv->flags & CRB_FL_CRB_START) 328 + /* The reason for the extra quirk is that the PTT in 4th Gen Core CPUs 329 + * report only ACPI start but in practice seems to require both 330 + * CRB start, hence invoking CRB start method if hid == MSFT0101. 331 + */ 332 + if ((priv->sm == ACPI_TPM2_COMMAND_BUFFER) || 333 + (priv->sm == ACPI_TPM2_MEMORY_MAPPED) || 334 + (!strcmp(priv->hid, "MSFT0101"))) 328 335 iowrite32(CRB_START_INVOKE, &priv->regs_t->ctrl_start); 329 336 330 - if (priv->flags & CRB_FL_ACPI_START) 337 + if ((priv->sm == ACPI_TPM2_START_METHOD) || 338 + (priv->sm == ACPI_TPM2_COMMAND_BUFFER_WITH_START_METHOD)) 331 339 rc = crb_do_acpi_start(chip); 332 340 333 - if (priv->flags & CRB_FL_CRB_SMC_START) { 341 + if (priv->sm == ACPI_TPM2_COMMAND_BUFFER_WITH_ARM_SMC) { 334 342 iowrite32(CRB_START_INVOKE, &priv->regs_t->ctrl_start); 335 343 rc = tpm_crb_smc_start(&chip->dev, priv->smc_func_id); 336 344 } ··· 351 345 352 346 iowrite32(CRB_CANCEL_INVOKE, &priv->regs_t->ctrl_cancel); 353 347 354 - if ((priv->flags & CRB_FL_ACPI_START) && crb_do_acpi_start(chip)) 348 + if (((priv->sm == ACPI_TPM2_START_METHOD) || 349 + (priv->sm == ACPI_TPM2_COMMAND_BUFFER_WITH_START_METHOD)) && 350 + crb_do_acpi_start(chip)) 355 351 dev_err(&chip->dev, "ACPI Start failed\n"); 356 352 } 357 353 ··· 466 458 * the control area, as one nice sane region except for some older 467 459 * stuff that puts the control area outside the ACPI IO region. 468 460 */ 469 - if (!(priv->flags & CRB_FL_ACPI_START)) { 461 + if ((priv->sm == ACPI_TPM2_COMMAND_BUFFER) || 462 + (priv->sm == ACPI_TPM2_MEMORY_MAPPED)) { 470 463 if (buf->control_address == io_res.start + 471 464 sizeof(*priv->regs_h)) 472 465 priv->regs_h = priv->iobase; ··· 561 552 if (!priv) 562 553 return -ENOMEM; 563 554 564 - /* The reason for the extra quirk is that the PTT in 4th Gen Core CPUs 565 - * report only ACPI start but in practice seems to require both 566 - * ACPI start and CRB start. 567 - */ 568 - if (sm == ACPI_TPM2_COMMAND_BUFFER || sm == ACPI_TPM2_MEMORY_MAPPED || 569 - !strcmp(acpi_device_hid(device), "MSFT0101")) 570 - priv->flags |= CRB_FL_CRB_START; 571 - 572 - if (sm == ACPI_TPM2_START_METHOD || 573 - sm == ACPI_TPM2_COMMAND_BUFFER_WITH_START_METHOD) 574 - priv->flags |= CRB_FL_ACPI_START; 575 - 576 555 if (sm == ACPI_TPM2_COMMAND_BUFFER_WITH_ARM_SMC) { 577 556 if (buf->header.length < (sizeof(*buf) + sizeof(*crb_smc))) { 578 557 dev_err(dev, ··· 571 574 } 572 575 crb_smc = ACPI_ADD_PTR(struct tpm2_crb_smc, buf, sizeof(*buf)); 573 576 priv->smc_func_id = crb_smc->smc_func_id; 574 - priv->flags |= CRB_FL_CRB_SMC_START; 575 577 } 578 + 579 + priv->sm = sm; 580 + priv->hid = acpi_device_hid(device); 576 581 577 582 rc = crb_map_io(device, priv, buf); 578 583 if (rc)
+3 -2
drivers/char/tpm/tpm_tis.c
··· 30 30 #include <linux/freezer.h> 31 31 #include <linux/of.h> 32 32 #include <linux/of_device.h> 33 + #include <linux/kernel.h> 33 34 #include "tpm.h" 34 35 #include "tpm_tis_core.h" 35 36 ··· 224 223 } 225 224 226 225 static int tpm_tcg_write_bytes(struct tpm_tis_data *data, u32 addr, u16 len, 227 - u8 *value) 226 + const u8 *value) 228 227 { 229 228 struct tpm_tis_tcg_phy *phy = to_tpm_tis_tcg_phy(data); 230 229 ··· 366 365 }, 367 366 }; 368 367 369 - #define TIS_HID_USR_IDX sizeof(tpm_pnp_tbl)/sizeof(struct pnp_device_id) -2 368 + #define TIS_HID_USR_IDX (ARRAY_SIZE(tpm_pnp_tbl) - 2) 370 369 module_param_string(hid, tpm_pnp_tbl[TIS_HID_USR_IDX].id, 371 370 sizeof(tpm_pnp_tbl[TIS_HID_USR_IDX].id), 0444); 372 371 MODULE_PARM_DESC(hid, "Set additional specific HID for this driver to probe");
+3 -3
drivers/char/tpm/tpm_tis_core.c
··· 252 252 * tpm.c can skip polling for the data to be available as the interrupt is 253 253 * waited for here 254 254 */ 255 - static int tpm_tis_send_data(struct tpm_chip *chip, u8 *buf, size_t len) 255 + static int tpm_tis_send_data(struct tpm_chip *chip, const u8 *buf, size_t len) 256 256 { 257 257 struct tpm_tis_data *priv = dev_get_drvdata(&chip->dev); 258 258 int rc, status, burstcnt; ··· 343 343 * tpm.c can skip polling for the data to be available as the interrupt is 344 344 * waited for here 345 345 */ 346 - static int tpm_tis_send_main(struct tpm_chip *chip, u8 *buf, size_t len) 346 + static int tpm_tis_send_main(struct tpm_chip *chip, const u8 *buf, size_t len) 347 347 { 348 348 struct tpm_tis_data *priv = dev_get_drvdata(&chip->dev); 349 349 int rc; ··· 445 445 { 446 446 struct tpm_tis_data *priv = dev_get_drvdata(&chip->dev); 447 447 int rc = 0; 448 - u8 cmd_getticks[] = { 448 + static const u8 cmd_getticks[] = { 449 449 0x00, 0xc1, 0x00, 0x00, 0x00, 0x0a, 450 450 0x00, 0x00, 0x00, 0xf1 451 451 };
+2 -2
drivers/char/tpm/tpm_tis_core.h
··· 98 98 int (*read_bytes)(struct tpm_tis_data *data, u32 addr, u16 len, 99 99 u8 *result); 100 100 int (*write_bytes)(struct tpm_tis_data *data, u32 addr, u16 len, 101 - u8 *value); 101 + const u8 *value); 102 102 int (*read16)(struct tpm_tis_data *data, u32 addr, u16 *result); 103 103 int (*read32)(struct tpm_tis_data *data, u32 addr, u32 *result); 104 104 int (*write32)(struct tpm_tis_data *data, u32 addr, u32 src); ··· 128 128 } 129 129 130 130 static inline int tpm_tis_write_bytes(struct tpm_tis_data *data, u32 addr, 131 - u16 len, u8 *value) 131 + u16 len, const u8 *value) 132 132 { 133 133 return data->phy_ops->write_bytes(data, addr, len, value); 134 134 }
+45 -28
drivers/char/tpm/tpm_tis_spi.c
··· 46 46 struct tpm_tis_spi_phy { 47 47 struct tpm_tis_data priv; 48 48 struct spi_device *spi_device; 49 - 50 - u8 tx_buf[4]; 51 - u8 rx_buf[4]; 49 + u8 *iobuf; 52 50 }; 53 51 54 52 static inline struct tpm_tis_spi_phy *to_tpm_tis_spi_phy(struct tpm_tis_data *data) ··· 55 57 } 56 58 57 59 static int tpm_tis_spi_transfer(struct tpm_tis_data *data, u32 addr, u16 len, 58 - u8 *buffer, u8 direction) 60 + u8 *in, const u8 *out) 59 61 { 60 62 struct tpm_tis_spi_phy *phy = to_tpm_tis_spi_phy(data); 61 63 int ret = 0; ··· 69 71 while (len) { 70 72 transfer_len = min_t(u16, len, MAX_SPI_FRAMESIZE); 71 73 72 - phy->tx_buf[0] = direction | (transfer_len - 1); 73 - phy->tx_buf[1] = 0xd4; 74 - phy->tx_buf[2] = addr >> 8; 75 - phy->tx_buf[3] = addr; 74 + phy->iobuf[0] = (in ? 0x80 : 0) | (transfer_len - 1); 75 + phy->iobuf[1] = 0xd4; 76 + phy->iobuf[2] = addr >> 8; 77 + phy->iobuf[3] = addr; 76 78 77 79 memset(&spi_xfer, 0, sizeof(spi_xfer)); 78 - spi_xfer.tx_buf = phy->tx_buf; 79 - spi_xfer.rx_buf = phy->rx_buf; 80 + spi_xfer.tx_buf = phy->iobuf; 81 + spi_xfer.rx_buf = phy->iobuf; 80 82 spi_xfer.len = 4; 81 83 spi_xfer.cs_change = 1; 82 84 ··· 86 88 if (ret < 0) 87 89 goto exit; 88 90 89 - if ((phy->rx_buf[3] & 0x01) == 0) { 91 + if ((phy->iobuf[3] & 0x01) == 0) { 90 92 // handle SPI wait states 91 - phy->tx_buf[0] = 0; 93 + phy->iobuf[0] = 0; 92 94 93 95 for (i = 0; i < TPM_RETRY; i++) { 94 96 spi_xfer.len = 1; ··· 97 99 ret = spi_sync_locked(phy->spi_device, &m); 98 100 if (ret < 0) 99 101 goto exit; 100 - if (phy->rx_buf[0] & 0x01) 102 + if (phy->iobuf[0] & 0x01) 101 103 break; 102 104 } 103 105 ··· 111 113 spi_xfer.len = transfer_len; 112 114 spi_xfer.delay_usecs = 5; 113 115 114 - if (direction) { 116 + if (in) { 115 117 spi_xfer.tx_buf = NULL; 116 - spi_xfer.rx_buf = buffer; 117 - } else { 118 - spi_xfer.tx_buf = buffer; 118 + } else if (out) { 119 119 spi_xfer.rx_buf = NULL; 120 + memcpy(phy->iobuf, out, transfer_len); 121 + out += transfer_len; 120 122 } 121 123 122 124 spi_message_init(&m); ··· 125 127 if (ret < 0) 126 128 goto exit; 127 129 130 + if (in) { 131 + memcpy(in, phy->iobuf, transfer_len); 132 + in += transfer_len; 133 + } 134 + 128 135 len -= transfer_len; 129 - buffer += transfer_len; 130 136 } 131 137 132 138 exit: ··· 141 139 static int tpm_tis_spi_read_bytes(struct tpm_tis_data *data, u32 addr, 142 140 u16 len, u8 *result) 143 141 { 144 - return tpm_tis_spi_transfer(data, addr, len, result, 0x80); 142 + return tpm_tis_spi_transfer(data, addr, len, result, NULL); 145 143 } 146 144 147 145 static int tpm_tis_spi_write_bytes(struct tpm_tis_data *data, u32 addr, 148 - u16 len, u8 *value) 146 + u16 len, const u8 *value) 149 147 { 150 - return tpm_tis_spi_transfer(data, addr, len, value, 0); 148 + return tpm_tis_spi_transfer(data, addr, len, NULL, value); 151 149 } 152 150 153 151 static int tpm_tis_spi_read16(struct tpm_tis_data *data, u32 addr, u16 *result) 154 152 { 153 + __le16 result_le; 155 154 int rc; 156 155 157 - rc = data->phy_ops->read_bytes(data, addr, sizeof(u16), (u8 *)result); 156 + rc = data->phy_ops->read_bytes(data, addr, sizeof(u16), 157 + (u8 *)&result_le); 158 158 if (!rc) 159 - *result = le16_to_cpu(*result); 159 + *result = le16_to_cpu(result_le); 160 + 160 161 return rc; 161 162 } 162 163 163 164 static int tpm_tis_spi_read32(struct tpm_tis_data *data, u32 addr, u32 *result) 164 165 { 166 + __le32 result_le; 165 167 int rc; 166 168 167 - rc = data->phy_ops->read_bytes(data, addr, sizeof(u32), (u8 *)result); 169 + rc = data->phy_ops->read_bytes(data, addr, sizeof(u32), 170 + (u8 *)&result_le); 168 171 if (!rc) 169 - *result = le32_to_cpu(*result); 172 + *result = le32_to_cpu(result_le); 173 + 170 174 return rc; 171 175 } 172 176 173 177 static int tpm_tis_spi_write32(struct tpm_tis_data *data, u32 addr, u32 value) 174 178 { 175 - value = cpu_to_le32(value); 176 - return data->phy_ops->write_bytes(data, addr, sizeof(u32), 177 - (u8 *)&value); 179 + __le32 value_le; 180 + int rc; 181 + 182 + value_le = cpu_to_le32(value); 183 + rc = data->phy_ops->write_bytes(data, addr, sizeof(u32), 184 + (u8 *)&value_le); 185 + 186 + return rc; 178 187 } 179 188 180 189 static const struct tpm_tis_phy_ops tpm_spi_phy_ops = { ··· 206 193 return -ENOMEM; 207 194 208 195 phy->spi_device = dev; 196 + 197 + phy->iobuf = devm_kmalloc(&dev->dev, MAX_SPI_FRAMESIZE, GFP_KERNEL); 198 + if (!phy->iobuf) 199 + return -ENOMEM; 209 200 210 201 return tpm_tis_core_init(&dev->dev, &phy->priv, -1, &tpm_spi_phy_ops, 211 202 NULL);
+128 -65
security/commoncap.c
··· 536 536 static inline int bprm_caps_from_vfs_caps(struct cpu_vfs_cap_data *caps, 537 537 struct linux_binprm *bprm, 538 538 bool *effective, 539 - bool *has_cap) 539 + bool *has_fcap) 540 540 { 541 541 struct cred *new = bprm->cred; 542 542 unsigned i; ··· 546 546 *effective = true; 547 547 548 548 if (caps->magic_etc & VFS_CAP_REVISION_MASK) 549 - *has_cap = true; 549 + *has_fcap = true; 550 550 551 551 CAP_FOR_EACH_U32(i) { 552 552 __u32 permitted = caps->permitted.cap[i]; ··· 653 653 * its xattrs and, if present, apply them to the proposed credentials being 654 654 * constructed by execve(). 655 655 */ 656 - static int get_file_caps(struct linux_binprm *bprm, bool *effective, bool *has_cap) 656 + static int get_file_caps(struct linux_binprm *bprm, bool *effective, bool *has_fcap) 657 657 { 658 658 int rc = 0; 659 659 struct cpu_vfs_cap_data vcaps; ··· 684 684 goto out; 685 685 } 686 686 687 - rc = bprm_caps_from_vfs_caps(&vcaps, bprm, effective, has_cap); 687 + rc = bprm_caps_from_vfs_caps(&vcaps, bprm, effective, has_fcap); 688 688 if (rc == -EINVAL) 689 689 printk(KERN_NOTICE "%s: cap_from_disk returned %d for %s\n", 690 690 __func__, rc, bprm->filename); ··· 694 694 cap_clear(bprm->cred->cap_permitted); 695 695 696 696 return rc; 697 + } 698 + 699 + static inline bool root_privileged(void) { return !issecure(SECURE_NOROOT); } 700 + 701 + static inline bool __is_real(kuid_t uid, struct cred *cred) 702 + { return uid_eq(cred->uid, uid); } 703 + 704 + static inline bool __is_eff(kuid_t uid, struct cred *cred) 705 + { return uid_eq(cred->euid, uid); } 706 + 707 + static inline bool __is_suid(kuid_t uid, struct cred *cred) 708 + { return !__is_real(uid, cred) && __is_eff(uid, cred); } 709 + 710 + /* 711 + * handle_privileged_root - Handle case of privileged root 712 + * @bprm: The execution parameters, including the proposed creds 713 + * @has_fcap: Are any file capabilities set? 714 + * @effective: Do we have effective root privilege? 715 + * @root_uid: This namespace' root UID WRT initial USER namespace 716 + * 717 + * Handle the case where root is privileged and hasn't been neutered by 718 + * SECURE_NOROOT. If file capabilities are set, they won't be combined with 719 + * set UID root and nothing is changed. If we are root, cap_permitted is 720 + * updated. If we have become set UID root, the effective bit is set. 721 + */ 722 + static void handle_privileged_root(struct linux_binprm *bprm, bool has_fcap, 723 + bool *effective, kuid_t root_uid) 724 + { 725 + const struct cred *old = current_cred(); 726 + struct cred *new = bprm->cred; 727 + 728 + if (!root_privileged()) 729 + return; 730 + /* 731 + * If the legacy file capability is set, then don't set privs 732 + * for a setuid root binary run by a non-root user. Do set it 733 + * for a root user just to cause least surprise to an admin. 734 + */ 735 + if (has_fcap && __is_suid(root_uid, new)) { 736 + warn_setuid_and_fcaps_mixed(bprm->filename); 737 + return; 738 + } 739 + /* 740 + * To support inheritance of root-permissions and suid-root 741 + * executables under compatibility mode, we override the 742 + * capability sets for the file. 743 + */ 744 + if (__is_eff(root_uid, new) || __is_real(root_uid, new)) { 745 + /* pP' = (cap_bset & ~0) | (pI & ~0) */ 746 + new->cap_permitted = cap_combine(old->cap_bset, 747 + old->cap_inheritable); 748 + } 749 + /* 750 + * If only the real uid is 0, we do not set the effective bit. 751 + */ 752 + if (__is_eff(root_uid, new)) 753 + *effective = true; 754 + } 755 + 756 + #define __cap_gained(field, target, source) \ 757 + !cap_issubset(target->cap_##field, source->cap_##field) 758 + #define __cap_grew(target, source, cred) \ 759 + !cap_issubset(cred->cap_##target, cred->cap_##source) 760 + #define __cap_full(field, cred) \ 761 + cap_issubset(CAP_FULL_SET, cred->cap_##field) 762 + 763 + static inline bool __is_setuid(struct cred *new, const struct cred *old) 764 + { return !uid_eq(new->euid, old->uid); } 765 + 766 + static inline bool __is_setgid(struct cred *new, const struct cred *old) 767 + { return !gid_eq(new->egid, old->gid); } 768 + 769 + /* 770 + * 1) Audit candidate if current->cap_effective is set 771 + * 772 + * We do not bother to audit if 3 things are true: 773 + * 1) cap_effective has all caps 774 + * 2) we became root *OR* are were already root 775 + * 3) root is supposed to have all caps (SECURE_NOROOT) 776 + * Since this is just a normal root execing a process. 777 + * 778 + * Number 1 above might fail if you don't have a full bset, but I think 779 + * that is interesting information to audit. 780 + * 781 + * A number of other conditions require logging: 782 + * 2) something prevented setuid root getting all caps 783 + * 3) non-setuid root gets fcaps 784 + * 4) non-setuid root gets ambient 785 + */ 786 + static inline bool nonroot_raised_pE(struct cred *new, const struct cred *old, 787 + kuid_t root, bool has_fcap) 788 + { 789 + bool ret = false; 790 + 791 + if ((__cap_grew(effective, ambient, new) && 792 + !(__cap_full(effective, new) && 793 + (__is_eff(root, new) || __is_real(root, new)) && 794 + root_privileged())) || 795 + (root_privileged() && 796 + __is_suid(root, new) && 797 + !__cap_full(effective, new)) || 798 + (!__is_setuid(new, old) && 799 + ((has_fcap && 800 + __cap_gained(permitted, new, old)) || 801 + __cap_gained(ambient, new, old)))) 802 + 803 + ret = true; 804 + 805 + return ret; 697 806 } 698 807 699 808 /** ··· 817 708 { 818 709 const struct cred *old = current_cred(); 819 710 struct cred *new = bprm->cred; 820 - bool effective, has_cap = false, is_setid; 711 + bool effective = false, has_fcap = false, is_setid; 821 712 int ret; 822 713 kuid_t root_uid; 823 714 824 715 if (WARN_ON(!cap_ambient_invariant_ok(old))) 825 716 return -EPERM; 826 717 827 - effective = false; 828 - ret = get_file_caps(bprm, &effective, &has_cap); 718 + ret = get_file_caps(bprm, &effective, &has_fcap); 829 719 if (ret < 0) 830 720 return ret; 831 721 832 722 root_uid = make_kuid(new->user_ns, 0); 833 723 834 - if (!issecure(SECURE_NOROOT)) { 835 - /* 836 - * If the legacy file capability is set, then don't set privs 837 - * for a setuid root binary run by a non-root user. Do set it 838 - * for a root user just to cause least surprise to an admin. 839 - */ 840 - if (has_cap && !uid_eq(new->uid, root_uid) && uid_eq(new->euid, root_uid)) { 841 - warn_setuid_and_fcaps_mixed(bprm->filename); 842 - goto skip; 843 - } 844 - /* 845 - * To support inheritance of root-permissions and suid-root 846 - * executables under compatibility mode, we override the 847 - * capability sets for the file. 848 - * 849 - * If only the real uid is 0, we do not set the effective bit. 850 - */ 851 - if (uid_eq(new->euid, root_uid) || uid_eq(new->uid, root_uid)) { 852 - /* pP' = (cap_bset & ~0) | (pI & ~0) */ 853 - new->cap_permitted = cap_combine(old->cap_bset, 854 - old->cap_inheritable); 855 - } 856 - if (uid_eq(new->euid, root_uid)) 857 - effective = true; 858 - } 859 - skip: 724 + handle_privileged_root(bprm, has_fcap, &effective, root_uid); 860 725 861 726 /* if we have fs caps, clear dangerous personality flags */ 862 - if (!cap_issubset(new->cap_permitted, old->cap_permitted)) 727 + if (__cap_gained(permitted, new, old)) 863 728 bprm->per_clear |= PER_CLEAR_ON_SETID; 864 - 865 729 866 730 /* Don't let someone trace a set[ug]id/setpcap binary with the revised 867 731 * credentials unless they have the appropriate permit. 868 732 * 869 733 * In addition, if NO_NEW_PRIVS, then ensure we get no new privs. 870 734 */ 871 - is_setid = !uid_eq(new->euid, old->uid) || !gid_eq(new->egid, old->gid); 735 + is_setid = __is_setuid(new, old) || __is_setgid(new, old); 872 736 873 - if ((is_setid || 874 - !cap_issubset(new->cap_permitted, old->cap_permitted)) && 737 + if ((is_setid || __cap_gained(permitted, new, old)) && 875 738 ((bprm->unsafe & ~LSM_UNSAFE_PTRACE) || 876 739 !ptracer_capable(current, new->user_ns))) { 877 740 /* downgrade; they get no more than they had, and maybe less */ ··· 860 779 new->sgid = new->fsgid = new->egid; 861 780 862 781 /* File caps or setid cancels ambient. */ 863 - if (has_cap || is_setid) 782 + if (has_fcap || is_setid) 864 783 cap_clear(new->cap_ambient); 865 784 866 785 /* ··· 881 800 if (WARN_ON(!cap_ambient_invariant_ok(new))) 882 801 return -EPERM; 883 802 884 - /* 885 - * Audit candidate if current->cap_effective is set 886 - * 887 - * We do not bother to audit if 3 things are true: 888 - * 1) cap_effective has all caps 889 - * 2) we are root 890 - * 3) root is supposed to have all caps (SECURE_NOROOT) 891 - * Since this is just a normal root execing a process. 892 - * 893 - * Number 1 above might fail if you don't have a full bset, but I think 894 - * that is interesting information to audit. 895 - */ 896 - if (!cap_issubset(new->cap_effective, new->cap_ambient)) { 897 - if (!cap_issubset(CAP_FULL_SET, new->cap_effective) || 898 - !uid_eq(new->euid, root_uid) || !uid_eq(new->uid, root_uid) || 899 - issecure(SECURE_NOROOT)) { 900 - ret = audit_log_bprm_fcaps(bprm, new, old); 901 - if (ret < 0) 902 - return ret; 903 - } 803 + if (nonroot_raised_pE(new, old, root_uid, has_fcap)) { 804 + ret = audit_log_bprm_fcaps(bprm, new, old); 805 + if (ret < 0) 806 + return ret; 904 807 } 905 808 906 809 new->securebits &= ~issecure_mask(SECURE_KEEP_CAPS); ··· 894 829 895 830 /* Check for privilege-elevated exec. */ 896 831 bprm->cap_elevated = 0; 897 - if (is_setid) { 832 + if (is_setid || 833 + (!__is_real(root_uid, new) && 834 + (effective || 835 + __cap_grew(permitted, ambient, new)))) 898 836 bprm->cap_elevated = 1; 899 - } else if (!uid_eq(new->uid, root_uid)) { 900 - if (effective || 901 - !cap_issubset(new->cap_permitted, new->cap_ambient)) 902 - bprm->cap_elevated = 1; 903 - } 904 837 905 838 return 0; 906 839 }
+79
security/smack/smack_lsm.c
··· 4600 4600 return 0; 4601 4601 } 4602 4602 4603 + static int smack_inode_copy_up(struct dentry *dentry, struct cred **new) 4604 + { 4605 + 4606 + struct task_smack *tsp; 4607 + struct smack_known *skp; 4608 + struct inode_smack *isp; 4609 + struct cred *new_creds = *new; 4610 + 4611 + if (new_creds == NULL) { 4612 + new_creds = prepare_creds(); 4613 + if (new_creds == NULL) 4614 + return -ENOMEM; 4615 + } 4616 + 4617 + tsp = new_creds->security; 4618 + 4619 + /* 4620 + * Get label from overlay inode and set it in create_sid 4621 + */ 4622 + isp = d_inode(dentry->d_parent)->i_security; 4623 + skp = isp->smk_inode; 4624 + tsp->smk_task = skp; 4625 + *new = new_creds; 4626 + return 0; 4627 + } 4628 + 4629 + static int smack_inode_copy_up_xattr(const char *name) 4630 + { 4631 + /* 4632 + * Return 1 if this is the smack access Smack attribute. 4633 + */ 4634 + if (strcmp(name, XATTR_NAME_SMACK) == 0) 4635 + return 1; 4636 + 4637 + return -EOPNOTSUPP; 4638 + } 4639 + 4640 + static int smack_dentry_create_files_as(struct dentry *dentry, int mode, 4641 + struct qstr *name, 4642 + const struct cred *old, 4643 + struct cred *new) 4644 + { 4645 + struct task_smack *otsp = old->security; 4646 + struct task_smack *ntsp = new->security; 4647 + struct inode_smack *isp; 4648 + int may; 4649 + 4650 + /* 4651 + * Use the process credential unless all of 4652 + * the transmuting criteria are met 4653 + */ 4654 + ntsp->smk_task = otsp->smk_task; 4655 + 4656 + /* 4657 + * the attribute of the containing directory 4658 + */ 4659 + isp = d_inode(dentry->d_parent)->i_security; 4660 + 4661 + if (isp->smk_flags & SMK_INODE_TRANSMUTE) { 4662 + rcu_read_lock(); 4663 + may = smk_access_entry(otsp->smk_task->smk_known, 4664 + isp->smk_inode->smk_known, 4665 + &otsp->smk_task->smk_rules); 4666 + rcu_read_unlock(); 4667 + 4668 + /* 4669 + * If the directory is transmuting and the rule 4670 + * providing access is transmuting use the containing 4671 + * directory label instead of the process label. 4672 + */ 4673 + if (may > 0 && (may & MAY_TRANSMUTE)) 4674 + ntsp->smk_task = isp->smk_inode; 4675 + } 4676 + return 0; 4677 + } 4678 + 4603 4679 static struct security_hook_list smack_hooks[] __lsm_ro_after_init = { 4604 4680 LSM_HOOK_INIT(ptrace_access_check, smack_ptrace_access_check), 4605 4681 LSM_HOOK_INIT(ptrace_traceme, smack_ptrace_traceme), ··· 4811 4735 LSM_HOOK_INIT(inode_notifysecctx, smack_inode_notifysecctx), 4812 4736 LSM_HOOK_INIT(inode_setsecctx, smack_inode_setsecctx), 4813 4737 LSM_HOOK_INIT(inode_getsecctx, smack_inode_getsecctx), 4738 + LSM_HOOK_INIT(inode_copy_up, smack_inode_copy_up), 4739 + LSM_HOOK_INIT(inode_copy_up_xattr, smack_inode_copy_up_xattr), 4740 + LSM_HOOK_INIT(dentry_create_files_as, smack_dentry_create_files_as), 4814 4741 }; 4815 4742 4816 4743
+1 -1
security/tomoyo/audit.c
··· 157 157 if (!buffer) 158 158 return NULL; 159 159 160 - tomoyo_convert_time(get_seconds(), &stamp); 160 + tomoyo_convert_time(ktime_get_real_seconds(), &stamp); 161 161 162 162 pos = snprintf(buffer, tomoyo_buffer_len - 1, 163 163 "#%04u/%02u/%02u %02u:%02u:%02u# profile=%u mode=%s "
+2 -2
security/tomoyo/common.c
··· 2257 2257 /* Timestamp counter for last updated. */ 2258 2258 static unsigned int tomoyo_stat_updated[TOMOYO_MAX_POLICY_STAT]; 2259 2259 /* Counter for number of updates. */ 2260 - static unsigned int tomoyo_stat_modified[TOMOYO_MAX_POLICY_STAT]; 2260 + static time64_t tomoyo_stat_modified[TOMOYO_MAX_POLICY_STAT]; 2261 2261 2262 2262 /** 2263 2263 * tomoyo_update_stat - Update statistic counters. ··· 2272 2272 * I don't use atomic operations because race condition is not fatal. 2273 2273 */ 2274 2274 tomoyo_stat_updated[index]++; 2275 - tomoyo_stat_modified[index] = get_seconds(); 2275 + tomoyo_stat_modified[index] = ktime_get_real_seconds(); 2276 2276 } 2277 2277 2278 2278 /**
+1 -1
security/tomoyo/common.h
··· 1037 1037 bool (*check_entry) (struct tomoyo_request_info *, 1038 1038 const struct tomoyo_acl_info *)); 1039 1039 void tomoyo_check_profile(void); 1040 - void tomoyo_convert_time(time_t time, struct tomoyo_time *stamp); 1040 + void tomoyo_convert_time(time64_t time, struct tomoyo_time *stamp); 1041 1041 void tomoyo_del_condition(struct list_head *element); 1042 1042 void tomoyo_fill_path_info(struct tomoyo_path_info *ptr); 1043 1043 void tomoyo_get_attributes(struct tomoyo_obj_info *obj);
+9 -30
security/tomoyo/util.c
··· 87 87 * @stamp: Pointer to "struct tomoyo_time". 88 88 * 89 89 * Returns nothing. 90 - * 91 - * This function does not handle Y2038 problem. 92 90 */ 93 - void tomoyo_convert_time(time_t time, struct tomoyo_time *stamp) 91 + void tomoyo_convert_time(time64_t time64, struct tomoyo_time *stamp) 94 92 { 95 - static const u16 tomoyo_eom[2][12] = { 96 - { 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365 }, 97 - { 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335, 366 } 98 - }; 99 - u16 y; 100 - u8 m; 101 - bool r; 102 - stamp->sec = time % 60; 103 - time /= 60; 104 - stamp->min = time % 60; 105 - time /= 60; 106 - stamp->hour = time % 24; 107 - time /= 24; 108 - for (y = 1970; ; y++) { 109 - const unsigned short days = (y & 3) ? 365 : 366; 110 - if (time < days) 111 - break; 112 - time -= days; 113 - } 114 - r = (y & 3) == 0; 115 - for (m = 0; m < 11 && time >= tomoyo_eom[r][m]; m++) 116 - ; 117 - if (m) 118 - time -= tomoyo_eom[r][m - 1]; 119 - stamp->year = y; 120 - stamp->month = ++m; 121 - stamp->day = ++time; 93 + struct tm tm; 94 + time64_to_tm(time64, 0, &tm); 95 + stamp->sec = tm.tm_sec; 96 + stamp->min = tm.tm_min; 97 + stamp->hour = tm.tm_hour; 98 + stamp->day = tm.tm_mday; 99 + stamp->month = tm.tm_mon + 1; 100 + stamp->year = tm.tm_year + 1900; 122 101 } 123 102 124 103 /**