bug#81016: Segmentation Fault using Address Sanitizer Compilation
Daniel Anderson <[email protected]> Sun, 10 May 2026 20:24:31 -0400
| Newsgroups | gmane.comp.gnu.parted.bugs |
|---|---|
| Message-ID | <[email protected]> |
--Apple-Mail=_F273FE5A-5D30-45A0-A455-80B40DC5663E
Content-Transfer-Encoding: quoted-printable
Content-Type: text/plain;
charset=utf-8
There=E2=80=99s a null pointer dereference bug in libparted/libparted.c =
that can cause a seg fault. I repreduced it by compiling under Adress =
Sanitizer.
Specificly on line 239+ This part here:
```C
ped_malloc (size_t size)
{
void* mem;
mem =3D (void*) malloc (size);
if (!mem) {
ped_exception_throw (PED_EXCEPTION_FATAL, =
PED_EXCEPTION_CANCEL,
_("Out of memory."));
return NULL;
}
return mem;
}
void* ped_calloc (size_t size)
{
void* buf =3D ped_malloc (size);
memset (buf, 0, size);
return buf;
}
```
You can see above that ped_malloc can return NULL in line 248 of the =
code but ped_calloc does not check for NULL values. It then calls =
memset on a NULL resulting in the seg fault.
I freshly compiled under Raspbian on Raspberry Pi 5 (aarch64) to show =
the bug works. I=E2=80=99m attaching a file, poc.sh, to trigger the seg =
fault under a parted build with ASAN enabled. I=E2=80=99m also =
attaching the patch.
You run the POC after making sure you have the ASAN build in your path, =
like:
```$ ASAN_PRELOAD=3D"$ASAN" =
LD_LIBRARY_PATH=3D/home/dan/local/parted-asan/lib =
PARTED_BIN=3D/home/dan/local/parted-asan/sbin/parted ./poc.sh```
I also ran the POC against the patched code and the patch works!
Full disclosure I found this but using the N184 bug and security =
vulnerability scanner. I wrote the bug report and patch myself. You =
can read more about N184 here: https://github.com/MillaFleurs/N184
Let me know if you have any questions.
Thanks,
Dan
--Apple-Mail=_F273FE5A-5D30-45A0-A455-80B40DC5663E
Content-Disposition: attachment;
filename=patch.diff
Content-Type: application/octet-stream;
x-unix-mode=0644;
name="patch.diff"
Content-Transfer-Encoding: 7bit
--- a/libparted/libparted.c
+++ b/libparted/libparted.c
@@ -255,6 +255,8 @@ void* ped_calloc (size_t size)
{
void* buf = ped_malloc (size);
+ if (buf == NULL)
+ return NULL;
memset (buf, 0, size);
return buf;
--Apple-Mail=_F273FE5A-5D30-45A0-A455-80B40DC5663E
Content-Disposition: attachment;
filename=poc.sh
Content-Type: application/octet-stream;
x-unix-mode=0755;
name="poc.sh"
Content-Transfer-Encoding: 7bit
#!/bin/sh
set -eu
case "$(uname -s)" in
Linux) ;;
*)
echo "PoC requires Linux LD_PRELOAD. Run this on Debian/Linux."
exit 0
;;
esac
parted_bin=${PARTED_BIN:-}
if [ -z "$parted_bin" ]; then
if which parted >/dev/null 2>&1; then
parted_bin=$(which parted)
fi
fi
if [ -z "$parted_bin" ]; then
echo "PoC skipped: set PARTED_BIN to a GNU parted binary, e.g. /usr/sbin/parted."
exit 0
fi
cc_bin=${CC:-cc}
if ! which "$cc_bin" >/dev/null 2>&1; then
echo "PoC requires a C compiler. Set CC=/path/to/cc if needed."
exit 1
fi
if ! which python3 >/dev/null 2>&1; then
echo "PoC requires python3."
exit 1
fi
tmp=$(mktemp -d "${TMPDIR:-/tmp}/parted-ped-calloc-poc.XXXXXX")
trap 'rm -rf "$tmp"' EXIT
lib="$tmp/fail-ped-malloc.so"
img=${IMAGE_PATH:-./ped-calloc-null-mbr.img}
cat >"$tmp/fail-ped-malloc.c" <<'C'
#define _GNU_SOURCE
#include <dlfcn.h>
#include <errno.h>
#include <execinfo.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
static void *(*real_ped_malloc)(size_t);
static int failed;
static int
stack_has_ped_calloc(void)
{
void *frames[48];
int n = backtrace(frames, 48);
for (int i = 0; i < n; i++) {
Dl_info info;
if (dladdr(frames[i], &info) == 0 || info.dli_sname == NULL)
continue;
if (strstr(info.dli_sname, "ped_calloc") != NULL)
return 1;
}
return 0;
}
void *
ped_malloc(size_t size)
{
if (real_ped_malloc == NULL) {
real_ped_malloc = dlsym(RTLD_NEXT, "ped_malloc");
if (real_ped_malloc == NULL) {
fprintf(stderr, "fail-ped-malloc: could not find real ped_malloc\n");
_exit(127);
}
}
if (!failed && stack_has_ped_calloc()) {
failed = 1;
errno = ENOMEM;
fprintf(stderr,
"fail-ped-malloc: returning NULL for ped_malloc(%zu) from ped_calloc stack\n",
size);
return NULL;
}
return real_ped_malloc(size);
}
C
"$cc_bin" -shared -fPIC "$tmp/fail-ped-malloc.c" -o "$lib" -ldl
python3 - "$img" <<'PY'
import struct
import sys
img = sys.argv[1]
sector_size = 512
sectors = 20480
with open(img, "wb") as f:
f.truncate(sectors * sector_size)
mbr = bytearray(sector_size)
# One normal Linux partition. Parsing it reaches msdos_partition_new(),
# which allocates DosPartitionData with ped_calloc().
mbr[446:462] = struct.pack(
"<B3sB3sII",
0x00,
b"\x00\x02\x00",
0x83,
b"\xff\xff\xff",
2048,
4096,
)
mbr[510:512] = b"\x55\xaa"
f.seek(0)
f.write(mbr)
print(f"created {img}")
print("image layout: raw MBR disk image with one Linux partition")
PY
echo
echo "Running with ped_malloc failure injected only from a ped_calloc() call stack:"
echo " $parted_bin -s $img unit s print"
preload=$lib
if [ -n "${ASAN_PRELOAD:-}" ]; then
preload="$ASAN_PRELOAD:$preload"
elif [ -n "${LD_PRELOAD:-}" ]; then
preload="$LD_PRELOAD:$preload"
fi
set +e
LD_PRELOAD="$preload" \
ASAN_OPTIONS="${ASAN_OPTIONS:-abort_on_error=1:symbolize=1}" \
"$parted_bin" -s "$img" unit s print >"$tmp/stdout" 2>"$tmp/stderr"
status=$?
set -e
echo "parted exit status: $status"
if [ -s "$tmp/stdout" ]; then
echo "stdout:"
sed 's/^/ /' "$tmp/stdout"
fi
if [ -s "$tmp/stderr" ]; then
echo "stderr:"
sed 's/^/ /' "$tmp/stderr"
fi
if ! grep -q 'fail-ped-malloc: returning NULL' "$tmp/stderr"; then
echo "Bug not triggered: ped_malloc failure did not occur from a visible ped_calloc() stack."
echo "Use an unstripped/shared GNU Parted build, preferably the ASAN build from ./asan-build-and-run.sh."
exit 1
fi
case "$status" in
139|134)
echo "BUG TRIGGERED: real GNU Parted crashed after ped_calloc() received NULL."
exit 0
;;
*)
if grep -qi 'AddressSanitizer\|SEGV\|segmentation fault\|null pointer' "$tmp/stderr" 2>/dev/null; then
echo "BUG TRIGGERED: sanitizer/crash text was reported."
exit 0
fi
echo "Malloc failure was injected, but this binary did not crash in the expected way."
exit 1
;;
esac
--Apple-Mail=_F273FE5A-5D30-45A0-A455-80B40DC5663E
Content-Transfer-Encoding: quoted-printable
Content-Type: text/plain;
charset=us-ascii
created ./ped-calloc-null-mbr.img image layout: raw MBR disk image with =
one Linux partition Running with ped_malloc failure injected only from a =
ped_calloc() call stack: /home/dan/local/parted-asan/sbin/parted -s =
./ped-calloc-null-mbr.img unit s print parted exit status: 139 stderr: =
fail-ped-malloc: returning NULL for ped_malloc(16) from ped_calloc stack =
You found a bug in GNU Parted! Here's what you have to do: Don't panic! =
The bug has most likely not affected any of your data. Help us to fix =
this bug by doing the following: Check whether the bug has already been =
fixed by checking
the last version of GNU Parted that you can find at: =
http://ftp.gnu.org/gnu/parted/ Please check this version prior to bug =
reporting. If this has not been fixed yet or if you don't know how to =
check, please visit the GNU Parted website: =
http://www.gnu.org/software/parted for further information. Your report =
should contain the version of this release (3.7.5-4fdb) along with the =
error message below, the output of=20
parted DEVICE unit co print unit s print and the following history of =
commands you entered. Also include any additional information about your =
setup you
consider important. Segmentation fault (core dumped) BUG TRIGGERED: =
real GNU Parted crashed after ped_calloc() received NULL.=
--Apple-Mail=_F273FE5A-5D30-45A0-A455-80B40DC5663E--