From d82c1912838f262b6f4b9157077f390f5f06b6c4 Mon Sep 17 00:00:00 2001
From: John Thomson <git@johnthomson.fastmail.com.au>
Date: Wed, 9 Dec 2020 13:03:04 +1000
Subject: [PATCH] package/base-files: caldata: use dd iflag fullblock
MIME-Version: 1.0
Content-Type: text/plain; charset=utf8
Content-Transfer-Encoding: 8bit

This dd flag ensures that the requested size
is retrieved from pipes or special filesystems (if available).

Without this flag, on multi-core systems,
Piped or special filesystem data can be truncated
when a size greater than PIPE_BUF is requested.

Fixes: FS#3494
Fixes: 7557e7f ("package/base-files: caldata: work around dd's
limitation")
Cc: Thibaut VARÈNE <hacks@slashdirt.org>

Signed-off-by: John Thomson <git@johnthomson.fastmail.com.au>
---
 package/base-files/Makefile                   |  2 +-
 .../base-files/files/lib/functions/caldata.sh | 37 +++++++++++++------
 2 files changed, 26 insertions(+), 13 deletions(-)

diff --git a/package/base-files/Makefile b/package/base-files/Makefile
index 0c612b73ca9b..fbcb69459201 100644
--- a/package/base-files/Makefile
+++ b/package/base-files/Makefile
@@ -12,7 +12,7 @@ include $(INCLUDE_DIR)/version.mk
 include $(INCLUDE_DIR)/feeds.mk
 
 PKG_NAME:=base-files
-PKG_RELEASE:=239
+PKG_RELEASE:=240
 PKG_FLAGS:=nonshared
 
 PKG_FILE_DEPENDS:=$(PLATFORM_DIR)/ $(GENERIC_PLATFORM_DIR)/base-files/
diff --git a/package/base-files/files/lib/functions/caldata.sh b/package/base-files/files/lib/functions/caldata.sh
index e22c7d27e69f..2177cf841532 100644
--- a/package/base-files/files/lib/functions/caldata.sh
+++ b/package/base-files/files/lib/functions/caldata.sh
@@ -3,6 +3,16 @@
 . /lib/functions.sh
 . /lib/functions/system.sh
 
+caldata_dd() {
+	local source=$1
+	local target=$2
+	local count=$(($3))
+	local offset=$(($4))
+
+	dd if=$source of=$target iflag=skip_bytes,fullblock bs=$count skip=$offset count=1 2>/dev/null
+	return $?
+}
+
 caldata_die() {
 	echo "caldata: " "$*"
 	exit 1
@@ -17,7 +27,7 @@ caldata_extract() {
 	mtd=$(find_mtd_chardev $part)
 	[ -n "$mtd" ] || caldata_die "no mtd device found for partition $part"
 
-	dd if=$mtd of=/lib/firmware/$FIRMWARE iflag=skip_bytes bs=$count skip=$offset count=1 2>/dev/null || \
+	caldata_dd $mtd /lib/firmware/$FIRMWARE $count $offset || \
 		caldata_die "failed to extract calibration data from $mtd"
 }
 
@@ -34,7 +44,7 @@ caldata_extract_ubi() {
 	ubi=$(nand_find_volume $ubidev $part)
 	[ -n "$ubi" ] || caldata_die "no UBI volume found for $part"
 
-	dd if=/dev/$ubi of=/lib/firmware/$FIRMWARE iflag=skip_bytes bs=$count skip=$offset count=1 2>/dev/null || \
+	caldata_dd /dev/$ubi /lib/firmware/$FIRMWARE $count $offset || \
 		caldata_die "failed to extract calibration data from $ubi"
 }
 
@@ -64,8 +74,7 @@ caldata_from_file() {
 
 	[ -n "$target" ] || target=/lib/firmware/$FIRMWARE
 
-	# dd doesn't handle partial reads from special files: use cat
-	cat $source | dd of=$target iflag=skip_bytes bs=$count skip=$offset count=1 2>/dev/null || \
+	caldata_dd $source $target $count $offset || \
 		caldata_die "failed to extract calibration data from $source"
 }
 
@@ -73,16 +82,20 @@ caldata_sysfsload_from_file() {
 	local source=$1
 	local offset=$(($2))
 	local count=$(($3))
+	local target_dir="/sys/$DEVPATH"
+	local target="$target_dir/data"
 
-	# dd doesn't handle partial reads from special files: use cat
-	# test extract to /dev/null first
-	cat $source | dd of=/dev/null iflag=skip_bytes bs=$count skip=$offset count=1 2>/dev/null || \
-		caldata_die "failed to extract calibration data from $source"
+	[ -d "$target_dir" ] || \
+		caldata_die "no sysfs dir to write: $target"
 
-	# can't fail now
-	echo 1 > /sys/$DEVPATH/loading
-	cat $source | dd of=/sys/$DEVPATH/data iflag=skip_bytes bs=$count skip=$offset count=1 2>/dev/null
-	echo 0 > /sys/$DEVPATH/loading
+	echo 1 > "$target_dir/loading"
+	caldata_dd $source $target $count $offset
+	if [ $? != 0 ]; then
+		echo 1 > "$target_dir/loading"
+		caldata_die "failed to extract calibration data from $source"
+	else
+		echo 0 > "$target_dir/loading"
+	fi
 }
 
 caldata_valid() {
-- 
2.30.2