2006-08-04 03:48:59 +04:00
/*
* NetLabel Unlabeled Support
*
* This file defines functions for dealing with unlabeled packets for the
* NetLabel system . 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 . , 2006
*
* 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/list.h>
# include <linux/spinlock.h>
# include <linux/socket.h>
# include <linux/string.h>
# include <linux/skbuff.h>
2006-11-18 01:38:55 +03:00
# include <linux/audit.h>
2006-08-04 03:48:59 +04:00
# include <net/sock.h>
# include <net/netlink.h>
# include <net/genetlink.h>
# include <net/netlabel.h>
# include <asm/bug.h>
# include "netlabel_user.h"
# include "netlabel_domainhash.h"
# include "netlabel_unlabeled.h"
/* Accept unlabeled packets flag */
2006-11-18 01:38:44 +03:00
static u8 netlabel_unlabel_acceptflg = 0 ;
2006-08-04 03:48:59 +04:00
/* NetLabel Generic NETLINK CIPSOv4 family */
static struct genl_family netlbl_unlabel_gnl_family = {
. id = GENL_ID_GENERATE ,
. hdrsize = 0 ,
. name = NETLBL_NLTYPE_UNLABELED_NAME ,
. version = NETLBL_PROTO_VERSION ,
2006-09-26 02:56:37 +04:00
. maxattr = NLBL_UNLABEL_A_MAX ,
2006-08-04 03:48:59 +04:00
} ;
2006-09-26 02:56:37 +04:00
/* NetLabel Netlink attribute policy */
2007-06-05 23:38:30 +04:00
static const struct nla_policy netlbl_unlabel_genl_policy [ NLBL_UNLABEL_A_MAX + 1 ] = {
2006-09-26 02:56:37 +04:00
[ NLBL_UNLABEL_A_ACPTFLG ] = { . type = NLA_U8 } ,
} ;
2006-08-04 03:48:59 +04:00
2006-09-29 01:51:47 +04:00
/*
* Helper Functions
*/
/**
* netlbl_unlabel_acceptflg_set - Set the unlabeled accept flag
* @ value : desired value
2006-09-30 04:05:05 +04:00
* @ audit_info : NetLabel audit information
2006-09-29 01:51:47 +04:00
*
* Description :
* Set the value of the unlabeled accept flag to @ value .
*
*/
2006-09-30 04:05:05 +04:00
static void netlbl_unlabel_acceptflg_set ( u8 value ,
struct netlbl_audit * audit_info )
2006-09-29 01:51:47 +04:00
{
2006-09-30 04:05:05 +04:00
struct audit_buffer * audit_buf ;
u8 old_val ;
2007-10-26 15:29:08 +04:00
old_val = netlabel_unlabel_acceptflg ;
2006-11-18 01:38:44 +03:00
netlabel_unlabel_acceptflg = value ;
2006-09-30 04:05:05 +04:00
audit_buf = netlbl_audit_start_common ( AUDIT_MAC_UNLBL_ALLOW ,
audit_info ) ;
2006-11-18 01:38:55 +03:00
if ( audit_buf ! = NULL ) {
audit_log_format ( audit_buf ,
" unlbl_accept=%u old=%u " , value , old_val ) ;
audit_log_end ( audit_buf ) ;
}
2006-09-29 01:51:47 +04:00
}
2006-08-04 03:48:59 +04:00
/*
* NetLabel Command Handlers
*/
/**
* netlbl_unlabel_accept - Handle an ACCEPT message
* @ skb : the NETLINK buffer
* @ info : the Generic NETLINK info block
*
* Description :
* Process a user generated ACCEPT message and set the accept flag accordingly .
* Returns zero on success , negative values on failure .
*
*/
static int netlbl_unlabel_accept ( struct sk_buff * skb , struct genl_info * info )
{
2006-09-26 02:56:37 +04:00
u8 value ;
2006-09-30 04:05:05 +04:00
struct netlbl_audit audit_info ;
2006-08-04 03:48:59 +04:00
2006-09-26 02:56:37 +04:00
if ( info - > attrs [ NLBL_UNLABEL_A_ACPTFLG ] ) {
value = nla_get_u8 ( info - > attrs [ NLBL_UNLABEL_A_ACPTFLG ] ) ;
2006-08-04 03:48:59 +04:00
if ( value = = 1 | | value = = 0 ) {
2006-09-30 04:05:05 +04:00
netlbl_netlink_auditinfo ( skb , & audit_info ) ;
netlbl_unlabel_acceptflg_set ( value , & audit_info ) ;
2006-09-29 01:51:47 +04:00
return 0 ;
2006-08-04 03:48:59 +04:00
}
}
2006-09-29 01:51:47 +04:00
return - EINVAL ;
2006-08-04 03:48:59 +04:00
}
/**
* netlbl_unlabel_list - Handle a LIST message
* @ skb : the NETLINK buffer
* @ info : the Generic NETLINK info block
*
* Description :
* Process a user generated LIST message and respond with the current status .
* Returns zero on success , negative values on failure .
*
*/
static int netlbl_unlabel_list ( struct sk_buff * skb , struct genl_info * info )
{
2006-09-26 02:56:37 +04:00
int ret_val = - EINVAL ;
2006-08-04 03:48:59 +04:00
struct sk_buff * ans_skb ;
2006-09-26 02:56:37 +04:00
void * data ;
2006-08-04 03:48:59 +04:00
2006-11-11 01:10:15 +03:00
ans_skb = nlmsg_new ( NLMSG_DEFAULT_SIZE , GFP_KERNEL ) ;
2006-08-04 03:48:59 +04:00
if ( ans_skb = = NULL )
goto list_failure ;
2006-11-15 06:46:02 +03:00
data = genlmsg_put_reply ( ans_skb , info , & netlbl_unlabel_gnl_family ,
0 , NLBL_UNLABEL_C_LIST ) ;
2006-09-26 02:56:37 +04:00
if ( data = = NULL ) {
ret_val = - ENOMEM ;
2006-08-04 03:48:59 +04:00
goto list_failure ;
2006-09-26 02:56:37 +04:00
}
2006-08-04 03:48:59 +04:00
2006-09-26 02:56:37 +04:00
ret_val = nla_put_u8 ( ans_skb ,
NLBL_UNLABEL_A_ACPTFLG ,
2006-11-18 01:38:44 +03:00
netlabel_unlabel_acceptflg ) ;
2006-08-04 03:48:59 +04:00
if ( ret_val ! = 0 )
goto list_failure ;
2006-09-26 02:56:37 +04:00
genlmsg_end ( ans_skb , data ) ;
2006-11-15 06:45:27 +03:00
ret_val = genlmsg_reply ( ans_skb , info ) ;
2006-08-04 03:48:59 +04:00
if ( ret_val ! = 0 )
goto list_failure ;
return 0 ;
list_failure :
2007-02-27 20:57:37 +03:00
kfree_skb ( ans_skb ) ;
2006-08-04 03:48:59 +04:00
return ret_val ;
}
/*
* NetLabel Generic NETLINK Command Definitions
*/
static struct genl_ops netlbl_unlabel_genl_c_accept = {
. cmd = NLBL_UNLABEL_C_ACCEPT ,
2006-09-26 02:56:37 +04:00
. flags = GENL_ADMIN_PERM ,
. policy = netlbl_unlabel_genl_policy ,
2006-08-04 03:48:59 +04:00
. doit = netlbl_unlabel_accept ,
. dumpit = NULL ,
} ;
static struct genl_ops netlbl_unlabel_genl_c_list = {
. cmd = NLBL_UNLABEL_C_LIST ,
. flags = 0 ,
2006-09-26 02:56:37 +04:00
. policy = netlbl_unlabel_genl_policy ,
2006-08-04 03:48:59 +04:00
. doit = netlbl_unlabel_list ,
. dumpit = NULL ,
} ;
/*
* NetLabel Generic NETLINK Protocol Functions
*/
/**
* netlbl_unlabel_genl_init - Register the Unlabeled NetLabel component
*
* Description :
* Register the unlabeled packet NetLabel component with the Generic NETLINK
* mechanism . Returns zero on success , negative values on failure .
*
*/
int netlbl_unlabel_genl_init ( void )
{
int ret_val ;
ret_val = genl_register_family ( & netlbl_unlabel_gnl_family ) ;
if ( ret_val ! = 0 )
return ret_val ;
ret_val = genl_register_ops ( & netlbl_unlabel_gnl_family ,
& netlbl_unlabel_genl_c_accept ) ;
if ( ret_val ! = 0 )
return ret_val ;
ret_val = genl_register_ops ( & netlbl_unlabel_gnl_family ,
& netlbl_unlabel_genl_c_list ) ;
if ( ret_val ! = 0 )
return ret_val ;
return 0 ;
}
/*
* NetLabel KAPI Hooks
*/
/**
* netlbl_unlabel_getattr - Get the security attributes for an unlabled packet
* @ secattr : the security attributes
*
* Description :
* Determine the security attributes , if any , for an unlabled packet and return
* them in @ secattr . Returns zero on success and negative values on failure .
*
*/
int netlbl_unlabel_getattr ( struct netlbl_lsm_secattr * secattr )
{
2008-01-29 16:37:52 +03:00
if ( netlabel_unlabel_acceptflg = = 0 )
return - ENOMSG ;
netlbl_secattr_init ( secattr ) ;
return 0 ;
2006-08-04 03:48:59 +04:00
}
/**
* netlbl_unlabel_defconf - Set the default config to allow unlabeled packets
*
* Description :
* Set the default NetLabel configuration to allow incoming unlabeled packets
* and to send unlabeled network traffic by default .
*
*/
int netlbl_unlabel_defconf ( void )
{
int ret_val ;
struct netlbl_dom_map * entry ;
2006-09-30 04:05:05 +04:00
struct netlbl_audit audit_info ;
2006-09-29 01:51:47 +04:00
2006-09-30 04:05:05 +04:00
/* Only the kernel is allowed to call this function and the only time
* it is called is at bootup before the audit subsystem is reporting
* messages so don ' t worry to much about these values . */
security_task_getsecid ( current , & audit_info . secid ) ;
audit_info . loginuid = 0 ;
2006-08-04 03:48:59 +04:00
entry = kzalloc ( sizeof ( * entry ) , GFP_KERNEL ) ;
if ( entry = = NULL )
return - ENOMEM ;
entry - > type = NETLBL_NLTYPE_UNLABELED ;
2006-09-30 04:05:05 +04:00
ret_val = netlbl_domhsh_add_default ( entry , & audit_info ) ;
2006-08-04 03:48:59 +04:00
if ( ret_val ! = 0 )
return ret_val ;
2006-09-30 04:05:05 +04:00
netlbl_unlabel_acceptflg_set ( 1 , & audit_info ) ;
2006-08-04 03:48:59 +04:00
return 0 ;
}