diff options
author | Guo Xuenan <guoxuenan@huawei.com> | 2023-06-05 20:58:15 +0800 |
---|---|---|
committer | Gao Xiang <hsiangkao@linux.alibaba.com> | 2023-06-06 22:19:30 +0800 |
commit | ecae5bdf1c888027aa3c8a2f55310002ecc0ce48 (patch) | |
tree | 9b9269bb168c67af2c151413c68dd65b361af0fa | |
parent | d42adfdeceab8839329ebb78f52e0e0ec0e73b77 (diff) | |
download | erofs-utils-ecae5bdf1c888027aa3c8a2f55310002ecc0ce48.tar.gz |
erofs-utils: fsck: fix segmentation fault for file extraction
Currently, we use fsckcfg.extract_path to record the path of file
to be extracted, when the name is too long, it will exceed the
fsckcfg.extract_path[PATH_MAX] array and segmentation fault may
occur.
Test and reproduce with the following script:
``` bash
FSCK=`which fsck.erofs`
MKFS=`which mkfs.erofs`
IN_DIR=./src
$MKFS x.img ${IN_DIR}
get_dst_dir()
{
local len=$1
local perlen=$2
local dst_dir=$(printf 'a%.0s' $(seq 1 $((perlen - 1))))
local n=$((len / ${perlen}))
local lastlen=$((len - perlen * n))
local lastdir=$(printf 'a%.0s' $(seq 1 $lastlen))
local outdir=""
for x in `seq 1 $n`
do
outdir=${outdir}/${dst_dir}
done
[[ -n $lastdir ]] && outdir=${outdir}/${lastdir}
echo ${outdir}
}
for n in `seq 4000 1 5000`
do
dst_dir=$(get_dst_dir $n 255)
echo ${#dst_dir}
OUT_DIR="./${dst_dir}"
rm -rf $(dirname $OUT_DIR) > /dev/null 2>&1
mkdir -p $OUT_DIR
$FSCK --extract=${OUT_DIR} x.img > /dev/null 2>&1
done
```
Fixes: f44043561491 ("erofs-utils: introduce fsck.erofs")
Fixes: b11f84f593f9 ("erofs-utils: fsck: convert to use erofs_iterate_dir()")
Fixes: 412c8f908132 ("erofs-utils: fsck: add --extract=X support to extract to path X")
Signed-off-by: Guo Xuenan <guoxuenan@huawei.com>
Reviewed-by: Gao Xiang <hsiangkao@linux.alibaba.com>
Link: https://lore.kernel.org/r/20230605125815.2835732-1-guoxuenan@huawei.com
Signed-off-by: Gao Xiang <hsiangkao@linux.alibaba.com>
-rw-r--r-- | fsck/main.c | 5 |
1 files changed, 5 insertions, 0 deletions
diff --git a/fsck/main.c b/fsck/main.c index a0377a7..47c01d8 100644 --- a/fsck/main.c +++ b/fsck/main.c @@ -131,6 +131,11 @@ static int erofsfsck_parse_options_cfg(int argc, char **argv) while (len > 1 && optarg[len - 1] == '/') len--; + if (len >= PATH_MAX) { + erofs_err("target directory name too long!"); + return -ENAMETOOLONG; + } + fsckcfg.extract_path = malloc(PATH_MAX); if (!fsckcfg.extract_path) return -ENOMEM; |