Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Modernize architectures and generate seccomp policy for all architectures supported by host OS #26

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
43 changes: 36 additions & 7 deletions tools/gen_syscalls/extract.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,11 @@
limitations under the License.
"""

import os
import re
import sys

out_file = open('output_syscalls.c', 'w')
# Functions

def output(str):
out_file.write(str)
Expand All @@ -45,24 +47,51 @@ def output_syscall(nr, name):
real_name = m.group(1)
else:
real_name = name
output('\t{"'+real_name+'", '+str(nr)+', {')
for j in xrange(0, nb_args):
output('\t{"'+real_name+'", '+str(nr | sys_call_bit)+', {')
for j in range(0, nb_args):
arg_name = get_string_val("print __syscall_meta__"+name+"->args["+str(j)+"]")
arg_type = get_string_val("print __syscall_meta__"+name+"->types["+str(j)+"]")
arg_size = get_int_val("print sizeof("+arg_type+")")
output('[ARG_'+str(j)+'] = {"'+arg_name+'", '+str(arg_size)+'}, ')
output('}},\n')

num_syscalls=get_int_val("print sizeof(sys_call_table)/sizeof(sys_call_table[0])")
table_cmd = "print sys_call_table"
# Start of script

# Define syscall table name

sys_call_table_name = os.getenv("SYSCALLTABLENAME")
if (sys_call_table_name is None) or (sys_call_table_name == ""):
print("WARNING: Environment variable 'SYSCALLTABLENAME' not set!")
out_file.close()
sys.exit(1)

# Define syscall bit

sys_call_bit = os.getenv("SYSCALLBIT")
if (sys_call_bit is None) or (sys_call_bit == ""):
print("WARNING: Environment variable 'SYSCALLBIT' not set!")
out_file.close()
sys.exit(1)
else:
try:
sys_call_bit = int(sys_call_bit)
except:
print("WARNING: Wring value of environment varibable 'SYSCALLBIT'!")
out_file.close()
sys.exit(1)

out_file = open('output_syscalls.c', 'a')

num_syscalls=get_int_val(str("print sizeof(" + sys_call_table_name + ")/sizeof(" + sys_call_table_name + "[0])"))
table_cmd = "print " + sys_call_table_name
syscall_regex = "<([Ss]y[Ss]|stub)_([^>]*)>"

if num_syscalls <= 0:
num_syscalls = 1000
table_cmd = "info symbol ((void**)sys_call_table)"
table_cmd = "info symbol ((void**)" + sys_call_table_name + ")"
syscall_regex = "([Ss]y[Ss]|stub)_([^ ]*)"

for i in xrange(0, num_syscalls):
for i in range(0, num_syscalls):
try:
out = gdb.execute(table_cmd+"["+str(i)+"]", False, True)
except gdb.error:
Expand Down
113 changes: 84 additions & 29 deletions tools/gen_syscalls/gen_syscalls.sh
Original file line number Diff line number Diff line change
Expand Up @@ -19,22 +19,28 @@
# limitations under the License.
#

if [ $# -ne 1 ] || [ ! -e "$1" -o -d "$1" ]; then
echo "USAGE: $0 [linux_with_debugging_symbols]"
exit 1
fi
# Start of functions

linux="$1"
arch="$(readelf -h "$linux" | sed -ne '/Machine:/{s/^[[:space:]]*Machine:[[:space:]]*//;P}')"
if [ "$arch" = "Advanced Micro Devices X86-64" ]; then
arch="AMD64"
fi
outname="${arch,,}_syscalls.c"
generate_syscall_file()
{
# $1 - linux file ($linux)
# $2 - architecture ($arch)
# $3 - (optional) syscall table symbol name (sys_call_table)
# $4 - (optional) syscall bit (0 or _X32_SYSCALL_BIT)

echo -n "Generating syscalls for $arch... "
linux="$1"
arch="$2"
SYSCALLTABLENAME="$3"
SYSCALLBIT="$4"

year=$(date +%Y)
cat > "$outname" <<HEADER
[ -z "$SYSCALLTABLENAME" ] && SYSCALLTABLENAME="sys_call_table"
[ -z "$SYSCALLBIT" ] && SYSCALLBIT=0

echo -n "Generating syscalls for $arch ... "
outname="${arch,,}_syscalls.c"

year=$(date +%Y)
cat > "$outname" <<HEADER
/*
Kafel - syscalls ($arch)
-----------------------------------------
Expand Down Expand Up @@ -69,26 +75,75 @@ cat > "$outname" <<HEADER
const struct syscall_descriptor ${arch,,}_syscall_list[] = {
HEADER

case "$arch" in
ARM)
gdb --batch -ex 'set gnutarget elf32-littlearm' -ex "file $linux" -x extract.py
;;
*)
gdb --batch -ex "file $linux" -x extract.py
;;
esac

if [ -f "missing/${arch,,}.c" ]; then
cat "missing/${arch,,}.c" >> output_syscalls.c
fi
echo -n "" > output_syscalls.c


case "$arch" in
ARM)
SYSCALLTABLENAME="$SYSCALLTABLENAME" \
SYSCALLBIT=$SYSCALLBIT \
"$GDB" --batch \
-ex 'set gnutarget elf32-littlearm' \
-ex "file $linux" \
-x extract.py
;;
*)
SYSCALLTABLENAME="$SYSCALLTABLENAME" \
SYSCALLBIT=$SYSCALLBIT \
"$GDB" --batch \
-ex "file $linux" \
-x extract.py
;;
esac

cat output_syscalls.c | sort -k1,1 --unique --stable -t',' >> "$outname"
rm output_syscalls.c
if [ -f "missing/${arch,,}.c" ]; then
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

would prefer that missing/{arch}.c takes precedence over automatically extracted as it was before

cat "missing/${arch,,}.c" >> output_syscalls.c
fi

cat >> "$outname" <<FOOTER
cat output_syscalls.c | sort -k1,1 --unique --stable -t',' >> "$outname"

rm output_syscalls.c

cat >> "$outname" <<FOOTER
};

const size_t ${arch,,}_syscall_list_size = sizeof(${arch,,}_syscall_list)/sizeof(${arch,,}_syscall_list[0]);
FOOTER

echo "DONE"
echo "DONE"
}

# End of functions

# Start of script

if [ $# -ne 1 ] || [ ! -e "$1" -o -d "$1" ]; then
echo "USAGE: $0 [linux_with_debugging_symbols]"
exit 1
fi

export LANG=C

# For gdb-multiarch or toolchain-provided gdb

[ -z "$GDB" ] && GDB="gdb"

linux="$1"
arch="$(readelf -h "$linux" | sed -ne '/Machine:/{s/^[[:space:]]*Machine:[[:space:]]*//;P}')"
class="$(readelf -h "$linux" | sed -ne '/Class:/{s/^[[:space:]]*Class:[[:space:]]*//;P}')"

if [ "$arch" = "Advanced Micro Devices X86-64" ]; then
arch="AMD64"
elif [ "$arch" = "Intel 80386" ]; then
arch="i386"
elif [ "$arch" = "MIPS R3000" ]; then
[ "$class" = "ELF32" ] && arch="mipso32" || arch="mips64"
fi

if [ "$arch" = "AMD64" ]; then
generate_syscall_file "$linux" amd64
generate_syscall_file "$linux" i386 ia32_sys_call_table 0
generate_syscall_file "$linux" x32 x32_sys_call_table 1073741824
else
generate_syscall_file "$linux" "$arch"
fi