Commit 1388dd56 authored by Mateusz Polchlopek's avatar Mateusz Polchlopek Committed by Tony Nguyen
Browse files

ice: fix using untrusted value of pkt_len in ice_vc_fdir_parse_raw()



Fix using the untrusted value of proto->raw.pkt_len in function
ice_vc_fdir_parse_raw() by verifying if it does not exceed the
VIRTCHNL_MAX_SIZE_RAW_PACKET value.

Fixes: 99f419df ("ice: enable FDIR filters from raw binary patterns for VFs")
Reviewed-by: default avatarPrzemek Kitszel <przemyslaw.kitszel@intel.com>
Signed-off-by: default avatarMateusz Polchlopek <mateusz.polchlopek@intel.com>
Signed-off-by: default avatarMartyna Szapar-Mudlaw <martyna.szapar-mudlaw@linux.intel.com>
Tested-by: default avatarRafal Romanowski <rafal.romanowski@intel.com>
Signed-off-by: default avatarTony Nguyen <anthony.l.nguyen@intel.com>
parent c5be6562
Loading
Loading
Loading
Loading
+15 −9
Original line number Diff line number Diff line
@@ -832,21 +832,27 @@ ice_vc_fdir_parse_raw(struct ice_vf *vf,
		      struct virtchnl_proto_hdrs *proto,
		      struct virtchnl_fdir_fltr_conf *conf)
{
	u8 *pkt_buf, *msk_buf __free(kfree);
	u8 *pkt_buf, *msk_buf __free(kfree) = NULL;
	struct ice_parser_result rslt;
	struct ice_pf *pf = vf->pf;
	u16 pkt_len, udp_port = 0;
	struct ice_parser *psr;
	int status = -ENOMEM;
	struct ice_hw *hw;
	u16 udp_port = 0;

	pkt_buf = kzalloc(proto->raw.pkt_len, GFP_KERNEL);
	msk_buf = kzalloc(proto->raw.pkt_len, GFP_KERNEL);
	pkt_len = proto->raw.pkt_len;

	if (!pkt_len || pkt_len > VIRTCHNL_MAX_SIZE_RAW_PACKET)
		return -EINVAL;

	pkt_buf = kzalloc(pkt_len, GFP_KERNEL);
	msk_buf = kzalloc(pkt_len, GFP_KERNEL);

	if (!pkt_buf || !msk_buf)
		goto err_mem_alloc;

	memcpy(pkt_buf, proto->raw.spec, proto->raw.pkt_len);
	memcpy(msk_buf, proto->raw.mask, proto->raw.pkt_len);
	memcpy(pkt_buf, proto->raw.spec, pkt_len);
	memcpy(msk_buf, proto->raw.mask, pkt_len);

	hw = &pf->hw;

@@ -862,7 +868,7 @@ ice_vc_fdir_parse_raw(struct ice_vf *vf,
	if (ice_get_open_tunnel_port(hw, &udp_port, TNL_VXLAN))
		ice_parser_vxlan_tunnel_set(psr, udp_port, true);

	status = ice_parser_run(psr, pkt_buf, proto->raw.pkt_len, &rslt);
	status = ice_parser_run(psr, pkt_buf, pkt_len, &rslt);
	if (status)
		goto err_parser_destroy;

@@ -876,7 +882,7 @@ ice_vc_fdir_parse_raw(struct ice_vf *vf,
	}

	status = ice_parser_profile_init(&rslt, pkt_buf, msk_buf,
					 proto->raw.pkt_len, ICE_BLK_FD,
					 pkt_len, ICE_BLK_FD,
					 conf->prof);
	if (status)
		goto err_parser_profile_init;
@@ -885,7 +891,7 @@ ice_vc_fdir_parse_raw(struct ice_vf *vf,
		ice_parser_profile_dump(hw, conf->prof);

	/* Store raw flow info into @conf */
	conf->pkt_len = proto->raw.pkt_len;
	conf->pkt_len = pkt_len;
	conf->pkt_buf = pkt_buf;
	conf->parser_ena = true;