Skip to content

Commit

Permalink
Merge branch 'next-general' of git://git.kernel.org/pub/scm/linux/ker…
Browse files Browse the repository at this point in the history
…nel/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
  ...
  • Loading branch information
torvalds committed Nov 13, 2017
2 parents dee0277 + 34d8751 commit 55b3a0c
Show file tree
Hide file tree
Showing 17 changed files with 385 additions and 279 deletions.
13 changes: 4 additions & 9 deletions MAINTAINERS
Original file line number Diff line number Diff line change
Expand Up @@ -5219,8 +5219,7 @@ F: fs/ext4/

Extended Verification Module (EVM)
M: Mimi Zohar <[email protected]>
L: [email protected]
L: [email protected]
L: [email protected]
S: Supported
F: security/integrity/evm/

Expand Down Expand Up @@ -6847,9 +6846,7 @@ L: [email protected]
INTEGRITY MEASUREMENT ARCHITECTURE (IMA)
M: Mimi Zohar <[email protected]>
M: Dmitry Kasatkin <[email protected]>
L: [email protected]
L: [email protected]
L: [email protected]
L: [email protected]
T: git git://git.kernel.org/pub/scm/linux/kernel/git/zohar/linux-integrity.git
S: Supported
F: security/integrity/ima/
Expand Down Expand Up @@ -7632,18 +7629,16 @@ F: kernel/kexec*

KEYS-ENCRYPTED
M: Mimi Zohar <[email protected]>
M: David Safford <[email protected]>
L: [email protected]
L: [email protected]
L: [email protected]
S: Supported
F: Documentation/security/keys/trusted-encrypted.rst
F: include/keys/encrypted-type.h
F: security/keys/encrypted-keys/

KEYS-TRUSTED
M: David Safford <[email protected]>
M: Mimi Zohar <[email protected]>
L: linux-security-module@vger.kernel.org
L: linux-integrity@vger.kernel.org
L: [email protected]
S: Supported
F: Documentation/security/keys/trusted-encrypted.rst
Expand Down
6 changes: 6 additions & 0 deletions drivers/char/tpm/tpm-dev-common.c
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,12 @@ ssize_t tpm_common_write(struct file *file, const char __user *buf,
return -EFAULT;
}

if (in_size < 6 ||
in_size < be32_to_cpu(*((__be32 *) (priv->data_buffer + 2)))) {
mutex_unlock(&priv->buffer_mutex);
return -EINVAL;
}

/* atomic tpm command send and result receive. We only hold the ops
* lock during this period so that the tpm can be unregistered even if
* the char dev is held open.
Expand Down
87 changes: 48 additions & 39 deletions drivers/char/tpm/tpm-sysfs.c
Original file line number Diff line number Diff line change
Expand Up @@ -20,44 +20,48 @@
#include <linux/device.h>
#include "tpm.h"

#define READ_PUBEK_RESULT_SIZE 314
struct tpm_readpubek_out {
u8 algorithm[4];
u8 encscheme[2];
u8 sigscheme[2];
__be32 paramsize;
u8 parameters[12];
__be32 keysize;
u8 modulus[256];
u8 checksum[20];
} __packed;

#define READ_PUBEK_RESULT_MIN_BODY_SIZE (28 + 256)
#define TPM_ORD_READPUBEK 124
static const struct tpm_input_header tpm_readpubek_header = {
.tag = cpu_to_be16(TPM_TAG_RQU_COMMAND),
.length = cpu_to_be32(30),
.ordinal = cpu_to_be32(TPM_ORD_READPUBEK)
};

static ssize_t pubek_show(struct device *dev, struct device_attribute *attr,
char *buf)
{
u8 *data;
struct tpm_cmd_t tpm_cmd;
ssize_t err;
int i, rc;
struct tpm_buf tpm_buf;
struct tpm_readpubek_out *out;
ssize_t rc;
int i;
char *str = buf;
struct tpm_chip *chip = to_tpm_chip(dev);
char anti_replay[20];

memset(&tpm_cmd, 0, sizeof(tpm_cmd));

tpm_cmd.header.in = tpm_readpubek_header;
err = tpm_transmit_cmd(chip, NULL, &tpm_cmd, READ_PUBEK_RESULT_SIZE,
READ_PUBEK_RESULT_MIN_BODY_SIZE, 0,
"attempting to read the PUBEK");
if (err)
goto out;

/*
ignore header 10 bytes
algorithm 32 bits (1 == RSA )
encscheme 16 bits
sigscheme 16 bits
parameters (RSA 12->bytes: keybit, #primes, expbit)
keylenbytes 32 bits
256 byte modulus
ignore checksum 20 bytes
*/
data = tpm_cmd.params.readpubek_out_buffer;
memset(&anti_replay, 0, sizeof(anti_replay));

rc = tpm_buf_init(&tpm_buf, TPM_TAG_RQU_COMMAND, TPM_ORD_READPUBEK);
if (rc)
return rc;

tpm_buf_append(&tpm_buf, anti_replay, sizeof(anti_replay));

rc = tpm_transmit_cmd(chip, NULL, tpm_buf.data, PAGE_SIZE,
READ_PUBEK_RESULT_MIN_BODY_SIZE, 0,
"attempting to read the PUBEK");
if (rc) {
tpm_buf_destroy(&tpm_buf);
return 0;
}

out = (struct tpm_readpubek_out *)&tpm_buf.data[10];
str +=
sprintf(str,
"Algorithm: %02X %02X %02X %02X\n"
Expand All @@ -68,21 +72,26 @@ static ssize_t pubek_show(struct device *dev, struct device_attribute *attr,
"%02X %02X %02X %02X\n"
"Modulus length: %d\n"
"Modulus:\n",
data[0], data[1], data[2], data[3],
data[4], data[5],
data[6], data[7],
data[12], data[13], data[14], data[15],
data[16], data[17], data[18], data[19],
data[20], data[21], data[22], data[23],
be32_to_cpu(*((__be32 *) (data + 24))));
out->algorithm[0], out->algorithm[1], out->algorithm[2],
out->algorithm[3],
out->encscheme[0], out->encscheme[1],
out->sigscheme[0], out->sigscheme[1],
out->parameters[0], out->parameters[1],
out->parameters[2], out->parameters[3],
out->parameters[4], out->parameters[5],
out->parameters[6], out->parameters[7],
out->parameters[8], out->parameters[9],
out->parameters[10], out->parameters[11],
be32_to_cpu(out->keysize));

for (i = 0; i < 256; i++) {
str += sprintf(str, "%02X ", data[i + 28]);
str += sprintf(str, "%02X ", out->modulus[i]);
if ((i + 1) % 16 == 0)
str += sprintf(str, "\n");
}
out:

rc = str - buf;
tpm_buf_destroy(&tpm_buf);
return rc;
}
static DEVICE_ATTR_RO(pubek);
Expand Down
15 changes: 1 addition & 14 deletions drivers/char/tpm/tpm.h
Original file line number Diff line number Diff line change
Expand Up @@ -345,17 +345,6 @@ enum tpm_sub_capabilities {
TPM_CAP_PROP_TIS_DURATION = 0x120,
};

struct tpm_readpubek_params_out {
u8 algorithm[4];
u8 encscheme[2];
u8 sigscheme[2];
__be32 paramsize;
u8 parameters[12]; /*assuming RSA*/
__be32 keysize;
u8 modulus[256];
u8 checksum[20];
} __packed;

typedef union {
struct tpm_input_header in;
struct tpm_output_header out;
Expand Down Expand Up @@ -385,8 +374,6 @@ struct tpm_getrandom_in {
} __packed;

typedef union {
struct tpm_readpubek_params_out readpubek_out;
u8 readpubek_out_buffer[sizeof(struct tpm_readpubek_params_out)];
struct tpm_pcrread_in pcrread_in;
struct tpm_pcrread_out pcrread_out;
struct tpm_getrandom_in getrandom_in;
Expand Down Expand Up @@ -557,7 +544,7 @@ static inline void tpm_add_ppi(struct tpm_chip *chip)
}
#endif

static inline inline u32 tpm2_rc_value(u32 rc)
static inline u32 tpm2_rc_value(u32 rc)
{
return (rc & BIT(7)) ? rc & 0xff : rc;
}
Expand Down
73 changes: 22 additions & 51 deletions drivers/char/tpm/tpm2-cmd.c
Original file line number Diff line number Diff line change
Expand Up @@ -834,72 +834,43 @@ static const struct tpm_input_header tpm2_selftest_header = {
};

/**
* tpm2_continue_selftest() - start a self test
*
* @chip: TPM chip to use
* @full: test all commands instead of testing only those that were not
* previously tested.
*
* Return: Same as with tpm_transmit_cmd with exception of RC_TESTING.
*/
static int tpm2_start_selftest(struct tpm_chip *chip, bool full)
{
int rc;
struct tpm2_cmd cmd;

cmd.header.in = tpm2_selftest_header;
cmd.params.selftest_in.full_test = full;

rc = tpm_transmit_cmd(chip, NULL, &cmd, TPM2_SELF_TEST_IN_SIZE, 0, 0,
"continue selftest");

/* At least some prototype chips seem to give RC_TESTING error
* immediately. This is a workaround for that.
*/
if (rc == TPM2_RC_TESTING) {
dev_warn(&chip->dev, "Got RC_TESTING, ignoring\n");
rc = 0;
}

return rc;
}

/**
* tpm2_do_selftest() - run a full self test
* tpm2_do_selftest() - ensure that all self tests have passed
*
* @chip: TPM chip to use
*
* Return: Same as with tpm_transmit_cmd.
*
* During the self test TPM2 commands return with the error code RC_TESTING.
* Waiting is done by issuing PCR read until it executes successfully.
* The TPM can either run all self tests synchronously and then return
* RC_SUCCESS once all tests were successful. Or it can choose to run the tests
* asynchronously and return RC_TESTING immediately while the self tests still
* execute in the background. This function handles both cases and waits until
* all tests have completed.
*/
static int tpm2_do_selftest(struct tpm_chip *chip)
{
int rc;
unsigned int loops;
unsigned int delay_msec = 100;
unsigned long duration;
int i;

duration = tpm2_calc_ordinal_duration(chip, TPM2_CC_SELF_TEST);
unsigned int delay_msec = 20;
long duration;
struct tpm2_cmd cmd;

loops = jiffies_to_msecs(duration) / delay_msec;
duration = jiffies_to_msecs(
tpm2_calc_ordinal_duration(chip, TPM2_CC_SELF_TEST));

rc = tpm2_start_selftest(chip, true);
if (rc)
return rc;
while (duration > 0) {
cmd.header.in = tpm2_selftest_header;
cmd.params.selftest_in.full_test = 0;

for (i = 0; i < loops; i++) {
/* Attempt to read a PCR value */
rc = tpm2_pcr_read(chip, 0, NULL);
if (rc < 0)
break;
rc = tpm_transmit_cmd(chip, NULL, &cmd, TPM2_SELF_TEST_IN_SIZE,
0, 0, "continue selftest");

if (rc != TPM2_RC_TESTING)
break;

tpm_msleep(delay_msec);
duration -= delay_msec;

/* wait longer the next round */
delay_msec *= 2;
}

return rc;
Expand Down Expand Up @@ -1009,7 +980,7 @@ static int tpm2_get_cc_attrs_tbl(struct tpm_chip *chip)
{
struct tpm_buf buf;
u32 nr_commands;
u32 *attrs;
__be32 *attrs;
u32 cc;
int i;
int rc;
Expand Down Expand Up @@ -1049,7 +1020,7 @@ static int tpm2_get_cc_attrs_tbl(struct tpm_chip *chip)

chip->nr_commands = nr_commands;

attrs = (u32 *)&buf.data[TPM_HEADER_SIZE + 9];
attrs = (__be32 *)&buf.data[TPM_HEADER_SIZE + 9];
for (i = 0; i < nr_commands; i++, attrs++) {
chip->cc_attrs_tbl[i] = be32_to_cpup(attrs);
cc = chip->cc_attrs_tbl[i] & 0xFFFF;
Expand Down
4 changes: 2 additions & 2 deletions drivers/char/tpm/tpm2-space.c
Original file line number Diff line number Diff line change
Expand Up @@ -242,7 +242,7 @@ static int tpm2_map_command(struct tpm_chip *chip, u32 cc, u8 *cmd)
struct tpm_space *space = &chip->work_space;
unsigned int nr_handles;
u32 attrs;
u32 *handle;
__be32 *handle;
int i;

i = tpm2_find_cc(chip, cc);
Expand All @@ -252,7 +252,7 @@ static int tpm2_map_command(struct tpm_chip *chip, u32 cc, u8 *cmd)
attrs = chip->cc_attrs_tbl[i];
nr_handles = (attrs >> TPM2_CC_ATTR_CHANDLES) & GENMASK(2, 0);

handle = (u32 *)&cmd[TPM_HEADER_SIZE];
handle = (__be32 *)&cmd[TPM_HEADER_SIZE];
for (i = 0; i < nr_handles; i++, handle++) {
if ((be32_to_cpu(*handle) & 0xFF000000) == TPM2_HT_TRANSIENT) {
if (!tpm2_map_to_phandle(space, handle))
Expand Down
Loading

0 comments on commit 55b3a0c

Please sign in to comment.