diff options
Diffstat (limited to 'net')
-rw-r--r-- | net/bluetooth/l2cap_core.c | 2 | ||||
-rw-r--r-- | net/bpfilter/bpfilter_kern.c | 2 | ||||
-rw-r--r-- | net/ceph/ceph_common.c | 2 | ||||
-rw-r--r-- | net/ceph/messenger.c | 3 | ||||
-rw-r--r-- | net/core/net_namespace.c | 20 | ||||
-rw-r--r-- | net/dns_resolver/dns_key.c | 13 | ||||
-rw-r--r-- | net/dns_resolver/dns_query.c | 20 | ||||
-rw-r--r-- | net/mac80211/Kconfig | 2 | ||||
-rw-r--r-- | net/mac80211/cfg.c | 4 | ||||
-rw-r--r-- | net/mac80211/ieee80211_i.h | 4 | ||||
-rw-r--r-- | net/mac80211/key.h | 1 | ||||
-rw-r--r-- | net/mac80211/main.c | 6 | ||||
-rw-r--r-- | net/mac80211/mlme.c | 3 | ||||
-rw-r--r-- | net/mac80211/tkip.c | 8 | ||||
-rw-r--r-- | net/mac80211/tkip.h | 4 | ||||
-rw-r--r-- | net/mac80211/wep.c | 49 | ||||
-rw-r--r-- | net/mac80211/wep.h | 5 | ||||
-rw-r--r-- | net/mac80211/wpa.c | 4 | ||||
-rw-r--r-- | net/netfilter/Kconfig | 2 | ||||
-rw-r--r-- | net/rxrpc/key.c | 21 | ||||
-rw-r--r-- | net/rxrpc/security.c | 2 | ||||
-rw-r--r-- | net/sunrpc/xprtrdma/svc_rdma_transport.c | 7 | ||||
-rw-r--r-- | net/wireless/Kconfig | 2 | ||||
-rw-r--r-- | net/wireless/lib80211_crypt_tkip.c | 48 | ||||
-rw-r--r-- | net/wireless/lib80211_crypt_wep.c | 51 | ||||
-rw-r--r-- | net/wireless/reg.c | 6 |
26 files changed, 141 insertions, 150 deletions
diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c index 9f77432dbe38..5406d7cd46ad 100644 --- a/net/bluetooth/l2cap_core.c +++ b/net/bluetooth/l2cap_core.c @@ -1353,7 +1353,7 @@ static bool l2cap_check_enc_key_size(struct hci_conn *hcon) * actually encrypted before enforcing a key size. */ return (!test_bit(HCI_CONN_ENCRYPT, &hcon->flags) || - hcon->enc_key_size > HCI_MIN_ENC_KEY_SIZE); + hcon->enc_key_size >= HCI_MIN_ENC_KEY_SIZE); } static void l2cap_do_start(struct l2cap_chan *chan) diff --git a/net/bpfilter/bpfilter_kern.c b/net/bpfilter/bpfilter_kern.c index 7ee4fea93637..c0f0990f30b6 100644 --- a/net/bpfilter/bpfilter_kern.c +++ b/net/bpfilter/bpfilter_kern.c @@ -22,7 +22,7 @@ static void shutdown_umh(void) tsk = get_pid_task(find_vpid(bpfilter_ops.info.pid), PIDTYPE_PID); if (tsk) { - force_sig(SIGKILL, tsk); + send_sig(SIGKILL, tsk, 1); put_task_struct(tsk); } } diff --git a/net/ceph/ceph_common.c b/net/ceph/ceph_common.c index 1c811c74bfc0..38de80d01aae 100644 --- a/net/ceph/ceph_common.c +++ b/net/ceph/ceph_common.c @@ -306,7 +306,7 @@ static int get_secret(struct ceph_crypto_key *dst, const char *name) { int err = 0; struct ceph_crypto_key *ckey; - ukey = request_key(&key_type_ceph, name, NULL); + ukey = request_key(&key_type_ceph, name, NULL, NULL); if (IS_ERR(ukey)) { /* request_key errors don't map nicely to mount(2) errors; don't even try, but still printk */ diff --git a/net/ceph/messenger.c b/net/ceph/messenger.c index cd0b094468b6..a33402c99321 100644 --- a/net/ceph/messenger.c +++ b/net/ceph/messenger.c @@ -1887,7 +1887,8 @@ static int ceph_dns_resolve_name(const char *name, size_t namelen, return -EINVAL; /* do dns_resolve upcall */ - ip_len = dns_query(NULL, name, end - name, NULL, &ip_addr, NULL, false); + ip_len = dns_query(current->nsproxy->net_ns, + NULL, name, end - name, NULL, &ip_addr, NULL, false); if (ip_len > 0) ret = ceph_pton(ip_addr, ip_len, addr, -1, NULL); else diff --git a/net/core/net_namespace.c b/net/core/net_namespace.c index 15f68842ac6b..f7b6dda798e0 100644 --- a/net/core/net_namespace.c +++ b/net/core/net_namespace.c @@ -39,9 +39,16 @@ EXPORT_SYMBOL_GPL(net_namespace_list); DECLARE_RWSEM(net_rwsem); EXPORT_SYMBOL_GPL(net_rwsem); +#ifdef CONFIG_KEYS +static struct key_tag init_net_key_domain = { .usage = REFCOUNT_INIT(1) }; +#endif + struct net init_net = { .count = REFCOUNT_INIT(1), .dev_base_head = LIST_HEAD_INIT(init_net.dev_base_head), +#ifdef CONFIG_KEYS + .key_domain = &init_net_key_domain, +#endif }; EXPORT_SYMBOL(init_net); @@ -387,10 +394,22 @@ static struct net *net_alloc(void) if (!net) goto out_free; +#ifdef CONFIG_KEYS + net->key_domain = kzalloc(sizeof(struct key_tag), GFP_KERNEL); + if (!net->key_domain) + goto out_free_2; + refcount_set(&net->key_domain->usage, 1); +#endif + rcu_assign_pointer(net->gen, ng); out: return net; +#ifdef CONFIG_KEYS +out_free_2: + kmem_cache_free(net_cachep, net); + net = NULL; +#endif out_free: kfree(ng); goto out; @@ -567,6 +586,7 @@ static void cleanup_net(struct work_struct *work) list_for_each_entry_safe(net, tmp, &net_exit_list, exit_list) { list_del_init(&net->exit_list); dec_net_namespaces(net->ucounts); + key_remove_domain(net->key_domain); put_user_ns(net->user_ns); net_drop_ns(net); } diff --git a/net/dns_resolver/dns_key.c b/net/dns_resolver/dns_key.c index a65d553e730d..6b201531b165 100644 --- a/net/dns_resolver/dns_key.c +++ b/net/dns_resolver/dns_key.c @@ -46,6 +46,15 @@ const struct cred *dns_resolver_cache; #define DNS_ERRORNO_OPTION "dnserror" +static struct key_acl dns_keyring_acl = { + .usage = REFCOUNT_INIT(1), + .nr_ace = 2, + .aces = { + KEY_POSSESSOR_ACE(KEY_ACE_SEARCH | KEY_ACE_WRITE), + KEY_OWNER_ACE(KEY_ACE_VIEW | KEY_ACE_READ | KEY_ACE_CLEAR), + } +}; + /* * Preparse instantiation data for a dns_resolver key. * @@ -314,6 +323,7 @@ static long dns_resolver_read(const struct key *key, struct key_type key_type_dns_resolver = { .name = "dns_resolver", + .flags = KEY_TYPE_NET_DOMAIN, .preparse = dns_resolver_preparse, .free_preparse = dns_resolver_free_preparse, .instantiate = generic_key_instantiate, @@ -342,8 +352,7 @@ static int __init init_dns_resolver(void) keyring = keyring_alloc(".dns_resolver", GLOBAL_ROOT_UID, GLOBAL_ROOT_GID, cred, - (KEY_POS_ALL & ~KEY_POS_SETATTR) | - KEY_USR_VIEW | KEY_USR_READ, + &dns_keyring_acl, KEY_ALLOC_NOT_IN_QUOTA, NULL, NULL); if (IS_ERR(keyring)) { ret = PTR_ERR(keyring); diff --git a/net/dns_resolver/dns_query.c b/net/dns_resolver/dns_query.c index 2d260432b3be..236baf2bfa4c 100644 --- a/net/dns_resolver/dns_query.c +++ b/net/dns_resolver/dns_query.c @@ -40,14 +40,26 @@ #include <linux/cred.h> #include <linux/dns_resolver.h> #include <linux/err.h> +#include <net/net_namespace.h> #include <keys/dns_resolver-type.h> #include <keys/user-type.h> #include "internal.h" +static struct key_acl dns_key_acl = { + .usage = REFCOUNT_INIT(1), + .nr_ace = 2, + .possessor_viewable = true, + .aces = { + KEY_POSSESSOR_ACE(KEY_ACE_VIEW | KEY_ACE_SEARCH | KEY_ACE_READ), + KEY_OWNER_ACE(KEY_ACE_VIEW | KEY_ACE_INVAL), + } +}; + /** * dns_query - Query the DNS + * @net: The network namespace to operate in. * @type: Query type (or NULL for straight host->IP lookup) * @name: Name to look up * @namelen: Length of name @@ -69,7 +81,8 @@ * * Returns the size of the result on success, -ve error code otherwise. */ -int dns_query(const char *type, const char *name, size_t namelen, +int dns_query(struct net *net, + const char *type, const char *name, size_t namelen, const char *options, char **_result, time64_t *_expiry, bool invalidate) { @@ -122,7 +135,8 @@ int dns_query(const char *type, const char *name, size_t namelen, * add_key() to preinstall malicious redirections */ saved_cred = override_creds(dns_resolver_cache); - rkey = request_key(&key_type_dns_resolver, desc, options); + rkey = request_key_net(&key_type_dns_resolver, desc, net, options, + &dns_key_acl); revert_creds(saved_cred); kfree(desc); if (IS_ERR(rkey)) { @@ -132,8 +146,6 @@ int dns_query(const char *type, const char *name, size_t namelen, down_read(&rkey->sem); set_bit(KEY_FLAG_ROOT_CAN_INVAL, &rkey->flags); - rkey->perm |= KEY_USR_VIEW; - ret = key_validate(rkey); if (ret < 0) goto put; diff --git a/net/mac80211/Kconfig b/net/mac80211/Kconfig index 0227cce9685e..0c93b1b7a826 100644 --- a/net/mac80211/Kconfig +++ b/net/mac80211/Kconfig @@ -3,7 +3,7 @@ config MAC80211 tristate "Generic IEEE 802.11 Networking Stack (mac80211)" depends on CFG80211 select CRYPTO - select CRYPTO_ARC4 + select CRYPTO_LIB_ARC4 select CRYPTO_AES select CRYPTO_CCM select CRYPTO_GCM diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c index a1973a26c7fc..3fae902937fd 100644 --- a/net/mac80211/cfg.c +++ b/net/mac80211/cfg.c @@ -14,6 +14,7 @@ #include <linux/slab.h> #include <net/net_namespace.h> #include <linux/rcupdate.h> +#include <linux/fips.h> #include <linux/if_ether.h> #include <net/cfg80211.h> #include "ieee80211_i.h" @@ -402,9 +403,8 @@ static int ieee80211_add_key(struct wiphy *wiphy, struct net_device *dev, case WLAN_CIPHER_SUITE_WEP40: case WLAN_CIPHER_SUITE_TKIP: case WLAN_CIPHER_SUITE_WEP104: - if (IS_ERR(local->wep_tx_tfm)) + if (WARN_ON_ONCE(fips_enabled)) return -EINVAL; - break; case WLAN_CIPHER_SUITE_CCMP: case WLAN_CIPHER_SUITE_CCMP_256: case WLAN_CIPHER_SUITE_AES_CMAC: diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h index 6396d46a9a71..004e2e3adb88 100644 --- a/net/mac80211/ieee80211_i.h +++ b/net/mac80211/ieee80211_i.h @@ -1255,8 +1255,8 @@ struct ieee80211_local { struct rate_control_ref *rate_ctrl; - struct crypto_cipher *wep_tx_tfm; - struct crypto_cipher *wep_rx_tfm; + struct arc4_ctx wep_tx_ctx; + struct arc4_ctx wep_rx_ctx; u32 wep_iv; /* see iface.c */ diff --git a/net/mac80211/key.h b/net/mac80211/key.h index be118c39433f..b8b9cd743bf4 100644 --- a/net/mac80211/key.h +++ b/net/mac80211/key.h @@ -11,6 +11,7 @@ #include <linux/list.h> #include <linux/crypto.h> #include <linux/rcupdate.h> +#include <crypto/arc4.h> #include <net/mac80211.h> #define NUM_DEFAULT_KEYS 4 diff --git a/net/mac80211/main.c b/net/mac80211/main.c index 55583b71ffaf..087c90e461b5 100644 --- a/net/mac80211/main.c +++ b/net/mac80211/main.c @@ -10,6 +10,7 @@ #include <net/mac80211.h> #include <linux/module.h> +#include <linux/fips.h> #include <linux/init.h> #include <linux/netdevice.h> #include <linux/types.h> @@ -730,8 +731,7 @@ EXPORT_SYMBOL(ieee80211_alloc_hw_nm); static int ieee80211_init_cipher_suites(struct ieee80211_local *local) { - bool have_wep = !(IS_ERR(local->wep_tx_tfm) || - IS_ERR(local->wep_rx_tfm)); + bool have_wep = !fips_enabled; /* FIPS does not permit the use of RC4 */ bool have_mfp = ieee80211_hw_check(&local->hw, MFP_CAPABLE); int n_suites = 0, r = 0, w = 0; u32 *suites; @@ -1298,7 +1298,6 @@ int ieee80211_register_hw(struct ieee80211_hw *hw) fail_rate: rtnl_unlock(); ieee80211_led_exit(local); - ieee80211_wep_free(local); fail_flows: destroy_workqueue(local->workqueue); fail_workqueue: @@ -1355,7 +1354,6 @@ void ieee80211_unregister_hw(struct ieee80211_hw *hw) destroy_workqueue(local->workqueue); wiphy_unregister(local->hw.wiphy); - ieee80211_wep_free(local); ieee80211_led_exit(local); kfree(local->int_scan_req); } diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c index 379d2ab6d327..a00b703bfdfd 100644 --- a/net/mac80211/mlme.c +++ b/net/mac80211/mlme.c @@ -12,6 +12,7 @@ */ #include <linux/delay.h> +#include <linux/fips.h> #include <linux/if_ether.h> #include <linux/skbuff.h> #include <linux/if_arp.h> @@ -5045,7 +5046,7 @@ int ieee80211_mgd_auth(struct ieee80211_sub_if_data *sdata, auth_alg = WLAN_AUTH_OPEN; break; case NL80211_AUTHTYPE_SHARED_KEY: - if (IS_ERR(local->wep_tx_tfm)) + if (fips_enabled) return -EOPNOTSUPP; auth_alg = WLAN_AUTH_SHARED_KEY; break; diff --git a/net/mac80211/tkip.c b/net/mac80211/tkip.c index 7914b8e3ce8c..727dc9f3f3b3 100644 --- a/net/mac80211/tkip.c +++ b/net/mac80211/tkip.c @@ -219,7 +219,7 @@ EXPORT_SYMBOL(ieee80211_get_tkip_p2k); * @payload_len is the length of payload (_not_ including IV/ICV length). * @ta is the transmitter addresses. */ -int ieee80211_tkip_encrypt_data(struct crypto_cipher *tfm, +int ieee80211_tkip_encrypt_data(struct arc4_ctx *ctx, struct ieee80211_key *key, struct sk_buff *skb, u8 *payload, size_t payload_len) @@ -228,7 +228,7 @@ int ieee80211_tkip_encrypt_data(struct crypto_cipher *tfm, ieee80211_get_tkip_p2k(&key->conf, skb, rc4key); - return ieee80211_wep_encrypt_data(tfm, rc4key, 16, + return ieee80211_wep_encrypt_data(ctx, rc4key, 16, payload, payload_len); } @@ -236,7 +236,7 @@ int ieee80211_tkip_encrypt_data(struct crypto_cipher *tfm, * beginning of the buffer containing IEEE 802.11 header payload, i.e., * including IV, Ext. IV, real data, Michael MIC, ICV. @payload_len is the * length of payload, including IV, Ext. IV, MIC, ICV. */ -int ieee80211_tkip_decrypt_data(struct crypto_cipher *tfm, +int ieee80211_tkip_decrypt_data(struct arc4_ctx *ctx, struct ieee80211_key *key, u8 *payload, size_t payload_len, u8 *ta, u8 *ra, int only_iv, int queue, @@ -294,7 +294,7 @@ int ieee80211_tkip_decrypt_data(struct crypto_cipher *tfm, tkip_mixing_phase2(tk, &rx_ctx->ctx, iv16, rc4key); - res = ieee80211_wep_decrypt_data(tfm, rc4key, 16, pos, payload_len - 12); + res = ieee80211_wep_decrypt_data(ctx, rc4key, 16, pos, payload_len - 12); done: if (res == TKIP_DECRYPT_OK) { /* diff --git a/net/mac80211/tkip.h b/net/mac80211/tkip.h index 676a7babdf5d..9d2f8bd36cc7 100644 --- a/net/mac80211/tkip.h +++ b/net/mac80211/tkip.h @@ -10,7 +10,7 @@ #include <linux/crypto.h> #include "key.h" -int ieee80211_tkip_encrypt_data(struct crypto_cipher *tfm, +int ieee80211_tkip_encrypt_data(struct arc4_ctx *ctx, struct ieee80211_key *key, struct sk_buff *skb, u8 *payload, size_t payload_len); @@ -21,7 +21,7 @@ enum { TKIP_DECRYPT_INVALID_KEYIDX = -2, TKIP_DECRYPT_REPLAY = -3, }; -int ieee80211_tkip_decrypt_data(struct crypto_cipher *tfm, +int ieee80211_tkip_decrypt_data(struct arc4_ctx *ctx, struct ieee80211_key *key, u8 *payload, size_t payload_len, u8 *ta, u8 *ra, int only_iv, int queue, diff --git a/net/mac80211/wep.c b/net/mac80211/wep.c index 3d9e92867ef0..b75c2c54e665 100644 --- a/net/mac80211/wep.c +++ b/net/mac80211/wep.c @@ -27,30 +27,9 @@ int ieee80211_wep_init(struct ieee80211_local *local) /* start WEP IV from a random value */ get_random_bytes(&local->wep_iv, IEEE80211_WEP_IV_LEN); - local->wep_tx_tfm = crypto_alloc_cipher("arc4", 0, 0); - if (IS_ERR(local->wep_tx_tfm)) { - local->wep_rx_tfm = ERR_PTR(-EINVAL); - return PTR_ERR(local->wep_tx_tfm); - } - - local->wep_rx_tfm = crypto_alloc_cipher("arc4", 0, 0); - if (IS_ERR(local->wep_rx_tfm)) { - crypto_free_cipher(local->wep_tx_tfm); - local->wep_tx_tfm = ERR_PTR(-EINVAL); - return PTR_ERR(local->wep_rx_tfm); - } - return 0; } -void ieee80211_wep_free(struct ieee80211_local *local) -{ - if (!IS_ERR(local->wep_tx_tfm)) - crypto_free_cipher(local->wep_tx_tfm); - if (!IS_ERR(local->wep_rx_tfm)) - crypto_free_cipher(local->wep_rx_tfm); -} - static inline bool ieee80211_wep_weak_iv(u32 iv, int keylen) { /* @@ -128,21 +107,17 @@ static void ieee80211_wep_remove_iv(struct ieee80211_local *local, /* Perform WEP encryption using given key. data buffer must have tailroom * for 4-byte ICV. data_len must not include this ICV. Note: this function * does _not_ add IV. data = RC4(data | CRC32(data)) */ -int ieee80211_wep_encrypt_data(struct crypto_cipher *tfm, u8 *rc4key, +int ieee80211_wep_encrypt_data(struct arc4_ctx *ctx, u8 *rc4key, size_t klen, u8 *data, size_t data_len) { __le32 icv; - int i; - - if (IS_ERR(tfm)) - return -1; icv = cpu_to_le32(~crc32_le(~0, data, data_len)); put_unaligned(icv, (__le32 *)(data + data_len)); - crypto_cipher_setkey(tfm, rc4key, klen); - for (i = 0; i < data_len + IEEE80211_WEP_ICV_LEN; i++) - crypto_cipher_encrypt_one(tfm, data + i, data + i); + arc4_setkey(ctx, rc4key, klen); + arc4_crypt(ctx, data, data, data_len + IEEE80211_WEP_ICV_LEN); + memzero_explicit(ctx, sizeof(*ctx)); return 0; } @@ -181,7 +156,7 @@ int ieee80211_wep_encrypt(struct ieee80211_local *local, /* Add room for ICV */ skb_put(skb, IEEE80211_WEP_ICV_LEN); - return ieee80211_wep_encrypt_data(local->wep_tx_tfm, rc4key, keylen + 3, + return ieee80211_wep_encrypt_data(&local->wep_tx_ctx, rc4key, keylen + 3, iv + IEEE80211_WEP_IV_LEN, len); } @@ -189,18 +164,14 @@ int ieee80211_wep_encrypt(struct ieee80211_local *local, /* Perform WEP decryption using given key. data buffer includes encrypted * payload, including 4-byte ICV, but _not_ IV. data_len must not include ICV. * Return 0 on success and -1 on ICV mismatch. */ -int ieee80211_wep_decrypt_data(struct crypto_cipher *tfm, u8 *rc4key, +int ieee80211_wep_decrypt_data(struct arc4_ctx *ctx, u8 *rc4key, size_t klen, u8 *data, size_t data_len) { __le32 crc; - int i; - - if (IS_ERR(tfm)) - return -1; - crypto_cipher_setkey(tfm, rc4key, klen); - for (i = 0; i < data_len + IEEE80211_WEP_ICV_LEN; i++) - crypto_cipher_decrypt_one(tfm, data + i, data + i); + arc4_setkey(ctx, rc4key, klen); + arc4_crypt(ctx, data, data, data_len + IEEE80211_WEP_ICV_LEN); + memzero_explicit(ctx, sizeof(*ctx)); crc = cpu_to_le32(~crc32_le(~0, data, data_len)); if (memcmp(&crc, data + data_len, IEEE80211_WEP_ICV_LEN) != 0) @@ -253,7 +224,7 @@ static int ieee80211_wep_decrypt(struct ieee80211_local *local, /* Copy rest of the WEP key (the secret part) */ memcpy(rc4key + 3, key->conf.key, key->conf.keylen); - if (ieee80211_wep_decrypt_data(local->wep_rx_tfm, rc4key, klen, + if (ieee80211_wep_decrypt_data(&local->wep_rx_ctx, rc4key, klen, skb->data + hdrlen + IEEE80211_WEP_IV_LEN, len)) ret = -1; diff --git a/net/mac80211/wep.h b/net/mac80211/wep.h index 866a6798c9ef..997a034233c2 100644 --- a/net/mac80211/wep.h +++ b/net/mac80211/wep.h @@ -14,13 +14,12 @@ #include "key.h" int ieee80211_wep_init(struct ieee80211_local *local); -void ieee80211_wep_free(struct ieee80211_local *local); -int ieee80211_wep_encrypt_data(struct crypto_cipher *tfm, u8 *rc4key, +int ieee80211_wep_encrypt_data(struct arc4_ctx *ctx, u8 *rc4key, size_t klen, u8 *data, size_t data_len); int ieee80211_wep_encrypt(struct ieee80211_local *local, struct sk_buff *skb, const u8 *key, int keylen, int keyidx); -int ieee80211_wep_decrypt_data(struct crypto_cipher *tfm, u8 *rc4key, +int ieee80211_wep_decrypt_data(struct arc4_ctx *ctx, u8 *rc4key, size_t klen, u8 *data, size_t data_len); ieee80211_rx_result diff --git a/net/mac80211/wpa.c b/net/mac80211/wpa.c index a51c7909366e..ee72779729e5 100644 --- a/net/mac80211/wpa.c +++ b/net/mac80211/wpa.c @@ -239,7 +239,7 @@ static int tkip_encrypt_skb(struct ieee80211_tx_data *tx, struct sk_buff *skb) /* Add room for ICV */ skb_put(skb, IEEE80211_TKIP_ICV_LEN); - return ieee80211_tkip_encrypt_data(tx->local->wep_tx_tfm, + return ieee80211_tkip_encrypt_data(&tx->local->wep_tx_ctx, key, skb, pos, len); } @@ -290,7 +290,7 @@ ieee80211_crypto_tkip_decrypt(struct ieee80211_rx_data *rx) if (status->flag & RX_FLAG_DECRYPTED) hwaccel = 1; - res = ieee80211_tkip_decrypt_data(rx->local->wep_rx_tfm, + res = ieee80211_tkip_decrypt_data(&rx->local->wep_rx_ctx, key, skb->data + hdrlen, skb->len - hdrlen, rx->sta->sta.addr, hdr->addr1, hwaccel, rx->security_idx, diff --git a/net/netfilter/Kconfig b/net/netfilter/Kconfig index 21025c2c605b..66cc11742355 100644 --- a/net/netfilter/Kconfig +++ b/net/netfilter/Kconfig @@ -906,7 +906,7 @@ config NETFILTER_XT_TARGET_LED echo netfilter-ssh > /sys/class/leds/<ledname>/trigger For more information on the LEDs available on your system, see - Documentation/leds/leds-class.txt + Documentation/leds/leds-class.rst config NETFILTER_XT_TARGET_LOG tristate "LOG target support" diff --git a/net/rxrpc/key.c b/net/rxrpc/key.c index 83e3357a65a6..2032f6a8225e 100644 --- a/net/rxrpc/key.c +++ b/net/rxrpc/key.c @@ -23,6 +23,14 @@ #include <keys/user-type.h> #include "ar-internal.h" +static struct key_acl rxrpc_null_key_acl = { + .usage = REFCOUNT_INIT(1), + .nr_ace = 1, + .aces = { + KEY_POSSESSOR_ACE(KEY_ACE_SEARCH | KEY_ACE_READ), + } +}; + static int rxrpc_vet_description_s(const char *); static int rxrpc_preparse(struct key_preparsed_payload *); static int rxrpc_preparse_s(struct key_preparsed_payload *); @@ -39,6 +47,7 @@ static long rxrpc_read(const struct key *, char __user *, size_t); */ struct key_type key_type_rxrpc = { .name = "rxrpc", + .flags = KEY_TYPE_NET_DOMAIN, .preparse = rxrpc_preparse, .free_preparse = rxrpc_free_preparse, .instantiate = generic_key_instantiate, @@ -54,6 +63,7 @@ EXPORT_SYMBOL(key_type_rxrpc); */ struct key_type key_type_rxrpc_s = { .name = "rxrpc_s", + .flags = KEY_TYPE_NET_DOMAIN, .vet_description = rxrpc_vet_description_s, .preparse = rxrpc_preparse_s, .free_preparse = rxrpc_free_preparse_s, @@ -908,7 +918,8 @@ int rxrpc_request_key(struct rxrpc_sock *rx, char __user *optval, int optlen) if (IS_ERR(description)) return PTR_ERR(description); - key = request_key(&key_type_rxrpc, description, NULL); + key = request_key_net(&key_type_rxrpc, description, sock_net(&rx->sk), + NULL, NULL); if (IS_ERR(key)) { kfree(description); _leave(" = %ld", PTR_ERR(key)); @@ -939,7 +950,8 @@ int rxrpc_server_keyring(struct rxrpc_sock *rx, char __user *optval, if (IS_ERR(description)) return PTR_ERR(description); - key = request_key(&key_type_keyring, description, NULL); + key = request_key_net(&key_type_keyring, description, sock_net(&rx->sk), + NULL, NULL); if (IS_ERR(key)) { kfree(description); _leave(" = %ld", PTR_ERR(key)); @@ -972,7 +984,8 @@ int rxrpc_get_server_data_key(struct rxrpc_connection *conn, _enter(""); key = key_alloc(&key_type_rxrpc, "x", - GLOBAL_ROOT_UID, GLOBAL_ROOT_GID, cred, 0, + GLOBAL_ROOT_UID, GLOBAL_ROOT_GID, cred, + &internal_key_acl, KEY_ALLOC_NOT_IN_QUOTA, NULL); if (IS_ERR(key)) { _leave(" = -ENOMEM [alloc %ld]", PTR_ERR(key)); @@ -1020,7 +1033,7 @@ struct key *rxrpc_get_null_key(const char *keyname) key = key_alloc(&key_type_rxrpc, keyname, GLOBAL_ROOT_UID, GLOBAL_ROOT_GID, cred, - KEY_POS_SEARCH, KEY_ALLOC_NOT_IN_QUOTA, NULL); + &rxrpc_null_key_acl, KEY_ALLOC_NOT_IN_QUOTA, NULL); if (IS_ERR(key)) return key; diff --git a/net/rxrpc/security.c b/net/rxrpc/security.c index 2e78f0cc7ef1..a4c47d2b7054 100644 --- a/net/rxrpc/security.c +++ b/net/rxrpc/security.c @@ -144,7 +144,7 @@ found_service: /* look through the service's keyring */ kref = keyring_search(make_key_ref(rx->securities, 1UL), - &key_type_rxrpc_s, kdesc); + &key_type_rxrpc_s, kdesc, true); if (IS_ERR(kref)) { read_unlock(&local->services_lock); _leave(" = %ld [search]", PTR_ERR(kref)); diff --git a/net/sunrpc/xprtrdma/svc_rdma_transport.c b/net/sunrpc/xprtrdma/svc_rdma_transport.c index 027a3b07d329..0004535c0188 100644 --- a/net/sunrpc/xprtrdma/svc_rdma_transport.c +++ b/net/sunrpc/xprtrdma/svc_rdma_transport.c @@ -211,9 +211,14 @@ static void handle_connect_req(struct rdma_cm_id *new_cma_id, /* Save client advertised inbound read limit for use later in accept. */ newxprt->sc_ord = param->initiator_depth; - /* Set the local and remote addresses in the transport */ sa = (struct sockaddr *)&newxprt->sc_cm_id->route.addr.dst_addr; svc_xprt_set_remote(&newxprt->sc_xprt, sa, svc_addr_len(sa)); + /* The remote port is arbitrary and not under the control of the + * client ULP. Set it to a fixed value so that the DRC continues + * to be effective after a reconnect. + */ + rpc_set_port((struct sockaddr *)&newxprt->sc_xprt.xpt_remote, 0); + sa = (struct sockaddr *)&newxprt->sc_cm_id->route.addr.src_addr; svc_xprt_set_local(&newxprt->sc_xprt, sa, svc_addr_len(sa)); diff --git a/net/wireless/Kconfig b/net/wireless/Kconfig index 6310ddede220..578cce4fbe6c 100644 --- a/net/wireless/Kconfig +++ b/net/wireless/Kconfig @@ -213,12 +213,14 @@ config LIB80211 config LIB80211_CRYPT_WEP tristate + select CRYPTO_LIB_ARC4 config LIB80211_CRYPT_CCMP tristate config LIB80211_CRYPT_TKIP tristate + select CRYPTO_LIB_ARC4 config LIB80211_DEBUG bool "lib80211 debugging messages" diff --git a/net/wireless/lib80211_crypt_tkip.c b/net/wireless/lib80211_crypt_tkip.c index 62edf5b01953..f5e842ba7673 100644 --- a/net/wireless/lib80211_crypt_tkip.c +++ b/net/wireless/lib80211_crypt_tkip.c @@ -9,6 +9,7 @@ #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt #include <linux/err.h> +#include <linux/fips.h> #include <linux/module.h> #include <linux/init.h> #include <linux/slab.h> @@ -25,6 +26,7 @@ #include <linux/ieee80211.h> #include <net/iw_handler.h> +#include <crypto/arc4.h> #include <crypto/hash.h> #include <linux/crypto.h> #include <linux/crc32.h> @@ -60,9 +62,9 @@ struct lib80211_tkip_data { int key_idx; - struct crypto_cipher *rx_tfm_arc4; + struct arc4_ctx rx_ctx_arc4; + struct arc4_ctx tx_ctx_arc4; struct crypto_shash *rx_tfm_michael; - struct crypto_cipher *tx_tfm_arc4; struct crypto_shash *tx_tfm_michael; /* scratch buffers for virt_to_page() (crypto API) */ @@ -89,30 +91,21 @@ static void *lib80211_tkip_init(int key_idx) { struct lib80211_tkip_data *priv; + if (fips_enabled) + return NULL; + priv = kzalloc(sizeof(*priv), GFP_ATOMIC); if (priv == NULL) goto fail; priv->key_idx = key_idx; - priv->tx_tfm_arc4 = crypto_alloc_cipher("arc4", 0, 0); - if (IS_ERR(priv->tx_tfm_arc4)) { - priv->tx_tfm_arc4 = NULL; - goto fail; - } - priv->tx_tfm_michael = crypto_alloc_shash("michael_mic", 0, 0); if (IS_ERR(priv->tx_tfm_michael)) { priv->tx_tfm_michael = NULL; goto fail; } - priv->rx_tfm_arc4 = crypto_alloc_cipher("arc4", 0, 0); - if (IS_ERR(priv->rx_tfm_arc4)) { - priv->rx_tfm_arc4 = NULL; - goto fail; - } - priv->rx_tfm_michael = crypto_alloc_shash("michael_mic", 0, 0); if (IS_ERR(priv->rx_tfm_michael)) { priv->rx_tfm_michael = NULL; @@ -124,9 +117,7 @@ static void *lib80211_tkip_init(int key_idx) fail: if (priv) { crypto_free_shash(priv->tx_tfm_michael); - crypto_free_cipher(priv->tx_tfm_arc4); crypto_free_shash(priv->rx_tfm_michael); - crypto_free_cipher(priv->rx_tfm_arc4); kfree(priv); } @@ -138,11 +129,9 @@ static void lib80211_tkip_deinit(void *priv) struct lib80211_tkip_data *_priv = priv; if (_priv) { crypto_free_shash(_priv->tx_tfm_michael); - crypto_free_cipher(_priv->tx_tfm_arc4); crypto_free_shash(_priv->rx_tfm_michael); - crypto_free_cipher(_priv->rx_tfm_arc4); } - kfree(priv); + kzfree(priv); } static inline u16 RotR1(u16 val) @@ -341,7 +330,6 @@ static int lib80211_tkip_encrypt(struct sk_buff *skb, int hdr_len, void *priv) int len; u8 rc4key[16], *pos, *icv; u32 crc; - int i; if (tkey->flags & IEEE80211_CRYPTO_TKIP_COUNTERMEASURES) { struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; @@ -366,9 +354,9 @@ static int lib80211_tkip_encrypt(struct sk_buff *skb, int hdr_len, void *priv) icv[2] = crc >> 16; icv[3] = crc >> 24; - crypto_cipher_setkey(tkey->tx_tfm_arc4, rc4key, 16); - for (i = 0; i < len + 4; i++) - crypto_cipher_encrypt_one(tkey->tx_tfm_arc4, pos + i, pos + i); + arc4_setkey(&tkey->tx_ctx_arc4, rc4key, 16); + arc4_crypt(&tkey->tx_ctx_arc4, pos, pos, len + 4); + return 0; } @@ -396,7 +384,6 @@ static int lib80211_tkip_decrypt(struct sk_buff *skb, int hdr_len, void *priv) u8 icv[4]; u32 crc; int plen; - int i; hdr = (struct ieee80211_hdr *)skb->data; @@ -449,9 +436,8 @@ static int lib80211_tkip_decrypt(struct sk_buff *skb, int hdr_len, void *priv) plen = skb->len - hdr_len - 12; - crypto_cipher_setkey(tkey->rx_tfm_arc4, rc4key, 16); - for (i = 0; i < plen + 4; i++) - crypto_cipher_decrypt_one(tkey->rx_tfm_arc4, pos + i, pos + i); + arc4_setkey(&tkey->rx_ctx_arc4, rc4key, 16); + arc4_crypt(&tkey->rx_ctx_arc4, pos, pos, plen + 4); crc = ~crc32_le(~0, pos, plen); icv[0] = crc; @@ -636,17 +622,17 @@ static int lib80211_tkip_set_key(void *key, int len, u8 * seq, void *priv) struct lib80211_tkip_data *tkey = priv; int keyidx; struct crypto_shash *tfm = tkey->tx_tfm_michael; - struct crypto_cipher *tfm2 = tkey->tx_tfm_arc4; + struct arc4_ctx *tfm2 = &tkey->tx_ctx_arc4; struct crypto_shash *tfm3 = tkey->rx_tfm_michael; - struct crypto_cipher *tfm4 = tkey->rx_tfm_arc4; + struct arc4_ctx *tfm4 = &tkey->rx_ctx_arc4; keyidx = tkey->key_idx; memset(tkey, 0, sizeof(*tkey)); tkey->key_idx = keyidx; tkey->tx_tfm_michael = tfm; - tkey->tx_tfm_arc4 = tfm2; + tkey->tx_ctx_arc4 = *tfm2; tkey->rx_tfm_michael = tfm3; - tkey->rx_tfm_arc4 = tfm4; + tkey->rx_ctx_arc4 = *tfm4; if (len == TKIP_KEY_LEN) { memcpy(tkey->key, key, TKIP_KEY_LEN); tkey->key_set = 1; diff --git a/net/wireless/lib80211_crypt_wep.c b/net/wireless/lib80211_crypt_wep.c index e127b6f7fc9f..dafc6f3571db 100644 --- a/net/wireless/lib80211_crypt_wep.c +++ b/net/wireless/lib80211_crypt_wep.c @@ -7,6 +7,7 @@ */ #include <linux/err.h> +#include <linux/fips.h> #include <linux/module.h> #include <linux/init.h> #include <linux/slab.h> @@ -18,7 +19,7 @@ #include <net/lib80211.h> -#include <linux/crypto.h> +#include <crypto/arc4.h> #include <linux/crc32.h> MODULE_AUTHOR("Jouni Malinen"); @@ -31,52 +32,31 @@ struct lib80211_wep_data { u8 key[WEP_KEY_LEN + 1]; u8 key_len; u8 key_idx; - struct crypto_cipher *tx_tfm; - struct crypto_cipher *rx_tfm; + struct arc4_ctx tx_ctx; + struct arc4_ctx rx_ctx; }; static void *lib80211_wep_init(int keyidx) { struct lib80211_wep_data *priv; + if (fips_enabled) + return NULL; + priv = kzalloc(sizeof(*priv), GFP_ATOMIC); if (priv == NULL) - goto fail; + return NULL; priv->key_idx = keyidx; - priv->tx_tfm = crypto_alloc_cipher("arc4", 0, 0); - if (IS_ERR(priv->tx_tfm)) { - priv->tx_tfm = NULL; - goto fail; - } - - priv->rx_tfm = crypto_alloc_cipher("arc4", 0, 0); - if (IS_ERR(priv->rx_tfm)) { - priv->rx_tfm = NULL; - goto fail; - } /* start WEP IV from a random value */ get_random_bytes(&priv->iv, 4); return priv; - - fail: - if (priv) { - crypto_free_cipher(priv->tx_tfm); - crypto_free_cipher(priv->rx_tfm); - kfree(priv); - } - return NULL; } static void lib80211_wep_deinit(void *priv) { - struct lib80211_wep_data *_priv = priv; - if (_priv) { - crypto_free_cipher(_priv->tx_tfm); - crypto_free_cipher(_priv->rx_tfm); - } - kfree(priv); + kzfree(priv); } /* Add WEP IV/key info to a frame that has at least 4 bytes of headroom */ @@ -128,7 +108,6 @@ static int lib80211_wep_encrypt(struct sk_buff *skb, int hdr_len, void *priv) u32 crc, klen, len; u8 *pos, *icv; u8 key[WEP_KEY_LEN + 3]; - int i; /* other checks are in lib80211_wep_build_iv */ if (skb_tailroom(skb) < 4) @@ -156,10 +135,8 @@ static int lib80211_wep_encrypt(struct sk_buff *skb, int hdr_len, void *priv) icv[2] = crc >> 16; icv[3] = crc >> 24; - crypto_cipher_setkey(wep->tx_tfm, key, klen); - - for (i = 0; i < len + 4; i++) - crypto_cipher_encrypt_one(wep->tx_tfm, pos + i, pos + i); + arc4_setkey(&wep->tx_ctx, key, klen); + arc4_crypt(&wep->tx_ctx, pos, pos, len + 4); return 0; } @@ -177,7 +154,6 @@ static int lib80211_wep_decrypt(struct sk_buff *skb, int hdr_len, void *priv) u32 crc, klen, plen; u8 key[WEP_KEY_LEN + 3]; u8 keyidx, *pos, icv[4]; - int i; if (skb->len < hdr_len + 8) return -1; @@ -198,9 +174,8 @@ static int lib80211_wep_decrypt(struct sk_buff *skb, int hdr_len, void *priv) /* Apply RC4 to data and compute CRC32 over decrypted data */ plen = skb->len - hdr_len - 8; - crypto_cipher_setkey(wep->rx_tfm, key, klen); - for (i = 0; i < plen + 4; i++) - crypto_cipher_decrypt_one(wep->rx_tfm, pos + i, pos + i); + arc4_setkey(&wep->rx_ctx, key, klen); + arc4_crypt(&wep->rx_ctx, pos, pos, plen + 4); crc = ~crc32_le(~0, pos, plen); icv[0] = crc; diff --git a/net/wireless/reg.c b/net/wireless/reg.c index 4831ad745f91..298fe91557f7 100644 --- a/net/wireless/reg.c +++ b/net/wireless/reg.c @@ -741,8 +741,7 @@ static void __init load_keys_from_buffer(const u8 *p, unsigned int buflen) key = key_create_or_update(make_key_ref(builtin_regdb_keys, 1), "asymmetric", NULL, p, plen, - ((KEY_POS_ALL & ~KEY_POS_SETATTR) | - KEY_USR_VIEW | KEY_USR_READ), + &internal_key_acl, KEY_ALLOC_NOT_IN_QUOTA | KEY_ALLOC_BUILT_IN | KEY_ALLOC_BYPASS_RESTRICTION); @@ -768,8 +767,7 @@ static int __init load_builtin_regdb_keys(void) builtin_regdb_keys = keyring_alloc(".builtin_regdb_keys", KUIDT_INIT(0), KGIDT_INIT(0), current_cred(), - ((KEY_POS_ALL & ~KEY_POS_SETATTR) | - KEY_USR_VIEW | KEY_USR_READ | KEY_USR_SEARCH), + &internal_keyring_acl, KEY_ALLOC_NOT_IN_QUOTA, NULL, NULL); if (IS_ERR(builtin_regdb_keys)) return PTR_ERR(builtin_regdb_keys); |