diff options
Diffstat (limited to 'security/selinux')
-rw-r--r-- | security/selinux/hooks.c | 54 | ||||
-rw-r--r-- | security/selinux/include/netlabel.h | 27 | ||||
-rw-r--r-- | security/selinux/netlabel.c | 186 |
3 files changed, 81 insertions, 186 deletions
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c index 7c52ba243c64..ee2e781d11d7 100644 --- a/security/selinux/hooks.c +++ b/security/selinux/hooks.c | |||
@@ -311,7 +311,7 @@ static int sk_alloc_security(struct sock *sk, int family, gfp_t priority) | |||
311 | ssec->sid = SECINITSID_UNLABELED; | 311 | ssec->sid = SECINITSID_UNLABELED; |
312 | sk->sk_security = ssec; | 312 | sk->sk_security = ssec; |
313 | 313 | ||
314 | selinux_netlbl_sk_security_reset(ssec, family); | 314 | selinux_netlbl_sk_security_reset(ssec); |
315 | 315 | ||
316 | return 0; | 316 | return 0; |
317 | } | 317 | } |
@@ -2945,7 +2945,6 @@ static void selinux_inode_getsecid(const struct inode *inode, u32 *secid) | |||
2945 | static int selinux_revalidate_file_permission(struct file *file, int mask) | 2945 | static int selinux_revalidate_file_permission(struct file *file, int mask) |
2946 | { | 2946 | { |
2947 | const struct cred *cred = current_cred(); | 2947 | const struct cred *cred = current_cred(); |
2948 | int rc; | ||
2949 | struct inode *inode = file->f_path.dentry->d_inode; | 2948 | struct inode *inode = file->f_path.dentry->d_inode; |
2950 | 2949 | ||
2951 | if (!mask) { | 2950 | if (!mask) { |
@@ -2957,29 +2956,15 @@ static int selinux_revalidate_file_permission(struct file *file, int mask) | |||
2957 | if ((file->f_flags & O_APPEND) && (mask & MAY_WRITE)) | 2956 | if ((file->f_flags & O_APPEND) && (mask & MAY_WRITE)) |
2958 | mask |= MAY_APPEND; | 2957 | mask |= MAY_APPEND; |
2959 | 2958 | ||
2960 | rc = file_has_perm(cred, file, | 2959 | return file_has_perm(cred, file, |
2961 | file_mask_to_av(inode->i_mode, mask)); | 2960 | file_mask_to_av(inode->i_mode, mask)); |
2962 | if (rc) | ||
2963 | return rc; | ||
2964 | |||
2965 | return selinux_netlbl_inode_permission(inode, mask); | ||
2966 | } | 2961 | } |
2967 | 2962 | ||
2968 | static int selinux_file_permission(struct file *file, int mask) | 2963 | static int selinux_file_permission(struct file *file, int mask) |
2969 | { | 2964 | { |
2970 | struct inode *inode = file->f_path.dentry->d_inode; | 2965 | if (!mask) |
2971 | struct file_security_struct *fsec = file->f_security; | ||
2972 | struct inode_security_struct *isec = inode->i_security; | ||
2973 | u32 sid = current_sid(); | ||
2974 | |||
2975 | if (!mask) { | ||
2976 | /* No permission to check. Existence test. */ | 2966 | /* No permission to check. Existence test. */ |
2977 | return 0; | 2967 | return 0; |
2978 | } | ||
2979 | |||
2980 | if (sid == fsec->sid && fsec->isid == isec->sid | ||
2981 | && fsec->pseqno == avc_policy_seqno()) | ||
2982 | return selinux_netlbl_inode_permission(inode, mask); | ||
2983 | 2968 | ||
2984 | return selinux_revalidate_file_permission(file, mask); | 2969 | return selinux_revalidate_file_permission(file, mask); |
2985 | } | 2970 | } |
@@ -3723,7 +3708,7 @@ static int selinux_socket_post_create(struct socket *sock, int family, | |||
3723 | sksec = sock->sk->sk_security; | 3708 | sksec = sock->sk->sk_security; |
3724 | sksec->sid = isec->sid; | 3709 | sksec->sid = isec->sid; |
3725 | sksec->sclass = isec->sclass; | 3710 | sksec->sclass = isec->sclass; |
3726 | err = selinux_netlbl_socket_post_create(sock); | 3711 | err = selinux_netlbl_socket_post_create(sock->sk, family); |
3727 | } | 3712 | } |
3728 | 3713 | ||
3729 | return err; | 3714 | return err; |
@@ -3914,13 +3899,7 @@ static int selinux_socket_accept(struct socket *sock, struct socket *newsock) | |||
3914 | static int selinux_socket_sendmsg(struct socket *sock, struct msghdr *msg, | 3899 | static int selinux_socket_sendmsg(struct socket *sock, struct msghdr *msg, |
3915 | int size) | 3900 | int size) |
3916 | { | 3901 | { |
3917 | int rc; | 3902 | return socket_has_perm(current, sock, SOCKET__WRITE); |
3918 | |||
3919 | rc = socket_has_perm(current, sock, SOCKET__WRITE); | ||
3920 | if (rc) | ||
3921 | return rc; | ||
3922 | |||
3923 | return selinux_netlbl_inode_permission(SOCK_INODE(sock), MAY_WRITE); | ||
3924 | } | 3903 | } |
3925 | 3904 | ||
3926 | static int selinux_socket_recvmsg(struct socket *sock, struct msghdr *msg, | 3905 | static int selinux_socket_recvmsg(struct socket *sock, struct msghdr *msg, |
@@ -4304,7 +4283,7 @@ static void selinux_sk_clone_security(const struct sock *sk, struct sock *newsk) | |||
4304 | newssec->peer_sid = ssec->peer_sid; | 4283 | newssec->peer_sid = ssec->peer_sid; |
4305 | newssec->sclass = ssec->sclass; | 4284 | newssec->sclass = ssec->sclass; |
4306 | 4285 | ||
4307 | selinux_netlbl_sk_security_reset(newssec, newsk->sk_family); | 4286 | selinux_netlbl_sk_security_reset(newssec); |
4308 | } | 4287 | } |
4309 | 4288 | ||
4310 | static void selinux_sk_getsecid(struct sock *sk, u32 *secid) | 4289 | static void selinux_sk_getsecid(struct sock *sk, u32 *secid) |
@@ -4348,16 +4327,15 @@ static int selinux_inet_conn_request(struct sock *sk, struct sk_buff *skb, | |||
4348 | if (peersid == SECSID_NULL) { | 4327 | if (peersid == SECSID_NULL) { |
4349 | req->secid = sksec->sid; | 4328 | req->secid = sksec->sid; |
4350 | req->peer_secid = SECSID_NULL; | 4329 | req->peer_secid = SECSID_NULL; |
4351 | return 0; | 4330 | } else { |
4331 | err = security_sid_mls_copy(sksec->sid, peersid, &newsid); | ||
4332 | if (err) | ||
4333 | return err; | ||
4334 | req->secid = newsid; | ||
4335 | req->peer_secid = peersid; | ||
4352 | } | 4336 | } |
4353 | 4337 | ||
4354 | err = security_sid_mls_copy(sksec->sid, peersid, &newsid); | 4338 | return selinux_netlbl_inet_conn_request(req, family); |
4355 | if (err) | ||
4356 | return err; | ||
4357 | |||
4358 | req->secid = newsid; | ||
4359 | req->peer_secid = peersid; | ||
4360 | return 0; | ||
4361 | } | 4339 | } |
4362 | 4340 | ||
4363 | static void selinux_inet_csk_clone(struct sock *newsk, | 4341 | static void selinux_inet_csk_clone(struct sock *newsk, |
@@ -4374,7 +4352,7 @@ static void selinux_inet_csk_clone(struct sock *newsk, | |||
4374 | 4352 | ||
4375 | /* We don't need to take any sort of lock here as we are the only | 4353 | /* We don't need to take any sort of lock here as we are the only |
4376 | * thread with access to newsksec */ | 4354 | * thread with access to newsksec */ |
4377 | selinux_netlbl_sk_security_reset(newsksec, req->rsk_ops->family); | 4355 | selinux_netlbl_inet_csk_clone(newsk, req->rsk_ops->family); |
4378 | } | 4356 | } |
4379 | 4357 | ||
4380 | static void selinux_inet_conn_established(struct sock *sk, struct sk_buff *skb) | 4358 | static void selinux_inet_conn_established(struct sock *sk, struct sk_buff *skb) |
@@ -4387,8 +4365,6 @@ static void selinux_inet_conn_established(struct sock *sk, struct sk_buff *skb) | |||
4387 | family = PF_INET; | 4365 | family = PF_INET; |
4388 | 4366 | ||
4389 | selinux_skb_peerlbl_sid(skb, family, &sksec->peer_sid); | 4367 | selinux_skb_peerlbl_sid(skb, family, &sksec->peer_sid); |
4390 | |||
4391 | selinux_netlbl_inet_conn_established(sk, family); | ||
4392 | } | 4368 | } |
4393 | 4369 | ||
4394 | static void selinux_req_classify_flow(const struct request_sock *req, | 4370 | static void selinux_req_classify_flow(const struct request_sock *req, |
diff --git a/security/selinux/include/netlabel.h b/security/selinux/include/netlabel.h index b913c8d06038..b4b5b9b2f0be 100644 --- a/security/selinux/include/netlabel.h +++ b/security/selinux/include/netlabel.h | |||
@@ -32,6 +32,7 @@ | |||
32 | #include <linux/net.h> | 32 | #include <linux/net.h> |
33 | #include <linux/skbuff.h> | 33 | #include <linux/skbuff.h> |
34 | #include <net/sock.h> | 34 | #include <net/sock.h> |
35 | #include <net/request_sock.h> | ||
35 | 36 | ||
36 | #include "avc.h" | 37 | #include "avc.h" |
37 | #include "objsec.h" | 38 | #include "objsec.h" |
@@ -42,8 +43,7 @@ void selinux_netlbl_cache_invalidate(void); | |||
42 | void selinux_netlbl_err(struct sk_buff *skb, int error, int gateway); | 43 | void selinux_netlbl_err(struct sk_buff *skb, int error, int gateway); |
43 | 44 | ||
44 | void selinux_netlbl_sk_security_free(struct sk_security_struct *ssec); | 45 | void selinux_netlbl_sk_security_free(struct sk_security_struct *ssec); |
45 | void selinux_netlbl_sk_security_reset(struct sk_security_struct *ssec, | 46 | void selinux_netlbl_sk_security_reset(struct sk_security_struct *ssec); |
46 | int family); | ||
47 | 47 | ||
48 | int selinux_netlbl_skbuff_getsid(struct sk_buff *skb, | 48 | int selinux_netlbl_skbuff_getsid(struct sk_buff *skb, |
49 | u16 family, | 49 | u16 family, |
@@ -53,9 +53,9 @@ int selinux_netlbl_skbuff_setsid(struct sk_buff *skb, | |||
53 | u16 family, | 53 | u16 family, |
54 | u32 sid); | 54 | u32 sid); |
55 | 55 | ||
56 | void selinux_netlbl_inet_conn_established(struct sock *sk, u16 family); | 56 | int selinux_netlbl_inet_conn_request(struct request_sock *req, u16 family); |
57 | int selinux_netlbl_socket_post_create(struct socket *sock); | 57 | void selinux_netlbl_inet_csk_clone(struct sock *sk, u16 family); |
58 | int selinux_netlbl_inode_permission(struct inode *inode, int mask); | 58 | int selinux_netlbl_socket_post_create(struct sock *sk, u16 family); |
59 | int selinux_netlbl_sock_rcv_skb(struct sk_security_struct *sksec, | 59 | int selinux_netlbl_sock_rcv_skb(struct sk_security_struct *sksec, |
60 | struct sk_buff *skb, | 60 | struct sk_buff *skb, |
61 | u16 family, | 61 | u16 family, |
@@ -85,8 +85,7 @@ static inline void selinux_netlbl_sk_security_free( | |||
85 | } | 85 | } |
86 | 86 | ||
87 | static inline void selinux_netlbl_sk_security_reset( | 87 | static inline void selinux_netlbl_sk_security_reset( |
88 | struct sk_security_struct *ssec, | 88 | struct sk_security_struct *ssec) |
89 | int family) | ||
90 | { | 89 | { |
91 | return; | 90 | return; |
92 | } | 91 | } |
@@ -113,17 +112,17 @@ static inline int selinux_netlbl_conn_setsid(struct sock *sk, | |||
113 | return 0; | 112 | return 0; |
114 | } | 113 | } |
115 | 114 | ||
116 | static inline void selinux_netlbl_inet_conn_established(struct sock *sk, | 115 | static inline int selinux_netlbl_inet_conn_request(struct request_sock *req, |
117 | u16 family) | 116 | u16 family) |
118 | { | 117 | { |
119 | return; | 118 | return 0; |
120 | } | 119 | } |
121 | static inline int selinux_netlbl_socket_post_create(struct socket *sock) | 120 | static inline void selinux_netlbl_inet_csk_clone(struct sock *sk, u16 family) |
122 | { | 121 | { |
123 | return 0; | 122 | return; |
124 | } | 123 | } |
125 | static inline int selinux_netlbl_inode_permission(struct inode *inode, | 124 | static inline int selinux_netlbl_socket_post_create(struct sock *sk, |
126 | int mask) | 125 | u16 family) |
127 | { | 126 | { |
128 | return 0; | 127 | return 0; |
129 | } | 128 | } |
diff --git a/security/selinux/netlabel.c b/security/selinux/netlabel.c index 350794ab9b42..2e984413c7b2 100644 --- a/security/selinux/netlabel.c +++ b/security/selinux/netlabel.c | |||
@@ -100,41 +100,6 @@ static struct netlbl_lsm_secattr *selinux_netlbl_sock_genattr(struct sock *sk) | |||
100 | } | 100 | } |
101 | 101 | ||
102 | /** | 102 | /** |
103 | * selinux_netlbl_sock_setsid - Label a socket using the NetLabel mechanism | ||
104 | * @sk: the socket to label | ||
105 | * | ||
106 | * Description: | ||
107 | * Attempt to label a socket using the NetLabel mechanism. Returns zero values | ||
108 | * on success, negative values on failure. | ||
109 | * | ||
110 | */ | ||
111 | static int selinux_netlbl_sock_setsid(struct sock *sk) | ||
112 | { | ||
113 | int rc; | ||
114 | struct sk_security_struct *sksec = sk->sk_security; | ||
115 | struct netlbl_lsm_secattr *secattr; | ||
116 | |||
117 | if (sksec->nlbl_state != NLBL_REQUIRE) | ||
118 | return 0; | ||
119 | |||
120 | secattr = selinux_netlbl_sock_genattr(sk); | ||
121 | if (secattr == NULL) | ||
122 | return -ENOMEM; | ||
123 | rc = netlbl_sock_setattr(sk, secattr); | ||
124 | switch (rc) { | ||
125 | case 0: | ||
126 | sksec->nlbl_state = NLBL_LABELED; | ||
127 | break; | ||
128 | case -EDESTADDRREQ: | ||
129 | sksec->nlbl_state = NLBL_REQSKB; | ||
130 | rc = 0; | ||
131 | break; | ||
132 | } | ||
133 | |||
134 | return rc; | ||
135 | } | ||
136 | |||
137 | /** | ||
138 | * selinux_netlbl_cache_invalidate - Invalidate the NetLabel cache | 103 | * selinux_netlbl_cache_invalidate - Invalidate the NetLabel cache |
139 | * | 104 | * |
140 | * Description: | 105 | * Description: |
@@ -188,13 +153,9 @@ void selinux_netlbl_sk_security_free(struct sk_security_struct *ssec) | |||
188 | * The caller is responsibile for all the NetLabel sk_security_struct locking. | 153 | * The caller is responsibile for all the NetLabel sk_security_struct locking. |
189 | * | 154 | * |
190 | */ | 155 | */ |
191 | void selinux_netlbl_sk_security_reset(struct sk_security_struct *ssec, | 156 | void selinux_netlbl_sk_security_reset(struct sk_security_struct *ssec) |
192 | int family) | ||
193 | { | 157 | { |
194 | if (family == PF_INET) | 158 | ssec->nlbl_state = NLBL_UNSET; |
195 | ssec->nlbl_state = NLBL_REQUIRE; | ||
196 | else | ||
197 | ssec->nlbl_state = NLBL_UNSET; | ||
198 | } | 159 | } |
199 | 160 | ||
200 | /** | 161 | /** |
@@ -281,127 +242,86 @@ skbuff_setsid_return: | |||
281 | } | 242 | } |
282 | 243 | ||
283 | /** | 244 | /** |
284 | * selinux_netlbl_inet_conn_established - Netlabel the newly accepted connection | 245 | * selinux_netlbl_inet_conn_request - Label an incoming stream connection |
285 | * @sk: the new connection | 246 | * @req: incoming connection request socket |
286 | * | 247 | * |
287 | * Description: | 248 | * Description: |
288 | * A new connection has been established on @sk so make sure it is labeled | 249 | * A new incoming connection request is represented by @req, we need to label |
289 | * correctly with the NetLabel susbsystem. | 250 | * the new request_sock here and the stack will ensure the on-the-wire label |
251 | * will get preserved when a full sock is created once the connection handshake | ||
252 | * is complete. Returns zero on success, negative values on failure. | ||
290 | * | 253 | * |
291 | */ | 254 | */ |
292 | void selinux_netlbl_inet_conn_established(struct sock *sk, u16 family) | 255 | int selinux_netlbl_inet_conn_request(struct request_sock *req, u16 family) |
293 | { | 256 | { |
294 | int rc; | 257 | int rc; |
295 | struct sk_security_struct *sksec = sk->sk_security; | 258 | struct netlbl_lsm_secattr secattr; |
296 | struct netlbl_lsm_secattr *secattr; | ||
297 | struct inet_sock *sk_inet = inet_sk(sk); | ||
298 | struct sockaddr_in addr; | ||
299 | |||
300 | if (sksec->nlbl_state != NLBL_REQUIRE) | ||
301 | return; | ||
302 | 259 | ||
303 | secattr = selinux_netlbl_sock_genattr(sk); | 260 | if (family != PF_INET) |
304 | if (secattr == NULL) | 261 | return 0; |
305 | return; | ||
306 | 262 | ||
307 | rc = netlbl_sock_setattr(sk, secattr); | 263 | netlbl_secattr_init(&secattr); |
308 | switch (rc) { | 264 | rc = security_netlbl_sid_to_secattr(req->secid, &secattr); |
309 | case 0: | 265 | if (rc != 0) |
310 | sksec->nlbl_state = NLBL_LABELED; | 266 | goto inet_conn_request_return; |
311 | break; | 267 | rc = netlbl_req_setattr(req, &secattr); |
312 | case -EDESTADDRREQ: | 268 | inet_conn_request_return: |
313 | /* no PF_INET6 support yet because we don't support any IPv6 | 269 | netlbl_secattr_destroy(&secattr); |
314 | * labeling protocols */ | 270 | return rc; |
315 | if (family != PF_INET) { | ||
316 | sksec->nlbl_state = NLBL_UNSET; | ||
317 | return; | ||
318 | } | ||
319 | |||
320 | addr.sin_family = family; | ||
321 | addr.sin_addr.s_addr = sk_inet->daddr; | ||
322 | if (netlbl_conn_setattr(sk, (struct sockaddr *)&addr, | ||
323 | secattr) != 0) { | ||
324 | /* we failed to label the connected socket (could be | ||
325 | * for a variety of reasons, the actual "why" isn't | ||
326 | * important here) so we have to go to our backup plan, | ||
327 | * labeling the packets individually in the netfilter | ||
328 | * local output hook. this is okay but we need to | ||
329 | * adjust the MSS of the connection to take into | ||
330 | * account any labeling overhead, since we don't know | ||
331 | * the exact overhead at this point we'll use the worst | ||
332 | * case value which is 40 bytes for IPv4 */ | ||
333 | struct inet_connection_sock *sk_conn = inet_csk(sk); | ||
334 | sk_conn->icsk_ext_hdr_len += 40 - | ||
335 | (sk_inet->opt ? sk_inet->opt->optlen : 0); | ||
336 | sk_conn->icsk_sync_mss(sk, sk_conn->icsk_pmtu_cookie); | ||
337 | |||
338 | sksec->nlbl_state = NLBL_REQSKB; | ||
339 | } else | ||
340 | sksec->nlbl_state = NLBL_CONNLABELED; | ||
341 | break; | ||
342 | default: | ||
343 | /* note that we are failing to label the socket which could be | ||
344 | * a bad thing since it means traffic could leave the system | ||
345 | * without the desired labeling, however, all is not lost as | ||
346 | * we have a check in selinux_netlbl_inode_permission() to | ||
347 | * pick up the pieces that we might drop here because we can't | ||
348 | * return an error code */ | ||
349 | break; | ||
350 | } | ||
351 | } | 271 | } |
352 | 272 | ||
353 | /** | 273 | /** |
354 | * selinux_netlbl_socket_post_create - Label a socket using NetLabel | 274 | * selinux_netlbl_inet_csk_clone - Initialize the newly created sock |
355 | * @sock: the socket to label | 275 | * @sk: the new sock |
356 | * | 276 | * |
357 | * Description: | 277 | * Description: |
358 | * Attempt to label a socket using the NetLabel mechanism using the given | 278 | * A new connection has been established using @sk, we've already labeled the |
359 | * SID. Returns zero values on success, negative values on failure. | 279 | * socket via the request_sock struct in selinux_netlbl_inet_conn_request() but |
280 | * we need to set the NetLabel state here since we now have a sock structure. | ||
360 | * | 281 | * |
361 | */ | 282 | */ |
362 | int selinux_netlbl_socket_post_create(struct socket *sock) | 283 | void selinux_netlbl_inet_csk_clone(struct sock *sk, u16 family) |
363 | { | 284 | { |
364 | return selinux_netlbl_sock_setsid(sock->sk); | 285 | struct sk_security_struct *sksec = sk->sk_security; |
286 | |||
287 | if (family == PF_INET) | ||
288 | sksec->nlbl_state = NLBL_LABELED; | ||
289 | else | ||
290 | sksec->nlbl_state = NLBL_UNSET; | ||
365 | } | 291 | } |
366 | 292 | ||
367 | /** | 293 | /** |
368 | * selinux_netlbl_inode_permission - Verify the socket is NetLabel labeled | 294 | * selinux_netlbl_socket_post_create - Label a socket using NetLabel |
369 | * @inode: the file descriptor's inode | 295 | * @sock: the socket to label |
370 | * @mask: the permission mask | 296 | * @family: protocol family |
371 | * | 297 | * |
372 | * Description: | 298 | * Description: |
373 | * Looks at a file's inode and if it is marked as a socket protected by | 299 | * Attempt to label a socket using the NetLabel mechanism using the given |
374 | * NetLabel then verify that the socket has been labeled, if not try to label | 300 | * SID. Returns zero values on success, negative values on failure. |
375 | * the socket now with the inode's SID. Returns zero on success, negative | ||
376 | * values on failure. | ||
377 | * | 301 | * |
378 | */ | 302 | */ |
379 | int selinux_netlbl_inode_permission(struct inode *inode, int mask) | 303 | int selinux_netlbl_socket_post_create(struct sock *sk, u16 family) |
380 | { | 304 | { |
381 | int rc; | 305 | int rc; |
382 | struct sock *sk; | 306 | struct sk_security_struct *sksec = sk->sk_security; |
383 | struct socket *sock; | 307 | struct netlbl_lsm_secattr *secattr; |
384 | struct sk_security_struct *sksec; | ||
385 | 308 | ||
386 | if (!S_ISSOCK(inode->i_mode) || | 309 | if (family != PF_INET) |
387 | ((mask & (MAY_WRITE | MAY_APPEND)) == 0)) | ||
388 | return 0; | ||
389 | sock = SOCKET_I(inode); | ||
390 | sk = sock->sk; | ||
391 | if (sk == NULL) | ||
392 | return 0; | ||
393 | sksec = sk->sk_security; | ||
394 | if (sksec == NULL || sksec->nlbl_state != NLBL_REQUIRE) | ||
395 | return 0; | 310 | return 0; |
396 | 311 | ||
397 | local_bh_disable(); | 312 | secattr = selinux_netlbl_sock_genattr(sk); |
398 | bh_lock_sock_nested(sk); | 313 | if (secattr == NULL) |
399 | if (likely(sksec->nlbl_state == NLBL_REQUIRE)) | 314 | return -ENOMEM; |
400 | rc = selinux_netlbl_sock_setsid(sk); | 315 | rc = netlbl_sock_setattr(sk, family, secattr); |
401 | else | 316 | switch (rc) { |
317 | case 0: | ||
318 | sksec->nlbl_state = NLBL_LABELED; | ||
319 | break; | ||
320 | case -EDESTADDRREQ: | ||
321 | sksec->nlbl_state = NLBL_REQSKB; | ||
402 | rc = 0; | 322 | rc = 0; |
403 | bh_unlock_sock(sk); | 323 | break; |
404 | local_bh_enable(); | 324 | } |
405 | 325 | ||
406 | return rc; | 326 | return rc; |
407 | } | 327 | } |