aboutsummaryrefslogtreecommitdiffstats
path: root/security/selinux/ss/services.c
diff options
context:
space:
mode:
Diffstat (limited to 'security/selinux/ss/services.c')
-rw-r--r--security/selinux/ss/services.c613
1 files changed, 613 insertions, 0 deletions
diff --git a/security/selinux/ss/services.c b/security/selinux/ss/services.c
index 85e429884393..7eb69a602d8f 100644
--- a/security/selinux/ss/services.c
+++ b/security/selinux/ss/services.c
@@ -13,6 +13,11 @@
13 * 13 *
14 * Added conditional policy language extensions 14 * Added conditional policy language extensions
15 * 15 *
16 * Updated: Hewlett-Packard <paul.moore@hp.com>
17 *
18 * Added support for NetLabel
19 *
20 * Copyright (C) 2006 Hewlett-Packard Development Company, L.P.
16 * Copyright (C) 2004-2006 Trusted Computer Solutions, Inc. 21 * Copyright (C) 2004-2006 Trusted Computer Solutions, Inc.
17 * Copyright (C) 2003 - 2004 Tresys Technology, LLC 22 * Copyright (C) 2003 - 2004 Tresys Technology, LLC
18 * Copyright (C) 2003 Red Hat, Inc., James Morris <jmorris@redhat.com> 23 * Copyright (C) 2003 Red Hat, Inc., James Morris <jmorris@redhat.com>
@@ -29,6 +34,8 @@
29#include <linux/sched.h> 34#include <linux/sched.h>
30#include <linux/audit.h> 35#include <linux/audit.h>
31#include <linux/mutex.h> 36#include <linux/mutex.h>
37#include <net/sock.h>
38#include <net/netlabel.h>
32 39
33#include "flask.h" 40#include "flask.h"
34#include "avc.h" 41#include "avc.h"
@@ -40,6 +47,8 @@
40#include "services.h" 47#include "services.h"
41#include "conditional.h" 48#include "conditional.h"
42#include "mls.h" 49#include "mls.h"
50#include "objsec.h"
51#include "selinux_netlabel.h"
43 52
44extern void selnl_notify_policyload(u32 seqno); 53extern void selnl_notify_policyload(u32 seqno);
45unsigned int policydb_loaded_version; 54unsigned int policydb_loaded_version;
@@ -1241,6 +1250,7 @@ int security_load_policy(void *data, size_t len)
1241 selinux_complete_init(); 1250 selinux_complete_init();
1242 avc_ss_reset(seqno); 1251 avc_ss_reset(seqno);
1243 selnl_notify_policyload(seqno); 1252 selnl_notify_policyload(seqno);
1253 selinux_netlbl_cache_invalidate();
1244 return 0; 1254 return 0;
1245 } 1255 }
1246 1256
@@ -1295,6 +1305,7 @@ int security_load_policy(void *data, size_t len)
1295 1305
1296 avc_ss_reset(seqno); 1306 avc_ss_reset(seqno);
1297 selnl_notify_policyload(seqno); 1307 selnl_notify_policyload(seqno);
1308 selinux_netlbl_cache_invalidate();
1298 1309
1299 return 0; 1310 return 0;
1300 1311
@@ -1817,6 +1828,75 @@ out:
1817 return rc; 1828 return rc;
1818} 1829}
1819 1830
1831/*
1832 * security_sid_mls_copy() - computes a new sid based on the given
1833 * sid and the mls portion of mls_sid.
1834 */
1835int security_sid_mls_copy(u32 sid, u32 mls_sid, u32 *new_sid)
1836{
1837 struct context *context1;
1838 struct context *context2;
1839 struct context newcon;
1840 char *s;
1841 u32 len;
1842 int rc = 0;
1843
1844 if (!ss_initialized || !selinux_mls_enabled) {
1845 *new_sid = sid;
1846 goto out;
1847 }
1848
1849 context_init(&newcon);
1850
1851 POLICY_RDLOCK;
1852 context1 = sidtab_search(&sidtab, sid);
1853 if (!context1) {
1854 printk(KERN_ERR "security_sid_mls_copy: unrecognized SID "
1855 "%d\n", sid);
1856 rc = -EINVAL;
1857 goto out_unlock;
1858 }
1859
1860 context2 = sidtab_search(&sidtab, mls_sid);
1861 if (!context2) {
1862 printk(KERN_ERR "security_sid_mls_copy: unrecognized SID "
1863 "%d\n", mls_sid);
1864 rc = -EINVAL;
1865 goto out_unlock;
1866 }
1867
1868 newcon.user = context1->user;
1869 newcon.role = context1->role;
1870 newcon.type = context1->type;
1871 rc = mls_copy_context(&newcon, context2);
1872 if (rc)
1873 goto out_unlock;
1874
1875
1876 /* Check the validity of the new context. */
1877 if (!policydb_context_isvalid(&policydb, &newcon)) {
1878 rc = convert_context_handle_invalid_context(&newcon);
1879 if (rc)
1880 goto bad;
1881 }
1882
1883 rc = sidtab_context_to_sid(&sidtab, &newcon, new_sid);
1884 goto out_unlock;
1885
1886bad:
1887 if (!context_struct_to_string(&newcon, &s, &len)) {
1888 audit_log(current->audit_context, GFP_ATOMIC, AUDIT_SELINUX_ERR,
1889 "security_sid_mls_copy: invalid context %s", s);
1890 kfree(s);
1891 }
1892
1893out_unlock:
1894 POLICY_RDUNLOCK;
1895 context_destroy(&newcon);
1896out:
1897 return rc;
1898}
1899
1820struct selinux_audit_rule { 1900struct selinux_audit_rule {
1821 u32 au_seqno; 1901 u32 au_seqno;
1822 struct context au_ctxt; 1902 struct context au_ctxt;
@@ -2064,3 +2144,536 @@ void selinux_audit_set_callback(int (*callback)(void))
2064{ 2144{
2065 aurule_callback = callback; 2145 aurule_callback = callback;
2066} 2146}
2147
2148#ifdef CONFIG_NETLABEL
2149/*
2150 * This is the structure we store inside the NetLabel cache block.
2151 */
2152#define NETLBL_CACHE(x) ((struct netlbl_cache *)(x))
2153#define NETLBL_CACHE_T_NONE 0
2154#define NETLBL_CACHE_T_SID 1
2155#define NETLBL_CACHE_T_MLS 2
2156struct netlbl_cache {
2157 u32 type;
2158 union {
2159 u32 sid;
2160 struct mls_range mls_label;
2161 } data;
2162};
2163
2164/**
2165 * selinux_netlbl_cache_free - Free the NetLabel cached data
2166 * @data: the data to free
2167 *
2168 * Description:
2169 * This function is intended to be used as the free() callback inside the
2170 * netlbl_lsm_cache structure.
2171 *
2172 */
2173static void selinux_netlbl_cache_free(const void *data)
2174{
2175 struct netlbl_cache *cache = NETLBL_CACHE(data);
2176 switch (cache->type) {
2177 case NETLBL_CACHE_T_MLS:
2178 ebitmap_destroy(&cache->data.mls_label.level[0].cat);
2179 break;
2180 }
2181 kfree(data);
2182}
2183
2184/**
2185 * selinux_netlbl_cache_add - Add an entry to the NetLabel cache
2186 * @skb: the packet
2187 * @ctx: the SELinux context
2188 *
2189 * Description:
2190 * Attempt to cache the context in @ctx, which was derived from the packet in
2191 * @skb, in the NetLabel subsystem cache.
2192 *
2193 */
2194static void selinux_netlbl_cache_add(struct sk_buff *skb, struct context *ctx)
2195{
2196 struct netlbl_cache *cache = NULL;
2197 struct netlbl_lsm_secattr secattr;
2198
2199 netlbl_secattr_init(&secattr);
2200
2201 cache = kzalloc(sizeof(*cache), GFP_ATOMIC);
2202 if (cache == NULL)
2203 goto netlbl_cache_add_failure;
2204 secattr.cache.free = selinux_netlbl_cache_free;
2205 secattr.cache.data = (void *)cache;
2206
2207 cache->type = NETLBL_CACHE_T_MLS;
2208 if (ebitmap_cpy(&cache->data.mls_label.level[0].cat,
2209 &ctx->range.level[0].cat) != 0)
2210 goto netlbl_cache_add_failure;
2211 cache->data.mls_label.level[1].cat.highbit =
2212 cache->data.mls_label.level[0].cat.highbit;
2213 cache->data.mls_label.level[1].cat.node =
2214 cache->data.mls_label.level[0].cat.node;
2215 cache->data.mls_label.level[0].sens = ctx->range.level[0].sens;
2216 cache->data.mls_label.level[1].sens = ctx->range.level[0].sens;
2217
2218 if (netlbl_cache_add(skb, &secattr) != 0)
2219 goto netlbl_cache_add_failure;
2220
2221 return;
2222
2223netlbl_cache_add_failure:
2224 netlbl_secattr_destroy(&secattr, 1);
2225}
2226
2227/**
2228 * selinux_netlbl_cache_invalidate - Invalidate the NetLabel cache
2229 *
2230 * Description:
2231 * Invalidate the NetLabel security attribute mapping cache.
2232 *
2233 */
2234void selinux_netlbl_cache_invalidate(void)
2235{
2236 netlbl_cache_invalidate();
2237}
2238
2239/**
2240 * selinux_netlbl_secattr_to_sid - Convert a NetLabel secattr to a SELinux SID
2241 * @skb: the network packet
2242 * @secattr: the NetLabel packet security attributes
2243 * @base_sid: the SELinux SID to use as a context for MLS only attributes
2244 * @sid: the SELinux SID
2245 *
2246 * Description:
2247 * Convert the given NetLabel packet security attributes in @secattr into a
2248 * SELinux SID. If the @secattr field does not contain a full SELinux
2249 * SID/context then use the context in @base_sid as the foundation. If @skb
2250 * is not NULL attempt to cache as much data as possibile. Returns zero on
2251 * success, negative values on failure.
2252 *
2253 */
2254static int selinux_netlbl_secattr_to_sid(struct sk_buff *skb,
2255 struct netlbl_lsm_secattr *secattr,
2256 u32 base_sid,
2257 u32 *sid)
2258{
2259 int rc = -EIDRM;
2260 struct context *ctx;
2261 struct context ctx_new;
2262 struct netlbl_cache *cache;
2263
2264 POLICY_RDLOCK;
2265
2266 if (secattr->cache.data) {
2267 cache = NETLBL_CACHE(secattr->cache.data);
2268 switch (cache->type) {
2269 case NETLBL_CACHE_T_SID:
2270 *sid = cache->data.sid;
2271 rc = 0;
2272 break;
2273 case NETLBL_CACHE_T_MLS:
2274 ctx = sidtab_search(&sidtab, base_sid);
2275 if (ctx == NULL)
2276 goto netlbl_secattr_to_sid_return;
2277
2278 ctx_new.user = ctx->user;
2279 ctx_new.role = ctx->role;
2280 ctx_new.type = ctx->type;
2281 ctx_new.range.level[0].sens =
2282 cache->data.mls_label.level[0].sens;
2283 ctx_new.range.level[0].cat.highbit =
2284 cache->data.mls_label.level[0].cat.highbit;
2285 ctx_new.range.level[0].cat.node =
2286 cache->data.mls_label.level[0].cat.node;
2287 ctx_new.range.level[1].sens =
2288 cache->data.mls_label.level[1].sens;
2289 ctx_new.range.level[1].cat.highbit =
2290 cache->data.mls_label.level[1].cat.highbit;
2291 ctx_new.range.level[1].cat.node =
2292 cache->data.mls_label.level[1].cat.node;
2293
2294 rc = sidtab_context_to_sid(&sidtab, &ctx_new, sid);
2295 break;
2296 default:
2297 goto netlbl_secattr_to_sid_return;
2298 }
2299 } else if (secattr->mls_lvl_vld) {
2300 ctx = sidtab_search(&sidtab, base_sid);
2301 if (ctx == NULL)
2302 goto netlbl_secattr_to_sid_return;
2303
2304 ctx_new.user = ctx->user;
2305 ctx_new.role = ctx->role;
2306 ctx_new.type = ctx->type;
2307 mls_import_lvl(&ctx_new, secattr->mls_lvl, secattr->mls_lvl);
2308 if (secattr->mls_cat) {
2309 if (mls_import_cat(&ctx_new,
2310 secattr->mls_cat,
2311 secattr->mls_cat_len,
2312 NULL,
2313 0) != 0)
2314 goto netlbl_secattr_to_sid_return;
2315 ctx_new.range.level[1].cat.highbit =
2316 ctx_new.range.level[0].cat.highbit;
2317 ctx_new.range.level[1].cat.node =
2318 ctx_new.range.level[0].cat.node;
2319 } else {
2320 ebitmap_init(&ctx_new.range.level[0].cat);
2321 ebitmap_init(&ctx_new.range.level[1].cat);
2322 }
2323 if (mls_context_isvalid(&policydb, &ctx_new) != 1)
2324 goto netlbl_secattr_to_sid_return_cleanup;
2325
2326 rc = sidtab_context_to_sid(&sidtab, &ctx_new, sid);
2327 if (rc != 0)
2328 goto netlbl_secattr_to_sid_return_cleanup;
2329
2330 if (skb != NULL)
2331 selinux_netlbl_cache_add(skb, &ctx_new);
2332 ebitmap_destroy(&ctx_new.range.level[0].cat);
2333 } else {
2334 *sid = SECINITSID_UNLABELED;
2335 rc = 0;
2336 }
2337
2338netlbl_secattr_to_sid_return:
2339 POLICY_RDUNLOCK;
2340 return rc;
2341netlbl_secattr_to_sid_return_cleanup:
2342 ebitmap_destroy(&ctx_new.range.level[0].cat);
2343 goto netlbl_secattr_to_sid_return;
2344}
2345
2346/**
2347 * selinux_netlbl_skbuff_getsid - Get the sid of a packet using NetLabel
2348 * @skb: the packet
2349 * @base_sid: the SELinux SID to use as a context for MLS only attributes
2350 * @sid: the SID
2351 *
2352 * Description:
2353 * Call the NetLabel mechanism to get the security attributes of the given
2354 * packet and use those attributes to determine the correct context/SID to
2355 * assign to the packet. Returns zero on success, negative values on failure.
2356 *
2357 */
2358static int selinux_netlbl_skbuff_getsid(struct sk_buff *skb,
2359 u32 base_sid,
2360 u32 *sid)
2361{
2362 int rc;
2363 struct netlbl_lsm_secattr secattr;
2364
2365 netlbl_secattr_init(&secattr);
2366 rc = netlbl_skbuff_getattr(skb, &secattr);
2367 if (rc == 0)
2368 rc = selinux_netlbl_secattr_to_sid(skb,
2369 &secattr,
2370 base_sid,
2371 sid);
2372 netlbl_secattr_destroy(&secattr, 0);
2373
2374 return rc;
2375}
2376
2377/**
2378 * selinux_netlbl_socket_setsid - Label a socket using the NetLabel mechanism
2379 * @sock: the socket to label
2380 * @sid: the SID to use
2381 *
2382 * Description:
2383 * Attempt to label a socket using the NetLabel mechanism using the given
2384 * SID. Returns zero values on success, negative values on failure.
2385 *
2386 */
2387static int selinux_netlbl_socket_setsid(struct socket *sock, u32 sid)
2388{
2389 int rc = -ENOENT;
2390 struct sk_security_struct *sksec = sock->sk->sk_security;
2391 struct netlbl_lsm_secattr secattr;
2392 struct context *ctx;
2393
2394 if (!ss_initialized)
2395 return 0;
2396
2397 POLICY_RDLOCK;
2398
2399 ctx = sidtab_search(&sidtab, sid);
2400 if (ctx == NULL)
2401 goto netlbl_socket_setsid_return;
2402
2403 netlbl_secattr_init(&secattr);
2404 secattr.domain = kstrdup(policydb.p_type_val_to_name[ctx->type - 1],
2405 GFP_ATOMIC);
2406 mls_export_lvl(ctx, &secattr.mls_lvl, NULL);
2407 secattr.mls_lvl_vld = 1;
2408 mls_export_cat(ctx,
2409 &secattr.mls_cat,
2410 &secattr.mls_cat_len,
2411 NULL,
2412 NULL);
2413
2414 rc = netlbl_socket_setattr(sock, &secattr);
2415 if (rc == 0)
2416 sksec->nlbl_state = NLBL_LABELED;
2417
2418 netlbl_secattr_destroy(&secattr, 0);
2419
2420netlbl_socket_setsid_return:
2421 POLICY_RDUNLOCK;
2422 return rc;
2423}
2424
2425/**
2426 * selinux_netlbl_sk_security_init - Setup the NetLabel fields
2427 * @ssec: the sk_security_struct
2428 * @family: the socket family
2429 *
2430 * Description:
2431 * Called when a new sk_security_struct is allocated to initialize the NetLabel
2432 * fields.
2433 *
2434 */
2435void selinux_netlbl_sk_security_init(struct sk_security_struct *ssec,
2436 int family)
2437{
2438 if (family == PF_INET)
2439 ssec->nlbl_state = NLBL_REQUIRE;
2440 else
2441 ssec->nlbl_state = NLBL_UNSET;
2442}
2443
2444/**
2445 * selinux_netlbl_sk_clone_security - Copy the NetLabel fields
2446 * @ssec: the original sk_security_struct
2447 * @newssec: the cloned sk_security_struct
2448 *
2449 * Description:
2450 * Clone the NetLabel specific sk_security_struct fields from @ssec to
2451 * @newssec.
2452 *
2453 */
2454void selinux_netlbl_sk_clone_security(struct sk_security_struct *ssec,
2455 struct sk_security_struct *newssec)
2456{
2457 newssec->sclass = ssec->sclass;
2458 if (ssec->nlbl_state != NLBL_UNSET)
2459 newssec->nlbl_state = NLBL_REQUIRE;
2460 else
2461 newssec->nlbl_state = NLBL_UNSET;
2462}
2463
2464/**
2465 * selinux_netlbl_socket_post_create - Label a socket using NetLabel
2466 * @sock: the socket to label
2467 * @sock_family: the socket family
2468 * @sid: the SID to use
2469 *
2470 * Description:
2471 * Attempt to label a socket using the NetLabel mechanism using the given
2472 * SID. Returns zero values on success, negative values on failure.
2473 *
2474 */
2475int selinux_netlbl_socket_post_create(struct socket *sock,
2476 int sock_family,
2477 u32 sid)
2478{
2479 struct inode_security_struct *isec = SOCK_INODE(sock)->i_security;
2480 struct sk_security_struct *sksec = sock->sk->sk_security;
2481
2482 sksec->sclass = isec->sclass;
2483
2484 if (sock_family != PF_INET)
2485 return 0;
2486
2487 sksec->nlbl_state = NLBL_REQUIRE;
2488 return selinux_netlbl_socket_setsid(sock, sid);
2489}
2490
2491/**
2492 * selinux_netlbl_sock_graft - Netlabel the new socket
2493 * @sk: the new connection
2494 * @sock: the new socket
2495 *
2496 * Description:
2497 * The connection represented by @sk is being grafted onto @sock so set the
2498 * socket's NetLabel to match the SID of @sk.
2499 *
2500 */
2501void selinux_netlbl_sock_graft(struct sock *sk, struct socket *sock)
2502{
2503 struct inode_security_struct *isec = SOCK_INODE(sock)->i_security;
2504 struct sk_security_struct *sksec = sk->sk_security;
2505
2506 sksec->sclass = isec->sclass;
2507
2508 if (sk->sk_family != PF_INET)
2509 return;
2510
2511 sksec->nlbl_state = NLBL_REQUIRE;
2512 sksec->peer_sid = sksec->sid;
2513
2514 /* Try to set the NetLabel on the socket to save time later, if we fail
2515 * here we will pick up the pieces in later calls to
2516 * selinux_netlbl_inode_permission(). */
2517 selinux_netlbl_socket_setsid(sock, sksec->sid);
2518}
2519
2520/**
2521 * selinux_netlbl_inet_conn_request - Handle a new connection request
2522 * @skb: the packet
2523 * @sock_sid: the SID of the parent socket
2524 *
2525 * Description:
2526 * If present, use the security attributes of the packet in @skb and the
2527 * parent sock's SID to arrive at a SID for the new child sock. Returns the
2528 * SID of the connection or SECSID_NULL on failure.
2529 *
2530 */
2531u32 selinux_netlbl_inet_conn_request(struct sk_buff *skb, u32 sock_sid)
2532{
2533 int rc;
2534 u32 peer_sid;
2535
2536 rc = selinux_netlbl_skbuff_getsid(skb, sock_sid, &peer_sid);
2537 if (rc != 0)
2538 return SECSID_NULL;
2539
2540 if (peer_sid == SECINITSID_UNLABELED)
2541 return SECSID_NULL;
2542
2543 return peer_sid;
2544}
2545
2546/**
2547 * selinux_netlbl_inode_permission - Verify the socket is NetLabel labeled
2548 * @inode: the file descriptor's inode
2549 * @mask: the permission mask
2550 *
2551 * Description:
2552 * Looks at a file's inode and if it is marked as a socket protected by
2553 * NetLabel then verify that the socket has been labeled, if not try to label
2554 * the socket now with the inode's SID. Returns zero on success, negative
2555 * values on failure.
2556 *
2557 */
2558int selinux_netlbl_inode_permission(struct inode *inode, int mask)
2559{
2560 int rc;
2561 struct inode_security_struct *isec;
2562 struct sk_security_struct *sksec;
2563 struct socket *sock;
2564
2565 if (!S_ISSOCK(inode->i_mode))
2566 return 0;
2567
2568 sock = SOCKET_I(inode);
2569 isec = inode->i_security;
2570 sksec = sock->sk->sk_security;
2571 down(&isec->sem);
2572 if (unlikely(sksec->nlbl_state == NLBL_REQUIRE &&
2573 (mask & (MAY_WRITE | MAY_APPEND)))) {
2574 lock_sock(sock->sk);
2575 rc = selinux_netlbl_socket_setsid(sock, sksec->sid);
2576 release_sock(sock->sk);
2577 } else
2578 rc = 0;
2579 up(&isec->sem);
2580
2581 return rc;
2582}
2583
2584/**
2585 * selinux_netlbl_sock_rcv_skb - Do an inbound access check using NetLabel
2586 * @sksec: the sock's sk_security_struct
2587 * @skb: the packet
2588 * @ad: the audit data
2589 *
2590 * Description:
2591 * Fetch the NetLabel security attributes from @skb and perform an access check
2592 * against the receiving socket. Returns zero on success, negative values on
2593 * error.
2594 *
2595 */
2596int selinux_netlbl_sock_rcv_skb(struct sk_security_struct *sksec,
2597 struct sk_buff *skb,
2598 struct avc_audit_data *ad)
2599{
2600 int rc;
2601 u32 netlbl_sid;
2602 u32 recv_perm;
2603
2604 rc = selinux_netlbl_skbuff_getsid(skb, sksec->sid, &netlbl_sid);
2605 if (rc != 0)
2606 return rc;
2607
2608 if (netlbl_sid == SECINITSID_UNLABELED)
2609 return 0;
2610
2611 switch (sksec->sclass) {
2612 case SECCLASS_UDP_SOCKET:
2613 recv_perm = UDP_SOCKET__RECV_MSG;
2614 break;
2615 case SECCLASS_TCP_SOCKET:
2616 recv_perm = TCP_SOCKET__RECV_MSG;
2617 break;
2618 default:
2619 recv_perm = RAWIP_SOCKET__RECV_MSG;
2620 }
2621
2622 rc = avc_has_perm(sksec->sid,
2623 netlbl_sid,
2624 sksec->sclass,
2625 recv_perm,
2626 ad);
2627 if (rc == 0)
2628 return 0;
2629
2630 netlbl_skbuff_err(skb, rc);
2631 return rc;
2632}
2633
2634/**
2635 * selinux_netlbl_socket_getpeersec_stream - Return the connected peer's SID
2636 * @sock: the socket
2637 *
2638 * Description:
2639 * Examine @sock to find the connected peer's SID. Returns the SID on success
2640 * or SECSID_NULL on error.
2641 *
2642 */
2643u32 selinux_netlbl_socket_getpeersec_stream(struct socket *sock)
2644{
2645 struct sk_security_struct *sksec = sock->sk->sk_security;
2646
2647 if (sksec->peer_sid == SECINITSID_UNLABELED)
2648 return SECSID_NULL;
2649
2650 return sksec->peer_sid;
2651}
2652
2653/**
2654 * selinux_netlbl_socket_getpeersec_dgram - Return the SID of a NetLabel packet
2655 * @skb: the packet
2656 *
2657 * Description:
2658 * Examine @skb to find the SID assigned to it by NetLabel. Returns the SID on
2659 * success, SECSID_NULL on error.
2660 *
2661 */
2662u32 selinux_netlbl_socket_getpeersec_dgram(struct sk_buff *skb)
2663{
2664 int peer_sid;
2665 struct sock *sk = skb->sk;
2666 struct inode_security_struct *isec;
2667
2668 if (sk == NULL || sk->sk_socket == NULL)
2669 return SECSID_NULL;
2670
2671 isec = SOCK_INODE(sk->sk_socket)->i_security;
2672 if (selinux_netlbl_skbuff_getsid(skb, isec->sid, &peer_sid) != 0)
2673 return SECSID_NULL;
2674 if (peer_sid == SECINITSID_UNLABELED)
2675 return SECSID_NULL;
2676
2677 return peer_sid;
2678}
2679#endif /* CONFIG_NETLABEL */