From ea45c4a0f07c699aec073f72daa5029438fab2c6 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Petr=20=C5=A0tetiar?= Date: Sun, 29 Dec 2019 21:25:33 +0100 Subject: [PATCH] system: fix failing image validation due to EINTR MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit It was quite common to see following error during sysupgrade on serial console: Failed to parse JSON: 4 This is happening due to the fact, that validate_firmware_image_call fork()s then waits in blocking read() for the input from the child process, but child finishes its tasks and exits, thus emitting SIGCHLD signal which then leads to the interruption of the blocking read() in the parent process with EINTR error. It seems like the recent fixes in the libubox library, particulary in the jshn sub-component (which empowers json_dump used in the shell script executed by the child process) made the execution somehow faster, thus exposing this racy behaviour in the validate_firmware_image_call at least on RPi-4 (Cortex-A72) target. So this patch fixes this issue by checking the read() return value and retrying the read() if interrupted due to the EINTR error. Ref: http://lists.infradead.org/pipermail/openwrt-devel/2020-January/020994.html Fixes: e990e215e8a3 ("system: add "validate_firmware_image" ubus method") Cc: Rafał Miłecki Tested-by: Kuan-Yi Li Tested-by: Petr Novák Reported-by: Petr Novák Reviewed-by: Hauke Mehrtens Signed-off-by: Petr Štetiar --- system.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/system.c b/system.c index 65d3f09..5cd88e0 100644 --- a/system.c +++ b/system.c @@ -466,6 +466,9 @@ static int validate_firmware_image_call(const char *file) blob_buf_init(&b, 0); while ((len = read(fds[0], buf, sizeof(buf)))) { + if (len < 0 && errno == EINTR) + continue; + jsobj = json_tokener_parse_ex(tok, buf, len); if (json_tokener_get_error(tok) == json_tokener_success) -- 2.30.2