forked from torvalds/linux
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel…
…/git/jmorris/linux-security Pull security layer updates from James Morris: "Changes for this kernel include maintenance updates for Smack, SELinux (and several networking fixes), IMA and TPM" * 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jmorris/linux-security: (39 commits) SELinux: Fix memory leak upon loading policy tpm/tpm-sysfs: active_show() can be static tpm: tpm_tis: Fix compile problems with CONFIG_PM_SLEEP/CONFIG_PNP tpm: Make tpm-dev allocate a per-file structure tpm: Use the ops structure instead of a copy in tpm_vendor_specific tpm: Create a tpm_class_ops structure and use it in the drivers tpm: Pull all driver sysfs code into tpm-sysfs.c tpm: Move sysfs functions from tpm-interface to tpm-sysfs tpm: Pull everything related to /dev/tpmX into tpm-dev.c char: tpm: nuvoton: remove unused variable tpm: MAINTAINERS: Cleanup TPM Maintainers file tpm/tpm_i2c_atmel: fix coccinelle warnings tpm/tpm_ibmvtpm: fix unreachable code warning (smatch warning) tpm/tpm_i2c_stm_st33: Check return code of get_burstcount tpm/tpm_ppi: Check return value of acpi_get_name tpm/tpm_ppi: Do not compare strcmp(a,b) == -1 ima: remove unneeded size_limit argument from ima_eventdigest_init_common() ima: update IMA-templates.txt documentation ima: pass HASH_ALGO__LAST as hash algo in ima_eventdigest_init() ima: change the default hash algorithm to SHA1 in ima_eventdigest_ng_init() ...
- v3.18-rc2
- v3.18-rc1
- v3.17
- v3.17-rc7
- v3.17-rc6
- v3.17-rc5
- v3.17-rc4
- v3.17-rc3
- v3.17-rc2
- v3.17-rc1
- v3.16
- v3.16-rc7
- v3.16-rc6
- v3.16-rc5
- v3.16-rc4
- v3.16-rc3
- v3.16-rc2
- v3.16-rc1
- v3.15
- v3.15-rc8
- v3.15-rc7
- v3.15-rc6
- v3.15-rc5
- v3.15-rc4
- v3.15-rc3
- v3.15-rc2
- v3.15-rc1
- v3.14
- v3.14-rc8
- v3.14-rc7
- v3.14-rc6
- v3.14-rc5
- v3.14-rc4
- v3.14-rc3
- v3.14-rc2
- v3.14-rc1
Showing
30 changed files
with
1,007 additions
and
1,041 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -8746,14 +8746,10 @@ S: Odd fixes | |
F: drivers/media/usb/tm6000/ | ||
|
||
TPM DEVICE DRIVER | ||
M: Leonidas Da Silva Barbosa <[email protected]> | ||
M: Ashley Lai <[email protected]> | ||
M: Peter Huewe <[email protected]> | ||
M: Rajiv Andrade <[email protected]> | ||
W: http://tpmdd.sourceforge.net | ||
M: Ashley Lai <[email protected]> | ||
M: Marcel Selhorst <[email protected]> | ||
M: Sirrix AG <[email protected]> | ||
W: http://www.sirrix.com | ||
W: http://tpmdd.sourceforge.net | ||
L: [email protected] (moderated for non-subscribers) | ||
S: Maintained | ||
F: drivers/char/tpm/ | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,213 @@ | ||
/* | ||
* Copyright (C) 2004 IBM Corporation | ||
* Authors: | ||
* Leendert van Doorn <[email protected]> | ||
* Dave Safford <[email protected]> | ||
* Reiner Sailer <[email protected]> | ||
* Kylene Hall <[email protected]> | ||
* | ||
* Copyright (C) 2013 Obsidian Research Corp | ||
* Jason Gunthorpe <[email protected]> | ||
* | ||
* Device file system interface to the TPM | ||
* | ||
* This program is free software; you can redistribute it and/or | ||
* modify it under the terms of the GNU General Public License as | ||
* published by the Free Software Foundation, version 2 of the | ||
* License. | ||
* | ||
*/ | ||
#include <linux/miscdevice.h> | ||
#include <linux/slab.h> | ||
#include <linux/uaccess.h> | ||
#include "tpm.h" | ||
|
||
struct file_priv { | ||
struct tpm_chip *chip; | ||
|
||
/* Data passed to and from the tpm via the read/write calls */ | ||
atomic_t data_pending; | ||
struct mutex buffer_mutex; | ||
|
||
struct timer_list user_read_timer; /* user needs to claim result */ | ||
struct work_struct work; | ||
|
||
u8 data_buffer[TPM_BUFSIZE]; | ||
}; | ||
|
||
static void user_reader_timeout(unsigned long ptr) | ||
{ | ||
struct file_priv *priv = (struct file_priv *)ptr; | ||
|
||
schedule_work(&priv->work); | ||
} | ||
|
||
static void timeout_work(struct work_struct *work) | ||
{ | ||
struct file_priv *priv = container_of(work, struct file_priv, work); | ||
|
||
mutex_lock(&priv->buffer_mutex); | ||
atomic_set(&priv->data_pending, 0); | ||
memset(priv->data_buffer, 0, sizeof(priv->data_buffer)); | ||
mutex_unlock(&priv->buffer_mutex); | ||
} | ||
|
||
static int tpm_open(struct inode *inode, struct file *file) | ||
{ | ||
struct miscdevice *misc = file->private_data; | ||
struct tpm_chip *chip = container_of(misc, struct tpm_chip, | ||
vendor.miscdev); | ||
struct file_priv *priv; | ||
|
||
/* It's assured that the chip will be opened just once, | ||
* by the check of is_open variable, which is protected | ||
* by driver_lock. */ | ||
if (test_and_set_bit(0, &chip->is_open)) { | ||
dev_dbg(chip->dev, "Another process owns this TPM\n"); | ||
return -EBUSY; | ||
} | ||
|
||
priv = kzalloc(sizeof(*priv), GFP_KERNEL); | ||
if (priv == NULL) { | ||
clear_bit(0, &chip->is_open); | ||
return -ENOMEM; | ||
} | ||
|
||
priv->chip = chip; | ||
atomic_set(&priv->data_pending, 0); | ||
mutex_init(&priv->buffer_mutex); | ||
setup_timer(&priv->user_read_timer, user_reader_timeout, | ||
(unsigned long)priv); | ||
INIT_WORK(&priv->work, timeout_work); | ||
|
||
file->private_data = priv; | ||
get_device(chip->dev); | ||
return 0; | ||
} | ||
|
||
static ssize_t tpm_read(struct file *file, char __user *buf, | ||
size_t size, loff_t *off) | ||
{ | ||
struct file_priv *priv = file->private_data; | ||
ssize_t ret_size; | ||
int rc; | ||
|
||
del_singleshot_timer_sync(&priv->user_read_timer); | ||
flush_work(&priv->work); | ||
ret_size = atomic_read(&priv->data_pending); | ||
if (ret_size > 0) { /* relay data */ | ||
ssize_t orig_ret_size = ret_size; | ||
if (size < ret_size) | ||
ret_size = size; | ||
|
||
mutex_lock(&priv->buffer_mutex); | ||
rc = copy_to_user(buf, priv->data_buffer, ret_size); | ||
memset(priv->data_buffer, 0, orig_ret_size); | ||
if (rc) | ||
ret_size = -EFAULT; | ||
|
||
mutex_unlock(&priv->buffer_mutex); | ||
} | ||
|
||
atomic_set(&priv->data_pending, 0); | ||
|
||
return ret_size; | ||
} | ||
|
||
static ssize_t tpm_write(struct file *file, const char __user *buf, | ||
size_t size, loff_t *off) | ||
{ | ||
struct file_priv *priv = file->private_data; | ||
size_t in_size = size; | ||
ssize_t out_size; | ||
|
||
/* cannot perform a write until the read has cleared | ||
either via tpm_read or a user_read_timer timeout. | ||
This also prevents splitted buffered writes from blocking here. | ||
*/ | ||
if (atomic_read(&priv->data_pending) != 0) | ||
return -EBUSY; | ||
|
||
if (in_size > TPM_BUFSIZE) | ||
return -E2BIG; | ||
|
||
mutex_lock(&priv->buffer_mutex); | ||
|
||
if (copy_from_user | ||
(priv->data_buffer, (void __user *) buf, in_size)) { | ||
mutex_unlock(&priv->buffer_mutex); | ||
return -EFAULT; | ||
} | ||
|
||
/* atomic tpm command send and result receive */ | ||
out_size = tpm_transmit(priv->chip, priv->data_buffer, | ||
sizeof(priv->data_buffer)); | ||
if (out_size < 0) { | ||
mutex_unlock(&priv->buffer_mutex); | ||
return out_size; | ||
} | ||
|
||
atomic_set(&priv->data_pending, out_size); | ||
mutex_unlock(&priv->buffer_mutex); | ||
|
||
/* Set a timeout by which the reader must come claim the result */ | ||
mod_timer(&priv->user_read_timer, jiffies + (60 * HZ)); | ||
|
||
return in_size; | ||
} | ||
|
||
/* | ||
* Called on file close | ||
*/ | ||
static int tpm_release(struct inode *inode, struct file *file) | ||
{ | ||
struct file_priv *priv = file->private_data; | ||
|
||
del_singleshot_timer_sync(&priv->user_read_timer); | ||
flush_work(&priv->work); | ||
file->private_data = NULL; | ||
atomic_set(&priv->data_pending, 0); | ||
clear_bit(0, &priv->chip->is_open); | ||
put_device(priv->chip->dev); | ||
kfree(priv); | ||
return 0; | ||
} | ||
|
||
static const struct file_operations tpm_fops = { | ||
.owner = THIS_MODULE, | ||
.llseek = no_llseek, | ||
.open = tpm_open, | ||
.read = tpm_read, | ||
.write = tpm_write, | ||
.release = tpm_release, | ||
}; | ||
|
||
int tpm_dev_add_device(struct tpm_chip *chip) | ||
{ | ||
int rc; | ||
|
||
chip->vendor.miscdev.fops = &tpm_fops; | ||
if (chip->dev_num == 0) | ||
chip->vendor.miscdev.minor = TPM_MINOR; | ||
else | ||
chip->vendor.miscdev.minor = MISC_DYNAMIC_MINOR; | ||
|
||
chip->vendor.miscdev.name = chip->devname; | ||
chip->vendor.miscdev.parent = chip->dev; | ||
|
||
rc = misc_register(&chip->vendor.miscdev); | ||
if (rc) { | ||
chip->vendor.miscdev.name = NULL; | ||
dev_err(chip->dev, | ||
"unable to misc_register %s, minor %d err=%d\n", | ||
chip->vendor.miscdev.name, | ||
chip->vendor.miscdev.minor, rc); | ||
} | ||
return rc; | ||
} | ||
|
||
void tpm_dev_del_device(struct tpm_chip *chip) | ||
{ | ||
if (chip->vendor.miscdev.name) | ||
misc_deregister(&chip->vendor.miscdev); | ||
} |
Oops, something went wrong.