mirror of
https://github.com/linux-msm/laptops-kernel.git
synced 2026-08-13 14:19:53 -07:00
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() ...
This commit is contained in:
commit
8d71ff0bef
29 files changed
+2849
-1080
No files matched your search
+47
-51
@@ -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;
|
||||
|
||||
flush_scheduled_work();
|
||||
spin_lock(&driver_lock);
|
||||
file->private_data = NULL;
|
||||
del_singleshot_timer_sync(&chip->user_read_timer);
|
||||
flush_scheduled_work();
|
||||
file->private_data = NULL;
|
||||
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);
|
||||
|
||||
@@ -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 *);
|
||||
|
||||
@@ -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);
|
||||
|
||||
+1
-2
@@ -26,8 +26,7 @@
|
||||
#include <linux/debugfs.h>
|
||||
#include <linux/fsnotify.h>
|
||||
#include <linux/string.h>
|
||||
|
||||
#define DEBUGFS_MAGIC 0x64626720
|
||||
#include <linux/magic.h>
|
||||
|
||||
static struct vfsmount *debugfs_mount;
|
||||
static int debugfs_mount_count;
|
||||
|
||||
@@ -6,6 +6,10 @@
|
||||
#define AFS_SUPER_MAGIC 0x5346414F
|
||||
#define AUTOFS_SUPER_MAGIC 0x0187
|
||||
#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 EXT2_SUPER_MAGIC 0xEF53
|
||||
#define EXT3_SUPER_MAGIC 0xEF53
|
||||
|
||||
+41
-14
@@ -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
@@ -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;
|
||||
}
|
||||
|
||||
+1
-3
@@ -50,14 +50,12 @@
|
||||
#include <linux/migrate.h>
|
||||
#include <linux/highmem.h>
|
||||
#include <linux/seq_file.h>
|
||||
#include <linux/magic.h>
|
||||
|
||||
#include <asm/uaccess.h>
|
||||
#include <asm/div64.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_PAGEPAGE (ENTRIES_PER_PAGE*ENTRIES_PER_PAGE)
|
||||
#define BLOCKS_PER_PAGE (PAGE_CACHE_SIZE/512)
|
||||
|
||||
+470
-204
File diff suppressed because it is too large.
Load diff
@@ -438,7 +438,7 @@ int ip_options_compile(struct net *net,
|
||||
goto error;
|
||||
}
|
||||
opt->cipso = optptr - iph;
|
||||
if (cipso_v4_validate(&optptr)) {
|
||||
if (cipso_v4_validate(skb, &optptr)) {
|
||||
pp_ptr = optptr;
|
||||
goto error;
|
||||
}
|
||||
|
||||
@@ -5,7 +5,8 @@
|
||||
#
|
||||
|
||||
# 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
|
||||
obj-y += netlabel_mgmt.o
|
||||
|
||||
@@ -0,0 +1,388 @@
|
||||
/*
|
||||
* 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
|
||||
*
|
||||
*/
|
||||
|
||||
#include <linux/types.h>
|
||||
#include <linux/rcupdate.h>
|
||||
#include <linux/list.h>
|
||||
#include <linux/spinlock.h>
|
||||
#include <linux/in.h>
|
||||
#include <linux/in6.h>
|
||||
#include <linux/ip.h>
|
||||
#include <linux/ipv6.h>
|
||||
#include <net/ip.h>
|
||||
#include <net/ipv6.h>
|
||||
#include <linux/audit.h>
|
||||
|
||||
#include "netlabel_addrlist.h"
|
||||
|
||||
/*
|
||||
* Address List Functions
|
||||
*/
|
||||
|
||||
/**
|
||||
* netlbl_af4list_search - Search for a matching IPv4 address entry
|
||||
* @addr: IPv4 address
|
||||
* @head: the list head
|
||||
*
|
||||
* Description:
|
||||
* Searches the IPv4 address list given by @head. If a matching address entry
|
||||
* is found it is returned, otherwise NULL is returned. The caller is
|
||||
* responsible for calling the rcu_read_[un]lock() functions.
|
||||
*
|
||||
*/
|
||||
struct netlbl_af4list *netlbl_af4list_search(__be32 addr,
|
||||
struct list_head *head)
|
||||
{
|
||||
struct netlbl_af4list *iter;
|
||||
|
||||
list_for_each_entry_rcu(iter, head, list)
|
||||
if (iter->valid && (addr & iter->mask) == iter->addr)
|
||||
return iter;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* netlbl_af4list_search_exact - Search for an exact IPv4 address entry
|
||||
* @addr: IPv4 address
|
||||
* @mask: IPv4 address mask
|
||||
* @head: the list head
|
||||
*
|
||||
* Description:
|
||||
* Searches the IPv4 address list given by @head. If an exact match if found
|
||||
* it is returned, otherwise NULL is returned. The caller is responsible for
|
||||
* calling the rcu_read_[un]lock() functions.
|
||||
*
|
||||
*/
|
||||
struct netlbl_af4list *netlbl_af4list_search_exact(__be32 addr,
|
||||
__be32 mask,
|
||||
struct list_head *head)
|
||||
{
|
||||
struct netlbl_af4list *iter;
|
||||
|
||||
list_for_each_entry_rcu(iter, head, list)
|
||||
if (iter->valid && iter->addr == addr && iter->mask == mask)
|
||||
return iter;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
|
||||
/**
|
||||
* netlbl_af6list_search - Search for a matching IPv6 address entry
|
||||
* @addr: IPv6 address
|
||||
* @head: the list head
|
||||
*
|
||||
* Description:
|
||||
* Searches the IPv6 address list given by @head. If a matching address entry
|
||||
* is found it is returned, otherwise NULL is returned. The caller is
|
||||
* responsible for calling the rcu_read_[un]lock() functions.
|
||||
*
|
||||
*/
|
||||
struct netlbl_af6list *netlbl_af6list_search(const struct in6_addr *addr,
|
||||
struct list_head *head)
|
||||
{
|
||||
struct netlbl_af6list *iter;
|
||||
|
||||
list_for_each_entry_rcu(iter, head, list)
|
||||
if (iter->valid &&
|
||||
ipv6_masked_addr_cmp(&iter->addr, &iter->mask, addr) == 0)
|
||||
return iter;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* netlbl_af6list_search_exact - Search for an exact IPv6 address entry
|
||||
* @addr: IPv6 address
|
||||
* @mask: IPv6 address mask
|
||||
* @head: the list head
|
||||
*
|
||||
* Description:
|
||||
* Searches the IPv6 address list given by @head. If an exact match if found
|
||||
* it is returned, otherwise NULL is returned. The caller is responsible for
|
||||
* calling the rcu_read_[un]lock() functions.
|
||||
*
|
||||
*/
|
||||
struct netlbl_af6list *netlbl_af6list_search_exact(const struct in6_addr *addr,
|
||||
const struct in6_addr *mask,
|
||||
struct list_head *head)
|
||||
{
|
||||
struct netlbl_af6list *iter;
|
||||
|
||||
list_for_each_entry_rcu(iter, head, list)
|
||||
if (iter->valid &&
|
||||
ipv6_addr_equal(&iter->addr, addr) &&
|
||||
ipv6_addr_equal(&iter->mask, mask))
|
||||
return iter;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
#endif /* IPv6 */
|
||||
|
||||
/**
|
||||
* netlbl_af4list_add - Add a new IPv4 address entry to a list
|
||||
* @entry: address entry
|
||||
* @head: the list head
|
||||
*
|
||||
* Description:
|
||||
* Add a new address entry to the list pointed to by @head. On success zero is
|
||||
* returned, otherwise a negative value is returned. The caller is responsible
|
||||
* for calling the necessary locking functions.
|
||||
*
|
||||
*/
|
||||
int netlbl_af4list_add(struct netlbl_af4list *entry, struct list_head *head)
|
||||
{
|
||||
struct netlbl_af4list *iter;
|
||||
|
||||
iter = netlbl_af4list_search(entry->addr, head);
|
||||
if (iter != NULL &&
|
||||
iter->addr == entry->addr && iter->mask == entry->mask)
|
||||
return -EEXIST;
|
||||
|
||||
/* in order to speed up address searches through the list (the common
|
||||
* case) we need to keep the list in order based on the size of the
|
||||
* address mask such that the entry with the widest mask (smallest
|
||||
* numerical value) appears first in the list */
|
||||
list_for_each_entry_rcu(iter, head, list)
|
||||
if (iter->valid &&
|
||||
ntohl(entry->mask) > ntohl(iter->mask)) {
|
||||
__list_add_rcu(&entry->list,
|
||||
iter->list.prev,
|
||||
&iter->list);
|
||||
return 0;
|
||||
}
|
||||
list_add_tail_rcu(&entry->list, head);
|
||||
return 0;
|
||||
}
|
||||
|
||||
#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
|
||||
/**
|
||||
* netlbl_af6list_add - Add a new IPv6 address entry to a list
|
||||
* @entry: address entry
|
||||
* @head: the list head
|
||||
*
|
||||
* Description:
|
||||
* Add a new address entry to the list pointed to by @head. On success zero is
|
||||
* returned, otherwise a negative value is returned. The caller is responsible
|
||||
* for calling the necessary locking functions.
|
||||
*
|
||||
*/
|
||||
int netlbl_af6list_add(struct netlbl_af6list *entry, struct list_head *head)
|
||||
{
|
||||
struct netlbl_af6list *iter;
|
||||
|
||||
iter = netlbl_af6list_search(&entry->addr, head);
|
||||
if (iter != NULL &&
|
||||
ipv6_addr_equal(&iter->addr, &entry->addr) &&
|
||||
ipv6_addr_equal(&iter->mask, &entry->mask))
|
||||
return -EEXIST;
|
||||
|
||||
/* in order to speed up address searches through the list (the common
|
||||
* case) we need to keep the list in order based on the size of the
|
||||
* address mask such that the entry with the widest mask (smallest
|
||||
* numerical value) appears first in the list */
|
||||
list_for_each_entry_rcu(iter, head, list)
|
||||
if (iter->valid &&
|
||||
ipv6_addr_cmp(&entry->mask, &iter->mask) > 0) {
|
||||
__list_add_rcu(&entry->list,
|
||||
iter->list.prev,
|
||||
&iter->list);
|
||||
return 0;
|
||||
}
|
||||
list_add_tail_rcu(&entry->list, head);
|
||||
return 0;
|
||||
}
|
||||
#endif /* IPv6 */
|
||||
|
||||
/**
|
||||
* netlbl_af4list_remove_entry - Remove an IPv4 address entry
|
||||
* @entry: address entry
|
||||
*
|
||||
* Description:
|
||||
* Remove the specified IP address entry. The caller is responsible for
|
||||
* calling the necessary locking functions.
|
||||
*
|
||||
*/
|
||||
void netlbl_af4list_remove_entry(struct netlbl_af4list *entry)
|
||||
{
|
||||
entry->valid = 0;
|
||||
list_del_rcu(&entry->list);
|
||||
}
|
||||
|
||||
/**
|
||||
* netlbl_af4list_remove - Remove an IPv4 address entry
|
||||
* @addr: IP address
|
||||
* @mask: IP address mask
|
||||
* @head: the list head
|
||||
*
|
||||
* Description:
|
||||
* Remove an IP address entry from the list pointed to by @head. Returns the
|
||||
* entry on success, NULL on failure. The caller is responsible for calling
|
||||
* the necessary locking functions.
|
||||
*
|
||||
*/
|
||||
struct netlbl_af4list *netlbl_af4list_remove(__be32 addr, __be32 mask,
|
||||
struct list_head *head)
|
||||
{
|
||||
struct netlbl_af4list *entry;
|
||||
|
||||
entry = netlbl_af4list_search(addr, head);
|
||||
if (entry != NULL && entry->addr == addr && entry->mask == mask) {
|
||||
netlbl_af4list_remove_entry(entry);
|
||||
return entry;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
|
||||
/**
|
||||
* netlbl_af6list_remove_entry - Remove an IPv6 address entry
|
||||
* @entry: address entry
|
||||
*
|
||||
* Description:
|
||||
* Remove the specified IP address entry. The caller is responsible for
|
||||
* calling the necessary locking functions.
|
||||
*
|
||||
*/
|
||||
void netlbl_af6list_remove_entry(struct netlbl_af6list *entry)
|
||||
{
|
||||
entry->valid = 0;
|
||||
list_del_rcu(&entry->list);
|
||||
}
|
||||
|
||||
/**
|
||||
* netlbl_af6list_remove - Remove an IPv6 address entry
|
||||
* @addr: IP address
|
||||
* @mask: IP address mask
|
||||
* @head: the list head
|
||||
*
|
||||
* Description:
|
||||
* Remove an IP address entry from the list pointed to by @head. Returns the
|
||||
* entry on success, NULL on failure. The caller is responsible for calling
|
||||
* the necessary locking functions.
|
||||
*
|
||||
*/
|
||||
struct netlbl_af6list *netlbl_af6list_remove(const struct in6_addr *addr,
|
||||
const struct in6_addr *mask,
|
||||
struct list_head *head)
|
||||
{
|
||||
struct netlbl_af6list *entry;
|
||||
|
||||
entry = netlbl_af6list_search(addr, head);
|
||||
if (entry != NULL &&
|
||||
ipv6_addr_equal(&entry->addr, addr) &&
|
||||
ipv6_addr_equal(&entry->mask, mask)) {
|
||||
netlbl_af6list_remove_entry(entry);
|
||||
return entry;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
#endif /* IPv6 */
|
||||
|
||||
/*
|
||||
* Audit Helper Functions
|
||||
*/
|
||||
|
||||
/**
|
||||
* netlbl_af4list_audit_addr - Audit an IPv4 address
|
||||
* @audit_buf: audit buffer
|
||||
* @src: true if source address, false if destination
|
||||
* @dev: network interface
|
||||
* @addr: IP address
|
||||
* @mask: IP address mask
|
||||
*
|
||||
* Description:
|
||||
* Write the IPv4 address and address mask, if necessary, to @audit_buf.
|
||||
*
|
||||
*/
|
||||
void netlbl_af4list_audit_addr(struct audit_buffer *audit_buf,
|
||||
int src, const char *dev,
|
||||
__be32 addr, __be32 mask)
|
||||
{
|
||||
u32 mask_val = ntohl(mask);
|
||||
char *dir = (src ? "src" : "dst");
|
||||
|
||||
if (dev != NULL)
|
||||
audit_log_format(audit_buf, " netif=%s", dev);
|
||||
audit_log_format(audit_buf, " %s=" NIPQUAD_FMT, dir, NIPQUAD(addr));
|
||||
if (mask_val != 0xffffffff) {
|
||||
u32 mask_len = 0;
|
||||
while (mask_val > 0) {
|
||||
mask_val <<= 1;
|
||||
mask_len++;
|
||||
}
|
||||
audit_log_format(audit_buf, " %s_prefixlen=%d", dir, mask_len);
|
||||
}
|
||||
}
|
||||
|
||||
#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
|
||||
/**
|
||||
* netlbl_af6list_audit_addr - Audit an IPv6 address
|
||||
* @audit_buf: audit buffer
|
||||
* @src: true if source address, false if destination
|
||||
* @dev: network interface
|
||||
* @addr: IP address
|
||||
* @mask: IP address mask
|
||||
*
|
||||
* Description:
|
||||
* Write the IPv6 address and address mask, if necessary, to @audit_buf.
|
||||
*
|
||||
*/
|
||||
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)
|
||||
{
|
||||
char *dir = (src ? "src" : "dst");
|
||||
|
||||
if (dev != NULL)
|
||||
audit_log_format(audit_buf, " netif=%s", dev);
|
||||
audit_log_format(audit_buf, " %s=" NIP6_FMT, dir, NIP6(*addr));
|
||||
if (ntohl(mask->s6_addr32[3]) != 0xffffffff) {
|
||||
u32 mask_len = 0;
|
||||
u32 mask_val;
|
||||
int iter = -1;
|
||||
while (ntohl(mask->s6_addr32[++iter]) == 0xffffffff)
|
||||
mask_len += 32;
|
||||
mask_val = ntohl(mask->s6_addr32[iter]);
|
||||
while (mask_val > 0) {
|
||||
mask_val <<= 1;
|
||||
mask_len++;
|
||||
}
|
||||
audit_log_format(audit_buf, " %s_prefixlen=%d", dir, mask_len);
|
||||
}
|
||||
}
|
||||
#endif /* IPv6 */
|
||||
@@ -0,0 +1,189 @@
|
||||
/*
|
||||
* 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 @@
|
||||
#include "netlabel_user.h"
|
||||
#include "netlabel_cipso_v4.h"
|
||||
#include "netlabel_mgmt.h"
|
||||
#include "netlabel_domainhash.h"
|
||||
|
||||
/* Argument struct for cipso_v4_doi_walk() */
|
||||
struct netlbl_cipsov4_doiwalk_arg {
|
||||
@@ -51,6 +52,12 @@ struct netlbl_cipsov4_doiwalk_arg {
|
||||
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 */
|
||||
static struct genl_family netlbl_cipsov4_gnl_family = {
|
||||
.id = GENL_ID_GENERATE,
|
||||
@@ -80,32 +87,6 @@ static const struct nla_policy netlbl_cipsov4_genl_policy[NLBL_CIPSOV4_A_MAX + 1
|
||||
* 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
|
||||
* @info: the Generic NETLINK info block
|
||||
@@ -151,9 +132,9 @@ static int netlbl_cipsov4_add_common(struct genl_info *info,
|
||||
* @info: the Generic NETLINK info block
|
||||
*
|
||||
* Description:
|
||||
* Create a new CIPSO_V4_MAP_STD 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.
|
||||
* Create a new CIPSO_V4_MAP_TRANS 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_std(struct genl_info *info)
|
||||
@@ -183,7 +164,7 @@ static int netlbl_cipsov4_add_std(struct genl_info *info)
|
||||
ret_val = -ENOMEM;
|
||||
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);
|
||||
if (ret_val != 0)
|
||||
@@ -342,7 +323,7 @@ static int netlbl_cipsov4_add_std(struct genl_info *info)
|
||||
|
||||
add_std_failure:
|
||||
if (doi_def)
|
||||
netlbl_cipsov4_doi_free(&doi_def->rcu);
|
||||
cipso_v4_doi_free(doi_def);
|
||||
return ret_val;
|
||||
}
|
||||
|
||||
@@ -379,7 +360,44 @@ static int netlbl_cipsov4_add_pass(struct genl_info *info)
|
||||
return 0;
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -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]);
|
||||
switch (type) {
|
||||
case CIPSO_V4_MAP_STD:
|
||||
type_str = "std";
|
||||
case CIPSO_V4_MAP_TRANS:
|
||||
type_str = "trans";
|
||||
ret_val = netlbl_cipsov4_add_std(info);
|
||||
break;
|
||||
case CIPSO_V4_MAP_PASS:
|
||||
type_str = "pass";
|
||||
ret_val = netlbl_cipsov4_add_pass(info);
|
||||
break;
|
||||
case CIPSO_V4_MAP_LOCAL:
|
||||
type_str = "local";
|
||||
ret_val = netlbl_cipsov4_add_local(info);
|
||||
break;
|
||||
}
|
||||
if (ret_val == 0)
|
||||
atomic_inc(&netlabel_mgmt_protocount);
|
||||
@@ -491,7 +513,7 @@ list_start:
|
||||
doi_def = cipso_v4_doi_getdef(doi);
|
||||
if (doi_def == NULL) {
|
||||
ret_val = -EINVAL;
|
||||
goto list_failure;
|
||||
goto list_failure_lock;
|
||||
}
|
||||
|
||||
ret_val = nla_put_u32(ans_skb, NLBL_CIPSOV4_A_MTYPE, doi_def->type);
|
||||
@@ -516,7 +538,7 @@ list_start:
|
||||
nla_nest_end(ans_skb, nla_a);
|
||||
|
||||
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);
|
||||
if (nla_a == NULL) {
|
||||
ret_val = -ENOMEM;
|
||||
@@ -655,7 +677,7 @@ static int netlbl_cipsov4_listall(struct sk_buff *skb,
|
||||
struct netlink_callback *cb)
|
||||
{
|
||||
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.skb = skb;
|
||||
@@ -667,6 +689,29 @@ static int netlbl_cipsov4_listall(struct sk_buff *skb,
|
||||
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
|
||||
* @skb: the NETLINK buffer
|
||||
@@ -681,8 +726,11 @@ static int netlbl_cipsov4_remove(struct sk_buff *skb, struct genl_info *info)
|
||||
{
|
||||
int ret_val = -EINVAL;
|
||||
u32 doi = 0;
|
||||
struct netlbl_domhsh_walk_arg cb_arg;
|
||||
struct audit_buffer *audit_buf;
|
||||
struct netlbl_audit audit_info;
|
||||
u32 skip_bkt = 0;
|
||||
u32 skip_chain = 0;
|
||||
|
||||
if (!info->attrs[NLBL_CIPSOV4_A_DOI])
|
||||
return -EINVAL;
|
||||
@@ -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]);
|
||||
netlbl_netlink_auditinfo(skb, &audit_info);
|
||||
|
||||
ret_val = cipso_v4_doi_remove(doi,
|
||||
&audit_info,
|
||||
netlbl_cipsov4_doi_free);
|
||||
if (ret_val == 0)
|
||||
atomic_dec(&netlabel_mgmt_protocount);
|
||||
cb_arg.doi = doi;
|
||||
cb_arg.audit_info = &audit_info;
|
||||
ret_val = netlbl_domhsh_walk(&skip_bkt, &skip_chain,
|
||||
netlbl_cipsov4_remove_cb, &cb_arg);
|
||||
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_info);
|
||||
|
||||
@@ -45,12 +45,13 @@
|
||||
* NLBL_CIPSOV4_A_MTYPE
|
||||
* 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_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:
|
||||
* Sent by an application to remove a specific DOI mapping table from the
|
||||
@@ -76,12 +77,13 @@
|
||||
* NLBL_CIPSOV4_A_MTYPE
|
||||
* 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_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:
|
||||
* This message is sent by an application to list the valid DOIs on the
|
||||
|
||||
+315
-100
File diff suppressed because it is too large.
Load diff
@@ -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
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
@@ -36,16 +36,43 @@
|
||||
#include <linux/rcupdate.h>
|
||||
#include <linux/list.h>
|
||||
|
||||
#include "netlabel_addrlist.h"
|
||||
|
||||
/* Domain hash table size */
|
||||
/* XXX - currently this number is an uneducated guess */
|
||||
#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 {
|
||||
char *domain;
|
||||
u32 type;
|
||||
union {
|
||||
struct cipso_v4_doi *cipsov4;
|
||||
struct netlbl_domaddr_map *addrsel;
|
||||
} type_def;
|
||||
|
||||
u32 valid;
|
||||
@@ -61,12 +88,21 @@ int netlbl_domhsh_add(struct netlbl_dom_map *entry,
|
||||
struct netlbl_audit *audit_info);
|
||||
int netlbl_domhsh_add_default(struct netlbl_dom_map *entry,
|
||||
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_default(struct netlbl_audit *audit_info);
|
||||
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,
|
||||
u32 *skip_chain,
|
||||
int (*callback) (struct netlbl_dom_map *entry, void *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
|
||||
+193
-81
@@ -10,7 +10,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
|
||||
@@ -82,7 +82,7 @@ int netlbl_cfg_unlbl_add_map(const char *domain,
|
||||
|
||||
entry = kzalloc(sizeof(*entry), GFP_ATOMIC);
|
||||
if (entry == NULL)
|
||||
goto cfg_unlbl_add_map_failure;
|
||||
return -ENOMEM;
|
||||
if (domain != NULL) {
|
||||
entry->domain = kstrdup(domain, GFP_ATOMIC);
|
||||
if (entry->domain == NULL)
|
||||
@@ -103,49 +103,6 @@ cfg_unlbl_add_map_failure:
|
||||
return ret_val;
|
||||
}
|
||||
|
||||
/**
|
||||
* netlbl_cfg_cipsov4_add - Add a new CIPSOv4 DOI definition
|
||||
* @doi_def: the DOI definition
|
||||
* @audit_info: NetLabel audit information
|
||||
*
|
||||
* Description:
|
||||
* Add a new CIPSOv4 DOI definition to the NetLabel subsystem. Returns zero on
|
||||
* success, negative values on failure.
|
||||
*
|
||||
*/
|
||||
int netlbl_cfg_cipsov4_add(struct cipso_v4_doi *doi_def,
|
||||
struct netlbl_audit *audit_info)
|
||||
{
|
||||
int ret_val;
|
||||
const char *type_str;
|
||||
struct audit_buffer *audit_buf;
|
||||
|
||||
ret_val = cipso_v4_doi_add(doi_def);
|
||||
|
||||
audit_buf = netlbl_audit_start_common(AUDIT_MAC_CIPSOV4_ADD,
|
||||
audit_info);
|
||||
if (audit_buf != NULL) {
|
||||
switch (doi_def->type) {
|
||||
case CIPSO_V4_MAP_STD:
|
||||
type_str = "std";
|
||||
break;
|
||||
case CIPSO_V4_MAP_PASS:
|
||||
type_str = "pass";
|
||||
break;
|
||||
default:
|
||||
type_str = "(unknown)";
|
||||
}
|
||||
audit_log_format(audit_buf,
|
||||
" cipso_doi=%u cipso_type=%s res=%u",
|
||||
doi_def->doi,
|
||||
type_str,
|
||||
ret_val == 0 ? 1 : 0);
|
||||
audit_log_end(audit_buf);
|
||||
}
|
||||
|
||||
return ret_val;
|
||||
}
|
||||
|
||||
/**
|
||||
* netlbl_cfg_cipsov4_add_map - Add a new CIPSOv4 DOI definition and mapping
|
||||
* @doi_def: the DOI definition
|
||||
@@ -164,58 +121,71 @@ int netlbl_cfg_cipsov4_add_map(struct cipso_v4_doi *doi_def,
|
||||
struct netlbl_audit *audit_info)
|
||||
{
|
||||
int ret_val = -ENOMEM;
|
||||
u32 doi;
|
||||
u32 doi_type;
|
||||
struct netlbl_dom_map *entry;
|
||||
const char *type_str;
|
||||
struct audit_buffer *audit_buf;
|
||||
|
||||
doi = doi_def->doi;
|
||||
doi_type = doi_def->type;
|
||||
|
||||
entry = kzalloc(sizeof(*entry), GFP_ATOMIC);
|
||||
if (entry == NULL)
|
||||
goto cfg_cipsov4_add_map_failure;
|
||||
return -ENOMEM;
|
||||
if (domain != NULL) {
|
||||
entry->domain = kstrdup(domain, GFP_ATOMIC);
|
||||
if (entry->domain == NULL)
|
||||
goto cfg_cipsov4_add_map_failure;
|
||||
}
|
||||
entry->type = NETLBL_NLTYPE_CIPSOV4;
|
||||
entry->type_def.cipsov4 = doi_def;
|
||||
|
||||
/* Grab a RCU read lock here so nothing happens to the doi_def variable
|
||||
* between adding it to the CIPSOv4 protocol engine and adding a
|
||||
* domain mapping for it. */
|
||||
|
||||
rcu_read_lock();
|
||||
ret_val = netlbl_cfg_cipsov4_add(doi_def, audit_info);
|
||||
if (ret_val != 0)
|
||||
goto cfg_cipsov4_add_map_failure_unlock;
|
||||
ret_val = netlbl_domhsh_add(entry, audit_info);
|
||||
ret_val = cipso_v4_doi_add(doi_def);
|
||||
if (ret_val != 0)
|
||||
goto cfg_cipsov4_add_map_failure_remove_doi;
|
||||
rcu_read_unlock();
|
||||
entry->type = NETLBL_NLTYPE_CIPSOV4;
|
||||
entry->type_def.cipsov4 = cipso_v4_doi_getdef(doi);
|
||||
if (entry->type_def.cipsov4 == NULL) {
|
||||
ret_val = -ENOENT;
|
||||
goto cfg_cipsov4_add_map_failure_remove_doi;
|
||||
}
|
||||
ret_val = netlbl_domhsh_add(entry, audit_info);
|
||||
if (ret_val != 0)
|
||||
goto cfg_cipsov4_add_map_failure_release_doi;
|
||||
|
||||
return 0;
|
||||
cfg_cipsov4_add_map_return:
|
||||
audit_buf = netlbl_audit_start_common(AUDIT_MAC_CIPSOV4_ADD,
|
||||
audit_info);
|
||||
if (audit_buf != NULL) {
|
||||
switch (doi_type) {
|
||||
case CIPSO_V4_MAP_TRANS:
|
||||
type_str = "trans";
|
||||
break;
|
||||
case CIPSO_V4_MAP_PASS:
|
||||
type_str = "pass";
|
||||
break;
|
||||
case CIPSO_V4_MAP_LOCAL:
|
||||
type_str = "local";
|
||||
break;
|
||||
default:
|
||||
type_str = "(unknown)";
|
||||
}
|
||||
audit_log_format(audit_buf,
|
||||
" cipso_doi=%u cipso_type=%s res=%u",
|
||||
doi, type_str, ret_val == 0 ? 1 : 0);
|
||||
audit_log_end(audit_buf);
|
||||
}
|
||||
|
||||
return ret_val;
|
||||
|
||||
cfg_cipsov4_add_map_failure_release_doi:
|
||||
cipso_v4_doi_putdef(doi_def);
|
||||
cfg_cipsov4_add_map_failure_remove_doi:
|
||||
cipso_v4_doi_remove(doi_def->doi, audit_info, netlbl_cipsov4_doi_free);
|
||||
cfg_cipsov4_add_map_failure_unlock:
|
||||
rcu_read_unlock();
|
||||
cipso_v4_doi_remove(doi, audit_info);
|
||||
cfg_cipsov4_add_map_failure:
|
||||
if (entry != NULL)
|
||||
kfree(entry->domain);
|
||||
kfree(entry);
|
||||
return ret_val;
|
||||
}
|
||||
|
||||
/**
|
||||
* netlbl_cfg_cipsov4_del - Removean existing CIPSOv4 DOI definition
|
||||
* @doi: the CIPSO DOI value
|
||||
* @audit_info: NetLabel audit information
|
||||
*
|
||||
* Description:
|
||||
* Removes an existing CIPSOv4 DOI definition from the NetLabel subsystem.
|
||||
* Returns zero on success, negative values on failure.
|
||||
*
|
||||
*/
|
||||
int netlbl_cfg_cipsov4_del(u32 doi, struct netlbl_audit *audit_info)
|
||||
{
|
||||
return cipso_v4_doi_remove(doi, audit_info, netlbl_cipsov4_doi_free);
|
||||
goto cfg_cipsov4_add_map_return;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -452,7 +422,9 @@ int netlbl_enabled(void)
|
||||
* Attach the correct label to the given socket using the security attributes
|
||||
* specified in @secattr. This function requires exclusive access to @sk,
|
||||
* which means it either needs to be in the process of being created or locked.
|
||||
* Returns zero on success, negative values on failure.
|
||||
* Returns zero on success, -EDESTADDRREQ if the domain is configured to use
|
||||
* network address selectors (can't blindly label the socket), and negative
|
||||
* values on all other failures.
|
||||
*
|
||||
*/
|
||||
int netlbl_sock_setattr(struct sock *sk,
|
||||
@@ -466,6 +438,9 @@ int netlbl_sock_setattr(struct sock *sk,
|
||||
if (dom_entry == NULL)
|
||||
goto socket_setattr_return;
|
||||
switch (dom_entry->type) {
|
||||
case NETLBL_NLTYPE_ADDRSELECT:
|
||||
ret_val = -EDESTADDRREQ;
|
||||
break;
|
||||
case NETLBL_NLTYPE_CIPSOV4:
|
||||
ret_val = cipso_v4_sock_setattr(sk,
|
||||
dom_entry->type_def.cipsov4,
|
||||
@@ -483,6 +458,20 @@ socket_setattr_return:
|
||||
return ret_val;
|
||||
}
|
||||
|
||||
/**
|
||||
* netlbl_sock_delattr - Delete all the NetLabel labels on a socket
|
||||
* @sk: the socket
|
||||
*
|
||||
* Description:
|
||||
* Remove all the NetLabel labeling from @sk. The caller is responsible for
|
||||
* ensuring that @sk is locked.
|
||||
*
|
||||
*/
|
||||
void netlbl_sock_delattr(struct sock *sk)
|
||||
{
|
||||
cipso_v4_sock_delattr(sk);
|
||||
}
|
||||
|
||||
/**
|
||||
* netlbl_sock_getattr - Determine the security attributes of a sock
|
||||
* @sk: the sock
|
||||
@@ -500,6 +489,128 @@ int netlbl_sock_getattr(struct sock *sk, struct netlbl_lsm_secattr *secattr)
|
||||
return cipso_v4_sock_getattr(sk, secattr);
|
||||
}
|
||||
|
||||
/**
|
||||
* netlbl_conn_setattr - Label a connected socket using the correct protocol
|
||||
* @sk: the socket to label
|
||||
* @addr: the destination address
|
||||
* @secattr: the security attributes
|
||||
*
|
||||
* Description:
|
||||
* Attach the correct label to the given connected socket using the security
|
||||
* attributes specified in @secattr. The caller is responsible for ensuring
|
||||
* that @sk is locked. Returns zero on success, negative values on failure.
|
||||
*
|
||||
*/
|
||||
int netlbl_conn_setattr(struct sock *sk,
|
||||
struct sockaddr *addr,
|
||||
const struct netlbl_lsm_secattr *secattr)
|
||||
{
|
||||
int ret_val;
|
||||
struct sockaddr_in *addr4;
|
||||
struct netlbl_domaddr4_map *af4_entry;
|
||||
|
||||
rcu_read_lock();
|
||||
switch (addr->sa_family) {
|
||||
case AF_INET:
|
||||
addr4 = (struct sockaddr_in *)addr;
|
||||
af4_entry = netlbl_domhsh_getentry_af4(secattr->domain,
|
||||
addr4->sin_addr.s_addr);
|
||||
if (af4_entry == NULL) {
|
||||
ret_val = -ENOENT;
|
||||
goto conn_setattr_return;
|
||||
}
|
||||
switch (af4_entry->type) {
|
||||
case NETLBL_NLTYPE_CIPSOV4:
|
||||
ret_val = cipso_v4_sock_setattr(sk,
|
||||
af4_entry->type_def.cipsov4,
|
||||
secattr);
|
||||
break;
|
||||
case NETLBL_NLTYPE_UNLABELED:
|
||||
/* just delete the protocols we support for right now
|
||||
* but we could remove other protocols if needed */
|
||||
cipso_v4_sock_delattr(sk);
|
||||
ret_val = 0;
|
||||
break;
|
||||
default:
|
||||
ret_val = -ENOENT;
|
||||
}
|
||||
break;
|
||||
#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
|
||||
case AF_INET6:
|
||||
/* since we don't support any IPv6 labeling protocols right
|
||||
* now we can optimize everything away until we do */
|
||||
ret_val = 0;
|
||||
break;
|
||||
#endif /* IPv6 */
|
||||
default:
|
||||
ret_val = 0;
|
||||
}
|
||||
|
||||
conn_setattr_return:
|
||||
rcu_read_unlock();
|
||||
return ret_val;
|
||||
}
|
||||
|
||||
/**
|
||||
* netlbl_skbuff_setattr - Label a packet using the correct protocol
|
||||
* @skb: the packet
|
||||
* @family: protocol family
|
||||
* @secattr: the security attributes
|
||||
*
|
||||
* Description:
|
||||
* Attach the correct label to the given packet using the security attributes
|
||||
* specified in @secattr. Returns zero on success, negative values on failure.
|
||||
*
|
||||
*/
|
||||
int netlbl_skbuff_setattr(struct sk_buff *skb,
|
||||
u16 family,
|
||||
const struct netlbl_lsm_secattr *secattr)
|
||||
{
|
||||
int ret_val;
|
||||
struct iphdr *hdr4;
|
||||
struct netlbl_domaddr4_map *af4_entry;
|
||||
|
||||
rcu_read_lock();
|
||||
switch (family) {
|
||||
case AF_INET:
|
||||
hdr4 = ip_hdr(skb);
|
||||
af4_entry = netlbl_domhsh_getentry_af4(secattr->domain,
|
||||
hdr4->daddr);
|
||||
if (af4_entry == NULL) {
|
||||
ret_val = -ENOENT;
|
||||
goto skbuff_setattr_return;
|
||||
}
|
||||
switch (af4_entry->type) {
|
||||
case NETLBL_NLTYPE_CIPSOV4:
|
||||
ret_val = cipso_v4_skbuff_setattr(skb,
|
||||
af4_entry->type_def.cipsov4,
|
||||
secattr);
|
||||
break;
|
||||
case NETLBL_NLTYPE_UNLABELED:
|
||||
/* just delete the protocols we support for right now
|
||||
* but we could remove other protocols if needed */
|
||||
ret_val = cipso_v4_skbuff_delattr(skb);
|
||||
break;
|
||||
default:
|
||||
ret_val = -ENOENT;
|
||||
}
|
||||
break;
|
||||
#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
|
||||
case AF_INET6:
|
||||
/* since we don't support any IPv6 labeling protocols right
|
||||
* now we can optimize everything away until we do */
|
||||
ret_val = 0;
|
||||
break;
|
||||
#endif /* IPv6 */
|
||||
default:
|
||||
ret_val = 0;
|
||||
}
|
||||
|
||||
skbuff_setattr_return:
|
||||
rcu_read_unlock();
|
||||
return ret_val;
|
||||
}
|
||||
|
||||
/**
|
||||
* netlbl_skbuff_getattr - Determine the security attributes of a packet
|
||||
* @skb: the packet
|
||||
@@ -528,6 +639,7 @@ int netlbl_skbuff_getattr(const struct sk_buff *skb,
|
||||
* netlbl_skbuff_err - Handle a LSM error on a sk_buff
|
||||
* @skb: the packet
|
||||
* @error: the error code
|
||||
* @gateway: true if host is acting as a gateway, false otherwise
|
||||
*
|
||||
* Description:
|
||||
* Deal with a LSM problem when handling the packet in @skb, typically this is
|
||||
@@ -535,10 +647,10 @@ int netlbl_skbuff_getattr(const struct sk_buff *skb,
|
||||
* according to the packet's labeling protocol.
|
||||
*
|
||||
*/
|
||||
void netlbl_skbuff_err(struct sk_buff *skb, int error)
|
||||
void netlbl_skbuff_err(struct sk_buff *skb, int error, int gateway)
|
||||
{
|
||||
if (CIPSO_V4_OPTEXIST(skb))
|
||||
cipso_v4_error(skb, error, 0);
|
||||
cipso_v4_error(skb, error, gateway);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
+327
-129
File diff suppressed because it is too large.
Load diff
@@ -45,6 +45,16 @@
|
||||
* NLBL_MGMT_A_DOMAIN
|
||||
* 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:
|
||||
*
|
||||
* NLBL_MGMT_A_CV4DOI
|
||||
@@ -68,13 +78,24 @@
|
||||
* Required attributes:
|
||||
*
|
||||
* NLBL_MGMT_A_DOMAIN
|
||||
*
|
||||
* If the IP address selectors are not used the following attribute is
|
||||
* required:
|
||||
*
|
||||
* 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
|
||||
*
|
||||
* 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:
|
||||
* Sent by an application to set the default domain mapping for the NetLabel
|
||||
@@ -100,15 +121,23 @@
|
||||
* application there is no payload. On success the kernel should send a
|
||||
* response using the following format.
|
||||
*
|
||||
* Required attributes:
|
||||
* If the IP address selectors are not used the following attribute is
|
||||
* required:
|
||||
*
|
||||
* 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
|
||||
*
|
||||
* 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:
|
||||
* Sent by an application to request a list of configured NetLabel protocols
|
||||
@@ -162,6 +191,26 @@ enum {
|
||||
NLBL_MGMT_A_CV4DOI,
|
||||
/* (NLA_U32)
|
||||
* 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,
|
||||
};
|
||||
#define NLBL_MGMT_A_MAX (__NLBL_MGMT_A_MAX - 1)
|
||||
|
||||
Loaded 20 of 29 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user