Skip to content

Commit

Permalink
arch: basic infrastructure for tracking per-syscall/ABI kernel versions
Browse files Browse the repository at this point in the history
This commit adds basic support for tracking what kernel introduced a
syscall for a given arch/ABI.  It does not provide any of that kernel
version information, leaving only a SCMP_KV_UNDEF placeholder, nor
does it attempt to do anything meaningful with this new source of
information; this patch simply establishes a new syscalls.csv format
so that we can start properly recording the kernel versions.

Acked-by: Tom Hromatka <[email protected]>
Signed-off-by: Paul Moore <[email protected]>
  • Loading branch information
pcmoore committed May 9, 2022
1 parent 832b65b commit 72198d9
Show file tree
Hide file tree
Showing 23 changed files with 699 additions and 532 deletions.
2 changes: 2 additions & 0 deletions src/arch-aarch64.c
Original file line number Diff line number Diff line change
Expand Up @@ -38,4 +38,6 @@ const struct arch_def arch_def_aarch64 = {
.syscall_resolve_num_raw = aarch64_syscall_resolve_num,
.syscall_rewrite = NULL,
.rule_add = NULL,
.syscall_name_kver = aarch64_syscall_name_kver,
.syscall_num_kver = aarch64_syscall_num_kver,
};
2 changes: 2 additions & 0 deletions src/arch-arm.c
Original file line number Diff line number Diff line change
Expand Up @@ -92,4 +92,6 @@ const struct arch_def arch_def_arm = {
.syscall_resolve_num_raw = arm_syscall_resolve_num,
.syscall_rewrite = NULL,
.rule_add = NULL,
.syscall_name_kver = arm_syscall_name_kver,
.syscall_num_kver = arm_syscall_num_kver,
};
5 changes: 3 additions & 2 deletions src/arch-gperf-generate
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,9 @@ sys_csv_tmp=$(mktemp -t generate_syscalls_XXXXXX)

# filter and prepare the syscall csv file
cat $sys_csv | grep -v '^#' | nl -ba -s, -v0 | \
sed -e 's/^[[:space:]]\+\([0-9]\+\),\([^,]\+\),\(.*\)/\2,\1,\3/' \
-e ':repeat; {s|\([^,]\+\)\(.*\)[^_]PNR|\1\2,__PNR_\1|g;}; t repeat' \
sed -e '{s|^[[:space:]]\+\([0-9]\+\),\([^,]\+\),\(.*\)|\2,\1,\3|;};' \
-e '{:r1; {s|\([^,]\+\)\(.*\)[^_]PNR|\1\2,__PNR_\1|g;}; t r1};' \
-e '{s|,KV_|,SCMP_KV_|g;};' \
> $sys_csv_tmp
[[ $? -ne 0 ]] && exit 1

Expand Down
4 changes: 4 additions & 0 deletions src/arch-mips.c
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,8 @@ const struct arch_def arch_def_mips = {
.syscall_resolve_num_raw = mips_syscall_resolve_num_raw,
.syscall_rewrite = abi_syscall_rewrite,
.rule_add = abi_rule_add,
.syscall_name_kver = mips_syscall_name_kver,
.syscall_num_kver = mips_syscall_num_kver,
};

const struct arch_def arch_def_mipsel = {
Expand All @@ -105,4 +107,6 @@ const struct arch_def arch_def_mipsel = {
.syscall_resolve_num_raw = mips_syscall_resolve_num_raw,
.syscall_rewrite = abi_syscall_rewrite,
.rule_add = abi_rule_add,
.syscall_name_kver = mips_syscall_name_kver,
.syscall_num_kver = mips_syscall_num_kver,
};
4 changes: 4 additions & 0 deletions src/arch-mips64.c
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,8 @@ const struct arch_def arch_def_mips64 = {
.syscall_resolve_num_raw = mips64_syscall_resolve_num,
.syscall_rewrite = NULL,
.rule_add = NULL,
.syscall_name_kver = mips64_syscall_name_kver,
.syscall_num_kver = mips64_syscall_num_kver,
};

const struct arch_def arch_def_mipsel64 = {
Expand All @@ -97,4 +99,6 @@ const struct arch_def arch_def_mipsel64 = {
.syscall_resolve_num_raw = mips64_syscall_resolve_num,
.syscall_rewrite = NULL,
.rule_add = NULL,
.syscall_name_kver = mips64_syscall_name_kver,
.syscall_num_kver = mips64_syscall_num_kver,
};
4 changes: 4 additions & 0 deletions src/arch-mips64n32.c
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,8 @@ const struct arch_def arch_def_mips64n32 = {
.syscall_resolve_num_raw = mips64n32_syscall_resolve_num,
.syscall_rewrite = NULL,
.rule_add = NULL,
.syscall_name_kver = mips64n32_syscall_name_kver,
.syscall_num_kver = mips64n32_syscall_num_kver,
};

const struct arch_def arch_def_mipsel64n32 = {
Expand All @@ -99,4 +101,6 @@ const struct arch_def arch_def_mipsel64n32 = {
.syscall_resolve_num_raw = mips64n32_syscall_resolve_num,
.syscall_rewrite = NULL,
.rule_add = NULL,
.syscall_name_kver = mips64n32_syscall_name_kver,
.syscall_num_kver = mips64n32_syscall_num_kver,
};
2 changes: 2 additions & 0 deletions src/arch-parisc.c
Original file line number Diff line number Diff line change
Expand Up @@ -22,4 +22,6 @@ const struct arch_def arch_def_parisc = {
.syscall_resolve_num_raw = parisc_syscall_resolve_num,
.syscall_rewrite = NULL,
.rule_add = NULL,
.syscall_name_kver = parisc_syscall_name_kver,
.syscall_num_kver = parisc_syscall_num_kver,
};
2 changes: 2 additions & 0 deletions src/arch-parisc64.c
Original file line number Diff line number Diff line change
Expand Up @@ -22,4 +22,6 @@ const struct arch_def arch_def_parisc64 = {
.syscall_resolve_num_raw = parisc64_syscall_resolve_num,
.syscall_rewrite = NULL,
.rule_add = NULL,
.syscall_name_kver = parisc64_syscall_name_kver,
.syscall_num_kver = parisc64_syscall_num_kver,
};
2 changes: 2 additions & 0 deletions src/arch-ppc.c
Original file line number Diff line number Diff line change
Expand Up @@ -49,4 +49,6 @@ const struct arch_def arch_def_ppc = {
.syscall_resolve_num_raw = ppc_syscall_resolve_num,
.syscall_rewrite = abi_syscall_rewrite,
.rule_add = abi_rule_add,
.syscall_name_kver = ppc_syscall_name_kver,
.syscall_num_kver = ppc_syscall_num_kver,
};
4 changes: 4 additions & 0 deletions src/arch-ppc64.c
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,8 @@ const struct arch_def arch_def_ppc64 = {
.syscall_resolve_num_raw = ppc64_syscall_resolve_num,
.syscall_rewrite = abi_syscall_rewrite,
.rule_add = abi_rule_add,
.syscall_name_kver = ppc64_syscall_name_kver,
.syscall_num_kver = ppc64_syscall_num_kver,
};

const struct arch_def arch_def_ppc64le = {
Expand All @@ -64,4 +66,6 @@ const struct arch_def arch_def_ppc64le = {
.syscall_resolve_num_raw = ppc64_syscall_resolve_num,
.syscall_rewrite = abi_syscall_rewrite,
.rule_add = abi_rule_add,
.syscall_name_kver = ppc64_syscall_name_kver,
.syscall_num_kver = ppc64_syscall_num_kver,
};
2 changes: 2 additions & 0 deletions src/arch-riscv64.c
Original file line number Diff line number Diff line change
Expand Up @@ -31,4 +31,6 @@ const struct arch_def arch_def_riscv64 = {
.syscall_resolve_num_raw = riscv64_syscall_resolve_num,
.syscall_rewrite = NULL,
.rule_add = NULL,
.syscall_name_kver = riscv64_syscall_name_kver,
.syscall_num_kver = riscv64_syscall_num_kver,
};
2 changes: 2 additions & 0 deletions src/arch-s390.c
Original file line number Diff line number Diff line change
Expand Up @@ -32,4 +32,6 @@ const struct arch_def arch_def_s390 = {
.syscall_resolve_num_raw = s390_syscall_resolve_num,
.syscall_rewrite = abi_syscall_rewrite,
.rule_add = abi_rule_add,
.syscall_name_kver = s390_syscall_name_kver,
.syscall_num_kver = s390_syscall_num_kver,
};
2 changes: 2 additions & 0 deletions src/arch-s390x.c
Original file line number Diff line number Diff line change
Expand Up @@ -32,4 +32,6 @@ const struct arch_def arch_def_s390x = {
.syscall_resolve_num_raw = s390x_syscall_resolve_num,
.syscall_rewrite = abi_syscall_rewrite,
.rule_add = abi_rule_add,
.syscall_name_kver = s390x_syscall_name_kver,
.syscall_num_kver = s390x_syscall_num_kver,
};
4 changes: 4 additions & 0 deletions src/arch-sh.c
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,8 @@ const struct arch_def arch_def_sheb = {
.syscall_resolve_num_raw = sh_syscall_resolve_num,
.syscall_rewrite = abi_syscall_rewrite,
.rule_add = abi_rule_add,
.syscall_name_kver = sh_syscall_name_kver,
.syscall_num_kver = sh_syscall_num_kver,
};

const struct arch_def arch_def_sh = {
Expand All @@ -56,4 +58,6 @@ const struct arch_def arch_def_sh = {
.syscall_resolve_num_raw = sh_syscall_resolve_num,
.syscall_rewrite = abi_syscall_rewrite,
.rule_add = abi_rule_add,
.syscall_name_kver = sh_syscall_name_kver,
.syscall_num_kver = sh_syscall_num_kver,
};
85 changes: 56 additions & 29 deletions src/arch-syscall-validate
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
#
# Copyright (c) 2014 Red Hat <[email protected]>
# Copyright (c) 2020 Cisco Systems, Inc. <[email protected]>
# Copyright (c) 2022 Microsoft Corporation. <[email protected]>
#
# Author: Paul Moore <[email protected]>
#
Expand Down Expand Up @@ -59,15 +60,15 @@ function verify_deps() {
#
function usage() {
cat << EOF
usage: arch-syscall-validate [-h] [-c] [-a <arch>] <kernel_directory>
usage: arch-syscall-validate [-h] [-c <file>] [-a <arch>] <kernel_directory>
libseccomp syscall validation script
optional arguments:
-h show this help message and exit
-a architecture
-l output the library's syscall definitions
-s output the kernel's syscall definitions
-c generate a CSV of the kernel's syscall definitions
-c <file> generate a CSV of the kernel's syscall definitions
EOF
}

Expand Down Expand Up @@ -733,6 +734,7 @@ function dump_lib() {
# Arguments:
# 1 path to the kernel source
# 2 "sys" or "lib" depending on the syscall list to use
# 3 csv file to use as input for saved fields
#
# Generare a syscall csv file from the given kernel sources.
#
Expand All @@ -755,6 +757,26 @@ function gen_csv() {
abi_list+=" s390 s390x"
abi_list+=" sh"

# read the csv to get the existing data
local -A csv
local csv_has_kver=0
local csv_input="$3"
[[ ! -e "$3" ]] && csv_input=/dev/null
grep -q "KV_" "$csv_input" && csv_has_kver=1
while read line; do
sc=$(echo $line | cut -d, -f 1)
local field=2
for abi in $abi_list; do
csv[$sc,$abi]=$(echo $line | cut -d, -f $field)
((field++))
if [[ $csv_has_kver -eq 1 ]]; then
csv[$sc,${abi}_KVER]=$(echo $line | \
cut -d, -f $field)
((field++))
fi
done
done < <(sed 's/#.*//;/^[ \t]*$/d' "$csv_input")

# get the full syscall list
for abi in $abi_list; do
eval output_$abi=$(mktemp -t syscall_validate_XXXXXX)
Expand All @@ -764,26 +786,31 @@ function gen_csv() {
cat $(eval echo $`eval echo output_$abi`);
done) | awk -F "," '{ print $1 }' | sort -u)
# output a simple header
printf "#syscall (v%s %s)" \
"$(kernel_version "$1")" "$(TZ=UTC date "+%Y-%m-%d")"
for abi in $abi_list; do
printf ",%s" $abi
done
printf "\n"
# output the syscall csv details
for sc in $sc_list; do
printf "%s" $sc
# redirect the subshell to the csv file
(
# output a simple header
printf "#syscall (v%s %s)" \
"$(kernel_version "$1")" "$(TZ=UTC date "+%Y-%m-%d")"
for abi in $abi_list; do
num=$(grep "^$sc," \
$(eval echo $`eval echo output_$abi`) | \
awk -F "," '{ print $2 }' )
[[ -z $num ]] && num="PNR"
printf ",%s" $num
printf ",%s,%s_kver" $abi $abi
done
printf "\n"
done
# output the syscall csv details
for sc in $sc_list; do
printf "%s" $sc
for abi in $abi_list; do
num=$(grep "^$sc," \
$(eval echo $`eval echo output_$abi`) | \
awk -F "," '{ print $2 }' )
kver=${csv[$sc,${abi}_KVER]}
[[ -z $num ]] && num="PNR"
[[ -z $kver ]] && kver="KV_UNDEF"
printf ",%s,%s" $num $kver
done
printf "\n"
done
) > "$3"
# cleanup
for abi in $abi_list; do
Expand All @@ -799,29 +826,29 @@ verify_deps gcc
verify_deps grep
verify_deps mktemp
verify_deps sed
if [[ ! -x $LIB_SYS_DUMP ]]; then
echo "error: \"$LIB_SYS_DUMP\" is not in the current working directory"
exit 1
fi
opt_arches=""
opt_csv=0
opt_csv=""
opt_sys=0
opt_lib=0
while getopts "a:cslh" opt; do
while getopts "a:c:slh" opt; do
case $opt in
a)
opt_arches+="$OPTARG "
;;
c)
opt_csv=1
opt_csv="$OPTARG"
;;
s)
opt_sys=1
opt_lib=0
;;
l)
if [[ ! -x $LIB_SYS_DUMP ]]; then
echo "error: \"$LIB_SYS_DUMP\" is not present"
exit 1
fi
opt_sys=0
opt_lib=1
;;
Expand Down Expand Up @@ -860,12 +887,12 @@ fi
tmp_lib=$(mktemp -t syscall_validate_XXXXXX)
tmp_sys=$(mktemp -t syscall_validate_XXXXXX)

if [[ $opt_csv -eq 1 ]]; then
if [[ -n $opt_csv ]]; then
# generate the syscall csv file
if [[ $opt_lib -eq 1 ]]; then
gen_csv $kernel_dir "lib"
gen_csv $kernel_dir "lib" $opt_csv
else
gen_csv $kernel_dir "sys"
gen_csv $kernel_dir "sys" $opt_csv
fi
else
# loop through the architectures and compare
Expand Down
2 changes: 2 additions & 0 deletions src/arch-x32.c
Original file line number Diff line number Diff line change
Expand Up @@ -83,4 +83,6 @@ const struct arch_def arch_def_x32 = {
.syscall_resolve_num_raw = x32_syscall_resolve_num,
.syscall_rewrite = NULL,
.rule_add = NULL,
.syscall_name_kver = x32_syscall_name_kver,
.syscall_num_kver = x32_syscall_num_kver,
};
2 changes: 2 additions & 0 deletions src/arch-x86.c
Original file line number Diff line number Diff line change
Expand Up @@ -48,4 +48,6 @@ const struct arch_def arch_def_x86 = {
.syscall_resolve_num_raw = x86_syscall_resolve_num,
.syscall_rewrite = abi_syscall_rewrite,
.rule_add = abi_rule_add,
.syscall_name_kver = x86_syscall_name_kver,
.syscall_num_kver = x86_syscall_num_kver,
};
2 changes: 2 additions & 0 deletions src/arch-x86_64.c
Original file line number Diff line number Diff line change
Expand Up @@ -38,4 +38,6 @@ const struct arch_def arch_def_x86_64 = {
.syscall_resolve_num_raw = x86_64_syscall_resolve_num,
.syscall_rewrite = NULL,
.rule_add = NULL,
.syscall_name_kver = x86_64_syscall_name_kver,
.syscall_num_kver = x86_64_syscall_num_kver,
};
23 changes: 20 additions & 3 deletions src/arch.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@
* Enhanced Seccomp Architecture/Machine Specific Code
*
* Copyright (c) 2012 Red Hat <[email protected]>
* Copyright (c) 2022 Microsoft Corporation. <[email protected]>
*
* Author: Paul Moore <[email protected]>
*/

Expand Down Expand Up @@ -62,6 +64,8 @@ struct arch_def {
const char *(*syscall_resolve_num_raw)(int num);
int (*syscall_rewrite)(const struct arch_def *arch, int *syscall);
int (*rule_add)(struct db_filter *db, struct db_api_rule_list *rule);
enum scmp_kver (*syscall_name_kver)(const char *name);
enum scmp_kver (*syscall_num_kver)(int num);
};

/* arch_def for the current architecture */
Expand All @@ -72,21 +76,34 @@ extern const struct arch_def *arch_def_native;
extern const struct arch_def arch_def_##NAME; \
int NAME##_syscall_resolve_name(const char *name); \
const char *NAME##_syscall_resolve_num(int num); \
enum scmp_kver NAME##_syscall_name_kver(const char *name); \
enum scmp_kver NAME##_syscall_num_kver(int num); \
const struct arch_syscall_def *NAME##_syscall_iterate(unsigned int spot);

/* macro to define the arch specific structures and functions */
#define ARCH_DEF(NAME) \
int NAME##_syscall_resolve_name(const char *name) \
{ \
return syscall_resolve_name(name, OFFSET_ARCH(NAME)); \
return syscall_resolve_name(name, SYSTBL_OFFSET(NAME)); \
} \
const char *NAME##_syscall_resolve_num(int num) \
{ \
return syscall_resolve_num(num, OFFSET_ARCH(NAME)); \
return syscall_resolve_num(num, SYSTBL_OFFSET(NAME)); \
} \
enum scmp_kver NAME##_syscall_name_kver(const char *name) \
{ \
return syscall_resolve_name_kver(name, \
SYSTBL_OFFSET(NAME##_kver)); \
} \
enum scmp_kver NAME##_syscall_num_kver(int num) \
{ \
return syscall_resolve_num_kver(num, \
SYSTBL_OFFSET(NAME), \
SYSTBL_OFFSET(NAME##_kver)); \
} \
const struct arch_syscall_def *NAME##_syscall_iterate(unsigned int spot) \
{ \
return syscall_iterate(spot, OFFSET_ARCH(NAME)); \
return syscall_iterate(spot, SYSTBL_OFFSET(NAME)); \
}

/* syscall name/num mapping */
Expand Down
Loading

0 comments on commit 72198d9

Please sign in to comment.