lists.openwall.net | lists / announce owl-users owl-dev john-users john-dev passwdqc-users yescrypt popa3d-users / oss-security kernel-hardening musl sabotage tlsify passwords / crypt-dev xvendor / Bugtraq Full-Disclosure linux-kernel linux-netdev linux-ext4 linux-hardening linux-cve-announce PHC | |
Open Source and information security mailing list archives
| ||
|
Date: Fri, 4 Nov 2022 10:47:59 +0100 From: Christian Lamparter <chunkeey@...il.com> To: linux-kernel@...r.kernel.org Cc: rafal@...ecki.pl, srinivas.kandagatla@...aro.org, gregkh@...uxfoundation.org, a.fatoum@...gutronix.de Subject: [PATCH v1] nvmem: address crc32 check on redundant-layout powerpc machines The Western Digital MyBook Live (PowerPC 464/APM82181) has a set of redundant u-boot-env. Loading up the driver causes it to error out with: | u_boot_env: Invalid calculated CRC32: 0x4f8f2c86 (expected: 0x98b14514) | u_boot_env: probe of partition@...00 failed with error -22 Looking up the userspace libubootenv utilities source [0], it looks like the "mark" or "flag" is not part of the crc32 sum... which is unfortunate :( |static int libuboot_load(struct uboot_ctx *ctx) |{ |[...] | if (ctx->redundant) { | [...] | offsetdata = offsetof(struct uboot_env_redund, data); | [...] | } | usable_envsize = ctx->size - offsetdata; | buf[0] = malloc(bufsize); |[...] | for (i = 0; i < copies; i++) { | data = (uint8_t *)(buf[i] + offsetdata); | uint32_t crc; | | ret = devread(ctx, i, buf[i]); | [...] | crc = *(uint32_t *)(buf[i] + offsetcrc); | dev->crc = crc32(0, (uint8_t *)data, usable_envsize); | Now, this alone didn't fully fix the kernel's uboot-env nvmem driver. The driver then ran into an endian error on the big-endian powerpc device: | u_boot_env: Invalid calculated CRC32: 0x1445b198 (expected: 0x98b14514) however the __le32 type for the crc32 value is justified because the the crc32() is just a macro for crc32_le(). So, to side-step that problem, the crc32 check gets extended to also accept a byteswapped crc32. [0] https://github.com/sbabic/libubootenv/blob/master/src/uboot_env.c#L951 Fixes: d5542923f200 ("nvmem: add driver handling U-Boot environment variables") Signed-off-by: Christian Lamparter <chunkeey@...il.com> --- Might it be better to add a dt-property (I wouldn't piggy-pack on the existing big-endian;) to specify that the crc32 value stored in the flash/rom is swapped? --- drivers/nvmem/u-boot-env.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/drivers/nvmem/u-boot-env.c b/drivers/nvmem/u-boot-env.c index 8e72d1bbd649..f78e2f5d2ef1 100644 --- a/drivers/nvmem/u-boot-env.c +++ b/drivers/nvmem/u-boot-env.c @@ -135,7 +135,7 @@ static int u_boot_env_parse(struct u_boot_env *priv) break; case U_BOOT_FORMAT_REDUNDANT: crc32_offset = offsetof(struct u_boot_env_image_redundant, crc32); - crc32_data_offset = offsetof(struct u_boot_env_image_redundant, mark); + crc32_data_offset = offsetof(struct u_boot_env_image_redundant, data); data_offset = offsetof(struct u_boot_env_image_redundant, data); break; } @@ -144,7 +144,11 @@ static int u_boot_env_parse(struct u_boot_env *priv) data_len = priv->mtd->size - data_offset; calc = crc32(~0, buf + crc32_data_offset, crc32_data_len) ^ ~0L; - if (calc != crc32) { + /* + * also accept byteswapped crc32 values for compatibility with + * existing legacy powerpc devices and userspace tools. + */ + if (calc != crc32 && calc != swab32(crc32)) { dev_err(dev, "Invalid calculated CRC32: 0x%08x (expected: 0x%08x)\n", calc, crc32); err = -EINVAL; goto err_kfree; -- 2.38.1
Powered by blists - more mailing lists