Merge branch '2021-07-15-assorted-fixes'

- Large number of Coverity reported issues addressed
- m41t62 bugfix
- Support more Android image compression formats
- FIT + DTO bugfix
This commit is contained in:
Tom Rini
2021-07-16 09:15:59 -04:00
17 changed files with 77 additions and 41 deletions

View File

@@ -78,6 +78,10 @@ static int state_read_file(struct sandbox_state *state, const char *fname)
err_read: err_read:
os_close(fd); os_close(fd);
err_open: err_open:
/*
* tainted scalar, since size is obtained from the file. But we can rely
* on os_malloc() to handle invalid values.
*/
os_free(state->state_fdt); os_free(state->state_fdt);
state->state_fdt = NULL; state->state_fdt = NULL;

View File

@@ -164,7 +164,7 @@ ulong android_image_get_kcomp(const struct andr_img_hdr *hdr)
else if (get_unaligned_le32(p) == LZ4F_MAGIC) else if (get_unaligned_le32(p) == LZ4F_MAGIC)
return IH_COMP_LZ4; return IH_COMP_LZ4;
else else
return IH_COMP_NONE; return image_decomp_type(p, sizeof(u32));
} }
int android_image_get_ramdisk(const struct andr_img_hdr *hdr, int android_image_get_ramdisk(const struct andr_img_hdr *hdr,

View File

@@ -17,6 +17,7 @@
#include <u-boot/crc.h> #include <u-boot/crc.h>
#else #else
#include <linux/compiler.h> #include <linux/compiler.h>
#include <linux/sizes.h>
#include <common.h> #include <common.h>
#include <errno.h> #include <errno.h>
#include <log.h> #include <log.h>
@@ -2267,10 +2268,10 @@ int boot_get_fdt_fit(bootm_headers_t *images, ulong addr,
ulong load, len; ulong load, len;
#ifdef CONFIG_OF_LIBFDT_OVERLAY #ifdef CONFIG_OF_LIBFDT_OVERLAY
ulong image_start, image_end; ulong image_start, image_end;
ulong ovload, ovlen; ulong ovload, ovlen, ovcopylen;
const char *uconfig; const char *uconfig;
const char *uname; const char *uname;
void *base, *ov; void *base, *ov, *ovcopy = NULL;
int i, err, noffset, ov_noffset; int i, err, noffset, ov_noffset;
#endif #endif
@@ -2360,7 +2361,7 @@ int boot_get_fdt_fit(bootm_headers_t *images, ulong addr,
addr, &uname, &uconfig, addr, &uname, &uconfig,
arch, IH_TYPE_FLATDT, arch, IH_TYPE_FLATDT,
BOOTSTAGE_ID_FIT_FDT_START, BOOTSTAGE_ID_FIT_FDT_START,
FIT_LOAD_REQUIRED, &ovload, &ovlen); FIT_LOAD_IGNORED, &ovload, &ovlen);
if (ov_noffset < 0) { if (ov_noffset < 0) {
printf("load of %s failed\n", uname); printf("load of %s failed\n", uname);
continue; continue;
@@ -2369,6 +2370,21 @@ int boot_get_fdt_fit(bootm_headers_t *images, ulong addr,
uname, ovload, ovlen); uname, ovload, ovlen);
ov = map_sysmem(ovload, ovlen); ov = map_sysmem(ovload, ovlen);
ovcopylen = ALIGN(fdt_totalsize(ov), SZ_4K);
ovcopy = malloc(ovcopylen);
if (!ovcopy) {
printf("failed to duplicate DTO before application\n");
fdt_noffset = -ENOMEM;
goto out;
}
err = fdt_open_into(ov, ovcopy, ovcopylen);
if (err < 0) {
printf("failed on fdt_open_into for DTO\n");
fdt_noffset = err;
goto out;
}
base = map_sysmem(load, len + ovlen); base = map_sysmem(load, len + ovlen);
err = fdt_open_into(base, base, len + ovlen); err = fdt_open_into(base, base, len + ovlen);
if (err < 0) { if (err < 0) {
@@ -2376,14 +2392,18 @@ int boot_get_fdt_fit(bootm_headers_t *images, ulong addr,
fdt_noffset = err; fdt_noffset = err;
goto out; goto out;
} }
/* the verbose method prints out messages on error */ /* the verbose method prints out messages on error */
err = fdt_overlay_apply_verbose(base, ov); err = fdt_overlay_apply_verbose(base, ovcopy);
if (err < 0) { if (err < 0) {
fdt_noffset = err; fdt_noffset = err;
goto out; goto out;
} }
fdt_pack(base); fdt_pack(base);
len = fdt_totalsize(base); len = fdt_totalsize(base);
free(ovcopy);
ovcopy = NULL;
} }
#else #else
printf("config with overlays but CONFIG_OF_LIBFDT_OVERLAY not set\n"); printf("config with overlays but CONFIG_OF_LIBFDT_OVERLAY not set\n");
@@ -2400,6 +2420,10 @@ out:
if (fit_uname_configp) if (fit_uname_configp)
*fit_uname_configp = fit_uname_config; *fit_uname_configp = fit_uname_config;
#ifdef CONFIG_OF_LIBFDT_OVERLAY
if (ovcopy)
free(ovcopy);
#endif
if (fit_uname_config_copy) if (fit_uname_config_copy)
free(fit_uname_config_copy); free(fit_uname_config_copy);
return fdt_noffset; return fdt_noffset;

View File

@@ -847,13 +847,17 @@ void devm_clk_put(struct udevice *dev, struct clk *clk)
int clk_uclass_post_probe(struct udevice *dev) int clk_uclass_post_probe(struct udevice *dev)
{ {
int ret;
/* /*
* when a clock provider is probed. Call clk_set_defaults() * when a clock provider is probed. Call clk_set_defaults()
* also after the device is probed. This takes care of cases * also after the device is probed. This takes care of cases
* where the DT is used to setup default parents and rates * where the DT is used to setup default parents and rates
* using assigned-clocks * using assigned-clocks
*/ */
clk_set_defaults(dev, CLK_DEFAULTS_POST); ret = clk_set_defaults(dev, CLK_DEFAULTS_POST);
if (ret)
return log_ret(ret);
return 0; return 0;
} }

View File

@@ -130,18 +130,19 @@ void dm_dump_drivers(void)
struct driver *entry; struct driver *entry;
struct udevice *udev; struct udevice *udev;
struct uclass *uc; struct uclass *uc;
int ret;
int i; int i;
puts("Driver uid uclass Devices\n"); puts("Driver uid uclass Devices\n");
puts("----------------------------------------------------------\n"); puts("----------------------------------------------------------\n");
for (entry = d; entry < d + n_ents; entry++) { for (entry = d; entry < d + n_ents; entry++) {
uclass_get(entry->id, &uc); ret = uclass_get(entry->id, &uc);
printf("%-25.25s %-3.3d %-20.20s ", entry->name, entry->id, printf("%-25.25s %-3.3d %-20.20s ", entry->name, entry->id,
uc ? uc->uc_drv->name : "<no uclass>"); !ret ? uc->uc_drv->name : "<no uclass>");
if (!uc) { if (ret) {
puts("\n"); puts("\n");
continue; continue;
} }

View File

@@ -293,6 +293,7 @@ struct regmap *devm_regmap_init(struct udevice *dev,
int rc; int rc;
struct regmap **mapp, *map; struct regmap **mapp, *map;
/* this looks like a leak, but devres takes care of it */
mapp = devres_alloc(devm_regmap_release, sizeof(struct regmap *), mapp = devres_alloc(devm_regmap_release, sizeof(struct regmap *),
__GFP_ZERO); __GFP_ZERO);
if (unlikely(!mapp)) if (unlikely(!mapp))

View File

@@ -5,6 +5,8 @@
* Copyright (c) 2013 The Chromium OS Authors. * Copyright (c) 2013 The Chromium OS Authors.
*/ */
#define LOG_CATEGORY UCLASS_CROS_EC
#include <common.h> #include <common.h>
#include <cros_ec.h> #include <cros_ec.h>
#include <dm.h> #include <dm.h>
@@ -221,11 +223,12 @@ static int keyscan_read_fdt_matrix(struct ec_state *ec, ofnode node)
int len; int len;
cell = ofnode_get_property(node, "linux,keymap", &len); cell = ofnode_get_property(node, "linux,keymap", &len);
if (!cell)
return log_msg_ret("prop", -EINVAL);
ec->matrix_count = len / 4; ec->matrix_count = len / 4;
ec->matrix = calloc(ec->matrix_count, sizeof(*ec->matrix)); ec->matrix = calloc(ec->matrix_count, sizeof(*ec->matrix));
if (!ec->matrix) { if (!ec->matrix) {
debug("%s: Out of memory for key matrix\n", __func__); return log_msg_ret("mem", -ENOMEM);
return -1;
} }
/* Now read the data */ /* Now read the data */
@@ -243,13 +246,12 @@ static int keyscan_read_fdt_matrix(struct ec_state *ec, ofnode node)
matrix->col >= KEYBOARD_COLS) { matrix->col >= KEYBOARD_COLS) {
debug("%s: Matrix pos out of range (%d,%d)\n", debug("%s: Matrix pos out of range (%d,%d)\n",
__func__, matrix->row, matrix->col); __func__, matrix->row, matrix->col);
return -1; return log_msg_ret("matrix", -ERANGE);
} }
} }
if (upto != ec->matrix_count) { if (upto != ec->matrix_count) {
debug("%s: Read mismatch from key matrix\n", __func__); return log_msg_ret("matrix", -E2BIG);
return -1;
} }
return 0; return 0;

View File

@@ -161,7 +161,7 @@ static int sb_eth_raw_of_to_plat(struct udevice *dev)
ifname = dev_read_string(dev, "host-raw-interface"); ifname = dev_read_string(dev, "host-raw-interface");
if (ifname) { if (ifname) {
strncpy(priv->host_ifname, ifname, IFNAMSIZ); strlcpy(priv->host_ifname, ifname, IFNAMSIZ);
printf(": Using %s from DT\n", priv->host_ifname); printf(": Using %s from DT\n", priv->host_ifname);
} }
if (dev_read_u32(dev, "host-raw-interface-idx", if (dev_read_u32(dev, "host-raw-interface-idx",

View File

@@ -471,6 +471,7 @@ static int single_probe(struct udevice *dev)
return -ENOMEM; return -ENOMEM;
#endif #endif
/* looks like a possible divide by 0, but data->width avoids this */
priv->npins = size / (pdata->width / BITS_PER_BYTE); priv->npins = size / (pdata->width / BITS_PER_BYTE);
if (pdata->bits_per_mux) { if (pdata->bits_per_mux) {
if (!pdata->mask) { if (!pdata->mask) {

View File

@@ -325,6 +325,8 @@ struct reset_ctl_bulk *devm_reset_bulk_get_by_node(struct udevice *dev,
bulk = devres_alloc(devm_reset_bulk_release, bulk = devres_alloc(devm_reset_bulk_release,
sizeof(struct reset_ctl_bulk), sizeof(struct reset_ctl_bulk),
__GFP_ZERO); __GFP_ZERO);
/* this looks like a leak, but devres takes care of it */
if (unlikely(!bulk)) if (unlikely(!bulk))
return ERR_PTR(-ENOMEM); return ERR_PTR(-ENOMEM);

View File

@@ -213,13 +213,13 @@ static int m41t62_rtc_restart_osc(struct udevice *dev)
/* 1. Set stop bit */ /* 1. Set stop bit */
val |= M41T62_SEC_ST; val |= M41T62_SEC_ST;
ret = dm_i2c_write(dev, M41T62_REG_ALARM_HOUR, &val, sizeof(val)); ret = dm_i2c_write(dev, M41T62_REG_SEC, &val, sizeof(val));
if (ret) if (ret)
return ret; return ret;
/* 2. Clear stop bit */ /* 2. Clear stop bit */
val &= ~M41T62_SEC_ST; val &= ~M41T62_SEC_ST;
ret = dm_i2c_write(dev, M41T62_REG_ALARM_HOUR, &val, sizeof(val)); ret = dm_i2c_write(dev, M41T62_REG_SEC, &val, sizeof(val));
if (ret) if (ret)
return ret; return ret;

View File

@@ -235,8 +235,10 @@ static int pwm_backlight_of_to_plat(struct udevice *dev)
priv->levels = malloc(len); priv->levels = malloc(len);
if (!priv->levels) if (!priv->levels)
return log_ret(-ENOMEM); return log_ret(-ENOMEM);
dev_read_u32_array(dev, "brightness-levels", priv->levels, ret = dev_read_u32_array(dev, "brightness-levels", priv->levels,
count); count);
if (ret)
return log_msg_ret("levels", ret);
priv->num_levels = count; priv->num_levels = count;
priv->default_level = priv->levels[index]; priv->default_level = priv->levels[index];
priv->max_level = priv->levels[count - 1]; priv->max_level = priv->levels[count - 1];

View File

@@ -167,6 +167,8 @@ static int file_cbfs_next_file(struct cbfs_priv *priv, void *start, int size,
} }
swap_file_header(&header, file_header); swap_file_header(&header, file_header);
if (header.offset >= size)
return log_msg_ret("range", -E2BIG);
ret = fill_node(node, start, &header); ret = fill_node(node, start, &header);
if (ret) { if (ret) {
priv->result = CBFS_BAD_FILE; priv->result = CBFS_BAD_FILE;

View File

@@ -176,6 +176,11 @@ u32 tpm_sendrecv_command(struct udevice *dev, const void *command,
} }
size = tpm_command_size(command); size = tpm_command_size(command);
/* sanity check, which also helps coverity */
if (size > COMMAND_BUFFER_SIZE)
return log_msg_ret("size", -E2BIG);
log_debug("TPM request [size:%d]: ", size); log_debug("TPM request [size:%d]: ", size);
for (i = 0; i < size; i++) for (i = 0; i < size; i++)
log_debug("%02x ", ((u8 *)command)[i]); log_debug("%02x ", ((u8 *)command)[i]);

View File

@@ -434,9 +434,9 @@ static char *uuid_string(char *buf, char *end, u8 *addr, int field_width,
* - 'i' [46] for 'raw' IPv4/IPv6 addresses, IPv6 omits the colons, IPv4 is * - 'i' [46] for 'raw' IPv4/IPv6 addresses, IPv6 omits the colons, IPv4 is
* currently the same * currently the same
* *
* Note: The difference between 'S' and 'F' is that on ia64 and ppc64 * Note: IPv6 support is currently if(0)'ed out. If you ever need
* function pointers are really function descriptors, which contain a * %pI6, please add an IPV6 Kconfig knob, make your code select or
* pointer to the real address. * depend on that, and change the 0 below to CONFIG_IS_ENABLED(IPV6).
*/ */
static char *pointer(const char *fmt, char *buf, char *end, void *ptr, static char *pointer(const char *fmt, char *buf, char *end, void *ptr,
int field_width, int precision, int flags) int field_width, int precision, int flags)
@@ -481,7 +481,8 @@ static char *pointer(const char *fmt, char *buf, char *end, void *ptr,
flags |= SPECIAL; flags |= SPECIAL;
/* Fallthrough */ /* Fallthrough */
case 'I': case 'I':
if (fmt[1] == '6') /* %pI6 currently unused */
if (0 && fmt[1] == '6')
return ip6_addr_string(buf, end, ptr, field_width, return ip6_addr_string(buf, end, ptr, field_width,
precision, flags); precision, flags);
if (fmt[1] == '4') if (fmt[1] == '4')
@@ -787,22 +788,11 @@ int printf(const char *fmt, ...)
{ {
va_list args; va_list args;
uint i; uint i;
char printbuffer[CONFIG_SYS_PBSIZE];
va_start(args, fmt); va_start(args, fmt);
i = vprintf(fmt, args);
/*
* For this to work, printbuffer must be larger than
* anything we ever want to print.
*/
i = vscnprintf(printbuffer, sizeof(printbuffer), fmt, args);
va_end(args); va_end(args);
/* Handle error */
if (i <= 0)
return i;
/* Print the string */
puts(printbuffer);
return i; return i;
} }

View File

@@ -270,8 +270,6 @@ static int setexpr_test_backref(struct unit_test_state *uts)
ut_asserteq_str("us this is surely! a test is it? yes us this is indeed! a test", ut_asserteq_str("us this is surely! a test is it? yes us this is indeed! a test",
buf); buf);
/* The following checks fail at present due to a bug in setexpr */
return 0;
for (i = BUF_SIZE; i < 0x1000; i++) { for (i = BUF_SIZE; i < 0x1000; i++) {
ut_assertf(buf[i] == (char)i, ut_assertf(buf[i] == (char)i,
"buf byte at %x should be %02x, got %02x)\n", "buf byte at %x should be %02x, got %02x)\n",

View File

@@ -329,7 +329,7 @@ static int get_random_data(void *data, int size)
{ {
unsigned char *tmp = data; unsigned char *tmp = data;
struct timespec date; struct timespec date;
int i, ret = 0; int i, ret;
if (!tmp) { if (!tmp) {
printf("%s: pointer data is NULL\n", __func__); printf("%s: pointer data is NULL\n", __func__);
@@ -338,9 +338,9 @@ static int get_random_data(void *data, int size)
} }
ret = clock_gettime(CLOCK_MONOTONIC, &date); ret = clock_gettime(CLOCK_MONOTONIC, &date);
if (ret < 0) { if (ret) {
printf("%s: clock_gettime has failed (err=%d, str=%s)\n", printf("%s: clock_gettime has failed (%s)\n", __func__,
__func__, ret, strerror(errno)); strerror(errno));
goto out; goto out;
} }