Commit 607bcc42 authored by Sakari Ailus's avatar Sakari Ailus Committed by Mauro Carvalho Chehab
Browse files

media: i2c: ccs: Check rules is non-NULL



Fix the following smatch warning:

drivers/media/i2c/ccs/ccs-data.c:524 ccs_data_parse_rules() warn: address
of NULL pointer 'rules'

The CCS static data rule parser does not check an if rule has been
obtained before checking for other rule types (which depend on the if
rule). In practice this means parsing invalid CCS static data could lead
to dereferencing a NULL pointer.

Reported-by: default avatarHans Verkuil <hverkuil@xs4all.nl>
Fixes: a6b396f4 ("media: ccs: Add CCS static data parser library")
Cc: stable@vger.kernel.org # for 5.11 and up
Signed-off-by: default avatarSakari Ailus <sakari.ailus@linux.intel.com>
Signed-off-by: default avatarMauro Carvalho Chehab <mchehab@kernel.org>
parent da57d120
Loading
Loading
Loading
Loading
+56 −45
Original line number Diff line number Diff line
@@ -464,8 +464,7 @@ static int ccs_data_parse_rules(struct bin_container *bin,
		rule_payload = __rule_type + 1;
		rule_plen2 = rule_plen - sizeof(*__rule_type);

		switch (*__rule_type) {
		case CCS_DATA_BLOCK_RULE_ID_IF: {
		if (*__rule_type == CCS_DATA_BLOCK_RULE_ID_IF) {
			const struct __ccs_data_block_rule_if *__if_rules =
				rule_payload;
			const size_t __num_if_rules =
@@ -514,11 +513,18 @@ static int ccs_data_parse_rules(struct bin_container *bin,
				rules->if_rules = if_rule;
				rules->num_if_rules = __num_if_rules;
			}
			break;
		}
		} else {
			/* Check there was an if rule before any other rules */
			if (bin->base && !rules)
				return -EINVAL;

			switch (*__rule_type) {
			case CCS_DATA_BLOCK_RULE_ID_READ_ONLY_REGS:
			rval = ccs_data_parse_reg_rules(bin, &rules->read_only_regs,
							&rules->num_read_only_regs,
				rval = ccs_data_parse_reg_rules(bin,
								rules ?
								&rules->read_only_regs : NULL,
								rules ?
								&rules->num_read_only_regs : NULL,
								rule_payload,
								rule_payload + rule_plen2,
								dev);
@@ -526,7 +532,8 @@ static int ccs_data_parse_rules(struct bin_container *bin,
					return rval;
				break;
			case CCS_DATA_BLOCK_RULE_ID_FFD:
			rval = ccs_data_parse_ffd(bin, &rules->frame_format,
				rval = ccs_data_parse_ffd(bin, rules ?
							  &rules->frame_format : NULL,
							  rule_payload,
							  rule_payload + rule_plen2,
							  dev);
@@ -535,8 +542,10 @@ static int ccs_data_parse_rules(struct bin_container *bin,
				break;
			case CCS_DATA_BLOCK_RULE_ID_MSR:
				rval = ccs_data_parse_reg_rules(bin,
							&rules->manufacturer_regs,
							&rules->num_manufacturer_regs,
								rules ?
								&rules->manufacturer_regs : NULL,
								rules ?
								&rules->num_manufacturer_regs : NULL,
								rule_payload,
								rule_payload + rule_plen2,
								dev);
@@ -545,7 +554,8 @@ static int ccs_data_parse_rules(struct bin_container *bin,
				break;
			case CCS_DATA_BLOCK_RULE_ID_PDAF_READOUT:
				rval = ccs_data_parse_pdaf_readout(bin,
							   &rules->pdaf_readout,
								   rules ?
								   &rules->pdaf_readout : NULL,
								   rule_payload,
								   rule_payload + rule_plen2,
								   dev);
@@ -558,6 +568,7 @@ static int ccs_data_parse_rules(struct bin_container *bin,
					*__rule_type);
				return -EINVAL;
			}
		}
		__next_rule = __next_rule + rule_hlen + rule_plen;
	}