[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <ZynwjJNz6kLa4p7x@hog>
Date: Tue, 5 Nov 2024 11:16:44 +0100
From: Sabrina Dubroca <sd@...asysnail.net>
To: Antonio Quartulli <antonio@...nvpn.net>
Cc: Eric Dumazet <edumazet@...gle.com>, Jakub Kicinski <kuba@...nel.org>,
Paolo Abeni <pabeni@...hat.com>,
Donald Hunter <donald.hunter@...il.com>,
Shuah Khan <shuah@...nel.org>, ryazanov.s.a@...il.com,
Andrew Lunn <andrew@...n.ch>, netdev@...r.kernel.org,
linux-kernel@...r.kernel.org, linux-kselftest@...r.kernel.org
Subject: Re: [PATCH net-next v11 19/23] ovpn: implement key add/get/del/swap
via netlink
2024-10-29, 11:47:32 +0100, Antonio Quartulli wrote:
> This change introduces the netlink commands needed to add, get, delete
> and swap keys for a specific peer.
>
> Userspace is expected to use these commands to create, inspect (non
> sensible data only), destroy and rotate session keys for a specific
nit: s/sensible/sensitive/
> +int ovpn_crypto_config_get(struct ovpn_crypto_state *cs,
> + enum ovpn_key_slot slot,
> + struct ovpn_key_config *keyconf)
> +{
[...]
> +
> + rcu_read_lock();
> + ks = rcu_dereference(cs->slots[idx]);
> + if (!ks || (ks && !ovpn_crypto_key_slot_hold(ks))) {
> + rcu_read_unlock();
> + return -ENOENT;
> + }
> + rcu_read_unlock();
You could stay under rcu_read_lock a little bit longer and avoid
taking a reference just to release it immediately.
> + keyconf->cipher_alg = ovpn_aead_crypto_alg(ks);
> + keyconf->key_id = ks->key_id;
> +
> + ovpn_crypto_key_slot_put(ks);
> +
> + return 0;
> +}
[...]
> int ovpn_nl_key_get_doit(struct sk_buff *skb, struct genl_info *info)
> {
[...]
> + if (NL_REQ_ATTR_CHECK(info->extack, info->attrs[OVPN_A_KEYCONF], attrs,
> + OVPN_A_KEYCONF_PEER_ID))
> + return -EINVAL;
> +
> + peer_id = nla_get_u32(attrs[OVPN_A_KEYCONF_PEER_ID]);
> +
> + peer = ovpn_peer_get_by_id(ovpn, peer_id);
> + if (!peer) {
> + NL_SET_ERR_MSG_FMT_MOD(info->extack,
> + "cannot find peer with id %u", 0);
peer_id?
> + return -ENOENT;
> + }
> +
> + if (NL_REQ_ATTR_CHECK(info->extack, info->attrs[OVPN_A_KEYCONF], attrs,
> + OVPN_A_KEYCONF_SLOT))
> + return -EINVAL;
Move this check before ovpn_peer_get_by_id? We're leaking a reference
on the peer.
> +
> + slot = nla_get_u32(attrs[OVPN_A_KEYCONF_SLOT]);
> +
> + ret = ovpn_crypto_config_get(&peer->crypto, slot, &keyconf);
> + if (ret < 0) {
> + NL_SET_ERR_MSG_FMT_MOD(info->extack,
> + "cannot extract key from slot %u for peer %u",
> + slot, peer_id);
> + goto err;
> + }
> +
> + msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
> + if (!msg) {
> + ret = -ENOMEM;
> + goto err;
> + }
> +
> + ret = ovpn_nl_send_key(msg, info, peer->id, slot, &keyconf,
> + info->snd_portid, info->snd_seq, 0);
info->snd_portid and info->snd_seq can be extracted from info directly
in ovpn_nl_send_key since there's no other caller, and flags=0 can be
skipped as well.
> + if (ret < 0) {
> + nlmsg_free(msg);
> + goto err;
> + }
> +
> + ret = genlmsg_reply(msg, info);
> +err:
> + ovpn_peer_put(peer);
> + return ret;
> }
[...]
> int ovpn_nl_key_del_doit(struct sk_buff *skb, struct genl_info *info)
> {
> - return -EOPNOTSUPP;
> + struct nlattr *attrs[OVPN_A_KEYCONF_MAX + 1];
> + struct ovpn_struct *ovpn = info->user_ptr[0];
> + enum ovpn_key_slot slot;
> + struct ovpn_peer *peer;
> + u32 peer_id;
> + int ret;
> +
> + if (GENL_REQ_ATTR_CHECK(info, OVPN_A_KEYCONF))
> + return -EINVAL;
> +
> + ret = nla_parse_nested(attrs, OVPN_A_KEYCONF_MAX,
> + info->attrs[OVPN_A_KEYCONF],
> + ovpn_keyconf_nl_policy, info->extack);
> + if (ret)
> + return ret;
> +
> + if (NL_REQ_ATTR_CHECK(info->extack, info->attrs[OVPN_A_KEYCONF], attrs,
> + OVPN_A_KEYCONF_PEER_ID))
> + return -EINVAL;
> +
> + if (ret)
> + return ret;
leftover?
> + if (NL_REQ_ATTR_CHECK(info->extack, info->attrs[OVPN_A_KEYCONF], attrs,
> + OVPN_A_KEYCONF_SLOT))
> + return -EINVAL;
--
Sabrina
Powered by blists - more mailing lists