diff mbox series

[net] enic: Validate length of nl attributes in enic_set_vf_port

Message ID 20240516154248.33134-1-rzats@paloaltonetworks.com (mailing list archive)
State Superseded
Delegated to: Netdev Maintainers
Headers show
Series [net] enic: Validate length of nl attributes in enic_set_vf_port | expand

Checks

Context Check Description
netdev/series_format success Single patches do not need cover letters
netdev/tree_selection success Clearly marked for net
netdev/ynl success Generated files up to date; no warnings/errors; no diff in generated;
netdev/fixes_present success Fixes tag present in non-next series
netdev/header_inline success No static functions without inline keyword in header files
netdev/build_32bit success Errors and warnings before: 928 this patch: 928
netdev/build_tools success No tools touched, skip
netdev/cc_maintainers success CCed 6 of 8 maintainers
netdev/build_clang success Errors and warnings before: 925 this patch: 925
netdev/verify_signedoff success Signed-off-by tag matches author and committer
netdev/deprecated_api success None detected
netdev/check_selftest success No net selftest shell script
netdev/verify_fixes success Fixes tag looks correct
netdev/build_allmodconfig_warn success Errors and warnings before: 935 this patch: 935
netdev/checkpatch success total: 0 errors, 0 warnings, 0 checks, 30 lines checked
netdev/build_clang_rust success No Rust files in patch. Skipping build
netdev/kdoc success Errors and warnings before: 0 this patch: 0
netdev/source_inline success Was 0 now: 0
netdev/contest success net-next-2024-05-19--03-00 (tests: 1039)

Commit Message

Roded Zats May 16, 2024, 3:42 p.m. UTC
enic_set_vf_port assumes that the nl attribute IFLA_PORT_PROFILE
is of length PORT_PROFILE_MAX and that the nl attributes
IFLA_PORT_INSTANCE_UUID, IFLA_PORT_HOST_UUID are of length PORT_UUID_MAX.
These attributes are validated (in the function do_setlink in rtnetlink.c)
using the nla_policy ifla_port_policy. The policy defines IFLA_PORT_PROFILE
as NLA_STRING, IFLA_PORT_INSTANCE_UUID as NLA_BINARY and
IFLA_PORT_HOST_UUID as NLA_STRING. That means that the length validation
using the policy is for the max size of the attributes and not on exact
size so the length of these attributes might be less than the sizes that
enic_set_vf_port expects. This might cause an out of bands
read access in the memcpys of the data of these
attributes in enic_set_vf_port.

Fixes: f8bd909183ac ("net: Add ndo_{set|get}_vf_port support for enic dynamic vnics")
Signed-off-by: Roded Zats <rzats@paloaltonetworks.com>
---
 drivers/net/ethernet/cisco/enic/enic_main.c | 12 ++++++++++++
 1 file changed, 12 insertions(+)

Comments

Paolo Abeni May 21, 2024, 10:38 a.m. UTC | #1
On Thu, 2024-05-16 at 18:42 +0300, Roded Zats wrote:
> enic_set_vf_port assumes that the nl attribute IFLA_PORT_PROFILE
> is of length PORT_PROFILE_MAX and that the nl attributes
> IFLA_PORT_INSTANCE_UUID, IFLA_PORT_HOST_UUID are of length PORT_UUID_MAX.
> These attributes are validated (in the function do_setlink in rtnetlink.c)
> using the nla_policy ifla_port_policy. The policy defines IFLA_PORT_PROFILE
> as NLA_STRING, IFLA_PORT_INSTANCE_UUID as NLA_BINARY and
> IFLA_PORT_HOST_UUID as NLA_STRING. That means that the length validation
> using the policy is for the max size of the attributes and not on exact
> size so the length of these attributes might be less than the sizes that
> enic_set_vf_port expects. This might cause an out of bands
> read access in the memcpys of the data of these
> attributes in enic_set_vf_port.
> 
> Fixes: f8bd909183ac ("net: Add ndo_{set|get}_vf_port support for enic dynamic vnics")
> Signed-off-by: Roded Zats <rzats@paloaltonetworks.com>
> ---
>  drivers/net/ethernet/cisco/enic/enic_main.c | 12 ++++++++++++
>  1 file changed, 12 insertions(+)
> 
> diff --git a/drivers/net/ethernet/cisco/enic/enic_main.c b/drivers/net/ethernet/cisco/enic/enic_main.c
> index f604119efc80..4179c6f9580d 100644
> --- a/drivers/net/ethernet/cisco/enic/enic_main.c
> +++ b/drivers/net/ethernet/cisco/enic/enic_main.c
> @@ -1117,18 +1117,30 @@ static int enic_set_vf_port(struct net_device *netdev, int vf,
>  	pp->request = nla_get_u8(port[IFLA_PORT_REQUEST]);
>  
>  	if (port[IFLA_PORT_PROFILE]) {
> +		if (nla_len(port[IFLA_PORT_PROFILE]) != PORT_PROFILE_MAX) {
> +			memcpy(pp, &prev_pp, sizeof(*pp));
> +			return -EOPNOTSUPP;

I think -EOPNOTSUPP is misleading here (and below), -EINVAL should be
appropriate.

Thanks,

Paolo
diff mbox series

Patch

diff --git a/drivers/net/ethernet/cisco/enic/enic_main.c b/drivers/net/ethernet/cisco/enic/enic_main.c
index f604119efc80..4179c6f9580d 100644
--- a/drivers/net/ethernet/cisco/enic/enic_main.c
+++ b/drivers/net/ethernet/cisco/enic/enic_main.c
@@ -1117,18 +1117,30 @@  static int enic_set_vf_port(struct net_device *netdev, int vf,
 	pp->request = nla_get_u8(port[IFLA_PORT_REQUEST]);
 
 	if (port[IFLA_PORT_PROFILE]) {
+		if (nla_len(port[IFLA_PORT_PROFILE]) != PORT_PROFILE_MAX) {
+			memcpy(pp, &prev_pp, sizeof(*pp));
+			return -EOPNOTSUPP;
+		}
 		pp->set |= ENIC_SET_NAME;
 		memcpy(pp->name, nla_data(port[IFLA_PORT_PROFILE]),
 			PORT_PROFILE_MAX);
 	}
 
 	if (port[IFLA_PORT_INSTANCE_UUID]) {
+		if (nla_len(port[IFLA_PORT_INSTANCE_UUID]) != PORT_UUID_MAX) {
+			memcpy(pp, &prev_pp, sizeof(*pp));
+			return -EOPNOTSUPP;
+		}
 		pp->set |= ENIC_SET_INSTANCE;
 		memcpy(pp->instance_uuid,
 			nla_data(port[IFLA_PORT_INSTANCE_UUID]), PORT_UUID_MAX);
 	}
 
 	if (port[IFLA_PORT_HOST_UUID]) {
+		if (nla_len(port[IFLA_PORT_HOST_UUID]) != PORT_UUID_MAX) {
+			memcpy(pp, &prev_pp, sizeof(*pp));
+			return -EOPNOTSUPP;
+		}
 		pp->set |= ENIC_SET_HOST;
 		memcpy(pp->host_uuid,
 			nla_data(port[IFLA_PORT_HOST_UUID]), PORT_UUID_MAX);