@@ -2383,38 +2383,31 @@ static struct smack_known *smack_ipv6host_label(struct sockaddr_in6 *sip)
23832383}
23842384
23852385/**
2386- * smack_netlabel - Set the secattr on a socket
2386+ * smack_netlbl_add - Set the secattr on a socket
23872387 * @sk: the socket
2388- * @labeled: socket label scheme
23892388 *
2390- * Convert the outbound smack value (smk_out) to a
2391- * secattr and attach it to the socket.
2389+ * Attach the outbound smack value (smk_out) to the socket.
23922390 *
23932391 * Returns 0 on success or an error code
23942392 */
2395- static int smack_netlabel (struct sock * sk , int labeled )
2393+ static int smack_netlbl_add (struct sock * sk )
23962394{
2397- struct smack_known * skp ;
23982395 struct socket_smack * ssp = sk -> sk_security ;
2399- int rc = 0 ;
2396+ struct smack_known * skp = ssp -> smk_out ;
2397+ int rc ;
24002398
2401- /*
2402- * Usually the netlabel code will handle changing the
2403- * packet labeling based on the label.
2404- * The case of a single label host is different, because
2405- * a single label host should never get a labeled packet
2406- * even though the label is usually associated with a packet
2407- * label.
2408- */
24092399 local_bh_disable ();
24102400 bh_lock_sock_nested (sk );
24112401
2412- if (ssp -> smk_out == smack_net_ambient ||
2413- labeled == SMACK_UNLABELED_SOCKET )
2414- netlbl_sock_delattr (sk );
2415- else {
2416- skp = ssp -> smk_out ;
2417- rc = netlbl_sock_setattr (sk , sk -> sk_family , & skp -> smk_netlabel );
2402+ rc = netlbl_sock_setattr (sk , sk -> sk_family , & skp -> smk_netlabel );
2403+ switch (rc ) {
2404+ case 0 :
2405+ ssp -> smk_state = SMK_NETLBL_LABELED ;
2406+ break ;
2407+ case - EDESTADDRREQ :
2408+ ssp -> smk_state = SMK_NETLBL_REQSKB ;
2409+ rc = 0 ;
2410+ break ;
24182411 }
24192412
24202413 bh_unlock_sock (sk );
@@ -2424,7 +2417,31 @@ static int smack_netlabel(struct sock *sk, int labeled)
24242417}
24252418
24262419/**
2427- * smack_netlbel_send - Set the secattr on a socket and perform access checks
2420+ * smack_netlbl_delete - Remove the secattr from a socket
2421+ * @sk: the socket
2422+ *
2423+ * Remove the outbound smack value from a socket
2424+ */
2425+ static void smack_netlbl_delete (struct sock * sk )
2426+ {
2427+ struct socket_smack * ssp = sk -> sk_security ;
2428+
2429+ /*
2430+ * Take the label off the socket if one is set.
2431+ */
2432+ if (ssp -> smk_state != SMK_NETLBL_LABELED )
2433+ return ;
2434+
2435+ local_bh_disable ();
2436+ bh_lock_sock_nested (sk );
2437+ netlbl_sock_delattr (sk );
2438+ bh_unlock_sock (sk );
2439+ local_bh_enable ();
2440+ ssp -> smk_state = SMK_NETLBL_UNLABELED ;
2441+ }
2442+
2443+ /**
2444+ * smk_ipv4_check - Perform IPv4 host access checks
24282445 * @sk: the socket
24292446 * @sap: the destination address
24302447 *
@@ -2434,11 +2451,10 @@ static int smack_netlabel(struct sock *sk, int labeled)
24342451 * Returns 0 on success or an error code.
24352452 *
24362453 */
2437- static int smack_netlabel_send (struct sock * sk , struct sockaddr_in * sap )
2454+ static int smk_ipv4_check (struct sock * sk , struct sockaddr_in * sap )
24382455{
24392456 struct smack_known * skp ;
2440- int rc ;
2441- int sk_lbl ;
2457+ int rc = 0 ;
24422458 struct smack_known * hkp ;
24432459 struct socket_smack * ssp = sk -> sk_security ;
24442460 struct smk_audit_info ad ;
@@ -2454,19 +2470,18 @@ static int smack_netlabel_send(struct sock *sk, struct sockaddr_in *sap)
24542470 ad .a .u .net -> dport = sap -> sin_port ;
24552471 ad .a .u .net -> v4info .daddr = sap -> sin_addr .s_addr ;
24562472#endif
2457- sk_lbl = SMACK_UNLABELED_SOCKET ;
24582473 skp = ssp -> smk_out ;
24592474 rc = smk_access (skp , hkp , MAY_WRITE , & ad );
24602475 rc = smk_bu_note ("IPv4 host check" , skp , hkp , MAY_WRITE , rc );
2461- } else {
2462- sk_lbl = SMACK_CIPSO_SOCKET ;
2463- rc = 0 ;
2476+ /*
2477+ * Clear the socket netlabel if it's set.
2478+ */
2479+ if (!rc )
2480+ smack_netlbl_delete (sk );
24642481 }
24652482 rcu_read_unlock ();
2466- if (rc != 0 )
2467- return rc ;
24682483
2469- return smack_netlabel ( sk , sk_lbl ) ;
2484+ return rc ;
24702485}
24712486
24722487/**
@@ -2703,7 +2718,7 @@ static int smack_inode_setsecurity(struct inode *inode, const char *name,
27032718 else if (strcmp (name , XATTR_SMACK_IPOUT ) == 0 ) {
27042719 ssp -> smk_out = skp ;
27052720 if (sock -> sk -> sk_family == PF_INET ) {
2706- rc = smack_netlabel (sock -> sk , SMACK_CIPSO_SOCKET );
2721+ rc = smack_netlbl_add (sock -> sk );
27072722 if (rc != 0 )
27082723 printk (KERN_WARNING
27092724 "Smack: \"%s\" netlbl error %d.\n" ,
@@ -2754,7 +2769,7 @@ static int smack_socket_post_create(struct socket *sock, int family,
27542769 /*
27552770 * Set the outbound netlbl.
27562771 */
2757- return smack_netlabel (sock -> sk , SMACK_CIPSO_SOCKET );
2772+ return smack_netlbl_add (sock -> sk );
27582773}
27592774
27602775/**
@@ -2845,7 +2860,7 @@ static int smack_socket_connect(struct socket *sock, struct sockaddr *sap,
28452860 }
28462861 if (sap -> sa_family != AF_INET || addrlen < sizeof (struct sockaddr_in ))
28472862 return 0 ;
2848- rc = smack_netlabel_send (sock -> sk , (struct sockaddr_in * )sap );
2863+ rc = smk_ipv4_check (sock -> sk , (struct sockaddr_in * )sap );
28492864 return rc ;
28502865}
28512866
@@ -3663,7 +3678,7 @@ static int smack_socket_sendmsg(struct socket *sock, struct msghdr *msg,
36633678 if (msg -> msg_namelen < sizeof (struct sockaddr_in ) ||
36643679 sip -> sin_family != AF_INET )
36653680 return - EINVAL ;
3666- rc = smack_netlabel_send (sock -> sk , sip );
3681+ rc = smk_ipv4_check (sock -> sk , sip );
36673682 break ;
36683683#if IS_ENABLED (CONFIG_IPV6 )
36693684 case AF_INET6 :
@@ -3824,6 +3839,33 @@ static struct smack_known *smack_from_skb(struct sk_buff *skb)
38243839 return smack_from_secid (skb -> secmark );
38253840}
38263841
3842+ /**
3843+ * smack_from_netlbl - Smack data from the IP options in an skb
3844+ * @sk: socket data came in on
3845+ * @family: address family
3846+ * @skb: packet
3847+ *
3848+ * Returns smack_known of the IP options or NULL if that won't work.
3849+ */
3850+ static struct smack_known * smack_from_netlbl (struct sock * sk , u16 family ,
3851+ struct sk_buff * skb )
3852+ {
3853+ struct netlbl_lsm_secattr secattr ;
3854+ struct socket_smack * ssp = NULL ;
3855+ struct smack_known * skp = NULL ;
3856+
3857+ netlbl_secattr_init (& secattr );
3858+
3859+ if (sk )
3860+ ssp = sk -> sk_security ;
3861+ if (netlbl_skbuff_getattr (skb , family , & secattr ) == 0 )
3862+ skp = smack_from_secattr (& secattr , ssp );
3863+
3864+ netlbl_secattr_destroy (& secattr );
3865+
3866+ return skp ;
3867+ }
3868+
38273869/**
38283870 * smack_socket_sock_rcv_skb - Smack packet delivery access check
38293871 * @sk: socket
@@ -3833,7 +3875,6 @@ static struct smack_known *smack_from_skb(struct sk_buff *skb)
38333875 */
38343876static int smack_socket_sock_rcv_skb (struct sock * sk , struct sk_buff * skb )
38353877{
3836- struct netlbl_lsm_secattr secattr ;
38373878 struct socket_smack * ssp = sk -> sk_security ;
38383879 struct smack_known * skp = NULL ;
38393880 int rc = 0 ;
@@ -3858,22 +3899,11 @@ static int smack_socket_sock_rcv_skb(struct sock *sk, struct sk_buff *skb)
38583899 * The secmark is assumed to reflect policy better.
38593900 */
38603901 skp = smack_from_skb (skb );
3861- if (skp )
3862- goto access_check ;
3863- /*
3864- * Translate what netlabel gave us.
3865- */
3866- netlbl_secattr_init (& secattr );
3867-
3868- rc = netlbl_skbuff_getattr (skb , family , & secattr );
3869- if (rc == 0 )
3870- skp = smack_from_secattr (& secattr , ssp );
3871- else
3872- skp = smack_net_ambient ;
3873-
3874- netlbl_secattr_destroy (& secattr );
3875-
3876- access_check :
3902+ if (skp == NULL ) {
3903+ skp = smack_from_netlbl (sk , family , skb );
3904+ if (skp == NULL )
3905+ skp = smack_net_ambient ;
3906+ }
38773907
38783908#ifdef CONFIG_AUDIT
38793909 smk_ad_init_net (& ad , __func__ , LSM_AUDIT_DATA_NET , & net );
@@ -3979,12 +4009,11 @@ static int smack_socket_getpeersec_dgram(struct socket *sock,
39794009 struct sk_buff * skb , u32 * secid )
39804010
39814011{
3982- struct netlbl_lsm_secattr secattr ;
39834012 struct socket_smack * ssp = NULL ;
39844013 struct smack_known * skp ;
4014+ struct sock * sk = NULL ;
39854015 int family = PF_UNSPEC ;
39864016 u32 s = 0 ; /* 0 is the invalid secid */
3987- int rc ;
39884017
39894018 if (skb != NULL ) {
39904019 if (skb -> protocol == htons (ETH_P_IP ))
@@ -4011,15 +4040,11 @@ static int smack_socket_getpeersec_dgram(struct socket *sock,
40114040 /*
40124041 * Translate what netlabel gave us.
40134042 */
4014- if (sock != NULL && sock -> sk != NULL )
4015- ssp = sock -> sk -> sk_security ;
4016- netlbl_secattr_init (& secattr );
4017- rc = netlbl_skbuff_getattr (skb , family , & secattr );
4018- if (rc == 0 ) {
4019- skp = smack_from_secattr (& secattr , ssp );
4043+ if (sock != NULL )
4044+ sk = sock -> sk ;
4045+ skp = smack_from_netlbl (sk , family , skb );
4046+ if (skp != NULL )
40204047 s = skp -> smk_secid ;
4021- }
4022- netlbl_secattr_destroy (& secattr );
40234048 break ;
40244049 case PF_INET6 :
40254050#ifdef SMACK_IPV6_SECMARK_LABELING
@@ -4073,7 +4098,6 @@ static int smack_inet_conn_request(struct sock *sk, struct sk_buff *skb,
40734098 u16 family = sk -> sk_family ;
40744099 struct smack_known * skp ;
40754100 struct socket_smack * ssp = sk -> sk_security ;
4076- struct netlbl_lsm_secattr secattr ;
40774101 struct sockaddr_in addr ;
40784102 struct iphdr * hdr ;
40794103 struct smack_known * hskp ;
@@ -4103,18 +4127,11 @@ static int smack_inet_conn_request(struct sock *sk, struct sk_buff *skb,
41034127 * The secmark is assumed to reflect policy better.
41044128 */
41054129 skp = smack_from_skb (skb );
4106- if (skp )
4107- goto access_check ;
4108-
4109- netlbl_secattr_init (& secattr );
4110- rc = netlbl_skbuff_getattr (skb , family , & secattr );
4111- if (rc == 0 )
4112- skp = smack_from_secattr (& secattr , ssp );
4113- else
4114- skp = & smack_known_huh ;
4115- netlbl_secattr_destroy (& secattr );
4116-
4117- access_check :
4130+ if (skp == NULL ) {
4131+ skp = smack_from_netlbl (sk , family , skb );
4132+ if (skp == NULL )
4133+ skp = & smack_known_huh ;
4134+ }
41184135
41194136#ifdef CONFIG_AUDIT
41204137 smk_ad_init_net (& ad , __func__ , LSM_AUDIT_DATA_NET , & net );
0 commit comments