mirror of
https://github.com/armbian/build.git
synced 2026-05-05 12:16:19 +02:00
helios64: defensive fixes on top of u-boot v2026.04 bump
Code-style and defensive-programming fixes to the helios64 u-boot
overlay, applied on top of the pristine v2026.04 vendor bump. All
changes are additive safety nets — none alter the happy-path
behaviour of the previous Kobol/Armbian code.
board/helios64.c:
- setup_leds(): check led_get_by_label() return value. Without
this, led_set_state() is called on an uninitialised udevice
pointer if LED lookup fails.
- sata_power_enable(): add the matching 10s mdelay after
enabling hdd_b_power, mirroring the one already present after
hdd_a_power. Previously rail B had no spin-up time before
scsi_scan(true) in last_stage_init(), so drives on the second
rail could miss the scan. The staggered spin-up between rails
is preserved (PSU in-rush protection for two 3.5" HDDs).
board/sys_otp.c:
- replace the || chain magic-number check in is_valid_header()
with memcmp() against a const expected_magic[8] (fixes a real
pre-existing bug: the || chain was always true);
- introduce otp_serial() / otp_mfg_year() helpers that assemble
the multi-byte values byte-by-byte, eliminating unaligned
u64/u16 casts into the packed otp struct (UB per the C standard,
also over-read into adjacent fields);
- bounds-check otp.variant against BOARD_VARIANT_MAX before
indexing var_str[], adding BOARD_VARIANT_INVALID slot;
- use strnlen() when printing packed fixed-length fields;
- use snprintf() with target buffer size instead of sprintf();
- retry read_otp_data() in ensure_otp_data_ready() on the first
access after a failed board_early_init_r(), instead of silently
skipping OTP-provided values for the whole boot.
cmd-fileenv-read-string-from-file-into-env.patch:
add 'depends on CMD_FAT' to the cherry-picked CMD_FILEENV Kconfig
entry. do_fat_fsload() is called unconditionally from the
fileenv implementation, so the dependency reflects reality.
general-fix-btrfs-zstd-decompression.patch:
tighten the decompression-success check to also reject short
reads ('|| ret < dlen'). zstd_is_error() alone does not cover
truncated output.
Assisted-by: Claude:claude-opus-4-7
This commit is contained in:
parent
eace2edf31
commit
c2ee2face9
@ -180,8 +180,14 @@ static int setup_boottargets(void)
|
||||
static void setup_leds(void)
|
||||
{
|
||||
struct udevice *dev;
|
||||
int ret;
|
||||
|
||||
ret = led_get_by_label("helios64::status", &dev);
|
||||
if (ret) {
|
||||
debug("%s: failed to get status LED: %d\n", __func__, ret);
|
||||
return;
|
||||
}
|
||||
|
||||
led_get_by_label("helios64::status", &dev);
|
||||
led_set_state(dev, LEDST_OFF);
|
||||
mdelay(250);
|
||||
led_set_state(dev, LEDST_ON);
|
||||
@ -274,8 +280,12 @@ static void sata_power_enable(void)
|
||||
}
|
||||
|
||||
ret = regulator_get_by_platname("hdd_b_power", &rail_b);
|
||||
if (!ret)
|
||||
if (!ret) {
|
||||
ret = regulator_set_enable(rail_b, true);
|
||||
if (!ret)
|
||||
/* Wait for HDD spinup before SCSI scan */
|
||||
mdelay(10000);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
@ -4,6 +4,7 @@
|
||||
#include <log.h>
|
||||
#include <env.h>
|
||||
#include <net.h>
|
||||
#include <string.h>
|
||||
#include <u-boot/crc.h>
|
||||
|
||||
#include "sys_otp.h"
|
||||
@ -42,16 +43,44 @@ static inline int is_data_valid(void)
|
||||
return data_valid;
|
||||
}
|
||||
|
||||
/*
|
||||
* Ensure OTP data is cached and valid. If a previous read failed (for example
|
||||
* on a transient SPI error during board_early_init_r()), retry here so
|
||||
* consumers don't silently skip using OTP-provided values for the whole boot.
|
||||
*/
|
||||
static int ensure_otp_data_ready(void)
|
||||
{
|
||||
if (is_data_valid())
|
||||
return 0;
|
||||
|
||||
return read_otp_data();
|
||||
}
|
||||
|
||||
/*
|
||||
* Decode the 6-byte serial number into a u64. Doing a casted *(uint64_t *)
|
||||
* read on otp.serial_num would over-read into otp.mfg_year and is unaligned
|
||||
* inside the packed struct (UB per the C standard).
|
||||
*/
|
||||
static inline u64 otp_serial(void)
|
||||
{
|
||||
return ((u64)otp.serial_num[0]) |
|
||||
((u64)otp.serial_num[1] << 8) |
|
||||
((u64)otp.serial_num[2] << 16) |
|
||||
((u64)otp.serial_num[3] << 24) |
|
||||
((u64)otp.serial_num[4] << 32) |
|
||||
((u64)otp.serial_num[5] << 40);
|
||||
}
|
||||
|
||||
static inline u16 otp_mfg_year(void)
|
||||
{
|
||||
return otp.mfg_year[0] | ((u16)otp.mfg_year[1] << 8);
|
||||
}
|
||||
|
||||
static inline int is_valid_header(void)
|
||||
{
|
||||
if ((otp.magic[0] == 'H') || (otp.magic[1] == '6') ||
|
||||
(otp.magic[2] == '4') || (otp.magic[3] == 'N') ||
|
||||
(otp.magic[4] == 'P') || (otp.magic[5] == 'V') ||
|
||||
(otp.magic[6] == '1') || (otp.magic[7] == 0))
|
||||
static const u8 expected_magic[8] = { 'H', '6', '4', 'N', 'P', 'V', '1', 0 };
|
||||
|
||||
return 1;
|
||||
|
||||
return 0;
|
||||
return memcmp(otp.magic, expected_magic, sizeof(expected_magic)) == 0;
|
||||
}
|
||||
|
||||
static int init_system_otp(int bus, int cs)
|
||||
@ -97,13 +126,16 @@ static void show_otp_data(void)
|
||||
if (!is_valid_header())
|
||||
return;
|
||||
|
||||
printf("Part Number: %s\n", otp.part_num);
|
||||
printf("Variant: %s\n", var_str[otp.variant]);
|
||||
printf("Part Number: %.*s\n",
|
||||
(int)strnlen((const char *)otp.part_num, sizeof(otp.part_num)),
|
||||
otp.part_num);
|
||||
printf("Variant: %s\n",
|
||||
(otp.variant < BOARD_VARIANT_MAX) ? var_str[otp.variant]
|
||||
: var_str[BOARD_VARIANT_INVALID]);
|
||||
printf("Revision: %x.%x\n", (otp.revision & 0xf0) >> 4, otp.revision & 0x0f);
|
||||
printf("Serial Number: %012llx\n", *((uint64_t*) otp.serial_num) &
|
||||
0xFFFFFFFFFFFF);
|
||||
printf("Serial Number: %012llx\n", otp_serial());
|
||||
printf("Manufacturing Date: %02X-%02X-%04X (DD-MM-YYYY)\n", otp.mfg_day,
|
||||
otp.mfg_month, *(u16*) otp.mfg_year);
|
||||
otp.mfg_month, otp_mfg_year());
|
||||
|
||||
printf("1GbE MAC Address: %02X:%02X:%02X:%02X:%02X:%02X\n",
|
||||
otp.mac_addr[0][0], otp.mac_addr[0][1], otp.mac_addr[0][2],
|
||||
@ -160,7 +192,13 @@ int read_otp_data(void)
|
||||
show_otp_data();
|
||||
#endif
|
||||
|
||||
has_been_read = (ret == 0) ? 1 : 0;
|
||||
if (ret) {
|
||||
debug("SPI: Failed to read OTP: %d\n", ret);
|
||||
/* Leave has_been_read = 0 so a later call can retry. */
|
||||
return ret;
|
||||
}
|
||||
has_been_read = 1;
|
||||
|
||||
if (!is_valid_header())
|
||||
goto data_invalid;
|
||||
|
||||
@ -180,7 +218,7 @@ data_invalid:
|
||||
|
||||
int get_revision(int *major, int *minor)
|
||||
{
|
||||
if (!is_data_valid())
|
||||
if (ensure_otp_data_ready())
|
||||
return -1;
|
||||
|
||||
*major = (otp.revision & 0xf0) >> 4;
|
||||
@ -191,15 +229,18 @@ int get_revision(int *major, int *minor)
|
||||
|
||||
const char *get_variant(void)
|
||||
{
|
||||
const char* var_str[BOARD_VARIANT_MAX] = {
|
||||
static const char * const var_str[BOARD_VARIANT_MAX] = {
|
||||
"Unknown",
|
||||
"Engineering Sample",
|
||||
"4GB non ECC"
|
||||
};
|
||||
|
||||
if (ensure_otp_data_ready())
|
||||
return var_str[BOARD_VARIANT_INVALID];
|
||||
|
||||
if ((otp.variant < BOARD_VARIANT_ENG_SAMPLE) ||
|
||||
(otp.variant >= BOARD_VARIANT_MAX))
|
||||
return var_str[0];
|
||||
return var_str[BOARD_VARIANT_INVALID];
|
||||
|
||||
return var_str[otp.variant];
|
||||
}
|
||||
@ -208,14 +249,13 @@ void set_board_info(void)
|
||||
{
|
||||
char env_str[13];
|
||||
|
||||
if (!is_data_valid())
|
||||
if (ensure_otp_data_ready())
|
||||
return;
|
||||
|
||||
snprintf(env_str, sizeof(env_str), "%i.%i", (otp.revision & 0xf0) >> 4, otp.revision & 0x0f);
|
||||
env_set("board_rev", env_str);
|
||||
|
||||
sprintf(env_str, "%012llx", *((uint64_t*) otp.serial_num) &
|
||||
0xFFFFFFFFFFFF);
|
||||
snprintf(env_str, sizeof(env_str), "%012llx", otp_serial());
|
||||
|
||||
env_set("serial#", env_str);
|
||||
}
|
||||
@ -224,7 +264,7 @@ int mac_read_from_otp(void)
|
||||
{
|
||||
unsigned int i;
|
||||
|
||||
if (!is_data_valid())
|
||||
if (ensure_otp_data_ready())
|
||||
return -1;
|
||||
|
||||
for (i = 0; i < MAX_NUM_PORTS; i++) {
|
||||
|
||||
@ -20,12 +20,13 @@ diff --git a/cmd/Kconfig b/cmd/Kconfig
|
||||
index 111111111111..222222222222 100644
|
||||
--- a/cmd/Kconfig
|
||||
+++ b/cmd/Kconfig
|
||||
@@ -1927,6 +1927,11 @@ config CMD_XXD
|
||||
@@ -1927,6 +1927,12 @@ config CMD_XXD
|
||||
help
|
||||
Print file as hexdump to standard output
|
||||
|
||||
+config CMD_FILEENV
|
||||
+ bool "fileenv"
|
||||
+ depends on CMD_FAT
|
||||
+ help
|
||||
+ Read a file into memory and store it to env.
|
||||
+
|
||||
|
||||
@ -103,7 +103,7 @@ diff --git a/fs/btrfs/compression.c b/fs/btrfs/compression.c
|
||||
+ ret = zstd_decompress_dctx(ctx, out_buf, out_len, cbuf, clen);
|
||||
+ free(workspace);
|
||||
+
|
||||
+ if (zstd_is_error(ret)) {
|
||||
+ if (zstd_is_error(ret) || ret < dlen) {
|
||||
+ free(tmp);
|
||||
+ return -1;
|
||||
+ }
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user