Re: [PATCH v4 15/16] leds: Add common LED binding parsing support to LED class/core

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hi Matti,

[auto build test WARNING on 31f4f5b495a62c9a8b15b1c3581acd5efeb9af8c]

url:    https://github.com/0day-ci/linux/commits/Matti-Vaittinen/Support-ROHM-BD71828-PMIC/20191117-030515
base:    31f4f5b495a62c9a8b15b1c3581acd5efeb9af8c

If you fix the issue, kindly add following tag
Reported-by: kbuild test robot <lkp@xxxxxxxxx>
Reported-by: Dan Carpenter <dan.carpenter@xxxxxxxxxx>

smatch warnings:
drivers/leds/led-core.c:400 fw_is_match() error: uninitialized symbol 'ret'.
drivers/leds/led-core.c:465 led_find_fwnode() error: double free of 'val'

# https://github.com/0day-ci/linux/commit/7b8033cfca34525c9e45fe2e74783fef74f4a49c
git remote add linux-review https://github.com/0day-ci/linux
git remote update linux-review
git checkout 7b8033cfca34525c9e45fe2e74783fef74f4a49c
vim +/ret +400 drivers/leds/led-core.c

7b8033cfca3452 Matti Vaittinen  2019-11-16  368  static int fw_is_match(struct fwnode_handle *fw,
7b8033cfca3452 Matti Vaittinen  2019-11-16  369  		       struct led_fw_match_property *mp, void *val)
bb4e9af0348dfe Jacek Anaszewski 2019-06-09  370  {
7b8033cfca3452 Matti Vaittinen  2019-11-16  371  	void *cmp = mp->raw_val;
bb4e9af0348dfe Jacek Anaszewski 2019-06-09  372  	int ret;
bb4e9af0348dfe Jacek Anaszewski 2019-06-09  373  
7b8033cfca3452 Matti Vaittinen  2019-11-16  374  	if (mp->raw_val) {
7b8033cfca3452 Matti Vaittinen  2019-11-16  375  		ret = fwnode_property_read_u8_array(fw, mp->name, val,
7b8033cfca3452 Matti Vaittinen  2019-11-16  376  						    mp->size);
7b8033cfca3452 Matti Vaittinen  2019-11-16  377  	} else if (mp->intval) {
                                                                   ^^^^^^^^^^
Smatch is complaining about if this is false then ret isn't set.

7b8033cfca3452 Matti Vaittinen  2019-11-16  378  		cmp = mp->intval;
7b8033cfca3452 Matti Vaittinen  2019-11-16  379  		switch (mp->size) {
7b8033cfca3452 Matti Vaittinen  2019-11-16  380  		case 1:
7b8033cfca3452 Matti Vaittinen  2019-11-16  381  			ret = fwnode_property_read_u8_array(fw, mp->name, val,
7b8033cfca3452 Matti Vaittinen  2019-11-16  382  						    mp->size);
7b8033cfca3452 Matti Vaittinen  2019-11-16  383  			break;
7b8033cfca3452 Matti Vaittinen  2019-11-16  384  		case 2:
7b8033cfca3452 Matti Vaittinen  2019-11-16  385  			ret = fwnode_property_read_u16_array(fw, mp->name, val,
7b8033cfca3452 Matti Vaittinen  2019-11-16  386  						    mp->size);
7b8033cfca3452 Matti Vaittinen  2019-11-16  387  			break;
7b8033cfca3452 Matti Vaittinen  2019-11-16  388  		case 4:
7b8033cfca3452 Matti Vaittinen  2019-11-16  389  			ret = fwnode_property_read_u32_array(fw, mp->name, val,
7b8033cfca3452 Matti Vaittinen  2019-11-16  390  						    mp->size);
7b8033cfca3452 Matti Vaittinen  2019-11-16  391  			break;
7b8033cfca3452 Matti Vaittinen  2019-11-16  392  		case 8:
7b8033cfca3452 Matti Vaittinen  2019-11-16  393  			ret = fwnode_property_read_u64_array(fw, mp->name, val,
7b8033cfca3452 Matti Vaittinen  2019-11-16  394  						    mp->size);
7b8033cfca3452 Matti Vaittinen  2019-11-16  395  			break;
7b8033cfca3452 Matti Vaittinen  2019-11-16  396  		default:
7b8033cfca3452 Matti Vaittinen  2019-11-16  397  			return -EINVAL;
7b8033cfca3452 Matti Vaittinen  2019-11-16  398  		}
7b8033cfca3452 Matti Vaittinen  2019-11-16  399  	}
7b8033cfca3452 Matti Vaittinen  2019-11-16 @400  	if (!ret && cmp) {
7b8033cfca3452 Matti Vaittinen  2019-11-16  401  		if (!memcmp(val, cmp, mp->size)) {
7b8033cfca3452 Matti Vaittinen  2019-11-16  402  			kfree(val);
                                                                        ^^^^^^^^^^
This kfree leads to a double free below.  Freeing it here is a
layering violation, so delete this one and keep the kfree in the caller.

7b8033cfca3452 Matti Vaittinen  2019-11-16  403  			return 1;
7b8033cfca3452 Matti Vaittinen  2019-11-16  404  		}
7b8033cfca3452 Matti Vaittinen  2019-11-16  405  	}
7b8033cfca3452 Matti Vaittinen  2019-11-16  406  	return 0;
7b8033cfca3452 Matti Vaittinen  2019-11-16  407  }
7b8033cfca3452 Matti Vaittinen  2019-11-16  408  /**
7b8033cfca3452 Matti Vaittinen  2019-11-16  409   * led_find_fwnode - find fwnode for led
7b8033cfca3452 Matti Vaittinen  2019-11-16  410   * @parent	LED controller device
7b8033cfca3452 Matti Vaittinen  2019-11-16  411   * @init_data	led init data with match information
7b8033cfca3452 Matti Vaittinen  2019-11-16  412   *
7b8033cfca3452 Matti Vaittinen  2019-11-16  413   * Scans the firmware nodes and returns node matching the given init_data.
7b8033cfca3452 Matti Vaittinen  2019-11-16  414   * NOTE: Function increases refcount for found node. Caller must decrease
7b8033cfca3452 Matti Vaittinen  2019-11-16  415   * refcount using fwnode_handle_put when finished with node.
7b8033cfca3452 Matti Vaittinen  2019-11-16  416   */
7b8033cfca3452 Matti Vaittinen  2019-11-16  417  struct fwnode_handle *led_find_fwnode(struct device *parent,
7b8033cfca3452 Matti Vaittinen  2019-11-16  418  				      struct led_init_data *init_data)
7b8033cfca3452 Matti Vaittinen  2019-11-16  419  {
7b8033cfca3452 Matti Vaittinen  2019-11-16  420  	struct fwnode_handle *fw;
7b8033cfca3452 Matti Vaittinen  2019-11-16  421  
7b8033cfca3452 Matti Vaittinen  2019-11-16  422  	/*
7b8033cfca3452 Matti Vaittinen  2019-11-16  423  	 * This should never be called W/O init data. We could always return
7b8033cfca3452 Matti Vaittinen  2019-11-16  424  	 * dev_fwnode() - but then we should pump-up the refcount
7b8033cfca3452 Matti Vaittinen  2019-11-16  425  	 */
7b8033cfca3452 Matti Vaittinen  2019-11-16  426  	if (!init_data)
7b8033cfca3452 Matti Vaittinen  2019-11-16  427  		return NULL;
7b8033cfca3452 Matti Vaittinen  2019-11-16  428  
7b8033cfca3452 Matti Vaittinen  2019-11-16  429  	if (!init_data->fwnode)
7b8033cfca3452 Matti Vaittinen  2019-11-16  430  		fw = dev_fwnode(parent);
7b8033cfca3452 Matti Vaittinen  2019-11-16  431  	else
7b8033cfca3452 Matti Vaittinen  2019-11-16  432  		fw = init_data->fwnode;
7b8033cfca3452 Matti Vaittinen  2019-11-16  433  
7b8033cfca3452 Matti Vaittinen  2019-11-16  434  	if (!fw)
7b8033cfca3452 Matti Vaittinen  2019-11-16  435  		return NULL;
7b8033cfca3452 Matti Vaittinen  2019-11-16  436  
7b8033cfca3452 Matti Vaittinen  2019-11-16  437  	/*
7b8033cfca3452 Matti Vaittinen  2019-11-16  438  	 * Simple things are pretty. I think simplest is to use DT node-name
7b8033cfca3452 Matti Vaittinen  2019-11-16  439  	 * for matching the node with LED - same way regulators use the node
7b8033cfca3452 Matti Vaittinen  2019-11-16  440  	 * name to match with desc.
7b8033cfca3452 Matti Vaittinen  2019-11-16  441  	 *
7b8033cfca3452 Matti Vaittinen  2019-11-16  442  	 * This may not work with existing LED DT entries if the node name has
7b8033cfca3452 Matti Vaittinen  2019-11-16  443  	 * been freely selectible. In order to this to work the binding doc
7b8033cfca3452 Matti Vaittinen  2019-11-16  444  	 * for LED driver should define usable node names.
7b8033cfca3452 Matti Vaittinen  2019-11-16  445  	 *
7b8033cfca3452 Matti Vaittinen  2019-11-16  446  	 * If this is not working we can define specific match property which
7b8033cfca3452 Matti Vaittinen  2019-11-16  447  	 * value we scan and use for matching for LEDs connected to the
7b8033cfca3452 Matti Vaittinen  2019-11-16  448  	 * controller.
7b8033cfca3452 Matti Vaittinen  2019-11-16  449  	 */
7b8033cfca3452 Matti Vaittinen  2019-11-16  450  	if (init_data->match_property.name && init_data->match_property.size) {
7b8033cfca3452 Matti Vaittinen  2019-11-16  451  		u8 *val;
7b8033cfca3452 Matti Vaittinen  2019-11-16  452  		int ret;
7b8033cfca3452 Matti Vaittinen  2019-11-16  453  		struct fwnode_handle *child;
7b8033cfca3452 Matti Vaittinen  2019-11-16  454  		struct led_fw_match_property *mp;
7b8033cfca3452 Matti Vaittinen  2019-11-16  455  
7b8033cfca3452 Matti Vaittinen  2019-11-16  456  		mp = &init_data->match_property;
7b8033cfca3452 Matti Vaittinen  2019-11-16  457  
7b8033cfca3452 Matti Vaittinen  2019-11-16  458  		val = kzalloc(mp->size, GFP_KERNEL);
7b8033cfca3452 Matti Vaittinen  2019-11-16  459  		if (!val)
7b8033cfca3452 Matti Vaittinen  2019-11-16  460  			return ERR_PTR(-ENOMEM);
7b8033cfca3452 Matti Vaittinen  2019-11-16  461  
7b8033cfca3452 Matti Vaittinen  2019-11-16  462  		fwnode_for_each_child_node(fw, child) {
7b8033cfca3452 Matti Vaittinen  2019-11-16  463  			ret = fw_is_match(child, mp, val);
                                                                                                     ^^^

7b8033cfca3452 Matti Vaittinen  2019-11-16  464  			if (ret > 0) {
7b8033cfca3452 Matti Vaittinen  2019-11-16 @465  				kfree(val);
                                                                                      ^^^

Oops.

7b8033cfca3452 Matti Vaittinen  2019-11-16  466  				return child;
7b8033cfca3452 Matti Vaittinen  2019-11-16  467  			}
7b8033cfca3452 Matti Vaittinen  2019-11-16  468  			if (ret < 0) {
7b8033cfca3452 Matti Vaittinen  2019-11-16  469  				dev_err(parent,
7b8033cfca3452 Matti Vaittinen  2019-11-16  470  					"invalid fw match. Use raw_val?\n");
7b8033cfca3452 Matti Vaittinen  2019-11-16  471  				fwnode_handle_put(child);
7b8033cfca3452 Matti Vaittinen  2019-11-16  472  				break;
7b8033cfca3452 Matti Vaittinen  2019-11-16  473  			}
7b8033cfca3452 Matti Vaittinen  2019-11-16  474  		}
7b8033cfca3452 Matti Vaittinen  2019-11-16  475  		kfree(val);
7b8033cfca3452 Matti Vaittinen  2019-11-16  476  	}
7b8033cfca3452 Matti Vaittinen  2019-11-16  477  	if (init_data->of_match)
7b8033cfca3452 Matti Vaittinen  2019-11-16  478  		fw = fwnode_get_named_child_node(fw, init_data->of_match);
7b8033cfca3452 Matti Vaittinen  2019-11-16  479  	else
7b8033cfca3452 Matti Vaittinen  2019-11-16  480  		fw = fwnode_handle_get(fw);
7b8033cfca3452 Matti Vaittinen  2019-11-16  481  
7b8033cfca3452 Matti Vaittinen  2019-11-16  482  	return fw;
7b8033cfca3452 Matti Vaittinen  2019-11-16  483  }

---
0-DAY kernel test infrastructure                 Open Source Technology Center
https://lists.01.org/hyperkitty/list/kbuild-all@xxxxxxxxxxxx Intel Corporation



[Index of Archives]     [Device Tree Compilter]     [Device Tree Spec]     [Linux Driver Backports]     [Video for Linux]     [Linux USB Devel]     [Linux PCI Devel]     [Linux Audio Users]     [Linux Kernel]     [Linux SCSI]     [XFree86]     [Yosemite Backpacking]


  Powered by Linux