aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMike Frysinger <vapier@gentoo.org>2021-10-23 05:49:00 -0400
committerMike Frysinger <vapier@gentoo.org>2021-10-23 18:18:04 -0400
commita07dffb605956bd37a1a0ce0801b7d5233c2f67a (patch)
tree2112b7d0e49c4c0efc7b506e48a26a52b2e6026f
parentlibsandbox: tweak how undefined symbols are declared (diff)
downloadsandbox-a07dffb6.tar.gz
sandbox-a07dffb6.tar.bz2
sandbox-a07dffb6.zip
libsandbox: extend symbols format to specify diff syscall name
This enables support for 64-bit time_t syscalls where the glibc symbol name is not the same as the kernel syscall name. Closes: https://bugs.gentoo.org/751241 Signed-off-by: Mike Frysinger <vapier@gentoo.org>
-rw-r--r--libsandbox/symbols.h.in2
-rw-r--r--libsandbox/trace.c14
-rw-r--r--scripts/gen_symbol_header.awk6
-rw-r--r--scripts/gen_symbol_version_map.awk6
-rw-r--r--scripts/gen_trace_header.awk42
5 files changed, 45 insertions, 25 deletions
diff --git a/libsandbox/symbols.h.in b/libsandbox/symbols.h.in
index 40c04e3..ecf141c 100644
--- a/libsandbox/symbols.h.in
+++ b/libsandbox/symbols.h.in
@@ -78,7 +78,7 @@ __utime64
utimes
__utimes64
utimensat
-__utimensat64
+__utimensat64 utimensat_time64
futimesat
__futimesat64
lutimes
diff --git a/libsandbox/trace.c b/libsandbox/trace.c
index ae5f935..b7e65b4 100644
--- a/libsandbox/trace.c
+++ b/libsandbox/trace.c
@@ -305,7 +305,7 @@ static bool trace_check_syscall(const struct syscall_entry *se, void *regs)
state.regs = regs;
state.nr = nr = se->sys;
state.func = name = se->name;
- if (!SB_NR_IS_DEFINED(nr)) goto done;
+ if (!SB_NR_IS_DEFINED(se->nr)) goto done;
else if (nr == SB_NR_MKDIR) state.pre_check = sb_mkdirat_pre_check;
else if (nr == SB_NR_MKDIRAT) state.pre_check = sb_mkdirat_pre_check;
else if (nr == SB_NR_UNLINK) state.pre_check = sb_unlinkat_pre_check;
@@ -313,8 +313,7 @@ static bool trace_check_syscall(const struct syscall_entry *se, void *regs)
else state.pre_check = NULL;
/* Hmm, add these functions to the syscall table and avoid this if() ? */
- if (!SB_NR_IS_DEFINED(nr)) goto done;
- else if (nr == SB_NR_CHMOD) return trace_check_syscall_C (&state);
+ if (nr == SB_NR_CHMOD) return trace_check_syscall_C (&state);
else if (nr == SB_NR_CHOWN) return trace_check_syscall_C (&state);
else if (nr == SB_NR_CREAT) return trace_check_syscall_C (&state);
/* NB: Linux syscall does not have a flags argument. */
@@ -343,7 +342,14 @@ static bool trace_check_syscall(const struct syscall_entry *se, void *regs)
else if (nr == SB_NR_UNLINKAT) return trace_check_syscall_DCF(&state);
else if (nr == SB_NR_UTIME) return trace_check_syscall_C (&state);
else if (nr == SB_NR_UTIMES) return trace_check_syscall_C (&state);
- else if (nr == SB_NR_UTIMENSAT) return _trace_check_syscall_DCF(&state, 1, 4);
+
+ else if (nr == SB_NR_UTIMENSAT) {
+ utimensat:
+ return _trace_check_syscall_DCF(&state, 1, 4);
+ } else if (nr == SB_NR___UTIMENSAT64) {
+ state.nr = SB_NR_UTIMENSAT;
+ goto utimensat;
+ }
else if (nr == SB_NR_ACCESS) {
char *path = do_peekstr(trace_arg(regs, 1));
diff --git a/scripts/gen_symbol_header.awk b/scripts/gen_symbol_header.awk
index 14e0a99..e669c85 100644
--- a/scripts/gen_symbol_header.awk
+++ b/scripts/gen_symbol_header.awk
@@ -3,9 +3,11 @@ BEGIN {
COUNT = 0;
sym_regex = "";
- while ((getline symbol < SYMBOLS_FILE) > 0) {
- if (symbol ~ /^ *#/ || symbol ~ /^$/)
+ while ((getline line < SYMBOLS_FILE) > 0) {
+ if (line ~ /^ *#/ || line ~ /^$/)
continue;
+ split(line, fields);
+ symbol = fields[1];
SYMBOLS[++COUNT] = symbol;
if (sym_regex)
diff --git a/scripts/gen_symbol_version_map.awk b/scripts/gen_symbol_version_map.awk
index cd0aa84..661cb1d 100644
--- a/scripts/gen_symbol_version_map.awk
+++ b/scripts/gen_symbol_version_map.awk
@@ -1,9 +1,11 @@
# Read the symbols list and create regexs to use for processing readelf output.
BEGIN {
sym_regex = "";
- while ((getline symbol < SYMBOLS_FILE) > 0) {
- if (symbol ~ /^ *#/ || symbol ~ /^$/)
+ while ((getline line < SYMBOLS_FILE) > 0) {
+ if (line ~ /^ *#/ || line ~ /^$/)
continue;
+ split(line, fields);
+ symbol = fields[1];
if (sym_regex)
sym_regex = sym_regex "|";
diff --git a/scripts/gen_trace_header.awk b/scripts/gen_trace_header.awk
index e9d84a6..0bb53b1 100644
--- a/scripts/gen_trace_header.awk
+++ b/scripts/gen_trace_header.awk
@@ -1,11 +1,16 @@
# Read the symbols list and create regexs to use for processing readelf output.
function read_symbols() {
COUNT = 0;
- while ((getline symbol < SYMBOLS_FILE) > 0) {
- if (symbol ~ /^ *#/ || symbol ~ /^$/)
+ while ((getline line < SYMBOLS_FILE) > 0) {
+ if (line ~ /^ *#/ || line ~ /^$/)
continue;
+ nfields = split(line, fields);
+ symbol = fields[1];
+ syscall = nfields > 1 ? fields[2] : symbol;
- SYMBOLS[++COUNT] = symbol;
+ c = ++COUNT
+ SYMBOLS[c] = symbol;
+ SYSCALLS[c] = syscall;
}
}
@@ -13,19 +18,22 @@ BEGIN {
read_symbols();
if (MODE == "gen") {
- for (x in SYMBOLS) {
- s = SYMBOLS[x]
- print "SB_" s " = SYS_" s
+ for (x in SYSCALLS) {
+ print "SB_" SYMBOLS[x] " = SYS_" SYSCALLS[x];
}
exit(0);
}
}
-function out(name, val)
+function out(name, syscall, val)
{
- name = toupper(name)
- print "#define SB_SYS" syscall_prefix "_" name " " val;
- print "S(" name ")";
+ uname = toupper(name)
+ syscall_define = "SB_SYS" syscall_prefix "_" uname
+ print "#define " syscall_define " " val;
+ if (name == syscall)
+ print "S(" uname ")";
+ else
+ print "{ " syscall_define ", SB_NR_" uname ", \"" uname "\" },";
}
{
@@ -42,21 +50,23 @@ function out(name, val)
# a straight number or an expression (a syscall base)
sub(/^[^=]*= /, "");
- for (i = 1; i <= COUNT; ++i)
+ syscall = "<awk_script_error>";
+ for (i = 1; i <= COUNT; ++i) {
if (SYMBOLS[i] == name) {
- SYMBOLS[i] = "";
+ FOUND[i] = 1;
+ syscall = SYSCALLS[i];
break;
}
+ }
- out(name, $0);
+ out(name, syscall, $0);
}
END {
if (MODE != "gen") {
for (x in SYMBOLS) {
- s = SYMBOLS[x];
- if (s != "")
- out(s, "SB_NR_UNDEF");
+ if (!FOUND[x])
+ out(SYMBOLS[x], SYSCALLS[x], "SB_NR_UNDEF");
}
}
}