diff options
Diffstat (limited to 'net/netlabel/netlabel_unlabeled.c')
-rw-r--r-- | net/netlabel/netlabel_unlabeled.c | 48 |
1 files changed, 31 insertions, 17 deletions
diff --git a/net/netlabel/netlabel_unlabeled.c b/net/netlabel/netlabel_unlabeled.c index 1833ad233b39..5bc37181662e 100644 --- a/net/netlabel/netlabel_unlabeled.c +++ b/net/netlabel/netlabel_unlabeled.c | |||
@@ -35,6 +35,7 @@ | |||
35 | #include <linux/socket.h> | 35 | #include <linux/socket.h> |
36 | #include <linux/string.h> | 36 | #include <linux/string.h> |
37 | #include <linux/skbuff.h> | 37 | #include <linux/skbuff.h> |
38 | #include <linux/audit.h> | ||
38 | #include <net/sock.h> | 39 | #include <net/sock.h> |
39 | #include <net/netlink.h> | 40 | #include <net/netlink.h> |
40 | #include <net/genetlink.h> | 41 | #include <net/genetlink.h> |
@@ -47,7 +48,8 @@ | |||
47 | #include "netlabel_unlabeled.h" | 48 | #include "netlabel_unlabeled.h" |
48 | 49 | ||
49 | /* Accept unlabeled packets flag */ | 50 | /* Accept unlabeled packets flag */ |
50 | static atomic_t netlabel_unlabel_accept_flg = ATOMIC_INIT(0); | 51 | static DEFINE_SPINLOCK(netlabel_unlabel_acceptflg_lock); |
52 | static u8 netlabel_unlabel_acceptflg = 0; | ||
51 | 53 | ||
52 | /* NetLabel Generic NETLINK CIPSOv4 family */ | 54 | /* NetLabel Generic NETLINK CIPSOv4 family */ |
53 | static struct genl_family netlbl_unlabel_gnl_family = { | 55 | static struct genl_family netlbl_unlabel_gnl_family = { |
@@ -82,13 +84,20 @@ static void netlbl_unlabel_acceptflg_set(u8 value, | |||
82 | struct audit_buffer *audit_buf; | 84 | struct audit_buffer *audit_buf; |
83 | u8 old_val; | 85 | u8 old_val; |
84 | 86 | ||
85 | old_val = atomic_read(&netlabel_unlabel_accept_flg); | 87 | rcu_read_lock(); |
86 | atomic_set(&netlabel_unlabel_accept_flg, value); | 88 | old_val = netlabel_unlabel_acceptflg; |
89 | spin_lock(&netlabel_unlabel_acceptflg_lock); | ||
90 | netlabel_unlabel_acceptflg = value; | ||
91 | spin_unlock(&netlabel_unlabel_acceptflg_lock); | ||
92 | rcu_read_unlock(); | ||
87 | 93 | ||
88 | audit_buf = netlbl_audit_start_common(AUDIT_MAC_UNLBL_ALLOW, | 94 | audit_buf = netlbl_audit_start_common(AUDIT_MAC_UNLBL_ALLOW, |
89 | audit_info); | 95 | audit_info); |
90 | audit_log_format(audit_buf, " unlbl_accept=%u old=%u", value, old_val); | 96 | if (audit_buf != NULL) { |
91 | audit_log_end(audit_buf); | 97 | audit_log_format(audit_buf, |
98 | " unlbl_accept=%u old=%u", value, old_val); | ||
99 | audit_log_end(audit_buf); | ||
100 | } | ||
92 | } | 101 | } |
93 | 102 | ||
94 | /* | 103 | /* |
@@ -138,29 +147,27 @@ static int netlbl_unlabel_list(struct sk_buff *skb, struct genl_info *info) | |||
138 | struct sk_buff *ans_skb; | 147 | struct sk_buff *ans_skb; |
139 | void *data; | 148 | void *data; |
140 | 149 | ||
141 | ans_skb = nlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL); | 150 | ans_skb = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); |
142 | if (ans_skb == NULL) | 151 | if (ans_skb == NULL) |
143 | goto list_failure; | 152 | goto list_failure; |
144 | data = netlbl_netlink_hdr_put(ans_skb, | 153 | data = genlmsg_put_reply(ans_skb, info, &netlbl_unlabel_gnl_family, |
145 | info->snd_pid, | 154 | 0, NLBL_UNLABEL_C_LIST); |
146 | info->snd_seq, | ||
147 | netlbl_unlabel_gnl_family.id, | ||
148 | 0, | ||
149 | NLBL_UNLABEL_C_LIST); | ||
150 | if (data == NULL) { | 155 | if (data == NULL) { |
151 | ret_val = -ENOMEM; | 156 | ret_val = -ENOMEM; |
152 | goto list_failure; | 157 | goto list_failure; |
153 | } | 158 | } |
154 | 159 | ||
160 | rcu_read_lock(); | ||
155 | ret_val = nla_put_u8(ans_skb, | 161 | ret_val = nla_put_u8(ans_skb, |
156 | NLBL_UNLABEL_A_ACPTFLG, | 162 | NLBL_UNLABEL_A_ACPTFLG, |
157 | atomic_read(&netlabel_unlabel_accept_flg)); | 163 | netlabel_unlabel_acceptflg); |
164 | rcu_read_unlock(); | ||
158 | if (ret_val != 0) | 165 | if (ret_val != 0) |
159 | goto list_failure; | 166 | goto list_failure; |
160 | 167 | ||
161 | genlmsg_end(ans_skb, data); | 168 | genlmsg_end(ans_skb, data); |
162 | 169 | ||
163 | ret_val = genlmsg_unicast(ans_skb, info->snd_pid); | 170 | ret_val = genlmsg_reply(ans_skb, info); |
164 | if (ret_val != 0) | 171 | if (ret_val != 0) |
165 | goto list_failure; | 172 | goto list_failure; |
166 | return 0; | 173 | return 0; |
@@ -240,10 +247,17 @@ int netlbl_unlabel_genl_init(void) | |||
240 | */ | 247 | */ |
241 | int netlbl_unlabel_getattr(struct netlbl_lsm_secattr *secattr) | 248 | int netlbl_unlabel_getattr(struct netlbl_lsm_secattr *secattr) |
242 | { | 249 | { |
243 | if (atomic_read(&netlabel_unlabel_accept_flg) == 1) | 250 | int ret_val; |
244 | return netlbl_secattr_init(secattr); | ||
245 | 251 | ||
246 | return -ENOMSG; | 252 | rcu_read_lock(); |
253 | if (netlabel_unlabel_acceptflg == 1) { | ||
254 | netlbl_secattr_init(secattr); | ||
255 | ret_val = 0; | ||
256 | } else | ||
257 | ret_val = -ENOMSG; | ||
258 | rcu_read_unlock(); | ||
259 | |||
260 | return ret_val; | ||
247 | } | 261 | } |
248 | 262 | ||
249 | /** | 263 | /** |