Skip to content

Commit 7e6cc86

Browse files
drakenclimberpcmoore
authored andcommitted
arch: Add a script to build the arch and kernel version syscall tables
Add a script, src/arch-build-kver-tables.py, that can build a table for every kernel version, every architecture, and every syscall. This tool leverages @hrw's syscalls-table [1] github project. Subsequent commits will show how these tables can be used to generate or update libseccomp's syscalls.csv table. [1] https://github.com/hrw/syscalls-table Signed-off-by: Tom Hromatka <[email protected]> [PM: updated to include Linux v6.17] Signed-off-by: Paul Moore <[email protected]>
1 parent a41f43a commit 7e6cc86

File tree

1 file changed

+145
-0
lines changed

1 file changed

+145
-0
lines changed

src/arch-build-kver-tables.py

Lines changed: 145 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,145 @@
1+
#!/usr/bin/env python3
2+
#
3+
# Seccomp Library program to build the kernel version tables
4+
#
5+
# Copyright (c) 2025 Oracle and/or its affiliates. All rights reserved.
6+
# Author: Tom Hromatka <[email protected]>
7+
#
8+
9+
#
10+
# This library is free software; you can redistribute it and/or modify it
11+
# under the terms of version 2.1 of the GNU Lesser General Public License as
12+
# published by the Free Software Foundation.
13+
#
14+
# This library is distributed in the hope that it will be useful, but WITHOUT
15+
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
16+
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
17+
# for more details.
18+
#
19+
# You should have received a copy of the GNU Lesser General Public License
20+
# along with this library; if not, see <http://www.gnu.org/licenses>.
21+
#
22+
23+
#######################################################
24+
#### WARNING - to generate proper headers for x32, you
25+
#### must install the glibc 32-bit headers
26+
####
27+
#### apt install libc6-dev-x32
28+
####
29+
#######################################################
30+
31+
from subprocess import TimeoutExpired
32+
import subprocess
33+
import argparse
34+
import os
35+
36+
kernel_versions = ['3.0', '3.1', '3.2', '3.3', '3.4', '3.5', '3.6', '3.7',
37+
'3.8', '3.9', '3.10', '3.11', '3.12', '3.13', '3.14',
38+
'3.15', '3.16', '3.17', '3.18', '3.19', '4.0', '4.1',
39+
'4.2', '4.3', '4.4', '4.5', '4.6', '4.7', '4.8', '4.9',
40+
'4.10', '4.11', '4.12', '4.13', '4.14', '4.15', '4.16',
41+
'4.17', '4.18', '4.19', '4.20', '5.0', '5.1', '5.2',
42+
'5.3', '5.4', '5.5', '5.6', '5.7', '5.8', '5.9', '5.10',
43+
'5.11', '5.12', '5.13', '5.14', '5.15', '5.16', '5.17',
44+
'5.18', '5.19', '6.0', '6.1', '6.2', '6.3', '6.4', '6.5',
45+
'6.6', '6.7', '6.8', '6.9', '6.10', '6.11', '6.12',
46+
'6.13', '6.14', '6.15', '6.16', '6.17']
47+
48+
def parse_args():
49+
parser = argparse.ArgumentParser('Script to populate the syscalls.csv kernel versions',
50+
formatter_class=argparse.RawTextHelpFormatter)
51+
parser.add_argument('-d', '--datapath', required=True, type=str, default=None,
52+
help="Path to the local copy of @hrw's syscalls-table tool")
53+
parser.add_argument('-k', '--kernelpath', required=True, type=str, default=None,
54+
help="Path to the kernel source directory")
55+
parser.add_argument('-V', '--versions', required=False, type=str, default=None,
56+
help="Comma-separated list of kernel versions to build, e.g "
57+
"3.0,6.1,6.10. If not specified all known kernel version "
58+
"tables are built")
59+
parser.add_argument('-v', '--verbose', action='store_true',
60+
help='Show verbose warnings')
61+
62+
args = parser.parse_args()
63+
64+
if not args.versions:
65+
args.versions = kernel_versions
66+
else:
67+
args.versions = args.versions.split(',')
68+
69+
return args
70+
71+
def run(command, verbose=False, shell=False, timeout=None):
72+
if shell:
73+
if isinstance(command, str):
74+
# nothing to do. command is already formatted as a string
75+
pass
76+
elif isinstance(command, list):
77+
command = ' '.join(command)
78+
else:
79+
raise ValueError('Unsupported command type')
80+
81+
subproc = subprocess.Popen(command, shell=shell,
82+
stdout=subprocess.PIPE,
83+
stderr=subprocess.PIPE)
84+
85+
if timeout:
86+
try:
87+
out, err = subproc.communicate(timeout=timeout)
88+
ret = subproc.returncode
89+
90+
out = out.strip().decode('UTF-8')
91+
err = err.strip().decode('UTF-8')
92+
except TimeoutExpired as timeout:
93+
if timeout.stdout:
94+
out = timeout.stdout.strip().decode('UTF-8')
95+
else:
96+
out = ''
97+
if timeout.stderr:
98+
err = timeout.stderr.strip().decode('UTF-8')
99+
else:
100+
err = ''
101+
102+
if len(err):
103+
ret = -1
104+
else:
105+
ret = 0
106+
else:
107+
out, err = subproc.communicate()
108+
ret = subproc.returncode
109+
110+
out = out.strip().decode('UTF-8')
111+
err = err.strip().decode('UTF-8')
112+
113+
if verbose:
114+
if not shell:
115+
command = ' '.join(command)
116+
print('run:\n\tcmd = {}\n\tret = {}\n\tstdout = {}\n\tstderr = {}\n'.format(
117+
command, ret, out, err))
118+
119+
return ret, out, err
120+
121+
def main(args):
122+
for kver in args.versions:
123+
print('Building version table for kernel {}'.format(kver))
124+
125+
checkout_cmd = 'cd {};git checkout v{}'.format(args.kernelpath, kver)
126+
ret, out, err = run(checkout_cmd, shell=True)
127+
if ret != 0:
128+
raise KeyError('Failed to checkout v{}: {}'.format(kver, ret))
129+
130+
update_cmd = 'cd {};bash scripts/update-tables.sh {}'.format(
131+
args.datapath, args.kernelpath)
132+
ret, out, err = run(update_cmd, shell=True)
133+
if ret != 0:
134+
raise RuntimeError('Failed to update tables: {}'.format(ret))
135+
136+
src_path = os.path.join(args.datapath, 'data/tables')
137+
dest_path = os.path.join(os.getcwd(), 'tables-{}'.format(kver))
138+
cp_cmd = 'cp -r {} {}'.format(src_path, dest_path)
139+
ret, out, err = run(cp_cmd, shell=True)
140+
if ret != 0:
141+
raise RuntimeError('Table copy failed: {}'.format(ret))
142+
143+
if __name__ == '__main__':
144+
args = parse_args()
145+
main(args)

0 commit comments

Comments
 (0)