Commit 8d71ff0b authored by Linus Torvalds's avatar Linus Torvalds

Merge branch 'for-linus' of...

Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jmorris/security-testing-2.6

* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jmorris/security-testing-2.6: (24 commits)
  integrity: special fs magic
  As pointed out by Jonathan Corbet, the timer must be deleted before
  ERROR: code indent should use tabs where possible
  The tpm_dev_release function is only called for platform devices, not pnp
  Protect tpm_chip_list when transversing it.
  Renames num_open to is_open, as only one process can open the file at a time.
  Remove the BKL calls from the TPM driver, which were added in the overall
  netlabel: Add configuration support for local labeling
  cipso: Add support for native local labeling and fixup mapping names
  netlabel: Changes to the NetLabel security attributes to allow LSMs to pass full contexts
  selinux: Cache NetLabel secattrs in the socket's security struct
  selinux: Set socket NetLabel based on connection endpoint
  netlabel: Add functionality to set the security attributes of a packet
  netlabel: Add network address selectors to the NetLabel/LSM domain mapping
  netlabel: Add a generic way to create ordered linked lists of network addrs
  netlabel: Replace protocol/NetLabel linking with refrerence counts
  smack: Fix missing calls to netlbl_skbuff_err()
  selinux: Fix missing calls to netlbl_skbuff_err()
  selinux: Fix a problem in security_netlbl_sid_to_secattr()
  selinux: Better local/forward check in selinux_ip_postroute()
  ...
parents 244dc4e5 92562927
...@@ -954,72 +954,63 @@ EXPORT_SYMBOL_GPL(tpm_store_cancel); ...@@ -954,72 +954,63 @@ EXPORT_SYMBOL_GPL(tpm_store_cancel);
/* /*
* Device file system interface to the TPM * 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 tpm_open(struct inode *inode, struct file *file)
{ {
int rc = 0, minor = iminor(inode); int minor = iminor(inode);
struct tpm_chip *chip = NULL, *pos; struct tpm_chip *chip = NULL, *pos;
lock_kernel(); rcu_read_lock();
spin_lock(&driver_lock); list_for_each_entry_rcu(pos, &tpm_chip_list, list) {
list_for_each_entry(pos, &tpm_chip_list, list) {
if (pos->vendor.miscdev.minor == minor) { if (pos->vendor.miscdev.minor == minor) {
chip = pos; chip = pos;
get_device(chip->dev);
break; break;
} }
} }
rcu_read_unlock();
if (chip == NULL) { if (!chip)
rc = -ENODEV; return -ENODEV;
goto err_out;
}
if (chip->num_opens) { if (test_and_set_bit(0, &chip->is_open)) {
dev_dbg(chip->dev, "Another process owns this TPM\n"); dev_dbg(chip->dev, "Another process owns this TPM\n");
rc = -EBUSY; put_device(chip->dev);
goto err_out; return -EBUSY;
} }
chip->num_opens++;
get_device(chip->dev);
spin_unlock(&driver_lock);
chip->data_buffer = kmalloc(TPM_BUFSIZE * sizeof(u8), GFP_KERNEL); chip->data_buffer = kmalloc(TPM_BUFSIZE * sizeof(u8), GFP_KERNEL);
if (chip->data_buffer == NULL) { if (chip->data_buffer == NULL) {
chip->num_opens--; clear_bit(0, &chip->is_open);
put_device(chip->dev); put_device(chip->dev);
unlock_kernel();
return -ENOMEM; return -ENOMEM;
} }
atomic_set(&chip->data_pending, 0); atomic_set(&chip->data_pending, 0);
file->private_data = chip; file->private_data = chip;
unlock_kernel();
return 0; return 0;
err_out:
spin_unlock(&driver_lock);
unlock_kernel();
return rc;
} }
EXPORT_SYMBOL_GPL(tpm_open); EXPORT_SYMBOL_GPL(tpm_open);
/*
* Called on file close
*/
int tpm_release(struct inode *inode, struct file *file) int tpm_release(struct inode *inode, struct file *file)
{ {
struct tpm_chip *chip = file->private_data; struct tpm_chip *chip = file->private_data;
del_singleshot_timer_sync(&chip->user_read_timer);
flush_scheduled_work(); flush_scheduled_work();
spin_lock(&driver_lock);
file->private_data = NULL; file->private_data = NULL;
del_singleshot_timer_sync(&chip->user_read_timer);
atomic_set(&chip->data_pending, 0); atomic_set(&chip->data_pending, 0);
chip->num_opens--;
put_device(chip->dev);
kfree(chip->data_buffer); kfree(chip->data_buffer);
spin_unlock(&driver_lock); clear_bit(0, &chip->is_open);
put_device(chip->dev);
return 0; return 0;
} }
EXPORT_SYMBOL_GPL(tpm_release); EXPORT_SYMBOL_GPL(tpm_release);
...@@ -1093,13 +1084,11 @@ void tpm_remove_hardware(struct device *dev) ...@@ -1093,13 +1084,11 @@ void tpm_remove_hardware(struct device *dev)
} }
spin_lock(&driver_lock); spin_lock(&driver_lock);
list_del_rcu(&chip->list);
list_del(&chip->list);
spin_unlock(&driver_lock); spin_unlock(&driver_lock);
synchronize_rcu();
misc_deregister(&chip->vendor.miscdev); misc_deregister(&chip->vendor.miscdev);
sysfs_remove_group(&dev->kobj, chip->vendor.attr_group); sysfs_remove_group(&dev->kobj, chip->vendor.attr_group);
tpm_bios_log_teardown(chip->bios_dir); tpm_bios_log_teardown(chip->bios_dir);
...@@ -1144,25 +1133,33 @@ int tpm_pm_resume(struct device *dev) ...@@ -1144,25 +1133,33 @@ int tpm_pm_resume(struct device *dev)
} }
EXPORT_SYMBOL_GPL(tpm_pm_resume); 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, * Once all references to platform device are down to 0,
* release all allocated structures. * release all allocated structures.
* In case vendor provided release function,
* call it too.
*/ */
static void tpm_dev_release(struct device *dev) static void tpm_dev_release(struct device *dev)
{ {
struct tpm_chip *chip = dev_get_drvdata(dev); struct tpm_chip *chip = dev_get_drvdata(dev);
if (chip->vendor.release) tpm_dev_vendor_release(chip);
chip->vendor.release(dev);
chip->release(dev); chip->release(dev);
clear_bit(chip->dev_num, dev_mask);
kfree(chip->vendor.miscdev.name);
kfree(chip); kfree(chip);
} }
EXPORT_SYMBOL_GPL(tpm_dev_release);
/* /*
* Called from tpm_<specific>.c probe function only for devices * Called from tpm_<specific>.c probe function only for devices
...@@ -1171,8 +1168,8 @@ static void tpm_dev_release(struct device *dev) ...@@ -1171,8 +1168,8 @@ static void tpm_dev_release(struct device *dev)
* upon errant exit from this function specific probe function should call * upon errant exit from this function specific probe function should call
* pci_disable_device * pci_disable_device
*/ */
struct tpm_chip *tpm_register_hardware(struct device *dev, const struct tpm_vendor_specific struct tpm_chip *tpm_register_hardware(struct device *dev,
*entry) const struct tpm_vendor_specific *entry)
{ {
#define DEVNAME_SIZE 7 #define DEVNAME_SIZE 7
...@@ -1231,21 +1228,20 @@ struct tpm_chip *tpm_register_hardware(struct device *dev, const struct tpm_vend ...@@ -1231,21 +1228,20 @@ struct tpm_chip *tpm_register_hardware(struct device *dev, const struct tpm_vend
return NULL; 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)) { if (sysfs_create_group(&dev->kobj, chip->vendor.attr_group)) {
list_del(&chip->list);
misc_deregister(&chip->vendor.miscdev); misc_deregister(&chip->vendor.miscdev);
put_device(chip->dev); put_device(chip->dev);
return NULL; return NULL;
} }
chip->bios_dir = tpm_bios_log_setup(devname); 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; return chip;
} }
EXPORT_SYMBOL_GPL(tpm_register_hardware); EXPORT_SYMBOL_GPL(tpm_register_hardware);
......
...@@ -90,7 +90,7 @@ struct tpm_chip { ...@@ -90,7 +90,7 @@ struct tpm_chip {
struct device *dev; /* Device stuff */ struct device *dev; /* Device stuff */
int dev_num; /* /dev/tpm# */ int dev_num; /* /dev/tpm# */
int num_opens; /* only one allowed */ unsigned long is_open; /* only one allowed */
int time_expired; int time_expired;
/* Data passed to and from the tpm via the read/write calls */ /* 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 *, ...@@ -132,6 +132,7 @@ extern struct tpm_chip* tpm_register_hardware(struct device *,
const struct tpm_vendor_specific *); const struct tpm_vendor_specific *);
extern int tpm_open(struct inode *, struct file *); extern int tpm_open(struct inode *, struct file *);
extern int tpm_release(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, extern ssize_t tpm_write(struct file *, const char __user *, size_t,
loff_t *); loff_t *);
extern ssize_t tpm_read(struct file *, char __user *, size_t, loff_t *); extern ssize_t tpm_read(struct file *, char __user *, size_t, loff_t *);
......
...@@ -630,12 +630,23 @@ static struct pnp_device_id tpm_pnp_tbl[] __devinitdata = { ...@@ -630,12 +630,23 @@ static struct pnp_device_id tpm_pnp_tbl[] __devinitdata = {
{"", 0} /* Terminator */ {"", 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 = { static struct pnp_driver tis_pnp_driver = {
.name = "tpm_tis", .name = "tpm_tis",
.id_table = tpm_pnp_tbl, .id_table = tpm_pnp_tbl,
.probe = tpm_tis_pnp_init, .probe = tpm_tis_pnp_init,
.suspend = tpm_tis_pnp_suspend, .suspend = tpm_tis_pnp_suspend,
.resume = tpm_tis_pnp_resume, .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 #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) ...@@ -683,6 +694,7 @@ static void __exit cleanup_tis(void)
spin_lock(&tis_lock); spin_lock(&tis_lock);
list_for_each_entry_safe(i, j, &tis_chips, list) { list_for_each_entry_safe(i, j, &tis_chips, list) {
chip = to_tpm_chip(i); chip = to_tpm_chip(i);
tpm_remove_hardware(chip->dev);
iowrite32(~TPM_GLOBAL_INT_ENABLE & iowrite32(~TPM_GLOBAL_INT_ENABLE &
ioread32(chip->vendor.iobase + ioread32(chip->vendor.iobase +
TPM_INT_ENABLE(chip->vendor. TPM_INT_ENABLE(chip->vendor.
...@@ -694,9 +706,9 @@ static void __exit cleanup_tis(void) ...@@ -694,9 +706,9 @@ static void __exit cleanup_tis(void)
free_irq(chip->vendor.irq, chip); free_irq(chip->vendor.irq, chip);
iounmap(i->iobase); iounmap(i->iobase);
list_del(&i->list); list_del(&i->list);
tpm_remove_hardware(chip->dev);
} }
spin_unlock(&tis_lock); spin_unlock(&tis_lock);
if (force) { if (force) {
platform_device_unregister(pdev); platform_device_unregister(pdev);
driver_unregister(&tis_drv); driver_unregister(&tis_drv);
......
...@@ -26,8 +26,7 @@ ...@@ -26,8 +26,7 @@
#include <linux/debugfs.h> #include <linux/debugfs.h>
#include <linux/fsnotify.h> #include <linux/fsnotify.h>
#include <linux/string.h> #include <linux/string.h>
#include <linux/magic.h>
#define DEBUGFS_MAGIC 0x64626720
static struct vfsmount *debugfs_mount; static struct vfsmount *debugfs_mount;
static int debugfs_mount_count; static int debugfs_mount_count;
......
...@@ -6,6 +6,10 @@ ...@@ -6,6 +6,10 @@
#define AFS_SUPER_MAGIC 0x5346414F #define AFS_SUPER_MAGIC 0x5346414F
#define AUTOFS_SUPER_MAGIC 0x0187 #define AUTOFS_SUPER_MAGIC 0x0187
#define CODA_SUPER_MAGIC 0x73757245 #define CODA_SUPER_MAGIC 0x73757245
#define DEBUGFS_MAGIC 0x64626720
#define SYSFS_MAGIC 0x62656572
#define SECURITYFS_MAGIC 0x73636673
#define TMPFS_MAGIC 0x01021994
#define EFS_SUPER_MAGIC 0x414A53 #define EFS_SUPER_MAGIC 0x414A53
#define EXT2_SUPER_MAGIC 0xEF53 #define EXT2_SUPER_MAGIC 0xEF53
#define EXT3_SUPER_MAGIC 0xEF53 #define EXT3_SUPER_MAGIC 0xEF53
......
...@@ -40,11 +40,12 @@ ...@@ -40,11 +40,12 @@
#include <linux/net.h> #include <linux/net.h>
#include <linux/skbuff.h> #include <linux/skbuff.h>
#include <net/netlabel.h> #include <net/netlabel.h>
#include <asm/atomic.h>
/* known doi values */ /* known doi values */
#define CIPSO_V4_DOI_UNKNOWN 0x00000000 #define CIPSO_V4_DOI_UNKNOWN 0x00000000
/* tag types */ /* standard tag types */
#define CIPSO_V4_TAG_INVALID 0 #define CIPSO_V4_TAG_INVALID 0
#define CIPSO_V4_TAG_RBITMAP 1 #define CIPSO_V4_TAG_RBITMAP 1
#define CIPSO_V4_TAG_ENUM 2 #define CIPSO_V4_TAG_ENUM 2
...@@ -52,10 +53,14 @@ ...@@ -52,10 +53,14 @@
#define CIPSO_V4_TAG_PBITMAP 6 #define CIPSO_V4_TAG_PBITMAP 6
#define CIPSO_V4_TAG_FREEFORM 7 #define CIPSO_V4_TAG_FREEFORM 7
/* non-standard tag types (tags > 127) */
#define CIPSO_V4_TAG_LOCAL 128
/* doi mapping types */ /* doi mapping types */
#define CIPSO_V4_MAP_UNKNOWN 0 #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_PASS 2
#define CIPSO_V4_MAP_LOCAL 3
/* limits */ /* limits */
#define CIPSO_V4_MAX_REM_LVLS 255 #define CIPSO_V4_MAX_REM_LVLS 255
...@@ -79,10 +84,9 @@ struct cipso_v4_doi { ...@@ -79,10 +84,9 @@ struct cipso_v4_doi {
} map; } map;
u8 tags[CIPSO_V4_TAG_MAXCNT]; u8 tags[CIPSO_V4_TAG_MAXCNT];
u32 valid; atomic_t refcount;
struct list_head list; struct list_head list;
struct rcu_head rcu; struct rcu_head rcu;
struct list_head dom_list;
}; };
/* Standard CIPSO mapping table */ /* Standard CIPSO mapping table */
...@@ -128,25 +132,26 @@ extern int cipso_v4_rbm_strictvalid; ...@@ -128,25 +132,26 @@ extern int cipso_v4_rbm_strictvalid;
#ifdef CONFIG_NETLABEL #ifdef CONFIG_NETLABEL
int cipso_v4_doi_add(struct cipso_v4_doi *doi_def); int cipso_v4_doi_add(struct cipso_v4_doi *doi_def);
int cipso_v4_doi_remove(u32 doi, void cipso_v4_doi_free(struct cipso_v4_doi *doi_def);
struct netlbl_audit *audit_info, int cipso_v4_doi_remove(u32 doi, struct netlbl_audit *audit_info);
void (*callback) (struct rcu_head * head));
struct cipso_v4_doi *cipso_v4_doi_getdef(u32 doi); 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 cipso_v4_doi_walk(u32 *skip_cnt,
int (*callback) (struct cipso_v4_doi *doi_def, void *arg), int (*callback) (struct cipso_v4_doi *doi_def, void *arg),
void *cb_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 #else
static inline int cipso_v4_doi_add(struct cipso_v4_doi *doi_def) static inline int cipso_v4_doi_add(struct cipso_v4_doi *doi_def)
{ {
return -ENOSYS; 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, static inline int cipso_v4_doi_remove(u32 doi,
struct netlbl_audit *audit_info, struct netlbl_audit *audit_info)
void (*callback) (struct rcu_head * head))
{ {
return 0; return 0;
} }
...@@ -206,10 +211,15 @@ void cipso_v4_error(struct sk_buff *skb, int error, u32 gateway); ...@@ -206,10 +211,15 @@ void cipso_v4_error(struct sk_buff *skb, int error, u32 gateway);
int cipso_v4_sock_setattr(struct sock *sk, int cipso_v4_sock_setattr(struct sock *sk,
const struct cipso_v4_doi *doi_def, const struct cipso_v4_doi *doi_def,
const struct netlbl_lsm_secattr *secattr); 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_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, int cipso_v4_skbuff_getattr(const struct sk_buff *skb,
struct netlbl_lsm_secattr *secattr); 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 #else
static inline void cipso_v4_error(struct sk_buff *skb, static inline void cipso_v4_error(struct sk_buff *skb,
int error, int error,
...@@ -225,19 +235,36 @@ static inline int cipso_v4_sock_setattr(struct sock *sk, ...@@ -225,19 +235,36 @@ static inline int cipso_v4_sock_setattr(struct sock *sk,
return -ENOSYS; return -ENOSYS;
} }
static inline void cipso_v4_sock_delattr(struct sock *sk)
{
}
static inline int cipso_v4_sock_getattr(struct sock *sk, static inline int cipso_v4_sock_getattr(struct sock *sk,
struct netlbl_lsm_secattr *secattr) struct netlbl_lsm_secattr *secattr)
{ {
return -ENOSYS; 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, static inline int cipso_v4_skbuff_getattr(const struct sk_buff *skb,
struct netlbl_lsm_secattr *secattr) struct netlbl_lsm_secattr *secattr)
{ {
return -ENOSYS; 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; return -ENOSYS;
} }
......
...@@ -9,7 +9,7 @@ ...@@ -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 * 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 * it under the terms of the GNU General Public License as published by
...@@ -72,8 +72,10 @@ struct cipso_v4_doi; ...@@ -72,8 +72,10 @@ struct cipso_v4_doi;
/* NetLabel NETLINK protocol version /* NetLabel NETLINK protocol version
* 1: initial version * 1: initial version
* 2: added static labels for unlabeled connections * 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 */ /* NetLabel NETLINK types/families */
#define NETLBL_NLTYPE_NONE 0 #define NETLBL_NLTYPE_NONE 0
...@@ -87,6 +89,8 @@ struct cipso_v4_doi; ...@@ -87,6 +89,8 @@ struct cipso_v4_doi;
#define NETLBL_NLTYPE_CIPSOV6_NAME "NLBL_CIPSOv6" #define NETLBL_NLTYPE_CIPSOV6_NAME "NLBL_CIPSOv6"
#define NETLBL_NLTYPE_UNLABELED 5 #define NETLBL_NLTYPE_UNLABELED 5
#define NETLBL_NLTYPE_UNLABELED_NAME "NLBL_UNLBL" #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. * NetLabel - Kernel API for accessing the network packet label mappings.
...@@ -200,7 +204,7 @@ struct netlbl_lsm_secattr { ...@@ -200,7 +204,7 @@ struct netlbl_lsm_secattr {
u32 type; u32 type;
char *domain; char *domain;
struct netlbl_lsm_cache *cache; struct netlbl_lsm_cache *cache;
union { struct {
struct { struct {
struct netlbl_lsm_secattr_catmap *cat; struct netlbl_lsm_secattr_catmap *cat;
u32 lvl; u32 lvl;
...@@ -352,12 +356,9 @@ static inline void netlbl_secattr_free(struct netlbl_lsm_secattr *secattr) ...@@ -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_map_del(const char *domain, struct netlbl_audit *audit_info);
int netlbl_cfg_unlbl_add_map(const char *domain, int netlbl_cfg_unlbl_add_map(const char *domain,
struct netlbl_audit *audit_info); 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, int netlbl_cfg_cipsov4_add_map(struct cipso_v4_doi *doi_def,
const char *domain, const char *domain,
struct netlbl_audit *audit_info); struct netlbl_audit *audit_info);
int netlbl_cfg_cipsov4_del(u32 doi, struct netlbl_audit *audit_info);
/* /*
* LSM security attribute operations * LSM security attribute operations
...@@ -380,12 +381,19 @@ int netlbl_secattr_catmap_setrng(struct netlbl_lsm_secattr_catmap *catmap, ...@@ -380,12 +381,19 @@ int netlbl_secattr_catmap_setrng(struct netlbl_lsm_secattr_catmap *catmap,
int netlbl_enabled(void); int netlbl_enabled(void);
int netlbl_sock_setattr(struct sock *sk, int netlbl_sock_setattr(struct sock *sk,
const struct netlbl_lsm_secattr *secattr); const struct netlbl_lsm_secattr *secattr);
void netlbl_sock_delattr(struct sock *sk);
int netlbl_sock_getattr(struct sock *sk, int netlbl_sock_getattr(struct sock *sk,
struct netlbl_lsm_secattr *secattr); 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, int netlbl_skbuff_getattr(const struct sk_buff *skb,
u16 family, u16 family,
struct netlbl_lsm_secattr *secattr); 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 * LSM label mapping cache operations
...@@ -404,22 +412,12 @@ static inline int netlbl_cfg_unlbl_add_map(const char *domain, ...@@ -404,22 +412,12 @@ static inline int netlbl_cfg_unlbl_add_map(const char *domain,
{ {
return -ENOSYS; 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, static inline int netlbl_cfg_cipsov4_add_map(struct cipso_v4_doi *doi_def,
const char *domain, const char *domain,
struct netlbl_audit *audit_info) struct netlbl_audit *audit_info)
{ {
return -ENOSYS; 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( static inline int netlbl_secattr_catmap_walk(
struct netlbl_lsm_secattr_catmap *catmap, struct netlbl_lsm_secattr_catmap *catmap,
u32 offset) u32 offset)
...@@ -456,18 +454,35 @@ static inline int netlbl_sock_setattr(struct sock *sk, ...@@ -456,18 +454,35 @@ static inline int netlbl_sock_setattr(struct sock *sk,
{ {
return -ENOSYS; return -ENOSYS;
} }
static inline void netlbl_sock_delattr(struct sock *sk)
{
}
static inline int netlbl_sock_getattr(struct sock *sk, static inline int netlbl_sock_getattr(struct sock *sk,
struct netlbl_lsm_secattr *secattr) struct netlbl_lsm_secattr *secattr)
{ {
return -ENOSYS; 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, static inline int netlbl_skbuff_getattr(const struct sk_buff *skb,
u16 family, u16 family,
struct netlbl_lsm_secattr *secattr) struct netlbl_lsm_secattr *secattr)
{ {
return -ENOSYS; 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; return;
} }
......
...@@ -50,14 +50,12 @@ ...@@ -50,14 +50,12 @@
#include <linux/migrate.h> #include <linux/migrate.h>
#include <linux/highmem.h> #include <linux/highmem.h>
#include <linux/seq_file.h> #include <linux/seq_file.h>
#include <linux/magic.h>
#include <asm/uaccess.h> #include <asm/uaccess.h>
#include <asm/div64.h> #include <asm/div64.h>
#include <asm/pgtable.h> #include <asm/pgtable.h>
/* This magic number is used in glibc for posix shared memory */
#define TMPFS_MAGIC 0x01021994
#define ENTRIES_PER_PAGE (PAGE_CACHE_SIZE/sizeof(unsigned long)) #define ENTRIES_PER_PAGE (PAGE_CACHE_SIZE/sizeof(unsigned long))
#define ENTRIES_PER_PAGEPAGE (ENTRIES_PER_PAGE*ENTRIES_PER_PAGE) #define ENTRIES_PER_PAGEPAGE (ENTRIES_PER_PAGE*ENTRIES_PER_PAGE)
#define BLOCKS_PER_PAGE (PAGE_CACHE_SIZE/512) #define BLOCKS_PER_PAGE (PAGE_CACHE_SIZE/512)
......
This diff is collapsed.
...@@ -438,7 +438,7 @@ int ip_options_compile(struct net *net, ...@@ -438,7 +438,7 @@ int ip_options_compile(struct net *net,
goto error; goto error;
} }
opt->cipso = optptr - iph; opt->cipso = optptr - iph;
if (cipso_v4_validate(&optptr)) { if (cipso_v4_validate(skb, &optptr)) {
pp_ptr = optptr; pp_ptr = optptr;
goto error; goto error;
} }
......
...@@ -5,7 +5,8 @@ ...@@ -5,7 +5,8 @@
# #
# base objects # base objects
obj-y := netlabel_user.o netlabel_kapi.o netlabel_domainhash.o obj-y := netlabel_user.o netlabel_kapi.o
obj-y += netlabel_domainhash.o netlabel_addrlist.o
# management objects # management objects
obj-y += netlabel_mgmt.o obj-y += netlabel_mgmt.o
......
This diff is collapsed.
/*
* NetLabel Network Address Lists
*
* This file contains network address list functions used to manage ordered
* lists of network addresses for use by the NetLabel subsystem. The NetLabel
* system manages static and dynamic label mappings for network protocols such
* as CIPSO and RIPSO.
*
* Author: Paul Moore <paul.moore@hp.com>
*
*/
/*
* (c) Copyright Hewlett-Packard Development Company, L.P., 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
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
* the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*/
#ifndef _NETLABEL_ADDRLIST_H
#define _NETLABEL_ADDRLIST_H
#include <linux/types.h>
#include <linux/rcupdate.h>
#include <linux/list.h>
#include <linux/in6.h>
#include <linux/audit.h>
/**
* struct netlbl_af4list - NetLabel IPv4 address list
* @addr: IPv4 address
* @mask: IPv4 address mask
* @valid: valid flag
* @list: list structure, used internally
*/
struct netlbl_af4list {
__be32 addr;
__be32 mask;
u32 valid;
struct list_head list;
};
/**
* struct netlbl_af6list - NetLabel IPv6 address list
* @addr: IPv6 address
* @mask: IPv6 address mask
* @valid: valid flag
* @list: list structure, used internally
*/
struct netlbl_af6list {
struct in6_addr addr;
struct in6_addr mask;
u32 valid;
struct list_head list;
};
#define __af4list_entry(ptr) container_of(ptr, struct netlbl_af4list, list)
static inline struct netlbl_af4list *__af4list_valid(struct list_head *s,
struct list_head *h)
{
struct list_head *i = s;
struct netlbl_af4list *n = __af4list_entry(s);
while (i != h && !n->valid) {
i = i->next;
n = __af4list_entry(i);
}
return n;
}
static inline struct netlbl_af4list *__af4list_valid_rcu(struct list_head *s,
struct list_head *h)
{
struct list_head *i = s;
struct netlbl_af4list *n = __af4list_entry(s);
while (i != h && !n->valid) {
i = rcu_dereference(i->next);
n = __af4list_entry(i);
}
return n;
}
#define netlbl_af4list_foreach(iter, head) \
for (iter = __af4list_valid((head)->next, head); \
prefetch(iter->list.next), &iter->list != (head); \
iter = __af4list_valid(iter->list.next, head))
#define netlbl_af4list_foreach_rcu(iter, head) \
for (iter = __af4list_valid_rcu((head)->next, head); \
prefetch(iter->list.next), &iter->list != (head); \
iter = __af4list_valid_rcu(iter->list.next, head))
#define netlbl_af4list_foreach_safe(iter, tmp, head) \
for (iter = __af4list_valid((head)->next, head), \
tmp = __af4list_valid(iter->list.next, head); \
&iter->list != (head); \
iter = tmp, tmp = __af4list_valid(iter->list.next, head))
int netlbl_af4list_add(struct netlbl_af4list *entry,
struct list_head *head);
struct netlbl_af4list *netlbl_af4list_remove(__be32 addr, __be32 mask,
struct list_head *head);
void netlbl_af4list_remove_entry(struct netlbl_af4list *entry);
struct netlbl_af4list *netlbl_af4list_search(__be32 addr,
struct list_head *head);
struct netlbl_af4list *netlbl_af4list_search_exact(__be32 addr,
__be32 mask,
struct list_head *head);
void netlbl_af4list_audit_addr(struct audit_buffer *audit_buf,
int src, const char *dev,
__be32 addr, __be32 mask);
#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
#define __af6list_entry(ptr) container_of(ptr, struct netlbl_af6list, list)
static inline struct netlbl_af6list *__af6list_valid(struct list_head *s,
struct list_head *h)
{
struct list_head *i = s;
struct netlbl_af6list *n = __af6list_entry(s);
while (i != h && !n->valid) {
i = i->next;
n = __af6list_entry(i);
}
return n;
}
static inline struct netlbl_af6list *__af6list_valid_rcu(struct list_head *s,
struct list_head *h)
{
struct list_head *i = s;
struct netlbl_af6list *n = __af6list_entry(s);
while (i != h && !n->valid) {
i = rcu_dereference(i->next);
n = __af6list_entry(i);
}
return n;
}
#define netlbl_af6list_foreach(iter, head) \
for (iter = __af6list_valid((head)->next, head); \
prefetch(iter->list.next), &iter->list != (head); \
iter = __af6list_valid(iter->list.next, head))
#define netlbl_af6list_foreach_rcu(iter, head) \
for (iter = __af6list_valid_rcu((head)->next, head); \
prefetch(iter->list.next), &iter->list != (head); \
iter = __af6list_valid_rcu(iter->list.next, head))
#define netlbl_af6list_foreach_safe(iter, tmp, head) \
for (iter = __af6list_valid((head)->next, head), \
tmp = __af6list_valid(iter->list.next, head); \
&iter->list != (head); \
iter = tmp, tmp = __af6list_valid(iter->list.next, head))
int netlbl_af6list_add(struct netlbl_af6list *entry,
struct list_head *head);
struct netlbl_af6list *netlbl_af6list_remove(const struct in6_addr *addr,
const struct in6_addr *mask,
struct list_head *head);
void netlbl_af6list_remove_entry(struct netlbl_af6list *entry);
struct netlbl_af6list *netlbl_af6list_search(const struct in6_addr *addr,
struct list_head *head);
struct netlbl_af6list *netlbl_af6list_search_exact(const struct in6_addr *addr,
const struct in6_addr *mask,
struct list_head *head);
void netlbl_af6list_audit_addr(struct audit_buffer *audit_buf,
int src,
const char *dev,
const struct in6_addr *addr,
const struct in6_addr *mask);
#endif /* IPV6 */
#endif
...@@ -43,6 +43,7 @@ ...@@ -43,6 +43,7 @@
#include "netlabel_user.h" #include "netlabel_user.h"
#include "netlabel_cipso_v4.h" #include "netlabel_cipso_v4.h"
#include "netlabel_mgmt.h" #include "netlabel_mgmt.h"
#include "netlabel_domainhash.h"
/* Argument struct for cipso_v4_doi_walk() */ /* Argument struct for cipso_v4_doi_walk() */
struct netlbl_cipsov4_doiwalk_arg { struct netlbl_cipsov4_doiwalk_arg {
...@@ -51,6 +52,12 @@ struct netlbl_cipsov4_doiwalk_arg { ...@@ -51,6 +52,12 @@ struct netlbl_cipsov4_doiwalk_arg {
u32 seq; u32 seq;
}; };
/* Argument struct for netlbl_domhsh_walk() */
struct netlbl_domhsh_walk_arg {
struct netlbl_audit *audit_info;
u32 doi;
};
/* NetLabel Generic NETLINK CIPSOv4 family */ /* NetLabel Generic NETLINK CIPSOv4 family */
static struct genl_family netlbl_cipsov4_gnl_family = { static struct genl_family netlbl_cipsov4_gnl_family = {
.id = GENL_ID_GENERATE, .id = GENL_ID_GENERATE,
...@@ -80,32 +87,6 @@ static const struct nla_policy netlbl_cipsov4_genl_policy[NLBL_CIPSOV4_A_MAX + 1 ...@@ -80,32 +87,6 @@ static const struct nla_policy netlbl_cipsov4_genl_policy[NLBL_CIPSOV4_A_MAX + 1
* Helper Functions * Helper Functions
*/ */
/**
* netlbl_cipsov4_doi_free - Frees a CIPSO V4 DOI definition
* @entry: the entry's RCU field
*
* Description:
* This function is designed to be used as a callback to the call_rcu()
* function so that the memory allocated to the DOI definition can be released
* safely.
*
*/
void netlbl_cipsov4_doi_free(struct rcu_head *entry)
{
struct cipso_v4_doi *ptr;
ptr = container_of(entry, struct cipso_v4_doi, rcu);
switch (ptr->type) {
case CIPSO_V4_MAP_STD:
kfree(ptr->map.std->lvl.cipso);
kfree(ptr->map.std->lvl.local);
kfree(ptr->map.std->cat.cipso);
kfree(ptr->map.std->cat.local);
break;
}
kfree(ptr);
}
/** /**
* netlbl_cipsov4_add_common - Parse the common sections of a ADD message * netlbl_cipsov4_add_common - Parse the common sections of a ADD message
* @info: the Generic NETLINK info block * @info: the Generic NETLINK info block
...@@ -151,9 +132,9 @@ static int netlbl_cipsov4_add_common(struct genl_info *info, ...@@ -151,9 +132,9 @@ static int netlbl_cipsov4_add_common(struct genl_info *info,
* @info: the Generic NETLINK info block * @info: the Generic NETLINK info block
* *
* Description: * Description:
* Create a new CIPSO_V4_MAP_STD DOI definition based on the given ADD message * Create a new CIPSO_V4_MAP_TRANS DOI definition based on the given ADD
* and add it to the CIPSO V4 engine. Return zero on success and non-zero on * message and add it to the CIPSO V4 engine. Return zero on success and
* error. * non-zero on error.
* *
*/ */
static int netlbl_cipsov4_add_std(struct genl_info *info) static int netlbl_cipsov4_add_std(struct genl_info *info)
...@@ -183,7 +164,7 @@ static int netlbl_cipsov4_add_std(struct genl_info *info) ...@@ -183,7 +164,7 @@ static int netlbl_cipsov4_add_std(struct genl_info *info)
ret_val = -ENOMEM; ret_val = -ENOMEM;
goto add_std_failure; goto add_std_failure;
} }
doi_def->type = CIPSO_V4_MAP_STD; doi_def->type = CIPSO_V4_MAP_TRANS;
ret_val = netlbl_cipsov4_add_common(info, doi_def); ret_val = netlbl_cipsov4_add_common(info, doi_def);
if (ret_val != 0) if (ret_val != 0)
...@@ -342,7 +323,7 @@ static int netlbl_cipsov4_add_std(struct genl_info *info) ...@@ -342,7 +323,7 @@ static int netlbl_cipsov4_add_std(struct genl_info *info)
add_std_failure: add_std_failure:
if (doi_def) if (doi_def)
netlbl_cipsov4_doi_free(&doi_def->rcu); cipso_v4_doi_free(doi_def);
return ret_val; return ret_val;
} }
...@@ -379,7 +360,44 @@ static int netlbl_cipsov4_add_pass(struct genl_info *info) ...@@ -379,7 +360,44 @@ static int netlbl_cipsov4_add_pass(struct genl_info *info)
return 0; return 0;
add_pass_failure: add_pass_failure:
netlbl_cipsov4_doi_free(&doi_def->rcu); cipso_v4_doi_free(doi_def);
return ret_val;
}
/**
* netlbl_cipsov4_add_local - Adds a CIPSO V4 DOI definition
* @info: the Generic NETLINK info block
*
* Description:
* Create a new CIPSO_V4_MAP_LOCAL DOI definition based on the given ADD
* message and add it to the CIPSO V4 engine. Return zero on success and
* non-zero on error.
*
*/
static int netlbl_cipsov4_add_local(struct genl_info *info)
{
int ret_val;
struct cipso_v4_doi *doi_def = NULL;
if (!info->attrs[NLBL_CIPSOV4_A_TAGLST])
return -EINVAL;
doi_def = kmalloc(sizeof(*doi_def), GFP_KERNEL);
if (doi_def == NULL)
return -ENOMEM;
doi_def->type = CIPSO_V4_MAP_LOCAL;
ret_val = netlbl_cipsov4_add_common(info, doi_def);
if (ret_val != 0)
goto add_local_failure;
ret_val = cipso_v4_doi_add(doi_def);
if (ret_val != 0)
goto add_local_failure;
return 0;
add_local_failure:
cipso_v4_doi_free(doi_def);
return ret_val; return ret_val;
} }
...@@ -412,14 +430,18 @@ static int netlbl_cipsov4_add(struct sk_buff *skb, struct genl_info *info) ...@@ -412,14 +430,18 @@ static int netlbl_cipsov4_add(struct sk_buff *skb, struct genl_info *info)
type = nla_get_u32(info->attrs[NLBL_CIPSOV4_A_MTYPE]); type = nla_get_u32(info->attrs[NLBL_CIPSOV4_A_MTYPE]);
switch (type) { switch (type) {
case CIPSO_V4_MAP_STD: case CIPSO_V4_MAP_TRANS:
type_str = "std"; type_str = "trans";
ret_val = netlbl_cipsov4_add_std(info); ret_val = netlbl_cipsov4_add_std(info);
break; break;
case CIPSO_V4_MAP_PASS: case CIPSO_V4_MAP_PASS:
type_str = "pass"; type_str = "pass";
ret_val = netlbl_cipsov4_add_pass(info); ret_val = netlbl_cipsov4_add_pass(info);
break; break;
case CIPSO_V4_MAP_LOCAL:
type_str = "local";
ret_val = netlbl_cipsov4_add_local(info);
break;
} }
if (ret_val == 0) if (ret_val == 0)
atomic_inc(&netlabel_mgmt_protocount); atomic_inc(&netlabel_mgmt_protocount);
...@@ -491,7 +513,7 @@ list_start: ...@@ -491,7 +513,7 @@ list_start:
doi_def = cipso_v4_doi_getdef(doi); doi_def = cipso_v4_doi_getdef(doi);
if (doi_def == NULL) { if (doi_def == NULL) {
ret_val = -EINVAL; ret_val = -EINVAL;
goto list_failure; goto list_failure_lock;
} }
ret_val = nla_put_u32(ans_skb, NLBL_CIPSOV4_A_MTYPE, doi_def->type); ret_val = nla_put_u32(ans_skb, NLBL_CIPSOV4_A_MTYPE, doi_def->type);
...@@ -516,7 +538,7 @@ list_start: ...@@ -516,7 +538,7 @@ list_start:
nla_nest_end(ans_skb, nla_a); nla_nest_end(ans_skb, nla_a);
switch (doi_def->type) { switch (doi_def->type) {
case CIPSO_V4_MAP_STD: case CIPSO_V4_MAP_TRANS:
nla_a = nla_nest_start(ans_skb, NLBL_CIPSOV4_A_MLSLVLLST); nla_a = nla_nest_start(ans_skb, NLBL_CIPSOV4_A_MLSLVLLST);
if (nla_a == NULL) { if (nla_a == NULL) {
ret_val = -ENOMEM; ret_val = -ENOMEM;
...@@ -655,7 +677,7 @@ static int netlbl_cipsov4_listall(struct sk_buff *skb, ...@@ -655,7 +677,7 @@ static int netlbl_cipsov4_listall(struct sk_buff *skb,
struct netlink_callback *cb) struct netlink_callback *cb)
{ {
struct netlbl_cipsov4_doiwalk_arg cb_arg; struct netlbl_cipsov4_doiwalk_arg cb_arg;
int doi_skip = cb->args[0]; u32 doi_skip = cb->args[0];
cb_arg.nl_cb = cb; cb_arg.nl_cb = cb;
cb_arg.skb = skb; cb_arg.skb = skb;
...@@ -667,6 +689,29 @@ static int netlbl_cipsov4_listall(struct sk_buff *skb, ...@@ -667,6 +689,29 @@ static int netlbl_cipsov4_listall(struct sk_buff *skb,
return skb->len; return skb->len;
} }
/**
* netlbl_cipsov4_remove_cb - netlbl_cipsov4_remove() callback for REMOVE
* @entry: LSM domain mapping entry
* @arg: the netlbl_domhsh_walk_arg structure
*
* Description:
* This function is intended for use by netlbl_cipsov4_remove() as the callback
* for the netlbl_domhsh_walk() function; it removes LSM domain map entries
* which are associated with the CIPSO DOI specified in @arg. Returns zero on
* success, negative values on failure.
*
*/
static int netlbl_cipsov4_remove_cb(struct netlbl_dom_map *entry, void *arg)
{
struct netlbl_domhsh_walk_arg *cb_arg = arg;
if (entry->type == NETLBL_NLTYPE_CIPSOV4 &&
entry->type_def.cipsov4->doi == cb_arg->doi)
return netlbl_domhsh_remove_entry(entry, cb_arg->audit_info);
return 0;
}
/** /**
* netlbl_cipsov4_remove - Handle a REMOVE message * netlbl_cipsov4_remove - Handle a REMOVE message
* @skb: the NETLINK buffer * @skb: the NETLINK buffer
...@@ -681,8 +726,11 @@ static int netlbl_cipsov4_remove(struct sk_buff *skb, struct genl_info *info) ...@@ -681,8 +726,11 @@ static int netlbl_cipsov4_remove(struct sk_buff *skb, struct genl_info *info)
{ {
int ret_val = -EINVAL; int ret_val = -EINVAL;
u32 doi = 0; u32 doi = 0;
struct netlbl_domhsh_walk_arg cb_arg;
struct audit_buffer *audit_buf; struct audit_buffer *audit_buf;
struct netlbl_audit audit_info; struct netlbl_audit audit_info;
u32 skip_bkt = 0;
u32 skip_chain = 0;
if (!info->attrs[NLBL_CIPSOV4_A_DOI]) if (!info->attrs[NLBL_CIPSOV4_A_DOI])
return -EINVAL; return -EINVAL;
...@@ -690,11 +738,15 @@ static int netlbl_cipsov4_remove(struct sk_buff *skb, struct genl_info *info) ...@@ -690,11 +738,15 @@ static int netlbl_cipsov4_remove(struct sk_buff *skb, struct genl_info *info)
doi = nla_get_u32(info->attrs[NLBL_CIPSOV4_A_DOI]); doi = nla_get_u32(info->attrs[NLBL_CIPSOV4_A_DOI]);
netlbl_netlink_auditinfo(skb, &audit_info); netlbl_netlink_auditinfo(skb, &audit_info);
ret_val = cipso_v4_doi_remove(doi, cb_arg.doi = doi;
&audit_info, cb_arg.audit_info = &audit_info;
netlbl_cipsov4_doi_free); ret_val = netlbl_domhsh_walk(&skip_bkt, &skip_chain,
if (ret_val == 0) netlbl_cipsov4_remove_cb, &cb_arg);
atomic_dec(&netlabel_mgmt_protocount); if (ret_val == 0 || ret_val == -ENOENT) {
ret_val = cipso_v4_doi_remove(doi, &audit_info);
if (ret_val == 0)
atomic_dec(&netlabel_mgmt_protocount);
}
audit_buf = netlbl_audit_start_common(AUDIT_MAC_CIPSOV4_DEL, audit_buf = netlbl_audit_start_common(AUDIT_MAC_CIPSOV4_DEL,
&audit_info); &audit_info);
......
...@@ -45,12 +45,13 @@ ...@@ -45,12 +45,13 @@
* NLBL_CIPSOV4_A_MTYPE * NLBL_CIPSOV4_A_MTYPE
* NLBL_CIPSOV4_A_TAGLST * NLBL_CIPSOV4_A_TAGLST
* *
* If using CIPSO_V4_MAP_STD the following attributes are required: * If using CIPSO_V4_MAP_TRANS the following attributes are required:
* *
* NLBL_CIPSOV4_A_MLSLVLLST * NLBL_CIPSOV4_A_MLSLVLLST
* NLBL_CIPSOV4_A_MLSCATLST * NLBL_CIPSOV4_A_MLSCATLST
* *
* If using CIPSO_V4_MAP_PASS no additional attributes are required. * If using CIPSO_V4_MAP_PASS or CIPSO_V4_MAP_LOCAL no additional attributes
* are required.
* *
* o REMOVE: * o REMOVE:
* Sent by an application to remove a specific DOI mapping table from the * Sent by an application to remove a specific DOI mapping table from the
...@@ -76,12 +77,13 @@ ...@@ -76,12 +77,13 @@
* NLBL_CIPSOV4_A_MTYPE * NLBL_CIPSOV4_A_MTYPE
* NLBL_CIPSOV4_A_TAGLST * NLBL_CIPSOV4_A_TAGLST
* *
* If using CIPSO_V4_MAP_STD the following attributes are required: * If using CIPSO_V4_MAP_TRANS the following attributes are required:
* *
* NLBL_CIPSOV4_A_MLSLVLLST * NLBL_CIPSOV4_A_MLSLVLLST
* NLBL_CIPSOV4_A_MLSCATLST * NLBL_CIPSOV4_A_MLSCATLST
* *
* If using CIPSO_V4_MAP_PASS no additional attributes are required. * If using CIPSO_V4_MAP_PASS or CIPSO_V4_MAP_LOCAL no additional attributes
* are required.
* *
* o LISTALL: * o LISTALL:
* This message is sent by an application to list the valid DOIs on the * This message is sent by an application to list the valid DOIs on the
......
This diff is collapsed.
...@@ -11,7 +11,7 @@ ...@@ -11,7 +11,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 * 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 * it under the terms of the GNU General Public License as published by
...@@ -36,16 +36,43 @@ ...@@ -36,16 +36,43 @@
#include <linux/rcupdate.h> #include <linux/rcupdate.h>
#include <linux/list.h> #include <linux/list.h>
#include "netlabel_addrlist.h"
/* Domain hash table size */ /* Domain hash table size */
/* XXX - currently this number is an uneducated guess */ /* XXX - currently this number is an uneducated guess */
#define NETLBL_DOMHSH_BITSIZE 7 #define NETLBL_DOMHSH_BITSIZE 7
/* Domain mapping definition struct */ /* Domain mapping definition structures */
#define netlbl_domhsh_addr4_entry(iter) \
container_of(iter, struct netlbl_domaddr4_map, list)
struct netlbl_domaddr4_map {
u32 type;
union {
struct cipso_v4_doi *cipsov4;
} type_def;
struct netlbl_af4list list;
};
#define netlbl_domhsh_addr6_entry(iter) \
container_of(iter, struct netlbl_domaddr6_map, list)
struct netlbl_domaddr6_map {
u32 type;
/* NOTE: no 'type_def' union needed at present since we don't currently
* support any IPv6 labeling protocols */
struct netlbl_af6list list;
};
struct netlbl_domaddr_map {
struct list_head list4;
struct list_head list6;
};
struct netlbl_dom_map { struct netlbl_dom_map {
char *domain; char *domain;
u32 type; u32 type;
union { union {
struct cipso_v4_doi *cipsov4; struct cipso_v4_doi *cipsov4;
struct netlbl_domaddr_map *addrsel;
} type_def; } type_def;
u32 valid; u32 valid;
...@@ -61,12 +88,21 @@ int netlbl_domhsh_add(struct netlbl_dom_map *entry, ...@@ -61,12 +88,21 @@ int netlbl_domhsh_add(struct netlbl_dom_map *entry,
struct netlbl_audit *audit_info); struct netlbl_audit *audit_info);
int netlbl_domhsh_add_default(struct netlbl_dom_map *entry, int netlbl_domhsh_add_default(struct netlbl_dom_map *entry,
struct netlbl_audit *audit_info); struct netlbl_audit *audit_info);
int netlbl_domhsh_remove_entry(struct netlbl_dom_map *entry,
struct netlbl_audit *audit_info);
int netlbl_domhsh_remove(const char *domain, struct netlbl_audit *audit_info); int netlbl_domhsh_remove(const char *domain, struct netlbl_audit *audit_info);
int netlbl_domhsh_remove_default(struct netlbl_audit *audit_info); int netlbl_domhsh_remove_default(struct netlbl_audit *audit_info);
struct netlbl_dom_map *netlbl_domhsh_getentry(const char *domain); struct netlbl_dom_map *netlbl_domhsh_getentry(const char *domain);
struct netlbl_domaddr4_map *netlbl_domhsh_getentry_af4(const char *domain,
__be32 addr);
int netlbl_domhsh_walk(u32 *skip_bkt, int netlbl_domhsh_walk(u32 *skip_bkt,
u32 *skip_chain, u32 *skip_chain,
int (*callback) (struct netlbl_dom_map *entry, void *arg), int (*callback) (struct netlbl_dom_map *entry, void *arg),
void *cb_arg); void *cb_arg);
#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
struct netlbl_domaddr6_map *netlbl_domhsh_getentry_af6(const char *domain,
const struct in6_addr *addr);
#endif /* IPv6 */
#endif #endif
This diff is collapsed.
This diff is collapsed.
...@@ -45,6 +45,16 @@ ...@@ -45,6 +45,16 @@
* NLBL_MGMT_A_DOMAIN * NLBL_MGMT_A_DOMAIN
* NLBL_MGMT_A_PROTOCOL * NLBL_MGMT_A_PROTOCOL
* *
* If IPv4 is specified the following attributes are required:
*
* NLBL_MGMT_A_IPV4ADDR
* NLBL_MGMT_A_IPV4MASK
*
* If IPv6 is specified the following attributes are required:
*
* NLBL_MGMT_A_IPV6ADDR
* NLBL_MGMT_A_IPV6MASK
*
* If using NETLBL_NLTYPE_CIPSOV4 the following attributes are required: * If using NETLBL_NLTYPE_CIPSOV4 the following attributes are required:
* *
* NLBL_MGMT_A_CV4DOI * NLBL_MGMT_A_CV4DOI
...@@ -68,13 +78,24 @@ ...@@ -68,13 +78,24 @@
* Required attributes: * Required attributes:
* *
* NLBL_MGMT_A_DOMAIN * NLBL_MGMT_A_DOMAIN
*
* If the IP address selectors are not used the following attribute is
* required:
*
* NLBL_MGMT_A_PROTOCOL * NLBL_MGMT_A_PROTOCOL
* *
* If using NETLBL_NLTYPE_CIPSOV4 the following attributes are required: * If the IP address selectors are used then the following attritbute is
* required:
*
* NLBL_MGMT_A_SELECTORLIST
*
* If the mapping is using the NETLBL_NLTYPE_CIPSOV4 type then the following
* attributes are required:
* *
* NLBL_MGMT_A_CV4DOI * NLBL_MGMT_A_CV4DOI
* *
* If using NETLBL_NLTYPE_UNLABELED no other attributes are required. * If the mapping is using the NETLBL_NLTYPE_UNLABELED type no other
* attributes are required.
* *
* o ADDDEF: * o ADDDEF:
* Sent by an application to set the default domain mapping for the NetLabel * Sent by an application to set the default domain mapping for the NetLabel
...@@ -100,15 +121,23 @@ ...@@ -100,15 +121,23 @@
* application there is no payload. On success the kernel should send a * application there is no payload. On success the kernel should send a
* response using the following format. * response using the following format.
* *
* Required attributes: * If the IP address selectors are not used the following attribute is
* required:
* *
* NLBL_MGMT_A_PROTOCOL * NLBL_MGMT_A_PROTOCOL
* *
* If using NETLBL_NLTYPE_CIPSOV4 the following attributes are required: * If the IP address selectors are used then the following attritbute is
* required:
*
* NLBL_MGMT_A_SELECTORLIST
*
* If the mapping is using the NETLBL_NLTYPE_CIPSOV4 type then the following
* attributes are required:
* *
* NLBL_MGMT_A_CV4DOI * NLBL_MGMT_A_CV4DOI
* *
* If using NETLBL_NLTYPE_UNLABELED no other attributes are required. * If the mapping is using the NETLBL_NLTYPE_UNLABELED type no other
* attributes are required.
* *
* o PROTOCOLS: * o PROTOCOLS:
* Sent by an application to request a list of configured NetLabel protocols * Sent by an application to request a list of configured NetLabel protocols
...@@ -162,6 +191,26 @@ enum { ...@@ -162,6 +191,26 @@ enum {
NLBL_MGMT_A_CV4DOI, NLBL_MGMT_A_CV4DOI,
/* (NLA_U32) /* (NLA_U32)
* the CIPSOv4 DOI value */ * the CIPSOv4 DOI value */
NLBL_MGMT_A_IPV6ADDR,
/* (NLA_BINARY, struct in6_addr)
* an IPv6 address */
NLBL_MGMT_A_IPV6MASK,
/* (NLA_BINARY, struct in6_addr)
* an IPv6 address mask */
NLBL_MGMT_A_IPV4ADDR,
/* (NLA_BINARY, struct in_addr)
* an IPv4 address */
NLBL_MGMT_A_IPV4MASK,
/* (NLA_BINARY, struct in_addr)
* and IPv4 address mask */
NLBL_MGMT_A_ADDRSELECTOR,
/* (NLA_NESTED)
* an IP address selector, must contain an address, mask, and protocol
* attribute plus any protocol specific attributes */
NLBL_MGMT_A_SELECTORLIST,
/* (NLA_NESTED)
* the selector list, there must be at least one
* NLBL_MGMT_A_ADDRSELECTOR attribute */
__NLBL_MGMT_A_MAX, __NLBL_MGMT_A_MAX,
}; };
#define NLBL_MGMT_A_MAX (__NLBL_MGMT_A_MAX - 1) #define NLBL_MGMT_A_MAX (__NLBL_MGMT_A_MAX - 1)
......
This diff is collapsed.
...@@ -20,8 +20,7 @@ ...@@ -20,8 +20,7 @@
#include <linux/init.h> #include <linux/init.h>
#include <linux/namei.h> #include <linux/namei.h>
#include <linux/security.h> #include <linux/security.h>
#include <linux/magic.h>
#define SECURITYFS_MAGIC 0x73636673
static struct vfsmount *mount; static struct vfsmount *mount;
static int mount_count; static int mount_count;
......
This diff is collapsed.
This diff is collapsed.
...@@ -109,16 +109,19 @@ struct netport_security_struct { ...@@ -109,16 +109,19 @@ struct netport_security_struct {
}; };
struct sk_security_struct { struct sk_security_struct {
u32 sid; /* SID of this object */
u32 peer_sid; /* SID of peer */
u16 sclass; /* sock security class */
#ifdef CONFIG_NETLABEL #ifdef CONFIG_NETLABEL
enum { /* NetLabel state */ enum { /* NetLabel state */
NLBL_UNSET = 0, NLBL_UNSET = 0,
NLBL_REQUIRE, NLBL_REQUIRE,
NLBL_LABELED, NLBL_LABELED,
NLBL_REQSKB,
NLBL_CONNLABELED,
} nlbl_state; } nlbl_state;
struct netlbl_lsm_secattr *nlbl_secattr; /* NetLabel sec attributes */
#endif #endif
u32 sid; /* SID of this object */
u32 peer_sid; /* SID of peer */
u16 sclass; /* sock security class */
}; };
struct key_security_struct { struct key_security_struct {
......
This diff is collapsed.
This diff is collapsed.
...@@ -2179,7 +2179,10 @@ static int smack_socket_sock_rcv_skb(struct sock *sk, struct sk_buff *skb) ...@@ -2179,7 +2179,10 @@ static int smack_socket_sock_rcv_skb(struct sock *sk, struct sk_buff *skb)
* This is the simplist possible security model * This is the simplist possible security model
* for networking. * for networking.
*/ */
return smk_access(smack, ssp->smk_in, MAY_WRITE); rc = smk_access(smack, ssp->smk_in, MAY_WRITE);
if (rc != 0)
netlbl_skbuff_err(skb, rc, 0);
return rc;
} }
/** /**
......
...@@ -354,9 +354,11 @@ static void smk_cipso_doi(void) ...@@ -354,9 +354,11 @@ static void smk_cipso_doi(void)
doip->tags[rc] = CIPSO_V4_TAG_INVALID; doip->tags[rc] = CIPSO_V4_TAG_INVALID;
rc = netlbl_cfg_cipsov4_add_map(doip, NULL, &audit_info); rc = netlbl_cfg_cipsov4_add_map(doip, NULL, &audit_info);
if (rc != 0) if (rc != 0) {
printk(KERN_WARNING "%s:%d add rc = %d\n", printk(KERN_WARNING "%s:%d add rc = %d\n",
__func__, __LINE__, rc); __func__, __LINE__, rc);
kfree(doip);
}
} }
/** /**
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment