lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <8ed53007-cc7c-4747-a690-f27915f2be8d@openvpn.net>
Date: Tue, 12 Nov 2024 16:40:19 +0100
From: Antonio Quartulli <antonio@...nvpn.net>
To: Sabrina Dubroca <sd@...asysnail.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

On 05/11/2024 11:16, Sabrina Dubroca wrote:
> 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.

ACK.

> 
>> +	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.

ACK

> 
> 
>> +
>> +	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.

I tried to keep the signature similar to send_peer, but indeed they can 
both be simplified.

> 
>> +	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?

very likely.

Thanks a lot

Regards,

> 
> 
>> +	if (NL_REQ_ATTR_CHECK(info->extack, info->attrs[OVPN_A_KEYCONF], attrs,
>> +			      OVPN_A_KEYCONF_SLOT))
>> +		return -EINVAL;
> 

-- 
Antonio Quartulli
OpenVPN Inc.


Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ