1
0
mirror of https://gitlab.alpinelinux.org/alpine/cloud/tiny-cloud.git synced 2026-02-04 12:32:45 +03:00

Fix user-data decompression on all shells

yash[1] and zsh does not handle 8-bit bytes in strings good. Work around it
by using printf ... | cmp ... to compare the header. This should be 100%
posix compatible.

Also fix some of the compression header magic bytes:

- unxz: Use octal aas the string '\3757zXZ\000' was misinterpreted by some
  shells.
- lzma: the third byte represents compression mode[2], and we want
  support all compression modes not only '8', so we only check the first
  three bytes instead of 4.

[1]: Upstream report: https://osdn.net/projects/yash/ticket/47772
[2]: https://github.com/frizb/FirmwareReverseEngineering/blob/master/IdentifyingCompressionAlgorithms.md#lzma
This commit is contained in:
Natanael Copa 2023-04-05 18:45:32 +02:00
parent bbb0c19ae6
commit 7ea8f69a06
3 changed files with 22 additions and 23 deletions

View File

@ -2,7 +2,7 @@ test-default:
image: alpine:latest image: alpine:latest
stage: test stage: test
script: script:
- apk add make kyua yx - apk add make kyua yx xz lz4 zstd
- make -j $(nproc) check - make -j $(nproc) check
tags: tags:
- docker-alpine - docker-alpine

View File

@ -40,11 +40,6 @@ set_ssh_keys() {
imds @ssh-keys > "$keys_file" imds @ssh-keys > "$keys_file"
} }
match_header() {
local bytes=$(echo -en "$1")
[ "$bytes" = "$(dd bs=1 count=${#bytes} if="$2" 2>/dev/null)" ]
}
save_userdata() { save_userdata() {
skip_action save_userdata && return skip_action save_userdata && return
@ -55,22 +50,25 @@ save_userdata() {
imds -e @userdata > "$tmpfile" imds -e @userdata > "$tmpfile"
cmd="cat" cmd="cat"
if ! skip_action decompress_userdata; then if ! skip_action decompress_userdata; then
if match_header '\037\213\010' "$tmpfile"; then if printf '\037\213\010' | cmp -s -n 3 "$tmpfile"; then
cmd="gzip -dc" gzip -dc "$tmpfile" > "$userdata"
elif match_header 'BZh' "$tmpfile"; then elif printf 'BZh' | cmp -s -n 3 "$tmpfile"; then
cmd="bzip2 -dc" bzip2 -dc "$tmpfile" > "$userdata"
elif match_header '\3757zXZ\000' "$tmpfile"; then elif printf '\375\067\172\130\132\000' | cmp -s -n 6 "$tmpfile"; then
cmd="unxz -c" unxz -c "$tmpfile" > "$userdata"
elif match_header '\135\0\0\0' "$tmpfile"; then elif printf '\135\000\000' | cmp -s -n 3 "$tmpfile"; then
cmd="lzma -dc" lzma -dc "$tmpfile" > "$userdata"
elif match_header '\211\114\132' "$tmpfile"; then elif printf '\211\114\132' | cmp -s -n 3 "$tmpfile"; then
cmd="lzop -dc" lzop -dc "$tmpfile" > "$userdata"
elif match_header '\004\042\115\030' "$tmpfile"; then elif printf '\004\042\115\030' | cmp -s -n 4 "$tmpfile"; then
cmd="lz4 -dc" lz4 -dc "$tmpfile" > "$userdata"
elif match_header '(\265/\375' "$tmpfile"; then elif printf '(\265/\375' | cmp -s -n 4 "$tmpfile"; then
cmd="zstd -dc" zstd -dc "$tmpfile" > "$userdata"
else
cp "$tmpfile" "$userdata"
fi fi
else
cp "$tmpfile" "$userdata"
fi fi
$cmd "$tmpfile" > "$userdata"
rm "$tmpfile" rm "$tmpfile"
} }

View File

@ -99,8 +99,9 @@ save_userdata_compressed_body() {
set_nocloud_userdata_from_file tmpfile set_nocloud_userdata_from_file tmpfile
CLOUD="nocloud" atf_check \ CLOUD="nocloud" atf_check \
sh -c ". \"$lib\"; save_userdata" sh -c ". \"$lib\"; save_userdata"
grep "^#cloud-config" var/lib/cloud/user-data \ if ! grep "^#cloud-config" var/lib/cloud/user-data; then
|| atf_fail "$comp failed" atf_fail "$comp failed"
fi
done done
} }