/** * 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 IS_ENABLED(CONFIG_IPV6) 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_socket_setattr - Label a socket using the correct protocol * @sock: the socket to label * @secattr: the security attributes * * Description: * Attach the correct label to the given socket using the security attributes * specified in @secattr. This function requires exclusive access to * @sock->sk, which means it either needs to be in the process of being * created or locked via lock_sock(sock->sk). Returns zero on success, * negative values on failure. * */ int netlbl_socket_setattr(const struct socket *sock, const struct netlbl_lsm_secattr *secattr) { int ret_val = -ENOENT; struct netlbl_dom_map *dom_entry; if ((secattr->flags & NETLBL_SECATTR_DOMAIN) == 0) return -ENOENT; rcu_read_lock(); dom_entry = netlbl_domhsh_getentry(secattr->domain); if (dom_entry == NULL) goto socket_setattr_return; switch (dom_entry->type) { case NETLBL_NLTYPE_CIPSOV4: ret_val = cipso_v4_socket_setattr(sock, dom_entry->type_def.cipsov4, secattr); break; case NETLBL_NLTYPE_UNLABELED: ret_val = 0; break; default: ret_val = -ENOENT; } socket_setattr_return: rcu_read_unlock(); return ret_val; }
/** * netlbl_sock_setattr - Label a socket using the correct protocol * @sk: the socket to label * @family: protocol family * @secattr: the security attributes * * Description: * Attach the correct label to the given socket using the security attributes * specified in @secattr. This function requires exclusive access to @sk, * which means it either needs to be in the process of being created or locked. * Returns zero on success, -EDESTADDRREQ if the domain is configured to use * network address selectors (can't blindly label the socket), and negative * values on all other failures. * */ int netlbl_sock_setattr(struct sock *sk, u16 family, const struct netlbl_lsm_secattr *secattr) { int ret_val; struct netlbl_dom_map *dom_entry; rcu_read_lock(); dom_entry = netlbl_domhsh_getentry(secattr->domain, family); if (dom_entry == NULL) { ret_val = -ENOENT; goto socket_setattr_return; } switch (family) { case AF_INET: switch (dom_entry->def.type) { case NETLBL_NLTYPE_ADDRSELECT: ret_val = -EDESTADDRREQ; break; case NETLBL_NLTYPE_CIPSOV4: ret_val = cipso_v4_sock_setattr(sk, dom_entry->def.cipso, secattr); break; case NETLBL_NLTYPE_UNLABELED: ret_val = 0; break; default: ret_val = -ENOENT; } break; #if IS_ENABLED(CONFIG_IPV6) case AF_INET6: switch (dom_entry->def.type) { case NETLBL_NLTYPE_ADDRSELECT: ret_val = -EDESTADDRREQ; break; case NETLBL_NLTYPE_CALIPSO: ret_val = calipso_sock_setattr(sk, dom_entry->def.calipso, secattr); break; case NETLBL_NLTYPE_UNLABELED: ret_val = 0; break; default: ret_val = -ENOENT; } break; #endif /* IPv6 */ default: ret_val = -EPROTONOSUPPORT; } socket_setattr_return: rcu_read_unlock(); return ret_val; }
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: 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: ret_val = 0; break; #endif default: ret_val = -EPROTONOSUPPORT; } req_setattr_return: rcu_read_unlock(); return ret_val; }
/** * netlbl_sock_setattr - Label a socket using the correct protocol * @sk: the socket to label * @family: protocol family * @secattr: the security attributes * * Description: * Attach the correct label to the given socket using the security attributes * specified in @secattr. This function requires exclusive access to @sk, * which means it either needs to be in the process of being created or locked. * Returns zero on success, -EDESTADDRREQ if the domain is configured to use * network address selectors (can't blindly label the socket), and negative * values on all other failures. * */ int netlbl_sock_setattr(struct sock *sk, u16 family, const struct netlbl_lsm_secattr *secattr) { int ret_val; struct netlbl_dom_map *dom_entry; rcu_read_lock(); dom_entry = netlbl_domhsh_getentry(secattr->domain); if (dom_entry == NULL) { ret_val = -ENOENT; goto socket_setattr_return; } switch (family) { case AF_INET: switch (dom_entry->type) { case NETLBL_NLTYPE_ADDRSELECT: ret_val = -EDESTADDRREQ; break; case NETLBL_NLTYPE_CIPSOV4: ret_val = cipso_v4_sock_setattr(sk, dom_entry->type_def.cipsov4, secattr); break; case NETLBL_NLTYPE_UNLABELED: ret_val = 0; break; default: ret_val = -ENOENT; } break; #if IS_ENABLED(CONFIG_IPV6) 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; } socket_setattr_return: rcu_read_unlock(); return ret_val; }