Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 93db6286 authored by James Morris's avatar James Morris
Browse files

Merge branch 'next' into for-linus

parents f1b2a5ac 0da939b0
Loading
Loading
Loading
Loading
+46 −50
Original line number Diff line number Diff line
@@ -954,72 +954,63 @@ EXPORT_SYMBOL_GPL(tpm_store_cancel);

/*
 * Device file system interface to the TPM
 *
 * It's assured that the chip will be opened just once,
 * by the check of is_open variable, which is protected
 * by driver_lock.
 */
int tpm_open(struct inode *inode, struct file *file)
{
	int rc = 0, minor = iminor(inode);
	int minor = iminor(inode);
	struct tpm_chip *chip = NULL, *pos;

	lock_kernel();
	spin_lock(&driver_lock);

	list_for_each_entry(pos, &tpm_chip_list, list) {
	rcu_read_lock();
	list_for_each_entry_rcu(pos, &tpm_chip_list, list) {
		if (pos->vendor.miscdev.minor == minor) {
			chip = pos;
			get_device(chip->dev);
			break;
		}
	}
	rcu_read_unlock();

	if (chip == NULL) {
		rc = -ENODEV;
		goto err_out;
	}
	if (!chip)
		return -ENODEV;

	if (chip->num_opens) {
	if (test_and_set_bit(0, &chip->is_open)) {
		dev_dbg(chip->dev, "Another process owns this TPM\n");
		rc = -EBUSY;
		goto err_out;
		put_device(chip->dev);
		return -EBUSY;
	}

	chip->num_opens++;
	get_device(chip->dev);

	spin_unlock(&driver_lock);

	chip->data_buffer = kmalloc(TPM_BUFSIZE * sizeof(u8), GFP_KERNEL);
	if (chip->data_buffer == NULL) {
		chip->num_opens--;
		clear_bit(0, &chip->is_open);
		put_device(chip->dev);
		unlock_kernel();
		return -ENOMEM;
	}

	atomic_set(&chip->data_pending, 0);

	file->private_data = chip;
	unlock_kernel();
	return 0;

err_out:
	spin_unlock(&driver_lock);
	unlock_kernel();
	return rc;
}
EXPORT_SYMBOL_GPL(tpm_open);

/*
 * Called on file close
 */
int tpm_release(struct inode *inode, struct file *file)
{
	struct tpm_chip *chip = file->private_data;

	del_singleshot_timer_sync(&chip->user_read_timer);
	flush_scheduled_work();
	spin_lock(&driver_lock);
	file->private_data = NULL;
	del_singleshot_timer_sync(&chip->user_read_timer);
	atomic_set(&chip->data_pending, 0);
	chip->num_opens--;
	put_device(chip->dev);
	kfree(chip->data_buffer);
	spin_unlock(&driver_lock);
	clear_bit(0, &chip->is_open);
	put_device(chip->dev);
	return 0;
}
EXPORT_SYMBOL_GPL(tpm_release);
@@ -1093,13 +1084,11 @@ void tpm_remove_hardware(struct device *dev)
	}

	spin_lock(&driver_lock);

	list_del(&chip->list);

	list_del_rcu(&chip->list);
	spin_unlock(&driver_lock);
	synchronize_rcu();

	misc_deregister(&chip->vendor.miscdev);

	sysfs_remove_group(&dev->kobj, chip->vendor.attr_group);
	tpm_bios_log_teardown(chip->bios_dir);

@@ -1144,25 +1133,33 @@ int tpm_pm_resume(struct device *dev)
}
EXPORT_SYMBOL_GPL(tpm_pm_resume);

/* In case vendor provided release function, call it too.*/

void tpm_dev_vendor_release(struct tpm_chip *chip)
{
	if (chip->vendor.release)
		chip->vendor.release(chip->dev);

	clear_bit(chip->dev_num, dev_mask);
	kfree(chip->vendor.miscdev.name);
}
EXPORT_SYMBOL_GPL(tpm_dev_vendor_release);


/*
 * Once all references to platform device are down to 0,
 * release all allocated structures.
 * In case vendor provided release function,
 * call it too.
 */
static void tpm_dev_release(struct device *dev)
{
	struct tpm_chip *chip = dev_get_drvdata(dev);

	if (chip->vendor.release)
		chip->vendor.release(dev);
	tpm_dev_vendor_release(chip);

	chip->release(dev);

	clear_bit(chip->dev_num, dev_mask);
	kfree(chip->vendor.miscdev.name);
	kfree(chip);
}
EXPORT_SYMBOL_GPL(tpm_dev_release);

/*
 * Called from tpm_<specific>.c probe function only for devices 
@@ -1171,8 +1168,8 @@ static void tpm_dev_release(struct device *dev)
 * upon errant exit from this function specific probe function should call
 * pci_disable_device
 */
struct tpm_chip *tpm_register_hardware(struct device *dev, const struct tpm_vendor_specific
				       *entry)
struct tpm_chip *tpm_register_hardware(struct device *dev,
					const struct tpm_vendor_specific *entry)
{
#define DEVNAME_SIZE 7

@@ -1231,21 +1228,20 @@ struct tpm_chip *tpm_register_hardware(struct device *dev, const struct tpm_vend
		return NULL;
	}

	spin_lock(&driver_lock);

	list_add(&chip->list, &tpm_chip_list);

	spin_unlock(&driver_lock);

	if (sysfs_create_group(&dev->kobj, chip->vendor.attr_group)) {
		list_del(&chip->list);
		misc_deregister(&chip->vendor.miscdev);
		put_device(chip->dev);

		return NULL;
	}

	chip->bios_dir = tpm_bios_log_setup(devname);

	/* Make chip available */
	spin_lock(&driver_lock);
	list_add_rcu(&chip->list, &tpm_chip_list);
	spin_unlock(&driver_lock);

	return chip;
}
EXPORT_SYMBOL_GPL(tpm_register_hardware);
+2 −1
Original line number Diff line number Diff line
@@ -90,7 +90,7 @@ struct tpm_chip {
	struct device *dev;	/* Device stuff */

	int dev_num;		/* /dev/tpm# */
	int num_opens;		/* only one allowed */
	unsigned long is_open;	/* only one allowed */
	int time_expired;

	/* Data passed to and from the tpm via the read/write calls */
@@ -132,6 +132,7 @@ extern struct tpm_chip* tpm_register_hardware(struct device *,
				 const struct tpm_vendor_specific *);
extern int tpm_open(struct inode *, struct file *);
extern int tpm_release(struct inode *, struct file *);
extern void tpm_dev_vendor_release(struct tpm_chip *);
extern ssize_t tpm_write(struct file *, const char __user *, size_t,
			 loff_t *);
extern ssize_t tpm_read(struct file *, char __user *, size_t, loff_t *);
+13 −1
Original line number Diff line number Diff line
@@ -630,12 +630,23 @@ static struct pnp_device_id tpm_pnp_tbl[] __devinitdata = {
	{"", 0}			/* Terminator */
};

static __devexit void tpm_tis_pnp_remove(struct pnp_dev *dev)
{
	struct tpm_chip *chip = pnp_get_drvdata(dev);

	tpm_dev_vendor_release(chip);

	kfree(chip);
}


static struct pnp_driver tis_pnp_driver = {
	.name = "tpm_tis",
	.id_table = tpm_pnp_tbl,
	.probe = tpm_tis_pnp_init,
	.suspend = tpm_tis_pnp_suspend,
	.resume = tpm_tis_pnp_resume,
	.remove = tpm_tis_pnp_remove,
};

#define TIS_HID_USR_IDX sizeof(tpm_pnp_tbl)/sizeof(struct pnp_device_id) -2
@@ -683,6 +694,7 @@ static void __exit cleanup_tis(void)
	spin_lock(&tis_lock);
	list_for_each_entry_safe(i, j, &tis_chips, list) {
		chip = to_tpm_chip(i);
		tpm_remove_hardware(chip->dev);
		iowrite32(~TPM_GLOBAL_INT_ENABLE &
			  ioread32(chip->vendor.iobase +
				   TPM_INT_ENABLE(chip->vendor.
@@ -694,9 +706,9 @@ static void __exit cleanup_tis(void)
			free_irq(chip->vendor.irq, chip);
		iounmap(i->iobase);
		list_del(&i->list);
		tpm_remove_hardware(chip->dev);
	}
	spin_unlock(&tis_lock);

	if (force) {
		platform_device_unregister(pdev);
		driver_unregister(&tis_drv);
+41 −14
Original line number Diff line number Diff line
@@ -40,11 +40,12 @@
#include <linux/net.h>
#include <linux/skbuff.h>
#include <net/netlabel.h>
#include <asm/atomic.h>

/* known doi values */
#define CIPSO_V4_DOI_UNKNOWN          0x00000000

/* tag types */
/* standard tag types */
#define CIPSO_V4_TAG_INVALID          0
#define CIPSO_V4_TAG_RBITMAP          1
#define CIPSO_V4_TAG_ENUM             2
@@ -52,10 +53,14 @@
#define CIPSO_V4_TAG_PBITMAP          6
#define CIPSO_V4_TAG_FREEFORM         7

/* non-standard tag types (tags > 127) */
#define CIPSO_V4_TAG_LOCAL            128

/* doi mapping types */
#define CIPSO_V4_MAP_UNKNOWN          0
#define CIPSO_V4_MAP_STD              1
#define CIPSO_V4_MAP_TRANS            1
#define CIPSO_V4_MAP_PASS             2
#define CIPSO_V4_MAP_LOCAL            3

/* limits */
#define CIPSO_V4_MAX_REM_LVLS         255
@@ -79,10 +84,9 @@ struct cipso_v4_doi {
	} map;
	u8 tags[CIPSO_V4_TAG_MAXCNT];

	u32 valid;
	atomic_t refcount;
	struct list_head list;
	struct rcu_head rcu;
	struct list_head dom_list;
};

/* Standard CIPSO mapping table */
@@ -128,25 +132,26 @@ extern int cipso_v4_rbm_strictvalid;

#ifdef CONFIG_NETLABEL
int cipso_v4_doi_add(struct cipso_v4_doi *doi_def);
int cipso_v4_doi_remove(u32 doi,
			struct netlbl_audit *audit_info,
			void (*callback) (struct rcu_head * head));
void cipso_v4_doi_free(struct cipso_v4_doi *doi_def);
int cipso_v4_doi_remove(u32 doi, struct netlbl_audit *audit_info);
struct cipso_v4_doi *cipso_v4_doi_getdef(u32 doi);
void cipso_v4_doi_putdef(struct cipso_v4_doi *doi_def);
int cipso_v4_doi_walk(u32 *skip_cnt,
		     int (*callback) (struct cipso_v4_doi *doi_def, void *arg),
	             void *cb_arg);
int cipso_v4_doi_domhsh_add(struct cipso_v4_doi *doi_def, const char *domain);
int cipso_v4_doi_domhsh_remove(struct cipso_v4_doi *doi_def,
			       const char *domain);
#else
static inline int cipso_v4_doi_add(struct cipso_v4_doi *doi_def)
{
	return -ENOSYS;
}

static inline void cipso_v4_doi_free(struct cipso_v4_doi *doi_def)
{
	return;
}

static inline int cipso_v4_doi_remove(u32 doi,
				    struct netlbl_audit *audit_info,
				    void (*callback) (struct rcu_head * head))
				      struct netlbl_audit *audit_info)
{
	return 0;
}
@@ -206,10 +211,15 @@ void cipso_v4_error(struct sk_buff *skb, int error, u32 gateway);
int cipso_v4_sock_setattr(struct sock *sk,
			  const struct cipso_v4_doi *doi_def,
			  const struct netlbl_lsm_secattr *secattr);
void cipso_v4_sock_delattr(struct sock *sk);
int cipso_v4_sock_getattr(struct sock *sk, struct netlbl_lsm_secattr *secattr);
int cipso_v4_skbuff_setattr(struct sk_buff *skb,
			    const struct cipso_v4_doi *doi_def,
			    const struct netlbl_lsm_secattr *secattr);
int cipso_v4_skbuff_delattr(struct sk_buff *skb);
int cipso_v4_skbuff_getattr(const struct sk_buff *skb,
			    struct netlbl_lsm_secattr *secattr);
int cipso_v4_validate(unsigned char **option);
int cipso_v4_validate(const struct sk_buff *skb, unsigned char **option);
#else
static inline void cipso_v4_error(struct sk_buff *skb,
				  int error,
@@ -225,19 +235,36 @@ static inline int cipso_v4_sock_setattr(struct sock *sk,
	return -ENOSYS;
}

static inline void cipso_v4_sock_delattr(struct sock *sk)
{
}

static inline int cipso_v4_sock_getattr(struct sock *sk,
					struct netlbl_lsm_secattr *secattr)
{
	return -ENOSYS;
}

static inline int cipso_v4_skbuff_setattr(struct sk_buff *skb,
				      const struct cipso_v4_doi *doi_def,
				      const struct netlbl_lsm_secattr *secattr)
{
	return -ENOSYS;
}

static inline int cipso_v4_skbuff_delattr(struct sk_buff *skb)
{
	return -ENOSYS;
}

static inline int cipso_v4_skbuff_getattr(const struct sk_buff *skb,
					  struct netlbl_lsm_secattr *secattr)
{
	return -ENOSYS;
}

static inline int cipso_v4_validate(unsigned char **option)
static inline int cipso_v4_validate(const struct sk_buff *skb,
				    unsigned char **option)
{
	return -ENOSYS;
}
+33 −18
Original line number Diff line number Diff line
@@ -9,7 +9,7 @@
 */

/*
 * (c) Copyright Hewlett-Packard Development Company, L.P., 2006
 * (c) Copyright Hewlett-Packard Development Company, L.P., 2006, 2008
 *
 * 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
@@ -72,8 +72,10 @@ struct cipso_v4_doi;
/* NetLabel NETLINK protocol version
 *  1: initial version
 *  2: added static labels for unlabeled connections
 *  3: network selectors added to the NetLabel/LSM domain mapping and the
 *     CIPSO_V4_MAP_LOCAL CIPSO mapping was added
 */
#define NETLBL_PROTO_VERSION            2
#define NETLBL_PROTO_VERSION            3

/* NetLabel NETLINK types/families */
#define NETLBL_NLTYPE_NONE              0
@@ -87,6 +89,8 @@ struct cipso_v4_doi;
#define NETLBL_NLTYPE_CIPSOV6_NAME      "NLBL_CIPSOv6"
#define NETLBL_NLTYPE_UNLABELED         5
#define NETLBL_NLTYPE_UNLABELED_NAME    "NLBL_UNLBL"
#define NETLBL_NLTYPE_ADDRSELECT        6
#define NETLBL_NLTYPE_ADDRSELECT_NAME   "NLBL_ADRSEL"

/*
 * NetLabel - Kernel API for accessing the network packet label mappings.
@@ -200,7 +204,7 @@ struct netlbl_lsm_secattr {
	u32 type;
	char *domain;
	struct netlbl_lsm_cache *cache;
	union {
	struct {
		struct {
			struct netlbl_lsm_secattr_catmap *cat;
			u32 lvl;
@@ -352,12 +356,9 @@ static inline void netlbl_secattr_free(struct netlbl_lsm_secattr *secattr)
int netlbl_cfg_map_del(const char *domain, struct netlbl_audit *audit_info);
int netlbl_cfg_unlbl_add_map(const char *domain,
			     struct netlbl_audit *audit_info);
int netlbl_cfg_cipsov4_add(struct cipso_v4_doi *doi_def,
			   struct netlbl_audit *audit_info);
int netlbl_cfg_cipsov4_add_map(struct cipso_v4_doi *doi_def,
			       const char *domain,
			       struct netlbl_audit *audit_info);
int netlbl_cfg_cipsov4_del(u32 doi, struct netlbl_audit *audit_info);

/*
 * LSM security attribute operations
@@ -380,12 +381,19 @@ int netlbl_secattr_catmap_setrng(struct netlbl_lsm_secattr_catmap *catmap,
int netlbl_enabled(void);
int netlbl_sock_setattr(struct sock *sk,
			const struct netlbl_lsm_secattr *secattr);
void netlbl_sock_delattr(struct sock *sk);
int netlbl_sock_getattr(struct sock *sk,
			struct netlbl_lsm_secattr *secattr);
int netlbl_conn_setattr(struct sock *sk,
			struct sockaddr *addr,
			const struct netlbl_lsm_secattr *secattr);
int netlbl_skbuff_setattr(struct sk_buff *skb,
			  u16 family,
			  const struct netlbl_lsm_secattr *secattr);
int netlbl_skbuff_getattr(const struct sk_buff *skb,
			  u16 family,
			  struct netlbl_lsm_secattr *secattr);
void netlbl_skbuff_err(struct sk_buff *skb, int error);
void netlbl_skbuff_err(struct sk_buff *skb, int error, int gateway);

/*
 * LSM label mapping cache operations
@@ -404,22 +412,12 @@ static inline int netlbl_cfg_unlbl_add_map(const char *domain,
{
	return -ENOSYS;
}
static inline int netlbl_cfg_cipsov4_add(struct cipso_v4_doi *doi_def,
					 struct netlbl_audit *audit_info)
{
	return -ENOSYS;
}
static inline int netlbl_cfg_cipsov4_add_map(struct cipso_v4_doi *doi_def,
					     const char *domain,
					     struct netlbl_audit *audit_info)
{
	return -ENOSYS;
}
static inline int netlbl_cfg_cipsov4_del(u32 doi,
					 struct netlbl_audit *audit_info)
{
	return -ENOSYS;
}
static inline int netlbl_secattr_catmap_walk(
	                              struct netlbl_lsm_secattr_catmap *catmap,
				      u32 offset)
@@ -456,18 +454,35 @@ static inline int netlbl_sock_setattr(struct sock *sk,
{
	return -ENOSYS;
}
static inline void netlbl_sock_delattr(struct sock *sk)
{
}
static inline int netlbl_sock_getattr(struct sock *sk,
				      struct netlbl_lsm_secattr *secattr)
{
	return -ENOSYS;
}
static inline int netlbl_conn_setattr(struct sock *sk,
				      struct sockaddr *addr,
				      const struct netlbl_lsm_secattr *secattr)
{
	return -ENOSYS;
}
static inline int netlbl_skbuff_setattr(struct sk_buff *skb,
				      u16 family,
				      const struct netlbl_lsm_secattr *secattr)
{
	return -ENOSYS;
}
static inline int netlbl_skbuff_getattr(const struct sk_buff *skb,
					u16 family,
					struct netlbl_lsm_secattr *secattr)
{
	return -ENOSYS;
}
static inline void netlbl_skbuff_err(struct sk_buff *skb, int error)
static inline void netlbl_skbuff_err(struct sk_buff *skb,
				     int error,
				     int gateway)
{
	return;
}
Loading