@@ -70,6 +70,7 @@ enum smk_inos {
7070static DEFINE_MUTEX (smack_cipso_lock );
7171static DEFINE_MUTEX (smack_ambient_lock );
7272static DEFINE_MUTEX (smk_net4addr_lock );
73+ static DEFINE_MUTEX (smk_cipso_doi_lock );
7374#if IS_ENABLED (CONFIG_IPV6 )
7475static DEFINE_MUTEX (smk_net6addr_lock );
7576#endif /* CONFIG_IPV6 */
@@ -141,7 +142,7 @@ struct smack_parsed_rule {
141142 int smk_access2 ;
142143};
143144
144- static int smk_cipso_doi_value = SMACK_CIPSO_DOI_DEFAULT ;
145+ static u32 smk_cipso_doi_value = CIPSO_V4_DOI_UNKNOWN ;
145146
146147/*
147148 * Values for parsing cipso rules
@@ -663,43 +664,60 @@ static const struct file_operations smk_load_ops = {
663664};
664665
665666/**
666- * smk_cipso_doi - initialize the CIPSO domain
667+ * smk_cipso_doi - set netlabel maps
668+ * @ndoi: new value for our CIPSO DOI
669+ * @gfp_flags: kmalloc allocation context
667670 */
668- static void smk_cipso_doi (void )
671+ static int
672+ smk_cipso_doi (u32 ndoi , gfp_t gfp_flags )
669673{
670- int rc ;
674+ int rc = 0 ;
671675 struct cipso_v4_doi * doip ;
672676 struct netlbl_audit nai ;
673677
674- smk_netlabel_audit_set ( & nai );
678+ mutex_lock ( & smk_cipso_doi_lock );
675679
676- rc = netlbl_cfg_map_del ( NULL , PF_INET , NULL , NULL , & nai );
677- if ( rc != 0 )
678- printk ( KERN_WARNING "%s:%d remove rc = %d\n" ,
679- __func__ , __LINE__ , rc );
680+ if ( smk_cipso_doi_value == ndoi )
681+ goto clr_doi_lock ;
682+
683+ smk_netlabel_audit_set ( & nai );
680684
681- doip = kmalloc (sizeof (struct cipso_v4_doi ), GFP_KERNEL | __GFP_NOFAIL );
685+ doip = kmalloc (sizeof (struct cipso_v4_doi ), gfp_flags );
686+ if (!doip ) {
687+ rc = - ENOMEM ;
688+ goto clr_doi_lock ;
689+ }
682690 doip -> map .std = NULL ;
683- doip -> doi = smk_cipso_doi_value ;
691+ doip -> doi = ndoi ;
684692 doip -> type = CIPSO_V4_MAP_PASS ;
685693 doip -> tags [0 ] = CIPSO_V4_TAG_RBITMAP ;
686694 for (rc = 1 ; rc < CIPSO_V4_TAG_MAXCNT ; rc ++ )
687695 doip -> tags [rc ] = CIPSO_V4_TAG_INVALID ;
688696
689697 rc = netlbl_cfg_cipsov4_add (doip , & nai );
690- if (rc != 0 ) {
691- printk (KERN_WARNING "%s:%d cipso add rc = %d\n" ,
692- __func__ , __LINE__ , rc );
698+ if (rc ) {
693699 kfree (doip );
694- return ;
700+ goto clr_doi_lock ;
695701 }
696- rc = netlbl_cfg_cipsov4_map_add (doip -> doi , NULL , NULL , NULL , & nai );
697- if (rc != 0 ) {
698- printk (KERN_WARNING "%s:%d map add rc = %d\n" ,
699- __func__ , __LINE__ , rc );
700- netlbl_cfg_cipsov4_del (doip -> doi , & nai );
701- return ;
702+
703+ if (smk_cipso_doi_value != CIPSO_V4_DOI_UNKNOWN ) {
704+ rc = netlbl_cfg_map_del (NULL , PF_INET , NULL , NULL , & nai );
705+ if (rc && rc != - ENOENT )
706+ goto clr_ndoi_def ;
707+
708+ netlbl_cfg_cipsov4_del (smk_cipso_doi_value , & nai );
702709 }
710+
711+ rc = netlbl_cfg_cipsov4_map_add (ndoi , NULL , NULL , NULL , & nai );
712+ if (rc ) {
713+ smk_cipso_doi_value = CIPSO_V4_DOI_UNKNOWN ; // no default map
714+ clr_ndoi_def : netlbl_cfg_cipsov4_del (ndoi , & nai );
715+ } else
716+ smk_cipso_doi_value = ndoi ;
717+
718+ clr_doi_lock :
719+ mutex_unlock (& smk_cipso_doi_lock );
720+ return rc ;
703721}
704722
705723/**
@@ -1562,7 +1580,7 @@ static ssize_t smk_read_doi(struct file *filp, char __user *buf,
15621580 if (* ppos != 0 )
15631581 return 0 ;
15641582
1565- sprintf (temp , "%d " , smk_cipso_doi_value );
1583+ sprintf (temp , "%lu " , ( unsigned long ) smk_cipso_doi_value );
15661584 rc = simple_read_from_buffer (buf , count , ppos , temp , strlen (temp ));
15671585
15681586 return rc ;
@@ -1581,7 +1599,7 @@ static ssize_t smk_write_doi(struct file *file, const char __user *buf,
15811599 size_t count , loff_t * ppos )
15821600{
15831601 char temp [80 ];
1584- int i ;
1602+ unsigned long u ;
15851603
15861604 if (!smack_privileged (CAP_MAC_ADMIN ))
15871605 return - EPERM ;
@@ -1594,14 +1612,13 @@ static ssize_t smk_write_doi(struct file *file, const char __user *buf,
15941612
15951613 temp [count ] = '\0' ;
15961614
1597- if (sscanf (temp , "%d" , & i ) != 1 )
1615+ if (kstrtoul (temp , 10 , & u ) )
15981616 return - EINVAL ;
15991617
1600- smk_cipso_doi_value = i ;
1601-
1602- smk_cipso_doi ();
1618+ if (u == CIPSO_V4_DOI_UNKNOWN || u > U32_MAX )
1619+ return - EINVAL ;
16031620
1604- return count ;
1621+ return smk_cipso_doi ( u , GFP_KERNEL ) ? : count ;
16051622}
16061623
16071624static const struct file_operations smk_doi_ops = {
@@ -2982,6 +2999,7 @@ int __init init_smk_fs(void)
29822999{
29833000 int err ;
29843001 int rc ;
3002+ struct netlbl_audit nai ;
29853003
29863004 if (smack_enabled == 0 )
29873005 return 0 ;
@@ -3000,7 +3018,10 @@ int __init init_smk_fs(void)
30003018 }
30013019 }
30023020
3003- smk_cipso_doi ();
3021+ smk_netlabel_audit_set (& nai );
3022+ (void ) netlbl_cfg_map_del (NULL , PF_INET , NULL , NULL , & nai );
3023+ (void ) smk_cipso_doi (SMACK_CIPSO_DOI_DEFAULT ,
3024+ GFP_KERNEL | __GFP_NOFAIL );
30043025 smk_unlbl_ambient (NULL );
30053026
30063027 rc = smack_populate_secattr (& smack_known_floor );
0 commit comments