38 Commits

Author SHA1 Message Date
Weijie Gao
42d3937654 jail/seccomp: add support for loongarch64
Add support for loongarch64 in utrace and ujail.

Signed-off-by: Weijie Gao <hackpascal@gmail.com>
2024-12-22 17:04:11 +01:00
Tony Ambardar
946552a7b5 trace: use standard POSIX header for basename()
The musl libc only implements POSIX basename() but provided a GNU header
kludge in <string.h>, which was removed in musl 1.2.5 [1]. Use the standard
<libgen.h> header to avoid compilation errors like:

trace/trace.c: In function 'main':
trace/trace.c:435:64: error: implicit declaration of function 'basename';
did you mean 'rename'? [-Werror=implicit-function-declaration]
  435 | if (asprintf(&json, "/tmp/%s.%u.json", basename(*argv), child) < 0)
      |                                        ^~~~~~~~
      |                                        rename
cc1: all warnings being treated as errors

Link 1: https://git.musl-libc.org/cgit/musl/log/?qt=grep&q=basename

Signed-off-by: Tony Ambardar <itugrok@yahoo.com>
2024-03-30 14:30:41 -07:00
Junnan Xu
a68088ef31 utrace: fix memory leak
Fixes following memory leak:

  14 bytes in 1 blocks are definitely lost in loss record 1 of 5
     at 0x4079514: malloc (vg_replace_malloc.c:309)
     by 0x4049A04: vasprintf (vasprintf.c:13)
     by 0x4046354: asprintf (asprintf.c:10)
     by 0x80491A9: main (in /root/utrace)

  134 bytes in 1 blocks are definitely lost in loss record 3 of 5
     at 0x4079514: malloc (vg_replace_malloc.c:309)
     by 0x4049A04: vasprintf (vasprintf.c:13)
     by 0x4046354: asprintf (asprintf.c:10)
     by 0x8049208: main (in /root/utrace)

Signed-off-by: Junnan Xu <junnanx.xu@gmail.com>
Reviewed-by: Rui Salvaterra <rsalvaterra@gmail.com>
2022-06-27 10:52:10 +01:00
Daniel Golle
8a60e7e066 trace: don't leak file descriptor in error path
Coverity CID: 1491022 Resource leak
Signed-off-by: Daniel Golle <daniel@makrotopia.org>
2021-09-15 21:43:16 +01:00
Daniel Golle
269c9e4c7e trace: preload: avoid NULL-dereference here as well
Fix potential NULL-pointer derefence in trace/preload.c similar to how
it was fixed in jail/preload.c by commit b824a89
("jail: preload: avoid NULL-dereference in case things go wrong").

Coverity CID: 1446096 Dereference after null check
Signed-off-by: Daniel Golle <daniel@makrotopia.org>
2021-08-31 00:46:59 +01:00
Nick Hainke
96d8bf2c7b trace: fix potential use-after-free occurence
char* tmp is used in the fprintf function altough it is already freed.

Fixes: e5b38fd1 ("trace: free memory allocated by blobmsg_format_json_indent()")

Signed-off-by: Nick Hainke <vincent@systemli.org>
2021-08-30 22:15:10 +01:00
Daniel Golle
e5b38fd129 trace: free memory allocated by blobmsg_format_json_indent()
Only one out of two occurances have been addressed previously.
Close the other one now.

Coverity CID: 1446205
Fixes: 51f1cd23 ("trace: free string returned by blobmsg_format_json_indent()")
Signed-off-by: Daniel Golle <daniel@makrotopia.org>
2021-08-30 20:30:43 +01:00
Daniel Golle
d716cb5ca3 trace: handle open() return value and make sure string is terminated
Coverity CID: 1446154 Argument cannot be negative

Signed-off-by: Daniel Golle <daniel@makrotopia.org>
2021-08-24 18:32:01 +01:00
Daniel Golle
51f1cd2366 trace: free string returned by blobmsg_format_json_indent()
Coverity CID: 1446205 Resource leak

Signed-off-by: Daniel Golle <daniel@makrotopia.org>
2021-08-24 18:31:56 +01:00
Daniel Golle
c23d8bf816 trace: fix build on aarch64
Signed-off-by: Daniel Golle <daniel@makrotopia.org>
2021-03-19 22:25:15 +00:00
Daniel Golle
3e88c6f2b1 jail/seccomp: add support for aarch64
Add support for Aarch64 in utrace and ujail.
Sort and unify architecture-specific definitions in headers.
Use new PTRACE_GET_SYSCALL_INFO call (available since Linux 5.3), for
now only for aarch64, but this may potentially unify things and get
rid of some #ifdef'ery for other platforms as well.

Signed-off-by: Daniel Golle <daniel@makrotopia.org>
2021-03-19 22:13:41 +00:00
Daniel Golle
c110405181 trace: switch to OCI seccomp JSON output
Generate JSON as specified on OCI runtime spec for seccomp syscall
filter instead of our previous OpenWrt-specific format.

[1]: https://github.com/opencontainers/runtime-spec/blob/master/config-linux.md#seccomp
Signed-off-by: Daniel Golle <daniel@makrotopia.org>
2020-11-17 13:05:12 +00:00
Rosen Penev
aed7fb3cf2 procd: fix compilation with uClibc-ng
_GNU_SOURCE was missing.

Also defined two macros unavailable with uClibc-ng.

Signed-off-by: Rosen Penev <rosenp@gmail.com>
[resolved conflict in jail.c]
Signed-off-by: Petr Štetiar <ynezz@true.cz>
2020-07-11 15:13:15 +02:00
Wojciech Dubowik
d876d1ca22 procd: trace: Define syscall registers for powerpc platform
According to manpage the syscall nr is stored in r0
and return value in r3 for powerpc. Define it so we
can use seccomp and utrace on powerpc.

Signed-off-by: Wojciech Dubowik <Wojciech.Dubowik@neratec.com>
2019-03-11 23:08:34 +01:00
Michal Sojka
5f57223913 trace: Use properly sized type for PTRACE_GETEVENTMSG
Without this, on 64-bit systems, ptrace call corrupts memory because
it stores 64bit value to 32bit pid_t variable.

Signed-off-by: Michal Sojka <michal.sojka@cvut.cz>
2018-07-30 15:24:15 +02:00
Hans Dedecker
653629f19e trace: check asprintf() return value
Check asprintf() return value; fixes ignoring return value warnings:

warning: ignoring return value of 'asprintf', declared with attribute
warn_unused_result [-Wunused-result]

Signed-off-by: Hans Dedecker <dedeckeh@gmail.com>
2018-01-23 08:36:36 +01:00
Hans Dedecker
67eb7e6816 trace: add missing limits.h include
Fixes compile issue when using glibc as INT_MAX is reported as
undeclared.

Signed-off-by: Hans Dedecker <dedeckeh@gmail.com>
2018-01-23 08:36:03 +01:00
Rosen Penev
fa5ce1c2b4 procd: Replace strerror(errno) with %m.
Saves 1496 bytes from compiled size under glibc. No functional difference.

Signed-off-by: Rosen Penev <rosenp@gmail.com>
2018-01-02 13:01:10 +01:00
Michal Sojka
260a4cd046 utrace: Start the tracee only after uloop initialization
Without this, early ptrace stops can be missed because they can happen
before the call to uloop_init().

Signed-off-by: Michal Sojka <sojkam1@fel.cvut.cz>
2017-09-28 08:26:56 +02:00
Michal Sojka
520ad3c715 utrace: Switch all logging to ulog
This unifies all logs messages produced by utrace and removes
duplicated functionality.

Signed-off-by: Michal Sojka <sojkam1@fel.cvut.cz>
2017-09-28 08:26:56 +02:00
Michal Sojka
1c48104ffc utrace: Support non-contiguous syscall numbers
ARM architecture does not have its system call numbers contiguous. So
far, utrace ignored the non-contiguous system calls, but it makes it
difficult to setup seccomp whitelists. This patch adds support for
these extra out-of-range syscalls.

It extends the generated file syscall_names.h to include a few
functions. Now, for ARM this file looks like:

    #include <asm/unistd.h>
    static const char *__syscall_names[] = {
     [280] = "waitid",
     [148] = "fdatasync",
    ...
     [252] = "epoll_wait",
     [74] = "sethostname",
    };
    static inline const char *syscall_name(unsigned i) {
      if (i < ARRAY_SIZE(__syscall_names))
        return __syscall_names[i];
      switch (i) {
        case 0x0f0001: return "breakpoint";
        case 0x0f0003: return "usr26";
        case 0x0f0004: return "usr32";
        case 0x0f0005: return "set_tls";
        case 0x0f0002: return "cacheflush";
      default: return (void*)0;
      }
    }
    static inline int syscall_index(unsigned i) {
      if (i < ARRAY_SIZE(__syscall_names))
        return i;
      switch (i) {
      case 0x0f0001: return ARRAY_SIZE(__syscall_names) + 0;
      case 0x0f0003: return ARRAY_SIZE(__syscall_names) + 1;
      case 0x0f0004: return ARRAY_SIZE(__syscall_names) + 2;
      case 0x0f0005: return ARRAY_SIZE(__syscall_names) + 3;
      case 0x0f0002: return ARRAY_SIZE(__syscall_names) + 4;
      default: return -1;
      }
    }
    static inline int syscall_index_to_number(unsigned i) {
      if (i < ARRAY_SIZE(__syscall_names))
        return i;
      switch (i) {
      case ARRAY_SIZE(__syscall_names) + 0: return 0x0f0001;
      case ARRAY_SIZE(__syscall_names) + 1: return 0x0f0003;
      case ARRAY_SIZE(__syscall_names) + 2: return 0x0f0004;
      case ARRAY_SIZE(__syscall_names) + 3: return 0x0f0005;
      case ARRAY_SIZE(__syscall_names) + 4: return 0x0f0002;
      default: return -1;
      }
    }
    #define SYSCALL_COUNT (ARRAY_SIZE(__syscall_names) + 5)

For x86, which does not have extra syscalls, the file looks this way:

    #include <asm/unistd.h>
    static const char *__syscall_names[] = {
     [247] = "waitid",
     [75] = "fdatasync",
     ...
     [232] = "epoll_wait",
     [170] = "sethostname",
    };
    static inline const char *syscall_name(unsigned i) {
      if (i < ARRAY_SIZE(__syscall_names))
        return __syscall_names[i];
      switch (i) {
      default: return (void*)0;
      }
    }
    static inline int syscall_index(unsigned i) {
      if (i < ARRAY_SIZE(__syscall_names))
        return i;
      switch (i) {
      default: return -1;
      }
    }
    static inline int syscall_index_to_number(unsigned i) {
      if (i < ARRAY_SIZE(__syscall_names))
        return i;
      switch (i) {
      default: return -1;
      }
    }
    #define SYSCALL_COUNT (ARRAY_SIZE(__syscall_names) + 0)

Signed-off-by: Michal Sojka <sojkam1@fel.cvut.cz>
2017-09-28 08:26:56 +02:00
Michal Sojka
582cf97315 utrace: Forward SIGTERM to the traced process
When a service is started with "/etc/init.d/<service> trace" or when
it has seccomp enabled (i.e. runs under seccomp-trace), stopping the
service with "/etc/init.d/<service> stop" stops only the tracer. The
service itself continue executing. This patch ensures that the service
is terminated as well.

Signed-off-by: Michal Sojka <sojkam1@fel.cvut.cz>
2017-09-28 08:26:56 +02:00
Michal Sojka
32534f7058 utrace: Report ptrace errors 2017-09-28 08:26:56 +02:00
Michal Sojka
5e4ad0270b seccomp: Log seccomp violations with utrace
Older kernel version shipped by LEDE/OpenWrt contained patch
target/linux/generic/patches-3.18/999-seccomp_log.patch that logged
seccomp violations. For some reason, newer kernels do not have this
patch. Without this kind of logging, it is very hard to setup seccomp
whitelist properly, so this commit modifies utrace to serve as a
logger for seccomp violations.

With this patch, when utrace is executed via seccomp-trace symlink, it
does not trace normal syscalls but only seccomp violations and logs
them to syslog. For example:

    seccomp-trace: uci[3955] tried to call non-whitelisted syscall: ftruncate64 (see /etc/seccomp/myservice.json)

Compared to the kernel-based logging, this approach gives users more
information - which json whitelist needs to be extended. This is
especially useful for services, which fork many diverse children such
as shell scripts.

Signed-off-by: Michal Sojka <sojkam1@fel.cvut.cz>
2017-09-28 08:26:56 +02:00
Michal Sojka
2661b2f7c1 utrace: Use PTHREAD_SEIZE instead of PTHREAD_TRACEME
This makes it easier to handle initial ptrace-stops (after
fork/clone/...), because we don't need to distinguish whether SIGSTOP
is from user or from ptrace. Also execve() does not deliver an extra
SIGTRAP, which we would have to handle.

Signed-off-by: Michal Sojka <sojkam1@fel.cvut.cz>
2017-09-28 08:26:56 +02:00
Michal Sojka
b5d53c6c68 utrace: Deliver signals to traced processes
Without this change, traced processes do not receive any signal,
because all the signals are "eaten" by the tracer.

Signed-off-by: Michal Sojka <sojkam1@fel.cvut.cz>
2017-09-28 08:26:56 +02:00
Michal Sojka
b416ed97c4 utrace: Support tracing multi-threaded processes and vfork
Signed-off-by: Michal Sojka <sojkam1@fel.cvut.cz>
2017-09-28 08:26:56 +02:00
Michal Sojka
8b7d47af20 utrace: Trace processes across forks
Without this change, utrace can trace only a single process. When the
process forks, syscalls of its children do not appear in utrace
output. This is a problem, because seccomp filters are inherited by
children and therefore filters generated by utrace may lack legitimate
syscalls.

This commit enables utrace to trace processes across forks. The
functionality can be demonstrated by the following examples:

    utrace /bin/touch /tmp/xxx

produces:

    {
            "whitelist": [
                    "rt_sigaction",
                    "rt_sigreturn",
                    "exit",
                    "getuid",
                    "exit_group",
                    "utimensat"
            ],
            "policy": 1
    }

The command:

    utrace /bin/sh -c 'touch /tmp/xxx'

without this commit produces:

    {
            "whitelist": [
                    "stat",
                    "rt_sigaction",
                    "rt_sigprocmask",
                    "rt_sigreturn",
                    "getpid",
                    "fork",
                    "exit",
                    "wait4",
                    "uname",
                    "getcwd",
                    "getuid",
                    "getppid",
                    "exit_group"
            ],
            "policy": 1
    }

but with this commit, the output is the following:

    {
            "whitelist": [
                    "read",
                    "open",
                    "close",
                    "stat",
                    "fstat",
                    "mmap",
                    "mprotect",
                    "rt_sigaction",
                    "rt_sigprocmask",
                    "rt_sigreturn",
                    "getpid",
                    "fork",
                    "execve",
                    "exit",
                    "wait4",
                    "uname",
                    "fcntl",
                    "getcwd",
                    "getuid",
                    "getppid",
                    "arch_prctl",
                    "gettid",
                    "set_tid_address",
                    "exit_group",
                    "utimensat"
            ],
            "policy": 1
    }

Note that in addition to utimensat syscall from touch, this output
contains more syscalls than what is in the union of single-process sh
and touch traces. The reason is that single-process traces do not
include syscalls from dynamic linker (due to preload trick), but the
trace of forked processes includes the dynamic linker syscalls. This
is unavoidable, because dynamic linker of the forked processes will be
subject to seccomp filters of the parent process.

Signed-off-by: Michal Sojka <sojkam1@fel.cvut.cz>
2017-09-28 08:26:56 +02:00
Michal Sojka
c6b6ec6d23 utrace: Sort syscalls by number of invocations
seccomp and service jailing announce email [1] mentioned that "utrace
tool will sort the syscalls by the number of invocations". The code
did not do that until this commit.

[1] https://lists.openwrt.org/pipermail/openwrt-devel/2015-March/032197.html

Signed-off-by: Michal Sojka <sojkam1@fel.cvut.cz>
2017-09-28 08:26:56 +02:00
Michal Sojka
017f3a1f9e utrace: Fix off-by-one errors
This fixes two errors:

1) memcpy() copies envc elements starting from index 1, so the number
   of elements in target array should be envc + 1. But only envc was
   allocated.

2) If original environment envp is empty, i.e. it contains only a NULL
   element, the while loop misses it.

Signed-off-by: Michal Sojka <sojkam1@fel.cvut.cz>
2017-09-28 08:26:56 +02:00
Michal Sojka
5acaf15b4e utrace: Fix environment initialization
We want to copy the existing environment instead of the new one to
itself. Other bugs in this code are fixed in the next commit.

Signed-off-by: Michal Sojka <sojkam1@fel.cvut.cz>
2017-09-28 08:26:56 +02:00
Felix Fietkau
794669c9ea trace: use the cloned environment pointer
Fixes an issue where it would overwrite the first environment variable
with the preload one

Signed-off-by: Felix Fietkau <nbd@nbd.name>
2016-12-05 18:19:10 +01:00
Rosen Penev
4004b68fe5 procd: Fix memory leaks found by cppcheck
Signed-off by: Rosen Penev <rosenp@gmail.com>
2016-12-05 18:19:10 +01:00
Ulrich Weber
890ac34c46 syslog: set sane priority values
otherwise LOG_USER/LOG_EMERG is used

Signed-off-by: Ulrich Weber <uw@ocedo.com>
2015-11-07 13:36:43 +01:00
Daniel Golle
11fa67184a trace: add support for ARM architecture
Signed-off-by: Daniel Golle <daniel@makrotopia.org>
2015-05-14 05:22:59 +02:00
John Crispin
27159f21f7 fix include order
this broke x86_64 builds on uclibc

Signed-off-by: John Crispin <blogic@openwrt.org>
2015-04-10 00:39:16 +02:00
John Crispin
91da63d3d3 properly handle return codes
Signed-off-by: John Crispin <blogic@openwrt.org>
2015-03-28 18:35:21 +01:00
John Crispin
dfcfcca7ba add initial version of ujail and utrace
Signed-off-by: John Crispin <blogic@openwrt.org>
2015-03-23 08:09:26 +01:00