Skip to content

Commit

Permalink
[NetLabel]: add audit support for configuration changes
Browse files Browse the repository at this point in the history
This patch adds audit support to NetLabel, including six new audit message
types shown below.

 #define AUDIT_MAC_UNLBL_ACCEPT 1406
 #define AUDIT_MAC_UNLBL_DENY   1407
 #define AUDIT_MAC_CIPSOV4_ADD  1408
 #define AUDIT_MAC_CIPSOV4_DEL  1409
 #define AUDIT_MAC_MAP_ADD      1410
 #define AUDIT_MAC_MAP_DEL      1411

Signed-off-by: Paul Moore <[email protected]>
Acked-by: James Morris <[email protected]>
Signed-off-by: David S. Miller <[email protected]>
  • Loading branch information
pcmoore authored and David S. Miller committed Sep 29, 2006
1 parent 8ea333e commit 32f50cd
Show file tree
Hide file tree
Showing 11 changed files with 235 additions and 36 deletions.
6 changes: 6 additions & 0 deletions include/linux/audit.h
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,12 @@
#define AUDIT_MAC_POLICY_LOAD 1403 /* Policy file load */
#define AUDIT_MAC_STATUS 1404 /* Changed enforcing,permissive,off */
#define AUDIT_MAC_CONFIG_CHANGE 1405 /* Changes to booleans */
#define AUDIT_MAC_UNLBL_ACCEPT 1406 /* NetLabel: allow unlabeled traffic */
#define AUDIT_MAC_UNLBL_DENY 1407 /* NetLabel: deny unlabeled traffic */
#define AUDIT_MAC_CIPSOV4_ADD 1408 /* NetLabel: add CIPSOv4 DOI entry */
#define AUDIT_MAC_CIPSOV4_DEL 1409 /* NetLabel: del CIPSOv4 DOI entry */
#define AUDIT_MAC_MAP_ADD 1410 /* NetLabel: add LSM domain mapping */
#define AUDIT_MAC_MAP_DEL 1411 /* NetLabel: del LSM domain mapping */

#define AUDIT_FIRST_KERN_ANOM_MSG 1700
#define AUDIT_LAST_KERN_ANOM_MSG 1799
Expand Down
5 changes: 4 additions & 1 deletion include/net/cipso_ipv4.h
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,9 @@ 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, void (*callback) (struct rcu_head * head));
int cipso_v4_doi_remove(u32 doi,
u32 audit_secid,
void (*callback) (struct rcu_head * head));
struct cipso_v4_doi *cipso_v4_doi_getdef(u32 doi);
int cipso_v4_doi_walk(u32 *skip_cnt,
int (*callback) (struct cipso_v4_doi *doi_def, void *arg),
Expand All @@ -143,6 +145,7 @@ static inline int cipso_v4_doi_add(struct cipso_v4_doi *doi_def)
}

static inline int cipso_v4_doi_remove(u32 doi,
u32 audit_secid,
void (*callback) (struct rcu_head * head))
{
return 0;
Expand Down
2 changes: 1 addition & 1 deletion include/net/netlabel.h
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@
struct netlbl_dom_map;

/* Domain mapping operations */
int netlbl_domhsh_remove(const char *domain);
int netlbl_domhsh_remove(const char *domain, u32 audit_secid);

/* LSM security attributes */
struct netlbl_lsm_cache {
Expand Down
8 changes: 6 additions & 2 deletions net/ipv4/cipso_ipv4.c
Original file line number Diff line number Diff line change
Expand Up @@ -474,6 +474,7 @@ int cipso_v4_doi_add(struct cipso_v4_doi *doi_def)
/**
* cipso_v4_doi_remove - Remove an existing DOI from the CIPSO protocol engine
* @doi: the DOI value
* @audit_secid: the LSM secid to use in the audit message
* @callback: the DOI cleanup/free callback
*
* Description:
Expand All @@ -483,7 +484,9 @@ int cipso_v4_doi_add(struct cipso_v4_doi *doi_def)
* success and negative values on failure.
*
*/
int cipso_v4_doi_remove(u32 doi, void (*callback) (struct rcu_head * head))
int cipso_v4_doi_remove(u32 doi,
u32 audit_secid,
void (*callback) (struct rcu_head * head))
{
struct cipso_v4_doi *doi_def;
struct cipso_v4_domhsh_entry *dom_iter;
Expand All @@ -502,7 +505,8 @@ int cipso_v4_doi_remove(u32 doi, void (*callback) (struct rcu_head * head))
spin_unlock(&cipso_v4_doi_list_lock);
list_for_each_entry_rcu(dom_iter, &doi_def->dom_list, list)
if (dom_iter->valid)
netlbl_domhsh_remove(dom_iter->domain);
netlbl_domhsh_remove(dom_iter->domain,
audit_secid);
cipso_v4_cache_invalidate();
rcu_read_unlock();

Expand Down
43 changes: 33 additions & 10 deletions net/netlabel/netlabel_cipso_v4.c
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
#include <linux/socket.h>
#include <linux/string.h>
#include <linux/skbuff.h>
#include <linux/audit.h>
#include <net/sock.h>
#include <net/netlink.h>
#include <net/genetlink.h>
Expand Down Expand Up @@ -162,8 +163,7 @@ static int netlbl_cipsov4_add_std(struct genl_info *info)
int nla_a_rem;
int nla_b_rem;

if (!info->attrs[NLBL_CIPSOV4_A_DOI] ||
!info->attrs[NLBL_CIPSOV4_A_TAGLST] ||
if (!info->attrs[NLBL_CIPSOV4_A_TAGLST] ||
!info->attrs[NLBL_CIPSOV4_A_MLSLVLLST])
return -EINVAL;

Expand Down Expand Up @@ -344,8 +344,7 @@ static int netlbl_cipsov4_add_pass(struct genl_info *info)
int ret_val;
struct cipso_v4_doi *doi_def = NULL;

if (!info->attrs[NLBL_CIPSOV4_A_DOI] ||
!info->attrs[NLBL_CIPSOV4_A_TAGLST])
if (!info->attrs[NLBL_CIPSOV4_A_TAGLST])
return -EINVAL;

doi_def = kmalloc(sizeof(*doi_def), GFP_KERNEL);
Expand Down Expand Up @@ -381,21 +380,35 @@ static int netlbl_cipsov4_add(struct sk_buff *skb, struct genl_info *info)

{
int ret_val = -EINVAL;
u32 map_type;
u32 type;
u32 doi;
const char *type_str = "(unknown)";
struct audit_buffer *audit_buf;

if (!info->attrs[NLBL_CIPSOV4_A_MTYPE])
if (!info->attrs[NLBL_CIPSOV4_A_DOI] ||
!info->attrs[NLBL_CIPSOV4_A_MTYPE])
return -EINVAL;

map_type = nla_get_u32(info->attrs[NLBL_CIPSOV4_A_MTYPE]);
switch (map_type) {
type = nla_get_u32(info->attrs[NLBL_CIPSOV4_A_MTYPE]);
switch (type) {
case CIPSO_V4_MAP_STD:
type_str = "std";
ret_val = netlbl_cipsov4_add_std(info);
break;
case CIPSO_V4_MAP_PASS:
type_str = "pass";
ret_val = netlbl_cipsov4_add_pass(info);
break;
}

if (ret_val == 0) {
doi = nla_get_u32(info->attrs[NLBL_CIPSOV4_A_DOI]);
audit_buf = netlbl_audit_start_common(AUDIT_MAC_CIPSOV4_ADD,
NETLINK_CB(skb).sid);
audit_log_format(audit_buf, " doi=%u type=%s", doi, type_str);
audit_log_end(audit_buf);
}

return ret_val;
}

Expand Down Expand Up @@ -653,11 +666,21 @@ static int netlbl_cipsov4_listall(struct sk_buff *skb,
static int netlbl_cipsov4_remove(struct sk_buff *skb, struct genl_info *info)
{
int ret_val = -EINVAL;
u32 doi;
u32 doi = 0;
struct audit_buffer *audit_buf;

if (info->attrs[NLBL_CIPSOV4_A_DOI]) {
doi = nla_get_u32(info->attrs[NLBL_CIPSOV4_A_DOI]);
ret_val = cipso_v4_doi_remove(doi, netlbl_cipsov4_doi_free);
ret_val = cipso_v4_doi_remove(doi,
NETLINK_CB(skb).sid,
netlbl_cipsov4_doi_free);
}

if (ret_val == 0) {
audit_buf = netlbl_audit_start_common(AUDIT_MAC_CIPSOV4_DEL,
NETLINK_CB(skb).sid);
audit_log_format(audit_buf, " doi=%u", doi);
audit_log_end(audit_buf);
}

return ret_val;
Expand Down
54 changes: 47 additions & 7 deletions net/netlabel/netlabel_domainhash.c
Original file line number Diff line number Diff line change
Expand Up @@ -35,12 +35,14 @@
#include <linux/skbuff.h>
#include <linux/spinlock.h>
#include <linux/string.h>
#include <linux/audit.h>
#include <net/netlabel.h>
#include <net/cipso_ipv4.h>
#include <asm/bug.h>

#include "netlabel_mgmt.h"
#include "netlabel_domainhash.h"
#include "netlabel_user.h"

struct netlbl_domhsh_tbl {
struct list_head *tbl;
Expand Down Expand Up @@ -186,17 +188,20 @@ int netlbl_domhsh_init(u32 size)
/**
* netlbl_domhsh_add - Adds a entry to the domain hash table
* @entry: the entry to add
* @audit_secid: the LSM secid to use in the audit message
*
* Description:
* Adds a new entry to the domain hash table and handles any updates to the
* lower level protocol handler (i.e. CIPSO). Returns zero on success,
* negative on failure.
*
*/
int netlbl_domhsh_add(struct netlbl_dom_map *entry)
int netlbl_domhsh_add(struct netlbl_dom_map *entry, u32 audit_secid)
{
int ret_val;
u32 bkt;
struct audit_buffer *audit_buf;
char *audit_domain;

switch (entry->type) {
case NETLBL_NLTYPE_UNLABELED:
Expand Down Expand Up @@ -236,6 +241,26 @@ int netlbl_domhsh_add(struct netlbl_dom_map *entry)
spin_unlock(&netlbl_domhsh_def_lock);
} else
ret_val = -EINVAL;
if (ret_val == 0) {
if (entry->domain != NULL)
audit_domain = entry->domain;
else
audit_domain = "(default)";
audit_buf = netlbl_audit_start_common(AUDIT_MAC_MAP_ADD,
audit_secid);
audit_log_format(audit_buf, " domain=%s", audit_domain);
switch (entry->type) {
case NETLBL_NLTYPE_UNLABELED:
audit_log_format(audit_buf, " protocol=unlbl");
break;
case NETLBL_NLTYPE_CIPSOV4:
audit_log_format(audit_buf,
" protocol=cipsov4 doi=%u",
entry->type_def.cipsov4->doi);
break;
}
audit_log_end(audit_buf);
}
rcu_read_unlock();

if (ret_val != 0) {
Expand All @@ -254,32 +279,36 @@ int netlbl_domhsh_add(struct netlbl_dom_map *entry)
/**
* netlbl_domhsh_add_default - Adds the default entry to the domain hash table
* @entry: the entry to add
* @audit_secid: the LSM secid to use in the audit message
*
* Description:
* Adds a new default entry to the domain hash table and handles any updates
* to the lower level protocol handler (i.e. CIPSO). Returns zero on success,
* negative on failure.
*
*/
int netlbl_domhsh_add_default(struct netlbl_dom_map *entry)
int netlbl_domhsh_add_default(struct netlbl_dom_map *entry, u32 audit_secid)
{
return netlbl_domhsh_add(entry);
return netlbl_domhsh_add(entry, audit_secid);
}

/**
* netlbl_domhsh_remove - Removes an entry from the domain hash table
* @domain: the domain to remove
* @audit_secid: the LSM secid to use in the audit message
*
* Description:
* Removes an entry from the domain hash table and handles any updates to the
* lower level protocol handler (i.e. CIPSO). Returns zero on success,
* negative on failure.
*
*/
int netlbl_domhsh_remove(const char *domain)
int netlbl_domhsh_remove(const char *domain, u32 audit_secid)
{
int ret_val = -ENOENT;
struct netlbl_dom_map *entry;
struct audit_buffer *audit_buf;
char *audit_domain;

rcu_read_lock();
if (domain != NULL)
Expand Down Expand Up @@ -316,8 +345,18 @@ int netlbl_domhsh_remove(const char *domain)
ret_val = -ENOENT;
spin_unlock(&netlbl_domhsh_def_lock);
}
if (ret_val == 0)
if (ret_val == 0) {
if (entry->domain != NULL)
audit_domain = entry->domain;
else
audit_domain = "(default)";
audit_buf = netlbl_audit_start_common(AUDIT_MAC_MAP_DEL,
audit_secid);
audit_log_format(audit_buf, " domain=%s", audit_domain);
audit_log_end(audit_buf);

call_rcu(&entry->rcu, netlbl_domhsh_free_entry);
}

remove_return:
rcu_read_unlock();
Expand All @@ -326,16 +365,17 @@ int netlbl_domhsh_remove(const char *domain)

/**
* netlbl_domhsh_remove_default - Removes the default entry from the table
* @audit_secid: the LSM secid to use in the audit message
*
* Description:
* Removes/resets the default entry for the domain hash table and handles any
* updates to the lower level protocol handler (i.e. CIPSO). Returns zero on
* success, non-zero on failure.
*
*/
int netlbl_domhsh_remove_default(void)
int netlbl_domhsh_remove_default(u32 audit_secid)
{
return netlbl_domhsh_remove(NULL);
return netlbl_domhsh_remove(NULL, audit_secid);
}

/**
Expand Down
6 changes: 3 additions & 3 deletions net/netlabel/netlabel_domainhash.h
Original file line number Diff line number Diff line change
Expand Up @@ -57,9 +57,9 @@ struct netlbl_dom_map {
int netlbl_domhsh_init(u32 size);

/* Manipulate the domain hash table */
int netlbl_domhsh_add(struct netlbl_dom_map *entry);
int netlbl_domhsh_add_default(struct netlbl_dom_map *entry);
int netlbl_domhsh_remove_default(void);
int netlbl_domhsh_add(struct netlbl_dom_map *entry, u32 audit_secid);
int netlbl_domhsh_add_default(struct netlbl_dom_map *entry, u32 audit_secid);
int netlbl_domhsh_remove_default(u32 audit_secid);
struct netlbl_dom_map *netlbl_domhsh_getentry(const char *domain);
int netlbl_domhsh_walk(u32 *skip_bkt,
u32 *skip_chain,
Expand Down
14 changes: 8 additions & 6 deletions net/netlabel/netlabel_mgmt.c
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ static int netlbl_mgmt_add(struct sk_buff *skb, struct genl_info *info)

switch (entry->type) {
case NETLBL_NLTYPE_UNLABELED:
ret_val = netlbl_domhsh_add(entry);
ret_val = netlbl_domhsh_add(entry, NETLINK_CB(skb).sid);
break;
case NETLBL_NLTYPE_CIPSOV4:
if (!info->attrs[NLBL_MGMT_A_CV4DOI])
Expand All @@ -125,7 +125,7 @@ static int netlbl_mgmt_add(struct sk_buff *skb, struct genl_info *info)
rcu_read_unlock();
goto add_failure;
}
ret_val = netlbl_domhsh_add(entry);
ret_val = netlbl_domhsh_add(entry, NETLINK_CB(skb).sid);
rcu_read_unlock();
break;
default:
Expand Down Expand Up @@ -161,7 +161,7 @@ static int netlbl_mgmt_remove(struct sk_buff *skb, struct genl_info *info)
return -EINVAL;

domain = nla_data(info->attrs[NLBL_MGMT_A_DOMAIN]);
return netlbl_domhsh_remove(domain);
return netlbl_domhsh_remove(domain, NETLINK_CB(skb).sid);
}

/**
Expand Down Expand Up @@ -277,7 +277,8 @@ static int netlbl_mgmt_adddef(struct sk_buff *skb, struct genl_info *info)

switch (entry->type) {
case NETLBL_NLTYPE_UNLABELED:
ret_val = netlbl_domhsh_add_default(entry);
ret_val = netlbl_domhsh_add_default(entry,
NETLINK_CB(skb).sid);
break;
case NETLBL_NLTYPE_CIPSOV4:
if (!info->attrs[NLBL_MGMT_A_CV4DOI])
Expand All @@ -294,7 +295,8 @@ static int netlbl_mgmt_adddef(struct sk_buff *skb, struct genl_info *info)
rcu_read_unlock();
goto adddef_failure;
}
ret_val = netlbl_domhsh_add_default(entry);
ret_val = netlbl_domhsh_add_default(entry,
NETLINK_CB(skb).sid);
rcu_read_unlock();
break;
default:
Expand Down Expand Up @@ -322,7 +324,7 @@ static int netlbl_mgmt_adddef(struct sk_buff *skb, struct genl_info *info)
*/
static int netlbl_mgmt_removedef(struct sk_buff *skb, struct genl_info *info)
{
return netlbl_domhsh_remove_default();
return netlbl_domhsh_remove_default(NETLINK_CB(skb).sid);
}

/**
Expand Down
Loading

0 comments on commit 32f50cd

Please sign in to comment.