You've already forked linux-apfs
mirror of
https://github.com/linux-apfs/linux-apfs.git
synced 2026-05-01 15:00:59 -07:00
Merge branch 'next' into for-linus
This commit is contained in:
@@ -315,3 +315,15 @@ When: 2.6.29 (ideally) or 2.6.30 (more likely)
|
|||||||
Why: Deprecated by the new (standard) device driver binding model. Use
|
Why: Deprecated by the new (standard) device driver binding model. Use
|
||||||
i2c_driver->probe() and ->remove() instead.
|
i2c_driver->probe() and ->remove() instead.
|
||||||
Who: Jean Delvare <khali@linux-fr.org>
|
Who: Jean Delvare <khali@linux-fr.org>
|
||||||
|
|
||||||
|
---------------------------
|
||||||
|
|
||||||
|
What: SELinux "compat_net" functionality
|
||||||
|
When: 2.6.30 at the earliest
|
||||||
|
Why: In 2.6.18 the Secmark concept was introduced to replace the "compat_net"
|
||||||
|
network access control functionality of SELinux. Secmark offers both
|
||||||
|
better performance and greater flexibility than the "compat_net"
|
||||||
|
mechanism. Now that the major Linux distributions have moved to
|
||||||
|
Secmark, it is time to deprecate the older mechanism and start the
|
||||||
|
process of removing the old code.
|
||||||
|
Who: Paul Moore <paul.moore@hp.com>
|
||||||
|
|||||||
@@ -529,8 +529,21 @@ extern const kernel_cap_t __cap_init_eff_set;
|
|||||||
*
|
*
|
||||||
* Note that this does not set PF_SUPERPRIV on the task.
|
* Note that this does not set PF_SUPERPRIV on the task.
|
||||||
*/
|
*/
|
||||||
#define has_capability(t, cap) (security_capable((t), (cap)) == 0)
|
#define has_capability(t, cap) (security_real_capable((t), (cap)) == 0)
|
||||||
#define has_capability_noaudit(t, cap) (security_capable_noaudit((t), (cap)) == 0)
|
|
||||||
|
/**
|
||||||
|
* has_capability_noaudit - Determine if a task has a superior capability available (unaudited)
|
||||||
|
* @t: The task in question
|
||||||
|
* @cap: The capability to be tested for
|
||||||
|
*
|
||||||
|
* Return true if the specified task has the given superior capability
|
||||||
|
* currently in effect, false if not, but don't write an audit message for the
|
||||||
|
* check.
|
||||||
|
*
|
||||||
|
* Note that this does not set PF_SUPERPRIV on the task.
|
||||||
|
*/
|
||||||
|
#define has_capability_noaudit(t, cap) \
|
||||||
|
(security_real_capable_noaudit((t), (cap)) == 0)
|
||||||
|
|
||||||
extern int capable(int cap);
|
extern int capable(int cap);
|
||||||
|
|
||||||
|
|||||||
@@ -48,7 +48,8 @@ struct audit_krule;
|
|||||||
* These functions are in security/capability.c and are used
|
* These functions are in security/capability.c and are used
|
||||||
* as the default capabilities functions
|
* as the default capabilities functions
|
||||||
*/
|
*/
|
||||||
extern int cap_capable(struct task_struct *tsk, int cap, int audit);
|
extern int cap_capable(struct task_struct *tsk, const struct cred *cred,
|
||||||
|
int cap, int audit);
|
||||||
extern int cap_settime(struct timespec *ts, struct timezone *tz);
|
extern int cap_settime(struct timespec *ts, struct timezone *tz);
|
||||||
extern int cap_ptrace_may_access(struct task_struct *child, unsigned int mode);
|
extern int cap_ptrace_may_access(struct task_struct *child, unsigned int mode);
|
||||||
extern int cap_ptrace_traceme(struct task_struct *parent);
|
extern int cap_ptrace_traceme(struct task_struct *parent);
|
||||||
@@ -1251,9 +1252,12 @@ static inline void security_free_mnt_opts(struct security_mnt_opts *opts)
|
|||||||
* @permitted contains the permitted capability set.
|
* @permitted contains the permitted capability set.
|
||||||
* Return 0 and update @new if permission is granted.
|
* Return 0 and update @new if permission is granted.
|
||||||
* @capable:
|
* @capable:
|
||||||
* Check whether the @tsk process has the @cap capability.
|
* Check whether the @tsk process has the @cap capability in the indicated
|
||||||
|
* credentials.
|
||||||
* @tsk contains the task_struct for the process.
|
* @tsk contains the task_struct for the process.
|
||||||
|
* @cred contains the credentials to use.
|
||||||
* @cap contains the capability <include/linux/capability.h>.
|
* @cap contains the capability <include/linux/capability.h>.
|
||||||
|
* @audit: Whether to write an audit message or not
|
||||||
* Return 0 if the capability is granted for @tsk.
|
* Return 0 if the capability is granted for @tsk.
|
||||||
* @acct:
|
* @acct:
|
||||||
* Check permission before enabling or disabling process accounting. If
|
* Check permission before enabling or disabling process accounting. If
|
||||||
@@ -1346,7 +1350,8 @@ struct security_operations {
|
|||||||
const kernel_cap_t *effective,
|
const kernel_cap_t *effective,
|
||||||
const kernel_cap_t *inheritable,
|
const kernel_cap_t *inheritable,
|
||||||
const kernel_cap_t *permitted);
|
const kernel_cap_t *permitted);
|
||||||
int (*capable) (struct task_struct *tsk, int cap, int audit);
|
int (*capable) (struct task_struct *tsk, const struct cred *cred,
|
||||||
|
int cap, int audit);
|
||||||
int (*acct) (struct file *file);
|
int (*acct) (struct file *file);
|
||||||
int (*sysctl) (struct ctl_table *table, int op);
|
int (*sysctl) (struct ctl_table *table, int op);
|
||||||
int (*quotactl) (int cmds, int type, int id, struct super_block *sb);
|
int (*quotactl) (int cmds, int type, int id, struct super_block *sb);
|
||||||
@@ -1628,8 +1633,9 @@ int security_capset(struct cred *new, const struct cred *old,
|
|||||||
const kernel_cap_t *effective,
|
const kernel_cap_t *effective,
|
||||||
const kernel_cap_t *inheritable,
|
const kernel_cap_t *inheritable,
|
||||||
const kernel_cap_t *permitted);
|
const kernel_cap_t *permitted);
|
||||||
int security_capable(struct task_struct *tsk, int cap);
|
int security_capable(int cap);
|
||||||
int security_capable_noaudit(struct task_struct *tsk, int cap);
|
int security_real_capable(struct task_struct *tsk, int cap);
|
||||||
|
int security_real_capable_noaudit(struct task_struct *tsk, int cap);
|
||||||
int security_acct(struct file *file);
|
int security_acct(struct file *file);
|
||||||
int security_sysctl(struct ctl_table *table, int op);
|
int security_sysctl(struct ctl_table *table, int op);
|
||||||
int security_quotactl(int cmds, int type, int id, struct super_block *sb);
|
int security_quotactl(int cmds, int type, int id, struct super_block *sb);
|
||||||
@@ -1826,14 +1832,31 @@ static inline int security_capset(struct cred *new,
|
|||||||
return cap_capset(new, old, effective, inheritable, permitted);
|
return cap_capset(new, old, effective, inheritable, permitted);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline int security_capable(struct task_struct *tsk, int cap)
|
static inline int security_capable(int cap)
|
||||||
{
|
{
|
||||||
return cap_capable(tsk, cap, SECURITY_CAP_AUDIT);
|
return cap_capable(current, current_cred(), cap, SECURITY_CAP_AUDIT);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline int security_capable_noaudit(struct task_struct *tsk, int cap)
|
static inline int security_real_capable(struct task_struct *tsk, int cap)
|
||||||
{
|
{
|
||||||
return cap_capable(tsk, cap, SECURITY_CAP_NOAUDIT);
|
int ret;
|
||||||
|
|
||||||
|
rcu_read_lock();
|
||||||
|
ret = cap_capable(tsk, __task_cred(tsk), cap, SECURITY_CAP_AUDIT);
|
||||||
|
rcu_read_unlock();
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline
|
||||||
|
int security_real_capable_noaudit(struct task_struct *tsk, int cap)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
rcu_read_lock();
|
||||||
|
ret = cap_capable(tsk, __task_cred(tsk), cap,
|
||||||
|
SECURITY_CAP_NOAUDIT);
|
||||||
|
rcu_read_unlock();
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline int security_acct(struct file *file)
|
static inline int security_acct(struct file *file)
|
||||||
|
|||||||
@@ -131,7 +131,8 @@ 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,
|
||||||
|
struct netlbl_audit *audit_info);
|
||||||
void cipso_v4_doi_free(struct cipso_v4_doi *doi_def);
|
void cipso_v4_doi_free(struct cipso_v4_doi *doi_def);
|
||||||
int cipso_v4_doi_remove(u32 doi, struct netlbl_audit *audit_info);
|
int cipso_v4_doi_remove(u32 doi, struct netlbl_audit *audit_info);
|
||||||
struct cipso_v4_doi *cipso_v4_doi_getdef(u32 doi);
|
struct cipso_v4_doi *cipso_v4_doi_getdef(u32 doi);
|
||||||
@@ -140,7 +141,8 @@ 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);
|
||||||
#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,
|
||||||
|
struct netlbl_audit *audit_info)
|
||||||
{
|
{
|
||||||
return -ENOSYS;
|
return -ENOSYS;
|
||||||
}
|
}
|
||||||
|
|||||||
+80
-6
@@ -33,6 +33,8 @@
|
|||||||
#include <linux/types.h>
|
#include <linux/types.h>
|
||||||
#include <linux/net.h>
|
#include <linux/net.h>
|
||||||
#include <linux/skbuff.h>
|
#include <linux/skbuff.h>
|
||||||
|
#include <linux/in.h>
|
||||||
|
#include <linux/in6.h>
|
||||||
#include <net/netlink.h>
|
#include <net/netlink.h>
|
||||||
#include <asm/atomic.h>
|
#include <asm/atomic.h>
|
||||||
|
|
||||||
@@ -353,13 +355,37 @@ static inline void netlbl_secattr_free(struct netlbl_lsm_secattr *secattr)
|
|||||||
/*
|
/*
|
||||||
* LSM configuration operations
|
* LSM configuration operations
|
||||||
*/
|
*/
|
||||||
int netlbl_cfg_map_del(const char *domain, struct netlbl_audit *audit_info);
|
int netlbl_cfg_map_del(const char *domain,
|
||||||
int netlbl_cfg_unlbl_add_map(const char *domain,
|
u16 family,
|
||||||
|
const void *addr,
|
||||||
|
const void *mask,
|
||||||
|
struct netlbl_audit *audit_info);
|
||||||
|
int netlbl_cfg_unlbl_map_add(const char *domain,
|
||||||
|
u16 family,
|
||||||
|
const void *addr,
|
||||||
|
const void *mask,
|
||||||
struct netlbl_audit *audit_info);
|
struct netlbl_audit *audit_info);
|
||||||
int netlbl_cfg_cipsov4_add_map(struct cipso_v4_doi *doi_def,
|
int netlbl_cfg_unlbl_static_add(struct net *net,
|
||||||
|
const char *dev_name,
|
||||||
|
const void *addr,
|
||||||
|
const void *mask,
|
||||||
|
u16 family,
|
||||||
|
u32 secid,
|
||||||
|
struct netlbl_audit *audit_info);
|
||||||
|
int netlbl_cfg_unlbl_static_del(struct net *net,
|
||||||
|
const char *dev_name,
|
||||||
|
const void *addr,
|
||||||
|
const void *mask,
|
||||||
|
u16 family,
|
||||||
|
struct netlbl_audit *audit_info);
|
||||||
|
int netlbl_cfg_cipsov4_add(struct cipso_v4_doi *doi_def,
|
||||||
|
struct netlbl_audit *audit_info);
|
||||||
|
void netlbl_cfg_cipsov4_del(u32 doi, struct netlbl_audit *audit_info);
|
||||||
|
int netlbl_cfg_cipsov4_map_add(u32 doi,
|
||||||
const char *domain,
|
const char *domain,
|
||||||
|
const struct in_addr *addr,
|
||||||
|
const struct in_addr *mask,
|
||||||
struct netlbl_audit *audit_info);
|
struct netlbl_audit *audit_info);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* LSM security attribute operations
|
* LSM security attribute operations
|
||||||
*/
|
*/
|
||||||
@@ -401,19 +427,62 @@ void netlbl_skbuff_err(struct sk_buff *skb, int error, int gateway);
|
|||||||
void netlbl_cache_invalidate(void);
|
void netlbl_cache_invalidate(void);
|
||||||
int netlbl_cache_add(const struct sk_buff *skb,
|
int netlbl_cache_add(const struct sk_buff *skb,
|
||||||
const struct netlbl_lsm_secattr *secattr);
|
const struct netlbl_lsm_secattr *secattr);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Protocol engine operations
|
||||||
|
*/
|
||||||
|
struct audit_buffer *netlbl_audit_start(int type,
|
||||||
|
struct netlbl_audit *audit_info);
|
||||||
#else
|
#else
|
||||||
static inline int netlbl_cfg_map_del(const char *domain,
|
static inline int netlbl_cfg_map_del(const char *domain,
|
||||||
|
u16 family,
|
||||||
|
const void *addr,
|
||||||
|
const void *mask,
|
||||||
struct netlbl_audit *audit_info)
|
struct netlbl_audit *audit_info)
|
||||||
{
|
{
|
||||||
return -ENOSYS;
|
return -ENOSYS;
|
||||||
}
|
}
|
||||||
static inline int netlbl_cfg_unlbl_add_map(const char *domain,
|
static inline int netlbl_cfg_unlbl_map_add(const char *domain,
|
||||||
|
u16 family,
|
||||||
|
void *addr,
|
||||||
|
void *mask,
|
||||||
struct netlbl_audit *audit_info)
|
struct netlbl_audit *audit_info)
|
||||||
{
|
{
|
||||||
return -ENOSYS;
|
return -ENOSYS;
|
||||||
}
|
}
|
||||||
static inline int netlbl_cfg_cipsov4_add_map(struct cipso_v4_doi *doi_def,
|
static inline int netlbl_cfg_unlbl_static_add(struct net *net,
|
||||||
|
const char *dev_name,
|
||||||
|
const void *addr,
|
||||||
|
const void *mask,
|
||||||
|
u16 family,
|
||||||
|
u32 secid,
|
||||||
|
struct netlbl_audit *audit_info)
|
||||||
|
{
|
||||||
|
return -ENOSYS;
|
||||||
|
}
|
||||||
|
static inline int netlbl_cfg_unlbl_static_del(struct net *net,
|
||||||
|
const char *dev_name,
|
||||||
|
const void *addr,
|
||||||
|
const void *mask,
|
||||||
|
u16 family,
|
||||||
|
struct netlbl_audit *audit_info)
|
||||||
|
{
|
||||||
|
return -ENOSYS;
|
||||||
|
}
|
||||||
|
static inline int netlbl_cfg_cipsov4_add(struct cipso_v4_doi *doi_def,
|
||||||
|
struct netlbl_audit *audit_info)
|
||||||
|
{
|
||||||
|
return -ENOSYS;
|
||||||
|
}
|
||||||
|
static inline void netlbl_cfg_cipsov4_del(u32 doi,
|
||||||
|
struct netlbl_audit *audit_info)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
static inline int netlbl_cfg_cipsov4_map_add(u32 doi,
|
||||||
const char *domain,
|
const char *domain,
|
||||||
|
const struct in_addr *addr,
|
||||||
|
const struct in_addr *mask,
|
||||||
struct netlbl_audit *audit_info)
|
struct netlbl_audit *audit_info)
|
||||||
{
|
{
|
||||||
return -ENOSYS;
|
return -ENOSYS;
|
||||||
@@ -495,6 +564,11 @@ static inline int netlbl_cache_add(const struct sk_buff *skb,
|
|||||||
{
|
{
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
static inline struct audit_buffer *netlbl_audit_start(int type,
|
||||||
|
struct netlbl_audit *audit_info)
|
||||||
|
{
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
#endif /* CONFIG_NETLABEL */
|
#endif /* CONFIG_NETLABEL */
|
||||||
|
|
||||||
#endif /* _NETLABEL_H */
|
#endif /* _NETLABEL_H */
|
||||||
|
|||||||
+1
-1
@@ -306,7 +306,7 @@ int capable(int cap)
|
|||||||
BUG();
|
BUG();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (has_capability(current, cap)) {
|
if (security_capable(cap) == 0) {
|
||||||
current->flags |= PF_SUPERPRIV;
|
current->flags |= PF_SUPERPRIV;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|||||||
+65
-21
@@ -38,6 +38,7 @@
|
|||||||
#include <linux/spinlock.h>
|
#include <linux/spinlock.h>
|
||||||
#include <linux/string.h>
|
#include <linux/string.h>
|
||||||
#include <linux/jhash.h>
|
#include <linux/jhash.h>
|
||||||
|
#include <linux/audit.h>
|
||||||
#include <net/ip.h>
|
#include <net/ip.h>
|
||||||
#include <net/icmp.h>
|
#include <net/icmp.h>
|
||||||
#include <net/tcp.h>
|
#include <net/tcp.h>
|
||||||
@@ -449,6 +450,7 @@ static struct cipso_v4_doi *cipso_v4_doi_search(u32 doi)
|
|||||||
/**
|
/**
|
||||||
* cipso_v4_doi_add - Add a new DOI to the CIPSO protocol engine
|
* cipso_v4_doi_add - Add a new DOI to the CIPSO protocol engine
|
||||||
* @doi_def: the DOI structure
|
* @doi_def: the DOI structure
|
||||||
|
* @audit_info: NetLabel audit information
|
||||||
*
|
*
|
||||||
* Description:
|
* Description:
|
||||||
* The caller defines a new DOI for use by the CIPSO engine and calls this
|
* The caller defines a new DOI for use by the CIPSO engine and calls this
|
||||||
@@ -458,50 +460,78 @@ static struct cipso_v4_doi *cipso_v4_doi_search(u32 doi)
|
|||||||
* zero on success and non-zero on failure.
|
* zero on success and non-zero on failure.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
int cipso_v4_doi_add(struct cipso_v4_doi *doi_def)
|
int cipso_v4_doi_add(struct cipso_v4_doi *doi_def,
|
||||||
|
struct netlbl_audit *audit_info)
|
||||||
{
|
{
|
||||||
|
int ret_val = -EINVAL;
|
||||||
u32 iter;
|
u32 iter;
|
||||||
|
u32 doi;
|
||||||
|
u32 doi_type;
|
||||||
|
struct audit_buffer *audit_buf;
|
||||||
|
|
||||||
|
doi = doi_def->doi;
|
||||||
|
doi_type = doi_def->type;
|
||||||
|
|
||||||
if (doi_def == NULL || doi_def->doi == CIPSO_V4_DOI_UNKNOWN)
|
if (doi_def == NULL || doi_def->doi == CIPSO_V4_DOI_UNKNOWN)
|
||||||
return -EINVAL;
|
goto doi_add_return;
|
||||||
for (iter = 0; iter < CIPSO_V4_TAG_MAXCNT; iter++) {
|
for (iter = 0; iter < CIPSO_V4_TAG_MAXCNT; iter++) {
|
||||||
switch (doi_def->tags[iter]) {
|
switch (doi_def->tags[iter]) {
|
||||||
case CIPSO_V4_TAG_RBITMAP:
|
case CIPSO_V4_TAG_RBITMAP:
|
||||||
break;
|
break;
|
||||||
case CIPSO_V4_TAG_RANGE:
|
case CIPSO_V4_TAG_RANGE:
|
||||||
if (doi_def->type != CIPSO_V4_MAP_PASS)
|
|
||||||
return -EINVAL;
|
|
||||||
break;
|
|
||||||
case CIPSO_V4_TAG_INVALID:
|
|
||||||
if (iter == 0)
|
|
||||||
return -EINVAL;
|
|
||||||
break;
|
|
||||||
case CIPSO_V4_TAG_ENUM:
|
case CIPSO_V4_TAG_ENUM:
|
||||||
if (doi_def->type != CIPSO_V4_MAP_PASS)
|
if (doi_def->type != CIPSO_V4_MAP_PASS)
|
||||||
return -EINVAL;
|
goto doi_add_return;
|
||||||
break;
|
break;
|
||||||
case CIPSO_V4_TAG_LOCAL:
|
case CIPSO_V4_TAG_LOCAL:
|
||||||
if (doi_def->type != CIPSO_V4_MAP_LOCAL)
|
if (doi_def->type != CIPSO_V4_MAP_LOCAL)
|
||||||
return -EINVAL;
|
goto doi_add_return;
|
||||||
|
break;
|
||||||
|
case CIPSO_V4_TAG_INVALID:
|
||||||
|
if (iter == 0)
|
||||||
|
goto doi_add_return;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
return -EINVAL;
|
goto doi_add_return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
atomic_set(&doi_def->refcount, 1);
|
atomic_set(&doi_def->refcount, 1);
|
||||||
|
|
||||||
spin_lock(&cipso_v4_doi_list_lock);
|
spin_lock(&cipso_v4_doi_list_lock);
|
||||||
if (cipso_v4_doi_search(doi_def->doi) != NULL)
|
if (cipso_v4_doi_search(doi_def->doi) != NULL) {
|
||||||
goto doi_add_failure;
|
spin_unlock(&cipso_v4_doi_list_lock);
|
||||||
|
ret_val = -EEXIST;
|
||||||
|
goto doi_add_return;
|
||||||
|
}
|
||||||
list_add_tail_rcu(&doi_def->list, &cipso_v4_doi_list);
|
list_add_tail_rcu(&doi_def->list, &cipso_v4_doi_list);
|
||||||
spin_unlock(&cipso_v4_doi_list_lock);
|
spin_unlock(&cipso_v4_doi_list_lock);
|
||||||
|
ret_val = 0;
|
||||||
|
|
||||||
return 0;
|
doi_add_return:
|
||||||
|
audit_buf = netlbl_audit_start(AUDIT_MAC_CIPSOV4_ADD, audit_info);
|
||||||
|
if (audit_buf != NULL) {
|
||||||
|
const char *type_str;
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
doi_add_failure:
|
return ret_val;
|
||||||
spin_unlock(&cipso_v4_doi_list_lock);
|
|
||||||
return -EEXIST;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -559,25 +589,39 @@ static void cipso_v4_doi_free_rcu(struct rcu_head *entry)
|
|||||||
*/
|
*/
|
||||||
int cipso_v4_doi_remove(u32 doi, struct netlbl_audit *audit_info)
|
int cipso_v4_doi_remove(u32 doi, struct netlbl_audit *audit_info)
|
||||||
{
|
{
|
||||||
|
int ret_val;
|
||||||
struct cipso_v4_doi *doi_def;
|
struct cipso_v4_doi *doi_def;
|
||||||
|
struct audit_buffer *audit_buf;
|
||||||
|
|
||||||
spin_lock(&cipso_v4_doi_list_lock);
|
spin_lock(&cipso_v4_doi_list_lock);
|
||||||
doi_def = cipso_v4_doi_search(doi);
|
doi_def = cipso_v4_doi_search(doi);
|
||||||
if (doi_def == NULL) {
|
if (doi_def == NULL) {
|
||||||
spin_unlock(&cipso_v4_doi_list_lock);
|
spin_unlock(&cipso_v4_doi_list_lock);
|
||||||
return -ENOENT;
|
ret_val = -ENOENT;
|
||||||
|
goto doi_remove_return;
|
||||||
}
|
}
|
||||||
if (!atomic_dec_and_test(&doi_def->refcount)) {
|
if (!atomic_dec_and_test(&doi_def->refcount)) {
|
||||||
spin_unlock(&cipso_v4_doi_list_lock);
|
spin_unlock(&cipso_v4_doi_list_lock);
|
||||||
return -EBUSY;
|
ret_val = -EBUSY;
|
||||||
|
goto doi_remove_return;
|
||||||
}
|
}
|
||||||
list_del_rcu(&doi_def->list);
|
list_del_rcu(&doi_def->list);
|
||||||
spin_unlock(&cipso_v4_doi_list_lock);
|
spin_unlock(&cipso_v4_doi_list_lock);
|
||||||
|
|
||||||
cipso_v4_cache_invalidate();
|
cipso_v4_cache_invalidate();
|
||||||
call_rcu(&doi_def->rcu, cipso_v4_doi_free_rcu);
|
call_rcu(&doi_def->rcu, cipso_v4_doi_free_rcu);
|
||||||
|
ret_val = 0;
|
||||||
|
|
||||||
return 0;
|
doi_remove_return:
|
||||||
|
audit_buf = netlbl_audit_start(AUDIT_MAC_CIPSOV4_DEL, audit_info);
|
||||||
|
if (audit_buf != NULL) {
|
||||||
|
audit_log_format(audit_buf,
|
||||||
|
" cipso_doi=%u res=%u",
|
||||||
|
doi, ret_val == 0 ? 1 : 0);
|
||||||
|
audit_log_end(audit_buf);
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret_val;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -130,6 +130,7 @@ static int netlbl_cipsov4_add_common(struct genl_info *info,
|
|||||||
/**
|
/**
|
||||||
* netlbl_cipsov4_add_std - Adds a CIPSO V4 DOI definition
|
* netlbl_cipsov4_add_std - Adds a CIPSO V4 DOI definition
|
||||||
* @info: the Generic NETLINK info block
|
* @info: the Generic NETLINK info block
|
||||||
|
* @audit_info: NetLabel audit information
|
||||||
*
|
*
|
||||||
* Description:
|
* Description:
|
||||||
* Create a new CIPSO_V4_MAP_TRANS DOI definition based on the given ADD
|
* Create a new CIPSO_V4_MAP_TRANS DOI definition based on the given ADD
|
||||||
@@ -137,7 +138,8 @@ static int netlbl_cipsov4_add_common(struct genl_info *info,
|
|||||||
* non-zero on 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,
|
||||||
|
struct netlbl_audit *audit_info)
|
||||||
{
|
{
|
||||||
int ret_val = -EINVAL;
|
int ret_val = -EINVAL;
|
||||||
struct cipso_v4_doi *doi_def = NULL;
|
struct cipso_v4_doi *doi_def = NULL;
|
||||||
@@ -316,7 +318,7 @@ static int netlbl_cipsov4_add_std(struct genl_info *info)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ret_val = cipso_v4_doi_add(doi_def);
|
ret_val = cipso_v4_doi_add(doi_def, audit_info);
|
||||||
if (ret_val != 0)
|
if (ret_val != 0)
|
||||||
goto add_std_failure;
|
goto add_std_failure;
|
||||||
return 0;
|
return 0;
|
||||||
@@ -330,6 +332,7 @@ add_std_failure:
|
|||||||
/**
|
/**
|
||||||
* netlbl_cipsov4_add_pass - Adds a CIPSO V4 DOI definition
|
* netlbl_cipsov4_add_pass - Adds a CIPSO V4 DOI definition
|
||||||
* @info: the Generic NETLINK info block
|
* @info: the Generic NETLINK info block
|
||||||
|
* @audit_info: NetLabel audit information
|
||||||
*
|
*
|
||||||
* Description:
|
* Description:
|
||||||
* Create a new CIPSO_V4_MAP_PASS DOI definition based on the given ADD message
|
* Create a new CIPSO_V4_MAP_PASS DOI definition based on the given ADD message
|
||||||
@@ -337,7 +340,8 @@ add_std_failure:
|
|||||||
* error.
|
* error.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
static int netlbl_cipsov4_add_pass(struct genl_info *info)
|
static int netlbl_cipsov4_add_pass(struct genl_info *info,
|
||||||
|
struct netlbl_audit *audit_info)
|
||||||
{
|
{
|
||||||
int ret_val;
|
int ret_val;
|
||||||
struct cipso_v4_doi *doi_def = NULL;
|
struct cipso_v4_doi *doi_def = NULL;
|
||||||
@@ -354,7 +358,7 @@ static int netlbl_cipsov4_add_pass(struct genl_info *info)
|
|||||||
if (ret_val != 0)
|
if (ret_val != 0)
|
||||||
goto add_pass_failure;
|
goto add_pass_failure;
|
||||||
|
|
||||||
ret_val = cipso_v4_doi_add(doi_def);
|
ret_val = cipso_v4_doi_add(doi_def, audit_info);
|
||||||
if (ret_val != 0)
|
if (ret_val != 0)
|
||||||
goto add_pass_failure;
|
goto add_pass_failure;
|
||||||
return 0;
|
return 0;
|
||||||
@@ -367,6 +371,7 @@ add_pass_failure:
|
|||||||
/**
|
/**
|
||||||
* netlbl_cipsov4_add_local - Adds a CIPSO V4 DOI definition
|
* netlbl_cipsov4_add_local - Adds a CIPSO V4 DOI definition
|
||||||
* @info: the Generic NETLINK info block
|
* @info: the Generic NETLINK info block
|
||||||
|
* @audit_info: NetLabel audit information
|
||||||
*
|
*
|
||||||
* Description:
|
* Description:
|
||||||
* Create a new CIPSO_V4_MAP_LOCAL DOI definition based on the given ADD
|
* Create a new CIPSO_V4_MAP_LOCAL DOI definition based on the given ADD
|
||||||
@@ -374,7 +379,8 @@ add_pass_failure:
|
|||||||
* non-zero on error.
|
* non-zero on error.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
static int netlbl_cipsov4_add_local(struct genl_info *info)
|
static int netlbl_cipsov4_add_local(struct genl_info *info,
|
||||||
|
struct netlbl_audit *audit_info)
|
||||||
{
|
{
|
||||||
int ret_val;
|
int ret_val;
|
||||||
struct cipso_v4_doi *doi_def = NULL;
|
struct cipso_v4_doi *doi_def = NULL;
|
||||||
@@ -391,7 +397,7 @@ static int netlbl_cipsov4_add_local(struct genl_info *info)
|
|||||||
if (ret_val != 0)
|
if (ret_val != 0)
|
||||||
goto add_local_failure;
|
goto add_local_failure;
|
||||||
|
|
||||||
ret_val = cipso_v4_doi_add(doi_def);
|
ret_val = cipso_v4_doi_add(doi_def, audit_info);
|
||||||
if (ret_val != 0)
|
if (ret_val != 0)
|
||||||
goto add_local_failure;
|
goto add_local_failure;
|
||||||
return 0;
|
return 0;
|
||||||
@@ -415,48 +421,31 @@ static int netlbl_cipsov4_add(struct sk_buff *skb, struct genl_info *info)
|
|||||||
|
|
||||||
{
|
{
|
||||||
int ret_val = -EINVAL;
|
int ret_val = -EINVAL;
|
||||||
u32 type;
|
|
||||||
u32 doi;
|
|
||||||
const char *type_str = "(unknown)";
|
const char *type_str = "(unknown)";
|
||||||
struct audit_buffer *audit_buf;
|
|
||||||
struct netlbl_audit audit_info;
|
struct netlbl_audit audit_info;
|
||||||
|
|
||||||
if (!info->attrs[NLBL_CIPSOV4_A_DOI] ||
|
if (!info->attrs[NLBL_CIPSOV4_A_DOI] ||
|
||||||
!info->attrs[NLBL_CIPSOV4_A_MTYPE])
|
!info->attrs[NLBL_CIPSOV4_A_MTYPE])
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
doi = nla_get_u32(info->attrs[NLBL_CIPSOV4_A_DOI]);
|
|
||||||
netlbl_netlink_auditinfo(skb, &audit_info);
|
netlbl_netlink_auditinfo(skb, &audit_info);
|
||||||
|
switch (nla_get_u32(info->attrs[NLBL_CIPSOV4_A_MTYPE])) {
|
||||||
type = nla_get_u32(info->attrs[NLBL_CIPSOV4_A_MTYPE]);
|
|
||||||
switch (type) {
|
|
||||||
case CIPSO_V4_MAP_TRANS:
|
case CIPSO_V4_MAP_TRANS:
|
||||||
type_str = "trans";
|
type_str = "trans";
|
||||||
ret_val = netlbl_cipsov4_add_std(info);
|
ret_val = netlbl_cipsov4_add_std(info, &audit_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, &audit_info);
|
||||||
break;
|
break;
|
||||||
case CIPSO_V4_MAP_LOCAL:
|
case CIPSO_V4_MAP_LOCAL:
|
||||||
type_str = "local";
|
type_str = "local";
|
||||||
ret_val = netlbl_cipsov4_add_local(info);
|
ret_val = netlbl_cipsov4_add_local(info, &audit_info);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (ret_val == 0)
|
if (ret_val == 0)
|
||||||
atomic_inc(&netlabel_mgmt_protocount);
|
atomic_inc(&netlabel_mgmt_protocount);
|
||||||
|
|
||||||
audit_buf = netlbl_audit_start_common(AUDIT_MAC_CIPSOV4_ADD,
|
|
||||||
&audit_info);
|
|
||||||
if (audit_buf != NULL) {
|
|
||||||
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;
|
return ret_val;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -725,9 +714,7 @@ static int netlbl_cipsov4_remove_cb(struct netlbl_dom_map *entry, void *arg)
|
|||||||
static int netlbl_cipsov4_remove(struct sk_buff *skb, struct genl_info *info)
|
static int netlbl_cipsov4_remove(struct sk_buff *skb, struct genl_info *info)
|
||||||
{
|
{
|
||||||
int ret_val = -EINVAL;
|
int ret_val = -EINVAL;
|
||||||
u32 doi = 0;
|
|
||||||
struct netlbl_domhsh_walk_arg cb_arg;
|
struct netlbl_domhsh_walk_arg cb_arg;
|
||||||
struct audit_buffer *audit_buf;
|
|
||||||
struct netlbl_audit audit_info;
|
struct netlbl_audit audit_info;
|
||||||
u32 skip_bkt = 0;
|
u32 skip_bkt = 0;
|
||||||
u32 skip_chain = 0;
|
u32 skip_chain = 0;
|
||||||
@@ -735,29 +722,17 @@ static int netlbl_cipsov4_remove(struct sk_buff *skb, struct genl_info *info)
|
|||||||
if (!info->attrs[NLBL_CIPSOV4_A_DOI])
|
if (!info->attrs[NLBL_CIPSOV4_A_DOI])
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
doi = nla_get_u32(info->attrs[NLBL_CIPSOV4_A_DOI]);
|
|
||||||
netlbl_netlink_auditinfo(skb, &audit_info);
|
netlbl_netlink_auditinfo(skb, &audit_info);
|
||||||
|
cb_arg.doi = nla_get_u32(info->attrs[NLBL_CIPSOV4_A_DOI]);
|
||||||
cb_arg.doi = doi;
|
|
||||||
cb_arg.audit_info = &audit_info;
|
cb_arg.audit_info = &audit_info;
|
||||||
ret_val = netlbl_domhsh_walk(&skip_bkt, &skip_chain,
|
ret_val = netlbl_domhsh_walk(&skip_bkt, &skip_chain,
|
||||||
netlbl_cipsov4_remove_cb, &cb_arg);
|
netlbl_cipsov4_remove_cb, &cb_arg);
|
||||||
if (ret_val == 0 || ret_val == -ENOENT) {
|
if (ret_val == 0 || ret_val == -ENOENT) {
|
||||||
ret_val = cipso_v4_doi_remove(doi, &audit_info);
|
ret_val = cipso_v4_doi_remove(cb_arg.doi, &audit_info);
|
||||||
if (ret_val == 0)
|
if (ret_val == 0)
|
||||||
atomic_dec(&netlabel_mgmt_protocount);
|
atomic_dec(&netlabel_mgmt_protocount);
|
||||||
}
|
}
|
||||||
|
|
||||||
audit_buf = netlbl_audit_start_common(AUDIT_MAC_CIPSOV4_DEL,
|
|
||||||
&audit_info);
|
|
||||||
if (audit_buf != NULL) {
|
|
||||||
audit_log_format(audit_buf,
|
|
||||||
" cipso_doi=%u res=%u",
|
|
||||||
doi,
|
|
||||||
ret_val == 0 ? 1 : 0);
|
|
||||||
audit_log_end(audit_buf);
|
|
||||||
}
|
|
||||||
|
|
||||||
return ret_val;
|
return ret_val;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -482,6 +482,73 @@ int netlbl_domhsh_remove_entry(struct netlbl_dom_map *entry,
|
|||||||
return ret_val;
|
return ret_val;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* netlbl_domhsh_remove_af4 - Removes an address selector entry
|
||||||
|
* @domain: the domain
|
||||||
|
* @addr: IPv4 address
|
||||||
|
* @mask: IPv4 address mask
|
||||||
|
* @audit_info: NetLabel audit information
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
* Removes an individual address selector from a domain mapping and potentially
|
||||||
|
* the entire mapping if it is empty. Returns zero on success, negative values
|
||||||
|
* on failure.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
int netlbl_domhsh_remove_af4(const char *domain,
|
||||||
|
const struct in_addr *addr,
|
||||||
|
const struct in_addr *mask,
|
||||||
|
struct netlbl_audit *audit_info)
|
||||||
|
{
|
||||||
|
struct netlbl_dom_map *entry_map;
|
||||||
|
struct netlbl_af4list *entry_addr;
|
||||||
|
struct netlbl_af4list *iter4;
|
||||||
|
#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
|
||||||
|
struct netlbl_af6list *iter6;
|
||||||
|
#endif /* IPv6 */
|
||||||
|
struct netlbl_domaddr4_map *entry;
|
||||||
|
|
||||||
|
rcu_read_lock();
|
||||||
|
|
||||||
|
if (domain)
|
||||||
|
entry_map = netlbl_domhsh_search(domain);
|
||||||
|
else
|
||||||
|
entry_map = netlbl_domhsh_search_def(domain);
|
||||||
|
if (entry_map == NULL || entry_map->type != NETLBL_NLTYPE_ADDRSELECT)
|
||||||
|
goto remove_af4_failure;
|
||||||
|
|
||||||
|
spin_lock(&netlbl_domhsh_lock);
|
||||||
|
entry_addr = netlbl_af4list_remove(addr->s_addr, mask->s_addr,
|
||||||
|
&entry_map->type_def.addrsel->list4);
|
||||||
|
spin_unlock(&netlbl_domhsh_lock);
|
||||||
|
|
||||||
|
if (entry_addr == NULL)
|
||||||
|
goto remove_af4_failure;
|
||||||
|
netlbl_af4list_foreach_rcu(iter4, &entry_map->type_def.addrsel->list4)
|
||||||
|
goto remove_af4_single_addr;
|
||||||
|
#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
|
||||||
|
netlbl_af6list_foreach_rcu(iter6, &entry_map->type_def.addrsel->list6)
|
||||||
|
goto remove_af4_single_addr;
|
||||||
|
#endif /* IPv6 */
|
||||||
|
/* the domain mapping is empty so remove it from the mapping table */
|
||||||
|
netlbl_domhsh_remove_entry(entry_map, audit_info);
|
||||||
|
|
||||||
|
remove_af4_single_addr:
|
||||||
|
rcu_read_unlock();
|
||||||
|
/* yick, we can't use call_rcu here because we don't have a rcu head
|
||||||
|
* pointer but hopefully this should be a rare case so the pause
|
||||||
|
* shouldn't be a problem */
|
||||||
|
synchronize_rcu();
|
||||||
|
entry = netlbl_domhsh_addr4_entry(entry_addr);
|
||||||
|
cipso_v4_doi_putdef(entry->type_def.cipsov4);
|
||||||
|
kfree(entry);
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
remove_af4_failure:
|
||||||
|
rcu_read_unlock();
|
||||||
|
return -ENOENT;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* netlbl_domhsh_remove - Removes an entry from the domain hash table
|
* netlbl_domhsh_remove - Removes an entry from the domain hash table
|
||||||
* @domain: the domain to remove
|
* @domain: the domain to remove
|
||||||
|
|||||||
@@ -90,6 +90,10 @@ 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,
|
int netlbl_domhsh_remove_entry(struct netlbl_dom_map *entry,
|
||||||
struct netlbl_audit *audit_info);
|
struct netlbl_audit *audit_info);
|
||||||
|
int netlbl_domhsh_remove_af4(const char *domain,
|
||||||
|
const struct in_addr *addr,
|
||||||
|
const struct in_addr *mask,
|
||||||
|
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);
|
||||||
|
|||||||
+288
-61
@@ -31,7 +31,10 @@
|
|||||||
#include <linux/init.h>
|
#include <linux/init.h>
|
||||||
#include <linux/types.h>
|
#include <linux/types.h>
|
||||||
#include <linux/audit.h>
|
#include <linux/audit.h>
|
||||||
|
#include <linux/in.h>
|
||||||
|
#include <linux/in6.h>
|
||||||
#include <net/ip.h>
|
#include <net/ip.h>
|
||||||
|
#include <net/ipv6.h>
|
||||||
#include <net/netlabel.h>
|
#include <net/netlabel.h>
|
||||||
#include <net/cipso_ipv4.h>
|
#include <net/cipso_ipv4.h>
|
||||||
#include <asm/bug.h>
|
#include <asm/bug.h>
|
||||||
@@ -42,6 +45,7 @@
|
|||||||
#include "netlabel_cipso_v4.h"
|
#include "netlabel_cipso_v4.h"
|
||||||
#include "netlabel_user.h"
|
#include "netlabel_user.h"
|
||||||
#include "netlabel_mgmt.h"
|
#include "netlabel_mgmt.h"
|
||||||
|
#include "netlabel_addrlist.h"
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Configuration Functions
|
* Configuration Functions
|
||||||
@@ -50,6 +54,9 @@
|
|||||||
/**
|
/**
|
||||||
* netlbl_cfg_map_del - Remove a NetLabel/LSM domain mapping
|
* netlbl_cfg_map_del - Remove a NetLabel/LSM domain mapping
|
||||||
* @domain: the domain mapping to remove
|
* @domain: the domain mapping to remove
|
||||||
|
* @family: address family
|
||||||
|
* @addr: IP address
|
||||||
|
* @mask: IP address mask
|
||||||
* @audit_info: NetLabel audit information
|
* @audit_info: NetLabel audit information
|
||||||
*
|
*
|
||||||
* Description:
|
* Description:
|
||||||
@@ -58,14 +65,32 @@
|
|||||||
* values on failure.
|
* values on failure.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
int netlbl_cfg_map_del(const char *domain, struct netlbl_audit *audit_info)
|
int netlbl_cfg_map_del(const char *domain,
|
||||||
|
u16 family,
|
||||||
|
const void *addr,
|
||||||
|
const void *mask,
|
||||||
|
struct netlbl_audit *audit_info)
|
||||||
{
|
{
|
||||||
return netlbl_domhsh_remove(domain, audit_info);
|
if (addr == NULL && mask == NULL) {
|
||||||
|
return netlbl_domhsh_remove(domain, audit_info);
|
||||||
|
} else if (addr != NULL && mask != NULL) {
|
||||||
|
switch (family) {
|
||||||
|
case AF_INET:
|
||||||
|
return netlbl_domhsh_remove_af4(domain, addr, mask,
|
||||||
|
audit_info);
|
||||||
|
default:
|
||||||
|
return -EPFNOSUPPORT;
|
||||||
|
}
|
||||||
|
} else
|
||||||
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* netlbl_cfg_unlbl_add_map - Add an unlabeled NetLabel/LSM domain mapping
|
* netlbl_cfg_unlbl_map_add - Add a new unlabeled mapping
|
||||||
* @domain: the domain mapping to add
|
* @domain: the domain mapping to add
|
||||||
|
* @family: address family
|
||||||
|
* @addr: IP address
|
||||||
|
* @mask: IP address mask
|
||||||
* @audit_info: NetLabel audit information
|
* @audit_info: NetLabel audit information
|
||||||
*
|
*
|
||||||
* Description:
|
* Description:
|
||||||
@@ -74,11 +99,19 @@ int netlbl_cfg_map_del(const char *domain, struct netlbl_audit *audit_info)
|
|||||||
* negative values on failure.
|
* negative values on failure.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
int netlbl_cfg_unlbl_add_map(const char *domain,
|
int netlbl_cfg_unlbl_map_add(const char *domain,
|
||||||
|
u16 family,
|
||||||
|
const void *addr,
|
||||||
|
const void *mask,
|
||||||
struct netlbl_audit *audit_info)
|
struct netlbl_audit *audit_info)
|
||||||
{
|
{
|
||||||
int ret_val = -ENOMEM;
|
int ret_val = -ENOMEM;
|
||||||
struct netlbl_dom_map *entry;
|
struct netlbl_dom_map *entry;
|
||||||
|
struct netlbl_domaddr_map *addrmap = NULL;
|
||||||
|
struct netlbl_domaddr4_map *map4 = NULL;
|
||||||
|
struct netlbl_domaddr6_map *map6 = NULL;
|
||||||
|
const struct in_addr *addr4, *mask4;
|
||||||
|
const struct in6_addr *addr6, *mask6;
|
||||||
|
|
||||||
entry = kzalloc(sizeof(*entry), GFP_ATOMIC);
|
entry = kzalloc(sizeof(*entry), GFP_ATOMIC);
|
||||||
if (entry == NULL)
|
if (entry == NULL)
|
||||||
@@ -86,49 +119,225 @@ int netlbl_cfg_unlbl_add_map(const char *domain,
|
|||||||
if (domain != NULL) {
|
if (domain != NULL) {
|
||||||
entry->domain = kstrdup(domain, GFP_ATOMIC);
|
entry->domain = kstrdup(domain, GFP_ATOMIC);
|
||||||
if (entry->domain == NULL)
|
if (entry->domain == NULL)
|
||||||
goto cfg_unlbl_add_map_failure;
|
goto cfg_unlbl_map_add_failure;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (addr == NULL && mask == NULL)
|
||||||
|
entry->type = NETLBL_NLTYPE_UNLABELED;
|
||||||
|
else if (addr != NULL && mask != NULL) {
|
||||||
|
addrmap = kzalloc(sizeof(*addrmap), GFP_ATOMIC);
|
||||||
|
if (addrmap == NULL)
|
||||||
|
goto cfg_unlbl_map_add_failure;
|
||||||
|
INIT_LIST_HEAD(&addrmap->list4);
|
||||||
|
INIT_LIST_HEAD(&addrmap->list6);
|
||||||
|
|
||||||
|
switch (family) {
|
||||||
|
case AF_INET:
|
||||||
|
addr4 = addr;
|
||||||
|
mask4 = mask;
|
||||||
|
map4 = kzalloc(sizeof(*map4), GFP_ATOMIC);
|
||||||
|
if (map4 == NULL)
|
||||||
|
goto cfg_unlbl_map_add_failure;
|
||||||
|
map4->type = NETLBL_NLTYPE_UNLABELED;
|
||||||
|
map4->list.addr = addr4->s_addr & mask4->s_addr;
|
||||||
|
map4->list.mask = mask4->s_addr;
|
||||||
|
map4->list.valid = 1;
|
||||||
|
ret_val = netlbl_af4list_add(&map4->list,
|
||||||
|
&addrmap->list4);
|
||||||
|
if (ret_val != 0)
|
||||||
|
goto cfg_unlbl_map_add_failure;
|
||||||
|
break;
|
||||||
|
case AF_INET6:
|
||||||
|
addr6 = addr;
|
||||||
|
mask6 = mask;
|
||||||
|
map6 = kzalloc(sizeof(*map6), GFP_ATOMIC);
|
||||||
|
if (map4 == NULL)
|
||||||
|
goto cfg_unlbl_map_add_failure;
|
||||||
|
map6->type = NETLBL_NLTYPE_UNLABELED;
|
||||||
|
ipv6_addr_copy(&map6->list.addr, addr6);
|
||||||
|
map6->list.addr.s6_addr32[0] &= mask6->s6_addr32[0];
|
||||||
|
map6->list.addr.s6_addr32[1] &= mask6->s6_addr32[1];
|
||||||
|
map6->list.addr.s6_addr32[2] &= mask6->s6_addr32[2];
|
||||||
|
map6->list.addr.s6_addr32[3] &= mask6->s6_addr32[3];
|
||||||
|
ipv6_addr_copy(&map6->list.mask, mask6);
|
||||||
|
map6->list.valid = 1;
|
||||||
|
ret_val = netlbl_af4list_add(&map4->list,
|
||||||
|
&addrmap->list4);
|
||||||
|
if (ret_val != 0)
|
||||||
|
goto cfg_unlbl_map_add_failure;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
goto cfg_unlbl_map_add_failure;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
entry->type_def.addrsel = addrmap;
|
||||||
|
entry->type = NETLBL_NLTYPE_ADDRSELECT;
|
||||||
|
} else {
|
||||||
|
ret_val = -EINVAL;
|
||||||
|
goto cfg_unlbl_map_add_failure;
|
||||||
}
|
}
|
||||||
entry->type = NETLBL_NLTYPE_UNLABELED;
|
|
||||||
|
|
||||||
ret_val = netlbl_domhsh_add(entry, audit_info);
|
ret_val = netlbl_domhsh_add(entry, audit_info);
|
||||||
if (ret_val != 0)
|
if (ret_val != 0)
|
||||||
goto cfg_unlbl_add_map_failure;
|
goto cfg_unlbl_map_add_failure;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
cfg_unlbl_add_map_failure:
|
cfg_unlbl_map_add_failure:
|
||||||
if (entry != NULL)
|
if (entry != NULL)
|
||||||
kfree(entry->domain);
|
kfree(entry->domain);
|
||||||
kfree(entry);
|
kfree(entry);
|
||||||
|
kfree(addrmap);
|
||||||
|
kfree(map4);
|
||||||
|
kfree(map6);
|
||||||
return ret_val;
|
return ret_val;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* netlbl_cfg_cipsov4_add_map - Add a new CIPSOv4 DOI definition and mapping
|
* netlbl_cfg_unlbl_static_add - Adds a new static label
|
||||||
* @doi_def: the DOI definition
|
* @net: network namespace
|
||||||
* @domain: the domain mapping to add
|
* @dev_name: interface name
|
||||||
|
* @addr: IP address in network byte order (struct in[6]_addr)
|
||||||
|
* @mask: address mask in network byte order (struct in[6]_addr)
|
||||||
|
* @family: address family
|
||||||
|
* @secid: LSM secid value for the entry
|
||||||
* @audit_info: NetLabel audit information
|
* @audit_info: NetLabel audit information
|
||||||
*
|
*
|
||||||
* Description:
|
* Description:
|
||||||
* Add a new CIPSOv4 DOI definition and NetLabel/LSM domain mapping for this
|
* Adds a new NetLabel static label to be used when protocol provided labels
|
||||||
* new DOI definition to the NetLabel subsystem. A @domain value of NULL adds
|
* are not present on incoming traffic. If @dev_name is NULL then the default
|
||||||
* a new default domain mapping. Returns zero on success, negative values on
|
* interface will be used. Returns zero on success, negative values on failure.
|
||||||
* failure.
|
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
int netlbl_cfg_cipsov4_add_map(struct cipso_v4_doi *doi_def,
|
int netlbl_cfg_unlbl_static_add(struct net *net,
|
||||||
|
const char *dev_name,
|
||||||
|
const void *addr,
|
||||||
|
const void *mask,
|
||||||
|
u16 family,
|
||||||
|
u32 secid,
|
||||||
|
struct netlbl_audit *audit_info)
|
||||||
|
{
|
||||||
|
u32 addr_len;
|
||||||
|
|
||||||
|
switch (family) {
|
||||||
|
case AF_INET:
|
||||||
|
addr_len = sizeof(struct in_addr);
|
||||||
|
break;
|
||||||
|
case AF_INET6:
|
||||||
|
addr_len = sizeof(struct in6_addr);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return -EPFNOSUPPORT;
|
||||||
|
}
|
||||||
|
|
||||||
|
return netlbl_unlhsh_add(net,
|
||||||
|
dev_name, addr, mask, addr_len,
|
||||||
|
secid, audit_info);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* netlbl_cfg_unlbl_static_del - Removes an existing static label
|
||||||
|
* @net: network namespace
|
||||||
|
* @dev_name: interface name
|
||||||
|
* @addr: IP address in network byte order (struct in[6]_addr)
|
||||||
|
* @mask: address mask in network byte order (struct in[6]_addr)
|
||||||
|
* @family: address family
|
||||||
|
* @secid: LSM secid value for the entry
|
||||||
|
* @audit_info: NetLabel audit information
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
* Removes an existing NetLabel static label used when protocol provided labels
|
||||||
|
* are not present on incoming traffic. If @dev_name is NULL then the default
|
||||||
|
* interface will be used. Returns zero on success, negative values on failure.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
int netlbl_cfg_unlbl_static_del(struct net *net,
|
||||||
|
const char *dev_name,
|
||||||
|
const void *addr,
|
||||||
|
const void *mask,
|
||||||
|
u16 family,
|
||||||
|
struct netlbl_audit *audit_info)
|
||||||
|
{
|
||||||
|
u32 addr_len;
|
||||||
|
|
||||||
|
switch (family) {
|
||||||
|
case AF_INET:
|
||||||
|
addr_len = sizeof(struct in_addr);
|
||||||
|
break;
|
||||||
|
case AF_INET6:
|
||||||
|
addr_len = sizeof(struct in6_addr);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return -EPFNOSUPPORT;
|
||||||
|
}
|
||||||
|
|
||||||
|
return netlbl_unlhsh_remove(net,
|
||||||
|
dev_name, addr, mask, addr_len,
|
||||||
|
audit_info);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* netlbl_cfg_cipsov4_add - Add a new CIPSOv4 DOI definition
|
||||||
|
* @doi_def: CIPSO DOI definition
|
||||||
|
* @audit_info: NetLabel audit information
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
* Add a new CIPSO DOI definition as defined by @doi_def. Returns zero on
|
||||||
|
* success and negative values on failure.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
int netlbl_cfg_cipsov4_add(struct cipso_v4_doi *doi_def,
|
||||||
|
struct netlbl_audit *audit_info)
|
||||||
|
{
|
||||||
|
return cipso_v4_doi_add(doi_def, audit_info);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* netlbl_cfg_cipsov4_del - Remove an existing CIPSOv4 DOI definition
|
||||||
|
* @doi: CIPSO DOI
|
||||||
|
* @audit_info: NetLabel audit information
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
* Remove an existing CIPSO DOI definition matching @doi. Returns zero on
|
||||||
|
* success and negative values on failure.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
void netlbl_cfg_cipsov4_del(u32 doi, struct netlbl_audit *audit_info)
|
||||||
|
{
|
||||||
|
cipso_v4_doi_remove(doi, audit_info);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* netlbl_cfg_cipsov4_map_add - Add a new CIPSOv4 DOI mapping
|
||||||
|
* @doi: the CIPSO DOI
|
||||||
|
* @domain: the domain mapping to add
|
||||||
|
* @addr: IP address
|
||||||
|
* @mask: IP address mask
|
||||||
|
* @audit_info: NetLabel audit information
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
* Add a new NetLabel/LSM domain mapping for the given CIPSO DOI to the NetLabel
|
||||||
|
* subsystem. A @domain value of NULL adds a new default domain mapping.
|
||||||
|
* Returns zero on success, negative values on failure.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
int netlbl_cfg_cipsov4_map_add(u32 doi,
|
||||||
const char *domain,
|
const char *domain,
|
||||||
|
const struct in_addr *addr,
|
||||||
|
const struct in_addr *mask,
|
||||||
struct netlbl_audit *audit_info)
|
struct netlbl_audit *audit_info)
|
||||||
{
|
{
|
||||||
int ret_val = -ENOMEM;
|
int ret_val = -ENOMEM;
|
||||||
u32 doi;
|
struct cipso_v4_doi *doi_def;
|
||||||
u32 doi_type;
|
|
||||||
struct netlbl_dom_map *entry;
|
struct netlbl_dom_map *entry;
|
||||||
const char *type_str;
|
struct netlbl_domaddr_map *addrmap = NULL;
|
||||||
struct audit_buffer *audit_buf;
|
struct netlbl_domaddr4_map *addrinfo = NULL;
|
||||||
|
|
||||||
doi = doi_def->doi;
|
doi_def = cipso_v4_doi_getdef(doi);
|
||||||
doi_type = doi_def->type;
|
if (doi_def == NULL)
|
||||||
|
return -ENOENT;
|
||||||
|
|
||||||
entry = kzalloc(sizeof(*entry), GFP_ATOMIC);
|
entry = kzalloc(sizeof(*entry), GFP_ATOMIC);
|
||||||
if (entry == NULL)
|
if (entry == NULL)
|
||||||
@@ -136,56 +345,52 @@ int netlbl_cfg_cipsov4_add_map(struct cipso_v4_doi *doi_def,
|
|||||||
if (domain != NULL) {
|
if (domain != NULL) {
|
||||||
entry->domain = kstrdup(domain, GFP_ATOMIC);
|
entry->domain = kstrdup(domain, GFP_ATOMIC);
|
||||||
if (entry->domain == NULL)
|
if (entry->domain == NULL)
|
||||||
goto cfg_cipsov4_add_map_failure;
|
goto cfg_cipsov4_map_add_failure;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret_val = cipso_v4_doi_add(doi_def);
|
if (addr == NULL && mask == NULL) {
|
||||||
if (ret_val != 0)
|
entry->type_def.cipsov4 = doi_def;
|
||||||
goto cfg_cipsov4_add_map_failure_remove_doi;
|
entry->type = NETLBL_NLTYPE_CIPSOV4;
|
||||||
entry->type = NETLBL_NLTYPE_CIPSOV4;
|
} else if (addr != NULL && mask != NULL) {
|
||||||
entry->type_def.cipsov4 = cipso_v4_doi_getdef(doi);
|
addrmap = kzalloc(sizeof(*addrmap), GFP_ATOMIC);
|
||||||
if (entry->type_def.cipsov4 == NULL) {
|
if (addrmap == NULL)
|
||||||
ret_val = -ENOENT;
|
goto cfg_cipsov4_map_add_failure;
|
||||||
goto cfg_cipsov4_add_map_failure_remove_doi;
|
INIT_LIST_HEAD(&addrmap->list4);
|
||||||
|
INIT_LIST_HEAD(&addrmap->list6);
|
||||||
|
|
||||||
|
addrinfo = kzalloc(sizeof(*addrinfo), GFP_ATOMIC);
|
||||||
|
if (addrinfo == NULL)
|
||||||
|
goto cfg_cipsov4_map_add_failure;
|
||||||
|
addrinfo->type_def.cipsov4 = doi_def;
|
||||||
|
addrinfo->type = NETLBL_NLTYPE_CIPSOV4;
|
||||||
|
addrinfo->list.addr = addr->s_addr & mask->s_addr;
|
||||||
|
addrinfo->list.mask = mask->s_addr;
|
||||||
|
addrinfo->list.valid = 1;
|
||||||
|
ret_val = netlbl_af4list_add(&addrinfo->list, &addrmap->list4);
|
||||||
|
if (ret_val != 0)
|
||||||
|
goto cfg_cipsov4_map_add_failure;
|
||||||
|
|
||||||
|
entry->type_def.addrsel = addrmap;
|
||||||
|
entry->type = NETLBL_NLTYPE_ADDRSELECT;
|
||||||
|
} else {
|
||||||
|
ret_val = -EINVAL;
|
||||||
|
goto cfg_cipsov4_map_add_failure;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret_val = netlbl_domhsh_add(entry, audit_info);
|
ret_val = netlbl_domhsh_add(entry, audit_info);
|
||||||
if (ret_val != 0)
|
if (ret_val != 0)
|
||||||
goto cfg_cipsov4_add_map_failure_release_doi;
|
goto cfg_cipsov4_map_add_failure;
|
||||||
|
|
||||||
cfg_cipsov4_add_map_return:
|
return 0;
|
||||||
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_map_add_failure:
|
||||||
|
|
||||||
cfg_cipsov4_add_map_failure_release_doi:
|
|
||||||
cipso_v4_doi_putdef(doi_def);
|
cipso_v4_doi_putdef(doi_def);
|
||||||
cfg_cipsov4_add_map_failure_remove_doi:
|
|
||||||
cipso_v4_doi_remove(doi, audit_info);
|
|
||||||
cfg_cipsov4_add_map_failure:
|
|
||||||
if (entry != NULL)
|
if (entry != NULL)
|
||||||
kfree(entry->domain);
|
kfree(entry->domain);
|
||||||
kfree(entry);
|
kfree(entry);
|
||||||
goto cfg_cipsov4_add_map_return;
|
kfree(addrmap);
|
||||||
|
kfree(addrinfo);
|
||||||
|
return ret_val;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -690,6 +895,28 @@ int netlbl_cache_add(const struct sk_buff *skb,
|
|||||||
return -ENOMSG;
|
return -ENOMSG;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Protocol Engine Functions
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* netlbl_audit_start - Start an audit message
|
||||||
|
* @type: audit message type
|
||||||
|
* @audit_info: NetLabel audit information
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
* Start an audit message using the type specified in @type and fill the audit
|
||||||
|
* message with some fields common to all NetLabel audit messages. This
|
||||||
|
* function should only be used by protocol engines, not LSMs. Returns a
|
||||||
|
* pointer to the audit buffer on success, NULL on failure.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
struct audit_buffer *netlbl_audit_start(int type,
|
||||||
|
struct netlbl_audit *audit_info)
|
||||||
|
{
|
||||||
|
return netlbl_audit_start_common(type, audit_info);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Setup Functions
|
* Setup Functions
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -450,13 +450,13 @@ add_iface_failure:
|
|||||||
* success, negative values on failure.
|
* success, negative values on failure.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
static int netlbl_unlhsh_add(struct net *net,
|
int netlbl_unlhsh_add(struct net *net,
|
||||||
const char *dev_name,
|
const char *dev_name,
|
||||||
const void *addr,
|
const void *addr,
|
||||||
const void *mask,
|
const void *mask,
|
||||||
u32 addr_len,
|
u32 addr_len,
|
||||||
u32 secid,
|
u32 secid,
|
||||||
struct netlbl_audit *audit_info)
|
struct netlbl_audit *audit_info)
|
||||||
{
|
{
|
||||||
int ret_val;
|
int ret_val;
|
||||||
int ifindex;
|
int ifindex;
|
||||||
@@ -720,12 +720,12 @@ unlhsh_condremove_failure:
|
|||||||
* Returns zero on success, negative values on failure.
|
* Returns zero on success, negative values on failure.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
static int netlbl_unlhsh_remove(struct net *net,
|
int netlbl_unlhsh_remove(struct net *net,
|
||||||
const char *dev_name,
|
const char *dev_name,
|
||||||
const void *addr,
|
const void *addr,
|
||||||
const void *mask,
|
const void *mask,
|
||||||
u32 addr_len,
|
u32 addr_len,
|
||||||
struct netlbl_audit *audit_info)
|
struct netlbl_audit *audit_info)
|
||||||
{
|
{
|
||||||
int ret_val;
|
int ret_val;
|
||||||
struct net_device *dev;
|
struct net_device *dev;
|
||||||
|
|||||||
@@ -221,6 +221,21 @@ int netlbl_unlabel_genl_init(void);
|
|||||||
/* General Unlabeled init function */
|
/* General Unlabeled init function */
|
||||||
int netlbl_unlabel_init(u32 size);
|
int netlbl_unlabel_init(u32 size);
|
||||||
|
|
||||||
|
/* Static/Fallback label management functions */
|
||||||
|
int netlbl_unlhsh_add(struct net *net,
|
||||||
|
const char *dev_name,
|
||||||
|
const void *addr,
|
||||||
|
const void *mask,
|
||||||
|
u32 addr_len,
|
||||||
|
u32 secid,
|
||||||
|
struct netlbl_audit *audit_info);
|
||||||
|
int netlbl_unlhsh_remove(struct net *net,
|
||||||
|
const char *dev_name,
|
||||||
|
const void *addr,
|
||||||
|
const void *mask,
|
||||||
|
u32 addr_len,
|
||||||
|
struct netlbl_audit *audit_info);
|
||||||
|
|
||||||
/* Process Unlabeled incoming network packets */
|
/* Process Unlabeled incoming network packets */
|
||||||
int netlbl_unlabel_getattr(const struct sk_buff *skb,
|
int netlbl_unlabel_getattr(const struct sk_buff *skb,
|
||||||
u16 family,
|
u16 family,
|
||||||
|
|||||||
+14
-15
@@ -45,26 +45,22 @@ EXPORT_SYMBOL(cap_netlink_recv);
|
|||||||
/**
|
/**
|
||||||
* cap_capable - Determine whether a task has a particular effective capability
|
* cap_capable - Determine whether a task has a particular effective capability
|
||||||
* @tsk: The task to query
|
* @tsk: The task to query
|
||||||
|
* @cred: The credentials to use
|
||||||
* @cap: The capability to check for
|
* @cap: The capability to check for
|
||||||
* @audit: Whether to write an audit message or not
|
* @audit: Whether to write an audit message or not
|
||||||
*
|
*
|
||||||
* Determine whether the nominated task has the specified capability amongst
|
* Determine whether the nominated task has the specified capability amongst
|
||||||
* its effective set, returning 0 if it does, -ve if it does not.
|
* its effective set, returning 0 if it does, -ve if it does not.
|
||||||
*
|
*
|
||||||
* NOTE WELL: cap_capable() cannot be used like the kernel's capable()
|
* NOTE WELL: cap_has_capability() cannot be used like the kernel's capable()
|
||||||
* function. That is, it has the reverse semantics: cap_capable() returns 0
|
* and has_capability() functions. That is, it has the reverse semantics:
|
||||||
* when a task has a capability, but the kernel's capable() returns 1 for this
|
* cap_has_capability() returns 0 when a task has a capability, but the
|
||||||
* case.
|
* kernel's capable() and has_capability() returns 1 for this case.
|
||||||
*/
|
*/
|
||||||
int cap_capable(struct task_struct *tsk, int cap, int audit)
|
int cap_capable(struct task_struct *tsk, const struct cred *cred, int cap,
|
||||||
|
int audit)
|
||||||
{
|
{
|
||||||
__u32 cap_raised;
|
return cap_raised(cred->cap_effective, cap) ? 0 : -EPERM;
|
||||||
|
|
||||||
/* Derived from include/linux/sched.h:capable. */
|
|
||||||
rcu_read_lock();
|
|
||||||
cap_raised = cap_raised(__task_cred(tsk)->cap_effective, cap);
|
|
||||||
rcu_read_unlock();
|
|
||||||
return cap_raised ? 0 : -EPERM;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -160,7 +156,8 @@ static inline int cap_inh_is_capped(void)
|
|||||||
/* they are so limited unless the current task has the CAP_SETPCAP
|
/* they are so limited unless the current task has the CAP_SETPCAP
|
||||||
* capability
|
* capability
|
||||||
*/
|
*/
|
||||||
if (cap_capable(current, CAP_SETPCAP, SECURITY_CAP_AUDIT) == 0)
|
if (cap_capable(current, current_cred(), CAP_SETPCAP,
|
||||||
|
SECURITY_CAP_AUDIT) == 0)
|
||||||
return 0;
|
return 0;
|
||||||
#endif
|
#endif
|
||||||
return 1;
|
return 1;
|
||||||
@@ -869,7 +866,8 @@ int cap_task_prctl(int option, unsigned long arg2, unsigned long arg3,
|
|||||||
& (new->securebits ^ arg2)) /*[1]*/
|
& (new->securebits ^ arg2)) /*[1]*/
|
||||||
|| ((new->securebits & SECURE_ALL_LOCKS & ~arg2)) /*[2]*/
|
|| ((new->securebits & SECURE_ALL_LOCKS & ~arg2)) /*[2]*/
|
||||||
|| (arg2 & ~(SECURE_ALL_LOCKS | SECURE_ALL_BITS)) /*[3]*/
|
|| (arg2 & ~(SECURE_ALL_LOCKS | SECURE_ALL_BITS)) /*[3]*/
|
||||||
|| (cap_capable(current, CAP_SETPCAP, SECURITY_CAP_AUDIT) != 0) /*[4]*/
|
|| (cap_capable(current, current_cred(), CAP_SETPCAP,
|
||||||
|
SECURITY_CAP_AUDIT) != 0) /*[4]*/
|
||||||
/*
|
/*
|
||||||
* [1] no changing of bits that are locked
|
* [1] no changing of bits that are locked
|
||||||
* [2] no unlocking of locks
|
* [2] no unlocking of locks
|
||||||
@@ -950,7 +948,8 @@ int cap_vm_enough_memory(struct mm_struct *mm, long pages)
|
|||||||
{
|
{
|
||||||
int cap_sys_admin = 0;
|
int cap_sys_admin = 0;
|
||||||
|
|
||||||
if (cap_capable(current, CAP_SYS_ADMIN, SECURITY_CAP_NOAUDIT) == 0)
|
if (cap_capable(current, current_cred(), CAP_SYS_ADMIN,
|
||||||
|
SECURITY_CAP_NOAUDIT) == 0)
|
||||||
cap_sys_admin = 1;
|
cap_sys_admin = 1;
|
||||||
return __vm_enough_memory(mm, pages, cap_sys_admin);
|
return __vm_enough_memory(mm, pages, cap_sys_admin);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1294,7 +1294,7 @@ asmlinkage long sys_keyctl(int option, unsigned long arg2, unsigned long arg3,
|
|||||||
|
|
||||||
case KEYCTL_GET_SECURITY:
|
case KEYCTL_GET_SECURITY:
|
||||||
return keyctl_get_security((key_serial_t) arg2,
|
return keyctl_get_security((key_serial_t) arg2,
|
||||||
(char *) arg3,
|
(char __user *) arg3,
|
||||||
(size_t) arg4);
|
(size_t) arg4);
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
|||||||
+22
-4
@@ -154,14 +154,32 @@ int security_capset(struct cred *new, const struct cred *old,
|
|||||||
effective, inheritable, permitted);
|
effective, inheritable, permitted);
|
||||||
}
|
}
|
||||||
|
|
||||||
int security_capable(struct task_struct *tsk, int cap)
|
int security_capable(int cap)
|
||||||
{
|
{
|
||||||
return security_ops->capable(tsk, cap, SECURITY_CAP_AUDIT);
|
return security_ops->capable(current, current_cred(), cap,
|
||||||
|
SECURITY_CAP_AUDIT);
|
||||||
}
|
}
|
||||||
|
|
||||||
int security_capable_noaudit(struct task_struct *tsk, int cap)
|
int security_real_capable(struct task_struct *tsk, int cap)
|
||||||
{
|
{
|
||||||
return security_ops->capable(tsk, cap, SECURITY_CAP_NOAUDIT);
|
const struct cred *cred;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
cred = get_task_cred(tsk);
|
||||||
|
ret = security_ops->capable(tsk, cred, cap, SECURITY_CAP_AUDIT);
|
||||||
|
put_cred(cred);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
int security_real_capable_noaudit(struct task_struct *tsk, int cap)
|
||||||
|
{
|
||||||
|
const struct cred *cred;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
cred = get_task_cred(tsk);
|
||||||
|
ret = security_ops->capable(tsk, cred, cap, SECURITY_CAP_NOAUDIT);
|
||||||
|
put_cred(cred);
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
int security_acct(struct file *file)
|
int security_acct(struct file *file)
|
||||||
|
|||||||
@@ -94,33 +94,6 @@ config SECURITY_SELINUX_CHECKREQPROT_VALUE
|
|||||||
|
|
||||||
If you are unsure how to answer this question, answer 1.
|
If you are unsure how to answer this question, answer 1.
|
||||||
|
|
||||||
config SECURITY_SELINUX_ENABLE_SECMARK_DEFAULT
|
|
||||||
bool "NSA SELinux enable new secmark network controls by default"
|
|
||||||
depends on SECURITY_SELINUX
|
|
||||||
default n
|
|
||||||
help
|
|
||||||
This option determines whether the new secmark-based network
|
|
||||||
controls will be enabled by default. If not, the old internal
|
|
||||||
per-packet controls will be enabled by default, preserving
|
|
||||||
old behavior.
|
|
||||||
|
|
||||||
If you enable the new controls, you will need updated
|
|
||||||
SELinux userspace libraries, tools and policy. Typically,
|
|
||||||
your distribution will provide these and enable the new controls
|
|
||||||
in the kernel they also distribute.
|
|
||||||
|
|
||||||
Note that this option can be overridden at boot with the
|
|
||||||
selinux_compat_net parameter, and after boot via
|
|
||||||
/selinux/compat_net. See Documentation/kernel-parameters.txt
|
|
||||||
for details on this parameter.
|
|
||||||
|
|
||||||
If you enable the new network controls, you will likely
|
|
||||||
also require the SECMARK and CONNSECMARK targets, as
|
|
||||||
well as any conntrack helpers for protocols which you
|
|
||||||
wish to control.
|
|
||||||
|
|
||||||
If you are unsure what to do here, select N.
|
|
||||||
|
|
||||||
config SECURITY_SELINUX_POLICYDB_VERSION_MAX
|
config SECURITY_SELINUX_POLICYDB_VERSION_MAX
|
||||||
bool "NSA SELinux maximum supported policy format version"
|
bool "NSA SELinux maximum supported policy format version"
|
||||||
depends on SECURITY_SELINUX
|
depends on SECURITY_SELINUX
|
||||||
|
|||||||
@@ -53,18 +53,20 @@ static const char *class_to_string[] = {
|
|||||||
#undef S_
|
#undef S_
|
||||||
|
|
||||||
static const struct av_inherit av_inherit[] = {
|
static const struct av_inherit av_inherit[] = {
|
||||||
#define S_(c, i, b) { c, common_##i##_perm_to_string, b },
|
#define S_(c, i, b) { .tclass = c,\
|
||||||
|
.common_pts = common_##i##_perm_to_string,\
|
||||||
|
.common_base = b },
|
||||||
#include "av_inherit.h"
|
#include "av_inherit.h"
|
||||||
#undef S_
|
#undef S_
|
||||||
};
|
};
|
||||||
|
|
||||||
const struct selinux_class_perm selinux_class_perm = {
|
const struct selinux_class_perm selinux_class_perm = {
|
||||||
av_perm_to_string,
|
.av_perm_to_string = av_perm_to_string,
|
||||||
ARRAY_SIZE(av_perm_to_string),
|
.av_pts_len = ARRAY_SIZE(av_perm_to_string),
|
||||||
class_to_string,
|
.class_to_string = class_to_string,
|
||||||
ARRAY_SIZE(class_to_string),
|
.cts_len = ARRAY_SIZE(class_to_string),
|
||||||
av_inherit,
|
.av_inherit = av_inherit,
|
||||||
ARRAY_SIZE(av_inherit)
|
.av_inherit_len = ARRAY_SIZE(av_inherit)
|
||||||
};
|
};
|
||||||
|
|
||||||
#define AVC_CACHE_SLOTS 512
|
#define AVC_CACHE_SLOTS 512
|
||||||
|
|||||||
@@ -1433,12 +1433,13 @@ static int current_has_perm(const struct task_struct *tsk,
|
|||||||
|
|
||||||
/* Check whether a task is allowed to use a capability. */
|
/* Check whether a task is allowed to use a capability. */
|
||||||
static int task_has_capability(struct task_struct *tsk,
|
static int task_has_capability(struct task_struct *tsk,
|
||||||
|
const struct cred *cred,
|
||||||
int cap, int audit)
|
int cap, int audit)
|
||||||
{
|
{
|
||||||
struct avc_audit_data ad;
|
struct avc_audit_data ad;
|
||||||
struct av_decision avd;
|
struct av_decision avd;
|
||||||
u16 sclass;
|
u16 sclass;
|
||||||
u32 sid = task_sid(tsk);
|
u32 sid = cred_sid(cred);
|
||||||
u32 av = CAP_TO_MASK(cap);
|
u32 av = CAP_TO_MASK(cap);
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
@@ -1865,15 +1866,16 @@ static int selinux_capset(struct cred *new, const struct cred *old,
|
|||||||
return cred_has_perm(old, new, PROCESS__SETCAP);
|
return cred_has_perm(old, new, PROCESS__SETCAP);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int selinux_capable(struct task_struct *tsk, int cap, int audit)
|
static int selinux_capable(struct task_struct *tsk, const struct cred *cred,
|
||||||
|
int cap, int audit)
|
||||||
{
|
{
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
rc = secondary_ops->capable(tsk, cap, audit);
|
rc = secondary_ops->capable(tsk, cred, cap, audit);
|
||||||
if (rc)
|
if (rc)
|
||||||
return rc;
|
return rc;
|
||||||
|
|
||||||
return task_has_capability(tsk, cap, audit);
|
return task_has_capability(tsk, cred, cap, audit);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int selinux_sysctl_get_sid(ctl_table *table, u16 tclass, u32 *sid)
|
static int selinux_sysctl_get_sid(ctl_table *table, u16 tclass, u32 *sid)
|
||||||
@@ -2037,7 +2039,8 @@ static int selinux_vm_enough_memory(struct mm_struct *mm, long pages)
|
|||||||
{
|
{
|
||||||
int rc, cap_sys_admin = 0;
|
int rc, cap_sys_admin = 0;
|
||||||
|
|
||||||
rc = selinux_capable(current, CAP_SYS_ADMIN, SECURITY_CAP_NOAUDIT);
|
rc = selinux_capable(current, current_cred(), CAP_SYS_ADMIN,
|
||||||
|
SECURITY_CAP_NOAUDIT);
|
||||||
if (rc == 0)
|
if (rc == 0)
|
||||||
cap_sys_admin = 1;
|
cap_sys_admin = 1;
|
||||||
|
|
||||||
@@ -2880,7 +2883,8 @@ static int selinux_inode_getsecurity(const struct inode *inode, const char *name
|
|||||||
* and lack of permission just means that we fall back to the
|
* and lack of permission just means that we fall back to the
|
||||||
* in-core context value, not a denial.
|
* in-core context value, not a denial.
|
||||||
*/
|
*/
|
||||||
error = selinux_capable(current, CAP_MAC_ADMIN, SECURITY_CAP_NOAUDIT);
|
error = selinux_capable(current, current_cred(), CAP_MAC_ADMIN,
|
||||||
|
SECURITY_CAP_NOAUDIT);
|
||||||
if (!error)
|
if (!error)
|
||||||
error = security_sid_to_context_force(isec->sid, &context,
|
error = security_sid_to_context_force(isec->sid, &context,
|
||||||
&size);
|
&size);
|
||||||
@@ -4185,7 +4189,7 @@ static int selinux_sock_rcv_skb_iptables_compat(struct sock *sk,
|
|||||||
static int selinux_sock_rcv_skb_compat(struct sock *sk, struct sk_buff *skb,
|
static int selinux_sock_rcv_skb_compat(struct sock *sk, struct sk_buff *skb,
|
||||||
u16 family)
|
u16 family)
|
||||||
{
|
{
|
||||||
int err;
|
int err = 0;
|
||||||
struct sk_security_struct *sksec = sk->sk_security;
|
struct sk_security_struct *sksec = sk->sk_security;
|
||||||
u32 peer_sid;
|
u32 peer_sid;
|
||||||
u32 sk_sid = sksec->sid;
|
u32 sk_sid = sksec->sid;
|
||||||
@@ -4202,7 +4206,7 @@ static int selinux_sock_rcv_skb_compat(struct sock *sk, struct sk_buff *skb,
|
|||||||
if (selinux_compat_net)
|
if (selinux_compat_net)
|
||||||
err = selinux_sock_rcv_skb_iptables_compat(sk, skb, &ad,
|
err = selinux_sock_rcv_skb_iptables_compat(sk, skb, &ad,
|
||||||
family, addrp);
|
family, addrp);
|
||||||
else
|
else if (selinux_secmark_enabled())
|
||||||
err = avc_has_perm(sk_sid, skb->secmark, SECCLASS_PACKET,
|
err = avc_has_perm(sk_sid, skb->secmark, SECCLASS_PACKET,
|
||||||
PACKET__RECV, &ad);
|
PACKET__RECV, &ad);
|
||||||
if (err)
|
if (err)
|
||||||
@@ -4705,7 +4709,7 @@ static unsigned int selinux_ip_postroute_compat(struct sk_buff *skb,
|
|||||||
if (selinux_ip_postroute_iptables_compat(skb->sk, ifindex,
|
if (selinux_ip_postroute_iptables_compat(skb->sk, ifindex,
|
||||||
&ad, family, addrp))
|
&ad, family, addrp))
|
||||||
return NF_DROP;
|
return NF_DROP;
|
||||||
} else {
|
} else if (selinux_secmark_enabled()) {
|
||||||
if (avc_has_perm(sksec->sid, skb->secmark,
|
if (avc_has_perm(sksec->sid, skb->secmark,
|
||||||
SECCLASS_PACKET, PACKET__SEND, &ad))
|
SECCLASS_PACKET, PACKET__SEND, &ad))
|
||||||
return NF_DROP;
|
return NF_DROP;
|
||||||
|
|||||||
@@ -17,16 +17,16 @@ struct av_perm_to_string {
|
|||||||
};
|
};
|
||||||
|
|
||||||
struct av_inherit {
|
struct av_inherit {
|
||||||
u16 tclass;
|
|
||||||
const char **common_pts;
|
const char **common_pts;
|
||||||
u32 common_base;
|
u32 common_base;
|
||||||
|
u16 tclass;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct selinux_class_perm {
|
struct selinux_class_perm {
|
||||||
const struct av_perm_to_string *av_perm_to_string;
|
const struct av_perm_to_string *av_perm_to_string;
|
||||||
u32 av_pts_len;
|
u32 av_pts_len;
|
||||||
const char **class_to_string;
|
|
||||||
u32 cts_len;
|
u32 cts_len;
|
||||||
|
const char **class_to_string;
|
||||||
const struct av_inherit *av_inherit;
|
const struct av_inherit *av_inherit;
|
||||||
u32 av_inherit_len;
|
u32 av_inherit_len;
|
||||||
};
|
};
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user