netlabel: Add new NetLabel KAPI interfaces for request_sock security attributes
authorPaul Moore <paul.moore@hp.com>
Fri, 8 May 2009 21:58:43 +0000 (17:58 -0400)
committerGreg Kroah-Hartman <gregkh@suse.de>
Mon, 18 May 2009 23:34:50 +0000 (16:34 -0700)
[NOTE: based on 389fb800ac8be2832efedd19978a2b8ced37eb61 and
                07feee8f812f7327a46186f7604df312c8c81962]

This patch adds the netlbl_req_setattr() and netlbl_req_delattr() functions
which can be used by LSMs to set and remove the NetLabel security attributes
from request_sock objects used in incoming connection requests.

Signed-off-by: Paul Moore <paul.moore@hp.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
include/net/netlabel.h
net/netlabel/netlabel_kapi.c

index 749011eedc0b2740ed47ca50f5b30b5717d86e57..bf77b5c602d653e1f0163e166afadca32a9d88b4 100644 (file)
@@ -36,6 +36,7 @@
 #include <linux/in.h>
 #include <linux/in6.h>
 #include <net/netlink.h>
+#include <net/request_sock.h>
 #include <asm/atomic.h>
 
 struct cipso_v4_doi;
@@ -413,6 +414,9 @@ int netlbl_sock_getattr(struct sock *sk,
 int netlbl_conn_setattr(struct sock *sk,
                        struct sockaddr *addr,
                        const struct netlbl_lsm_secattr *secattr);
+int netlbl_req_setattr(struct request_sock *req,
+                      const struct netlbl_lsm_secattr *secattr);
+void netlbl_req_delattr(struct request_sock *req);
 int netlbl_skbuff_setattr(struct sk_buff *skb,
                          u16 family,
                          const struct netlbl_lsm_secattr *secattr);
@@ -519,7 +523,7 @@ static inline int netlbl_enabled(void)
        return 0;
 }
 static inline int netlbl_sock_setattr(struct sock *sk,
-                                    const struct netlbl_lsm_secattr *secattr)
+                                     const struct netlbl_lsm_secattr *secattr)
 {
        return -ENOSYS;
 }
@@ -537,6 +541,15 @@ static inline int netlbl_conn_setattr(struct sock *sk,
 {
        return -ENOSYS;
 }
+static inline int netlbl_req_setattr(struct request_sock *req,
+                                    const struct netlbl_lsm_secattr *secattr)
+{
+       return -ENOSYS;
+}
+static inline void netlbl_req_delattr(struct request_sock *req)
+{
+       return;
+}
 static inline int netlbl_skbuff_setattr(struct sk_buff *skb,
                                      u16 family,
                                      const struct netlbl_lsm_secattr *secattr)
index fd9229db075cbc64a74dcc25367bc4a478f79c90..a52ca1c3dfc9204321a242baf6bb447b438f3025 100644 (file)
@@ -756,6 +756,90 @@ conn_setattr_return:
        return ret_val;
 }
 
+/**
+ * netlbl_req_setattr - Label a request socket using the correct protocol
+ * @req: the request socket to label
+ * @secattr: the security attributes
+ *
+ * Description:
+ * Attach the correct label to the given socket using the security attributes
+ * specified in @secattr.  Returns zero on success, negative values on failure.
+ *
+ */
+int netlbl_req_setattr(struct request_sock *req,
+                      const struct netlbl_lsm_secattr *secattr)
+{
+       int ret_val;
+       struct netlbl_dom_map *dom_entry;
+       struct netlbl_domaddr4_map *af4_entry;
+       u32 proto_type;
+       struct cipso_v4_doi *proto_cv4;
+
+       rcu_read_lock();
+       dom_entry = netlbl_domhsh_getentry(secattr->domain);
+       if (dom_entry == NULL) {
+               ret_val = -ENOENT;
+               goto req_setattr_return;
+       }
+       switch (req->rsk_ops->family) {
+       case AF_INET:
+               if (dom_entry->type == NETLBL_NLTYPE_ADDRSELECT) {
+                       struct inet_request_sock *req_inet = inet_rsk(req);
+                       af4_entry = netlbl_domhsh_getentry_af4(secattr->domain,
+                                                           req_inet->rmt_addr);
+                       if (af4_entry == NULL) {
+                               ret_val = -ENOENT;
+                               goto req_setattr_return;
+                       }
+                       proto_type = af4_entry->type;
+                       proto_cv4 = af4_entry->type_def.cipsov4;
+               } else {
+                       proto_type = dom_entry->type;
+                       proto_cv4 = dom_entry->type_def.cipsov4;
+               }
+               switch (proto_type) {
+               case NETLBL_NLTYPE_CIPSOV4:
+                       ret_val = cipso_v4_req_setattr(req, proto_cv4, secattr);
+                       break;
+               case NETLBL_NLTYPE_UNLABELED:
+                       /* just delete the protocols we support for right now
+                        * but we could remove other protocols if needed */
+                       cipso_v4_req_delattr(req);
+                       ret_val = 0;
+                       break;
+               default:
+                       ret_val = -ENOENT;
+               }
+               break;
+#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
+       case AF_INET6:
+               /* since we don't support any IPv6 labeling protocols right
+                * now we can optimize everything away until we do */
+               ret_val = 0;
+               break;
+#endif /* IPv6 */
+       default:
+               ret_val = -EPROTONOSUPPORT;
+       }
+
+req_setattr_return:
+       rcu_read_unlock();
+       return ret_val;
+}
+
+/**
+* netlbl_req_delattr - Delete all the NetLabel labels on a socket
+* @req: the socket
+*
+* Description:
+* Remove all the NetLabel labeling from @req.
+*
+*/
+void netlbl_req_delattr(struct request_sock *req)
+{
+       cipso_v4_req_delattr(req);
+}
+
 /**
  * netlbl_skbuff_setattr - Label a packet using the correct protocol
  * @skb: the packet