Skip to content

Instantly share code, notes, and snippets.

@sprout42
Created November 12, 2019 17:18
Show Gist options
  • Save sprout42/ca53936ff7364d2eb1697c0fe3601c10 to your computer and use it in GitHub Desktop.
Save sprout42/ca53936ff7364d2eb1697c0fe3601c10 to your computer and use it in GitHub Desktop.
Compile unfork
#!/bin/bash -ex
# Downloads and builds the dependencies of https://github.com/whitequark/unfork.
# For some reason I keep getting an ENOMEM error from the kernel (Ubuntu 19.10:
# 5.3.0-19-generic) when unfork tries to mmap the vsyscall segment of a target
# process. For now this script works around that with a patch until I figure out why.
# Make sure a 32bit compiler is installed
sudo apt install -y gcc-multilib-i686-linux-gnu g++-multilib-i686-linux-gnu
if [ ! -d unfork ]; then
git clone https://github.com/whitequark/unfork
fi
if [ ! -d unfork ]; then
git clone git://git.musl-libc.org/musl
git -C musl checkout v1.1.24
(
cd musl
patch -p1 < ../unfork/musl-no-vdso.patch
)
fi
if [ ! -f x86_64-linux-musl/bin/musl-gcc ]; then
mkdir -p x86_64-linux-musl
(
cd musl
make distclean
./configure --prefix=$(pwd)/../x86_64-linux-musl
make
make install
)
ln -s -f /usr/include/linux x86_64-linux-musl/include/
ln -s -f /usr/include/x86_64-linux-gnu/asm x86_64-linux-musl/include/
ln -s -f /usr/include/asm-generic x86_64-linux-musl/include/
fi
if [ ! -f i386-linux-musl/bin/musl-gcc ]; then
mkdir -p i386-linux-musl
(
cd musl
make distclean
./configure --prefix=$(pwd)/../i386-linux-musl --target=i686-linux-gnu
make
make install
)
ln -s -f /usr/include/linux i386-linux-musl/include/
ln -s -f /usr/include/i386-linux-gnu/asm i386-linux-musl/include/
ln -s -f /usr/include/asm-generic i386-linux-musl/include/
fi
if [ ! -f unfork/unfork64.elf ]; then
(
cd unfork
cat <<'EOF' | patch -p1
diff --git a/Makefile b/Makefile
index 7b15a0f..59e0248 100644
--- a/Makefile
+++ b/Makefile
@@ -10,7 +10,7 @@ CXXFLAGS = -std=c++14 -fno-exceptions -Wall -Wextra -g
LDFLAGS = -pthread -static -Wl,-Ttext-segment,0x00100000
$(NAME)64.elf: unfork.cc agent.cc
- gcc -specs musl-gcc-64.specs -m64 $(CXXFLAGS) $(LDFLAGS) -o $@ $^
+ ../x86_64-linux-musl/bin/musl-gcc -m64 $(CXXFLAGS) $(LDFLAGS) -o $@ $^
$(NAME)32.elf: unfork.cc agent.cc
- gcc -specs musl-gcc-32.specs -m32 $(CXXFLAGS) $(LDFLAGS) -o $@ $^
+ ../i386-linux-musl/bin/musl-gcc -m32 $(CXXFLAGS) $(LDFLAGS) -o $@ $^
diff --git a/unfork.cc b/unfork.cc
index 6cf64eb..28f17f2 100644
--- a/unfork.cc
+++ b/unfork.cc
@@ -325,12 +325,24 @@ int unfork_stage2(void *info_p) {
struct mapping *mapping_it;
uintptr_t vdso_addr = 0;
for (mapping_it = rmappings; mapping_it; mapping_it = mapping_it->prev) {
+ // For some reason 64bit binaries always fail when trying to mmap the
+ // vsyscall segment
+ if (mapping_it->pathname != NULL && strcmp(mapping_it->pathname, "[vsyscall]") == 0) {
+ log("[x] " WPRIxPTR "-" WPRIxPTR " %c%c%c " WPRIxSZ " %s\n",
+ mapping_it->start, mapping_it->end,
+ (mapping_it->prot & PROT_READ) ? 'r' : '-',
+ (mapping_it->prot & PROT_WRITE) ? 'w' : '-',
+ (mapping_it->prot & PROT_EXEC) ? 'x' : '-',
+ mapping_it->offset, mapping_it->pathname);
+ continue;
+ }
log("[=] " WPRIxPTR "-" WPRIxPTR " %c%c%c " WPRIxSZ " %s\n",
mapping_it->start, mapping_it->end,
(mapping_it->prot & PROT_READ) ? 'r' : '-',
(mapping_it->prot & PROT_WRITE) ? 'w' : '-',
(mapping_it->prot & PROT_EXEC) ? 'x' : '-',
mapping_it->offset, mapping_it->pathname);
+ log("%016llx\n", mapping_it->end - mapping_it->start);
// Check against now-highest used point in our address space, which is the top of userfaultfd
// thread stack.
EOF
make
)
fi
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment