project/procd.git
5 years agostate: fix shutdown when running in a container (FS#2425)
Paul Spooren [Mon, 5 Aug 2019 16:07:45 +0000 (18:07 +0200)]
state: fix shutdown when running in a container (FS#2425)

Applies patch from @mikma [0] to fix Docker shutdown. Added detection to
state.c if running in a container or not.

Tested with a x86/64 Docker image.

Fixes FS#2425

CC: Mikael Magnusson <mikma@users.sourceforge.net>
CC: Petr Štetiar <ynezz@true.cz>
[0]: https://github.com/mikma/lxd-openwrt/blob/master/patches/procd-master/0003-docker-fix-problem-stopping-container.patch

Signed-off-by: Paul Spooren <mail@aparcar.org>
Signed-off-by: Hans Dedecker <dedeckeh@gmail.com> [coding style aligment]
5 years agoprocd: check strchr() result before using it
Justinas Grauslis [Mon, 8 Jul 2019 08:01:09 +0000 (11:01 +0300)]
procd: check strchr() result before using it

Subtracting some address from NULL does not necessary
results in negative value. It's lower level dependent.

In our case (IPQ4019 + Yocto + meta-openwrt) subtracting
token address from NULL strchr() return value results in
large positive number which causes out-of-boundary memory
access and eventually a segfault.

Signed-off-by: Justinas Grauslis <justinas@8devices.com>
5 years agocontainer: fix .dockerenv stat check
Petr Štetiar [Thu, 30 May 2019 05:53:26 +0000 (07:53 +0200)]
container: fix .dockerenv stat check

applied check wasn't evaluating the existence of the file properly.

Fixes: 7f0f6b2a73f8 ("procd: add docker support")
Signed-off-by: Petr Štetiar <ynezz@true.cz>
5 years agohotplug: improve error message during group ownership change
Petr Štetiar [Fri, 24 May 2019 11:04:41 +0000 (13:04 +0200)]
hotplug: improve error message during group ownership change

procd currently outputs following error messages:

 procd: cannot set group dialout for /dev/ttyw8
 procd: cannot set group dialout for /dev/ttyq1
 procd: cannot set group dialout for /dev/ttywf

from which it's not clear where the problem is, if it's either getgrnam
or chown failing and why it's failing so this patch adds name of failed
function and its errno.

Ref: https://github.com/openwrt/openwrt/pull/1773#issuecomment-495555284
Signed-off-by: Petr Štetiar <ynezz@true.cz>
5 years agoprocd: add docker support
Paul Spooren [Mon, 27 May 2019 09:33:29 +0000 (11:33 +0200)]
procd: add docker support

detects if running in a docker container, which then requires special
treatment of mounts. OpenWrt within Docker is useful for CI testing.

Signed-off-by: Paul Spooren <mail@aparcar.org>
5 years agocontainer: include stdbool.h
Hans Dedecker [Thu, 9 May 2019 16:01:46 +0000 (18:01 +0200)]
container: include stdbool.h

Fixes following compile issue :

container.h:18:15: error: unknown type name 'bool'
 static inline bool is_container() {
               ^~~~
make[5]: *** [CMakeFiles/init.dir/build.make:154: CMakeFiles/init.dir/initd/zram.c.o] Error 1

Signed-off-by: Hans Dedecker <dedeckeh@gmail.com>
5 years agoprocd: detect lxc container and behave accordingly
Paul Spooren [Sun, 5 May 2019 16:31:41 +0000 (18:31 +0200)]
procd: detect lxc container and behave accordingly

meaning to not mount some specific parts witch cause trouble.

The patch is based on previous work of @mikma to combine OpenWrt with
lxd[0]. This patch however adds a detection copied from *virt-what* to
check /proc/1/environment for the string "container".

Thanks to @dangowrt for the cleanup.

[0]: https://github.com/containercraft/openwrt-lxd/blob/master/patches/procd-openwrt-18.06/001_lxd_no_mounts.patch

Signed-off-by: Paul Spooren <mail@aparcar.org>
5 years agoinstance: dump user and group as well
Hans Dedecker [Tue, 30 Apr 2019 19:49:26 +0000 (21:49 +0200)]
instance: dump user and group as well

Signed-off-by: Hans Dedecker <dedeckeh@gmail.com>
5 years agoservice: allow setting a dedicated group id
Michael Heimpold [Thu, 11 Apr 2019 19:01:07 +0000 (21:01 +0200)]
service: allow setting a dedicated group id

Sometimes is desirable to run a process with a specific group id
instead of the default one which is derived from passwd entry.

However, we still want to initialize supplementary group ids
(including the default one), thus we have to store the specific
one in a dedicated structure element.

Signed-off-by: Michael Heimpold <mhei@heimpold.de>
5 years agoinstance: add support for customizable syslog facilities
Michael Heimpold [Thu, 11 Apr 2019 19:01:06 +0000 (21:01 +0200)]
instance: add support for customizable syslog facilities

Signed-off-by: Michael Heimpold <mhei@heimpold.de>
5 years agoprocd: add SIGPWR as signal
Paul Spooren [Fri, 26 Apr 2019 15:32:45 +0000 (17:32 +0200)]
procd: add SIGPWR as signal

to use procd in LXC containers they have to support SIGPWR to shutdown.

Signed-off-by: Paul Spooren <mail@aparcar.org>
5 years agoprocd: copy the respawn property of new instance
Yashavanth Chowrikoppalu [Wed, 17 Apr 2019 13:21:18 +0000 (15:21 +0200)]
procd: copy the respawn property of new instance

On updating an existing instance, the respawn property is reset
in instance_stop(). Subsequent instance_update() call does not copy
the respawn property from new instance in instance_config_move(). As
a result, the respawning does not happen, if the process is killed
externally.

Signed-off-by: Yashavanth Chowrikoppalu <Yashavanth.hsn@gmail.com>
5 years agoprocd: instance: Support deleting stopped instances
Kristian Evensen [Sat, 6 Apr 2019 12:28:30 +0000 (14:28 +0200)]
procd: instance: Support deleting stopped instances

procd currently does not support deleting a stopped instance. The reason
is that we return in instance_stop(), if pending is set to false. This
patch adds a new function, instance_delete(), which does the necessary
clean-up of an instance. instance_delete() is called before we return in
instance_stop(), as well as when a process that should not be restarted
has exited in instance_exit().

Signed-off-by: Kristian Evensen <kristian.evensen@gmail.com>
5 years agoprocd: trace: Define syscall registers for powerpc platform
Wojciech Dubowik [Fri, 8 Mar 2019 08:36:12 +0000 (09:36 +0100)]
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>
5 years agohotplug.c: Make sure hotplug buffer is NULL terminated
Hauke Mehrtens [Wed, 19 Dec 2018 09:51:57 +0000 (10:51 +0100)]
hotplug.c: Make sure hotplug buffer is NULL terminated

Sets the final byte explicitly to NULL because we later do string
operations on this buffer.

Fixes Coverity issue 1430926 String not null terminated

Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
5 years agoearly: set /tmp permissions explicitly
Hans Dedecker [Fri, 23 Nov 2018 11:02:45 +0000 (12:02 +0100)]
early: set /tmp permissions explicitly

In case ramfs is used as tmpfs it creates /tmp with permissions 755
which are the the default permissions.
Therefore when mounting tmp set permissions explicitly to 1777

Signed-off-by: Hans Dedecker <dedeckeh@gmail.com>
Acked-by: John Crispin <john@phrozen.org>
5 years agowatchdog: improve seting watchdog timeout and frequency
Hans Dedecker [Sun, 4 Nov 2018 10:14:31 +0000 (11:14 +0100)]
watchdog: improve seting watchdog timeout and frequency

Due to the watchdog file descriptor check in both watchdog_timeout and
watchdog_frequency it's impossible to set the timeout/frequency via ubus
in case the watchdog was stopped.
Fix this by removing the watchdog file descriptor check in both functions
and by caching locally the set watchdog driver timeout value. The latter
will be used to set the watchdog driver timeout value in case the
watchdog is active or when the watchdog is started.
In addition when parsing the watchdog ubus call check if timeout
attribute is set so the correct value is used when doing the frequency
sanity check.

Signed-off-by: Hans Dedecker <dedeckeh@gmail.com>
6 years agoprocd: Add cpu string to board detection
Chris Blake [Fri, 14 Sep 2018 01:37:45 +0000 (20:37 -0500)]
procd: Add cpu string to board detection

This patch is in relation to
https://github.com/openwrt/openwrt/pull/1307 to help fix architecture
detection in LuCI which was added in
https://github.com/openwrt/luci/commit/b8f32b6da7accc672c5887e894a861de3f806cf5

Signed-off-by: Chris Blake <chrisrblake93@gmail.com>
6 years agoAllow disabling seccomp or changing the whitelist
Michal Sojka [Mon, 30 Jul 2018 07:32:19 +0000 (09:32 +0200)]
Allow disabling seccomp or changing the whitelist

Without this change, once a service is started with seccomp, it is
impossible to restart it without seccomp or change the whitelist file
name. This commit fixes that. Disabling seccomp is as easy as
commenting out the "procd_set_param seccomp" line in init.d script.

Signed-off-by: Michal Sojka <michal.sojka@cvut.cz>
6 years agotrace: Use properly sized type for PTRACE_GETEVENTMSG
Michal Sojka [Mon, 30 Jul 2018 07:31:09 +0000 (09:31 +0200)]
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>
6 years agoprocd: fix ustream deadlock when there are 0 bytes or no newlines
John Crispin [Tue, 13 Feb 2018 15:33:48 +0000 (16:33 +0100)]
procd: fix ustream deadlock when there are 0 bytes or no newlines

Signed-off-by: John Crispin <john@phrozen.org>
6 years agoprocd: increase watchdog fd_buf storage size to fix gcc8 build error
Felix Fietkau [Thu, 5 Jul 2018 09:13:31 +0000 (11:13 +0200)]
procd: increase watchdog fd_buf storage size to fix gcc8 build error

Signed-off-by: Felix Fietkau <nbd@nbd.name>
6 years agoservice: initialize supplementary group ids
Yousong Zhou [Sun, 11 Feb 2018 09:19:11 +0000 (17:19 +0800)]
service: initialize supplementary group ids

We currently only call setgid() with user's primary group id for service
instance processes.  In the case of a user belong to multiple groups,
it's natural to also explicitly initialize their supplementary group ids

Fixes FS#988

Signed-off-by: Yousong Zhou <yszhou4tech@gmail.com>
6 years agoservice: add func for string config change check
Yousong Zhou [Sun, 11 Feb 2018 09:17:08 +0000 (17:17 +0800)]
service: add func for string config change check

To also prepare for following commits introducing more string value
change detection

Signed-off-by: Yousong Zhou <yszhou4tech@gmail.com>
6 years agoprocd: get rid of putenv usage.
Rosen Penev [Tue, 23 Jan 2018 20:30:52 +0000 (12:30 -0800)]
procd: get rid of putenv usage.

setenv is prefered according to POSIX. Also allows staticly allocated strings.

Saves 200 bytes when stripped. 432 without.

Signed-off-by: Rosen Penev <rosenp@gmail.com>
6 years agotrace: check asprintf() return value
Hans Dedecker [Mon, 22 Jan 2018 17:51:23 +0000 (18:51 +0100)]
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>
6 years agotrace: add missing limits.h include
Hans Dedecker [Mon, 22 Jan 2018 17:51:22 +0000 (18:51 +0100)]
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>
6 years agoprocd: add timing to start/stop logging
Karl Vogel [Wed, 17 Jan 2018 11:13:15 +0000 (12:13 +0100)]
procd: add timing to start/stop logging

Shows how long an initd task took, for example:

 procd: stop /etc/init.d/dropbear running - took 0.088824s
 procd: Update service dnsmasq
 procd: Update instance dnsmasq::dnsmasq
 procd: running /etc/init.d/dnsmasq running
 procd: start /etc/init.d/dnsmasq running
 procd: stop /etc/init.d/dnsmasq running - took 0.092586s

 v2: rename variables, correct time unit
 v3: use CLOCK_MONOTONIC_RAW to prevent issues with NTP and adjtime

Signed-off-by: Karl Vogel <karl.vogel@gmail.com>
6 years agoprocd: Add %m to several functions that return errno.
Rosen Penev [Mon, 25 Dec 2017 22:14:46 +0000 (14:14 -0800)]
procd: Add %m to several functions that return errno.

Might help with debugging. No size impact.

Signed-off-by: Rosen Penev <rosenp@gmail.com>
6 years agoprocd: Remove redundant errno variable in several printf functions.
Rosen Penev [Mon, 25 Dec 2017 22:14:45 +0000 (14:14 -0800)]
procd: Remove redundant errno variable in several printf functions.

%m, aka strerror(errno) is already used. No need to repeat it. Saves 280 bytes.

Signed-off-by: Rosen Penev <rosenp@gmail.com>
6 years agoprocd: Replace strerror(errno) with %m.
Rosen Penev [Mon, 25 Dec 2017 22:14:44 +0000 (14:14 -0800)]
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>
6 years agoprocd: Fix minor null pointer dereference.
Rosen Penev [Mon, 25 Dec 2017 22:52:20 +0000 (14:52 -0800)]
procd: Fix minor null pointer dereference.

Null pointer check was placed after assigning values to c.

Signed-off-by: Rosen Penev <rosenp@gmail.com>
6 years agoprocd: initd: fix path allocation in early_insmod
Nathan Hintz [Fri, 29 Dec 2017 04:48:26 +0000 (04:48 +0000)]
procd: initd: fix path allocation in early_insmod

Noticed that /tmp was not being created on /dev/zram0.  This was on
ixp4xx (nslu2) using GCC 6.3 and musl.

The allocation should be using the length of the passed string
(module path), not the size of the pointer to the string.

Signed-off-by: Nathan Hintz <nlhintz@hotmail.com>
6 years agoprocd: Remove unnecessary memset calls.
Rosen Penev [Tue, 7 Nov 2017 20:05:12 +0000 (12:05 -0800)]
procd: Remove unnecessary memset calls.

Changes allocation to calloc and {} as needed.

Signed-off-by: Rosen Penev <rosenp@gmail.com>
6 years agoservice: add data within the service itself
Pierre Lebleu [Fri, 10 Nov 2017 10:04:47 +0000 (11:04 +0100)]
service: add data within the service itself

It gives the ability to create firewall data within the
service itself.

Signed-off-by: Pierre Lebleu <pme.lebleu@gmail.com>
6 years agoservice: fix calls to blobmsg_parse()
Pierre Lebleu [Fri, 10 Nov 2017 09:59:35 +0000 (10:59 +0100)]
service: fix calls to blobmsg_parse()

We should use blobmsg_data() rather than blob_data() and
blobmsg_data_len() rather than blob_len().

Signed-off-by: Pierre Lebleu <pme.lebleu@gmail.com>
7 years agoprocd: lower the logging threshold
John Crispin [Mon, 6 Nov 2017 07:39:09 +0000 (08:39 +0100)]
procd: lower the logging threshold

Signed-off-by: John Crispin <john@phrozen.org>
7 years agoservice: Start services normally when seccomp is disabled
Michal Sojka [Fri, 3 Nov 2017 21:31:41 +0000 (22:31 +0100)]
service: Start services normally when seccomp is disabled

When service init file declares seccomp support (procd_set_param seccomp),
but procd is compiled without seccomp support, the service should be
started normally, because seccomp-trace and utrace are not available.

Older procd versions decided about whether to start a service in
seccomp sandbox or not based on existence of seccomp whitelist in the
filesystem. This was recently removed (c8faedc "Do not disable seccomp
when configuration is not found", 2017-09-12) because it could be easy
for attackers to disable seccomp support. This changes is a follow-up
to the mentioned commit. With it, procd decides about whether to use
seccomp sandbox based only on compile-time configuration.

Signed-off-by: Michal Sojka <sojkam1@fel.cvut.cz>
Tested-by: Hans Dedecker <dedeckeh@gmail.com>
7 years agoprocd: add missing new lines inside debug code
John Crispin [Thu, 26 Oct 2017 07:39:52 +0000 (09:39 +0200)]
procd: add missing new lines inside debug code

Signed-off-by: John Crispin <john@phrozen.org>
7 years agoservice: fix service_handle_event array
Pierre Lebleu [Wed, 25 Oct 2017 15:43:16 +0000 (17:43 +0200)]
service: fix service_handle_event array

The array concerning the "config.change" is __VALIDATE_MAX length,
not __DATA_MAX length.

Signed-off-by: Pierre Lebleu <pme.lebleu@gmail.com>
7 years agoservice: fix SERVICE_ATTR_NAME usage in service_handle_set
pme.lebleu@gmail.com [Wed, 4 Oct 2017 11:14:16 +0000 (13:14 +0200)]
service: fix SERVICE_ATTR_NAME usage in service_handle_set

The SERVICE_SET_NAME belongs to enum SERVICE_SET_XXXX, not SERVICE_ATTR_NAME.

Signed-off-by: Pierre Lebleu <pme.lebleu@gmail.com>
7 years agoinstance: properly compare and reload respawn config
Karl Palsson [Mon, 25 Sep 2017 12:28:16 +0000 (12:28 +0000)]
instance: properly compare and reload respawn config

respawn configuration variables were not checked for changes, and were
not copied to new instances.

Signed-off-by: Karl Palsson <karlp@etactica.com>
7 years agoutrace: Start the tracee only after uloop initialization
Michal Sojka [Wed, 27 Sep 2017 08:59:54 +0000 (10:59 +0200)]
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>
7 years agoutrace: Switch all logging to ulog
Michal Sojka [Tue, 12 Sep 2017 11:12:49 +0000 (13:12 +0200)]
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>
7 years agoutrace: Support non-contiguous syscall numbers
Michal Sojka [Sun, 24 Sep 2017 14:38:21 +0000 (16:38 +0200)]
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>
7 years agoutrace: Forward SIGTERM to the traced process
Michal Sojka [Tue, 12 Sep 2017 11:12:47 +0000 (13:12 +0200)]
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>
7 years agoutrace: Report ptrace errors
Michal Sojka [Tue, 12 Sep 2017 11:12:46 +0000 (13:12 +0200)]
utrace: Report ptrace errors

7 years agoseccomp: Improve error message
Michal Sojka [Tue, 12 Sep 2017 11:12:45 +0000 (13:12 +0200)]
seccomp: Improve error message

Print "SECCOMP_FILE not specified" instead of "failed to load (null)".

Signed-off-by: Michal Sojka <sojkam1@fel.cvut.cz>
7 years agopreload-seccomp: Use proper log level for error messages
Michal Sojka [Tue, 12 Sep 2017 11:12:44 +0000 (13:12 +0200)]
preload-seccomp: Use proper log level for error messages

Signed-off-by: Michal Sojka <sojkam1@fel.cvut.cz>
7 years agoStart seccomp-enabled services via seccomp-trace
Michal Sojka [Tue, 12 Sep 2017 11:12:43 +0000 (13:12 +0200)]
Start seccomp-enabled services via seccomp-trace

Signed-off-by: Michal Sojka <sojkam1@fel.cvut.cz>
7 years agoseccomp: Log seccomp violations with utrace
Michal Sojka [Sun, 24 Sep 2017 22:56:33 +0000 (00:56 +0200)]
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>
7 years agoutrace: Use PTHREAD_SEIZE instead of PTHREAD_TRACEME
Michal Sojka [Tue, 12 Sep 2017 11:12:41 +0000 (13:12 +0200)]
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>
7 years agoutrace: Deliver signals to traced processes
Michal Sojka [Tue, 12 Sep 2017 11:12:40 +0000 (13:12 +0200)]
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>
7 years agoutrace: Support tracing multi-threaded processes and vfork
Michal Sojka [Tue, 12 Sep 2017 11:12:39 +0000 (13:12 +0200)]
utrace: Support tracing multi-threaded processes and vfork

Signed-off-by: Michal Sojka <sojkam1@fel.cvut.cz>
7 years agoutrace: Trace processes across forks
Michal Sojka [Tue, 12 Sep 2017 11:12:38 +0000 (13:12 +0200)]
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>
7 years agoutrace: Sort syscalls by number of invocations
Michal Sojka [Tue, 12 Sep 2017 11:12:37 +0000 (13:12 +0200)]
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>
7 years agoUpdate trace attribute
Michal Sojka [Tue, 12 Sep 2017 11:12:36 +0000 (13:12 +0200)]
Update trace attribute

When a service is started for the first time without trace
attribute (e.g. during boot), then it was impossible to restart it in
tracing mode (/etc/init.d/service trace). This is fixed here.

Signed-off-by: Michal Sojka <sojkam1@fel.cvut.cz>
7 years agoDo not disable seccomp when configuration is not found
Michal Sojka [Tue, 12 Sep 2017 11:12:35 +0000 (13:12 +0200)]
Do not disable seccomp when configuration is not found

Previously, when seccomp configuration file for a service was not
found, the service was started without seccomp. I consider this
potential attack vector.

With this change, procd starts the service as if the configuration
existed but the service fails in libpreload-seccomp.so, because the
configuration cannot be loaded. This is announced in the syslog.

Signed-off-by: Michal Sojka <sojkam1@fel.cvut.cz>
7 years agoutrace: Fix off-by-one errors
Michal Sojka [Tue, 12 Sep 2017 11:12:34 +0000 (13:12 +0200)]
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>
7 years agoutrace: Fix environment initialization
Michal Sojka [Tue, 12 Sep 2017 11:12:33 +0000 (13:12 +0200)]
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>
7 years agoprocd: send ubus notify when a config file has changed
John Crispin [Tue, 22 Aug 2017 14:43:54 +0000 (16:43 +0200)]
procd: send ubus notify when a config file has changed

Signed-off-by: John Crispin <john@phrozen.org>
7 years agowatchdog: fix inline watchdog_get_magicclose function prototype
Hans Dedecker [Tue, 8 Aug 2017 07:49:26 +0000 (09:49 +0200)]
watchdog: fix inline watchdog_get_magicclose function prototype

Fix procd compilation issue which occurs when DISABLE_INIT is set as the
inline watchdog_get_magicclose function prototype was wrong.

Signed-off-by: Hans Dedecker <dedeckeh@gmail.com>
7 years agoprocd: Do not leak pipe file descriptors to children
Michal Sojka [Thu, 6 Jul 2017 20:25:16 +0000 (22:25 +0200)]
procd: Do not leak pipe file descriptors to children

Without this change, a process started by procd can have access to
stdout/err of processes started by procd before.

Signed-off-by: Michal Sojka <sojkam1@fel.cvut.cz>
7 years agosystem: return ubus error when sysupgrade_exec_upgraded() has failed
Matthias Schiffer [Thu, 20 Jul 2017 19:35:14 +0000 (21:35 +0200)]
system: return ubus error when sysupgrade_exec_upgraded() has failed

When sysupgrade_exec_upgraded() is successful, it will replace procd with
upgraded, so it won't ever return (making the ubus call hang forever, which
is fine as stage2 will kill all processes anyways).

Signed-off-by: Matthias Schiffer <mschiffer@universe-factory.net>
7 years agoupgraded: Check chroot() return value
Florian Fainelli [Sat, 15 Jul 2017 17:59:51 +0000 (10:59 -0700)]
upgraded: Check chroot() return value

Check the chroot() return value, fixes unused return value warnings/errors:

procd-2017-06-22-e5e99c46/upgraded/upgraded.c:78:8: error: ignoring return
value of 'chroot', declared with attribute warn_unused_result
[-Werror=unused-result] chroot(".");

Fixes: 056d8ddda8d5 ("upgraded: link dynamically, chroot during exec")
Reviewed-by: Matthias Schiffer <mschiffer@universe-factory.net>
Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
7 years agoinit: Check chroot return value in sysupgrade_exec_upgraded()
Florian Fainelli [Sat, 15 Jul 2017 17:51:20 +0000 (10:51 -0700)]
init: Check chroot return value in sysupgrade_exec_upgraded()

chroot() can fail and its return value should be checked against, in that case
do an exit() since this is a fatal condition that we cannot recover from.

Fixes: 63789e51ed91 ("init: add support for sysupgrades triggered from preinit")
Reviewed-by: Matthias Schiffer <mschiffer@universe-factory.net>
Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
7 years agoupgraded: improve error handling
Matthias Schiffer [Thu, 13 Jul 2017 11:18:00 +0000 (13:18 +0200)]
upgraded: improve error handling

* exit with code 1 instead of unusual -1 in the parent process
* exit using _exit() when child exec fails
* fix fork/exec error messages
* only uloop_run() after successful child fork (uloop_end() before
  uloop_run() doesn't have any effect, so uloop_run() would hang forever)
* minor code cleanup

Signed-off-by: Matthias Schiffer <mschiffer@universe-factory.net>
7 years agoupgraded: register stage2 process in uloop as intended
Matthias Schiffer [Wed, 12 Jul 2017 22:04:49 +0000 (00:04 +0200)]
upgraded: register stage2 process in uloop as intended

Make the process callback effective, so an exit of state2 will trigger a
reboot.

Signed-off-by: Matthias Schiffer <mschiffer@universe-factory.net>
7 years agowatchdog: add support for starting/stopping kernel watchdog
Hans Dedecker [Mon, 19 Jun 2017 09:14:27 +0000 (11:14 +0200)]
watchdog: add support for starting/stopping kernel watchdog

Extend the ubus watchdog cmd with the parameter magicclose; when set and
in case the stopped parameter is enabled the kernel watchdog will be stopped
by first sending the magic character 'V' followed by a close of the watchdog
fd. In case stopped is set to disabled the watchdog fd will be created again.

Signed-off-by: Hans Dedecker <dedeckeh@gmail.com>
Acked-by: John Crispin <john@phrozen.org>
7 years agosystem: introduce new attribute board_name
Daniel Golle [Sun, 18 Jun 2017 22:53:00 +0000 (00:53 +0200)]
system: introduce new attribute board_name

Instead of modifying the already defined 'model' attribute rather
introduce a new attribute board_name to return either
/tmp/sysinfo/board_name or /proc/device-tree/compatible.

Signed-off-by: Daniel Golle <daniel@makrotopia.org>
7 years agopreinit: define _GNU_SOURCE
Hans Dedecker [Fri, 16 Jun 2017 14:09:01 +0000 (16:09 +0200)]
preinit: define _GNU_SOURCE

In uClibc getdelim is only defined if _GNU_SOURCE is defined; fix
compilation issue by defining _GNU_SOURCE

Signed-off-by: Hans Dedecker <dedeckeh@gmail.com>
7 years agoupgraded: cmake: Find and include uloop.h
Florian Fainelli [Wed, 31 May 2017 21:00:34 +0000 (14:00 -0700)]
upgraded: cmake: Find and include uloop.h

Add a CMake FIND_PATH and INCLUDE_DIRECTORIES searching for
libubox/uloop.h. Some external toolchains which do not include standard
locations would fail to find the header otherwise.

Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
7 years agohotplug: fix a memory leak in handle_button_complete()
Alexander Couzens [Sun, 11 Jun 2017 09:52:47 +0000 (11:52 +0200)]
hotplug: fix a memory leak in handle_button_complete()

Found-by: Coverity Scan #1412460
Signed-off-by: Alexander Couzens <lynxis@fe80.eu>
7 years agoservice/service_stopped(): fix a use-after-free
Alexander Couzens [Sun, 11 Jun 2017 09:49:00 +0000 (11:49 +0200)]
service/service_stopped(): fix a use-after-free

Found-by: Coverity Scan #1412548
Signed-off-by: Alexander Couzens <lynxis@fe80.eu>
7 years agosystem: return legacy board name
Daniel Golle [Thu, 8 Jun 2017 20:21:27 +0000 (22:21 +0200)]
system: return legacy board name

The system board call returns the verbose model string instead of the
board name. Unfortunately we have not yet estabkushed clear convention
regarding device-tree 'compatible' or 'model' property and sysupgrade
image name (same accounts for scraping /proc/cpuinfo on legacy
targets). This is odd as the idea was to return information needed to
identify the right sysupgrade image. On most targets we got a large
shell-script which translates either /proc/cpuinfo or the 'model'
property back into the board name used here. Hence
/tmp/sysinfo/board_name should be returned instead of
/tmp/sysinfo/model for the board ubus call as well.

Signed-off-by: Daniel Golle <daniel@makrotopia.org>
7 years agoupgraded: define __GNU_SOURCE
Matthias Schiffer [Tue, 30 May 2017 05:23:57 +0000 (07:23 +0200)]
upgraded: define __GNU_SOURCE

It is required on non-musl libcs for O_DIRECTORY.

Signed-off-by: Matthias Schiffer <mschiffer@universe-factory.net>
7 years agorcS: add missing fcntl.h include
Matthias Schiffer [Mon, 29 May 2017 21:39:53 +0000 (23:39 +0200)]
rcS: add missing fcntl.h include

Fixes: d42b21ed9305 "procd/rcS: Use /dev/null as stdin"
Signed-off-by: Matthias Schiffer <mschiffer@universe-factory.net>
7 years agoinit: add support for sysupgrades triggered from preinit
Matthias Schiffer [Sun, 23 Apr 2017 22:40:27 +0000 (00:40 +0200)]
init: add support for sysupgrades triggered from preinit

This will allow to add support for sysupgrades via upgraded from failsafe
mode.

Signed-off-by: Matthias Schiffer <mschiffer@universe-factory.net>
7 years agoRemove code that has become unnecessary after sysupgrade changes
Matthias Schiffer [Sun, 23 Apr 2017 17:06:12 +0000 (19:06 +0200)]
Remove code that has become unnecessary after sysupgrade changes

Signed-off-by: Matthias Schiffer <mschiffer@universe-factory.net>
7 years agoupgraded: add support for passing a "command" argument to stage2
Matthias Schiffer [Sun, 23 Apr 2017 17:04:25 +0000 (19:04 +0200)]
upgraded: add support for passing a "command" argument to stage2

This allows us to make use of upgraded in "snapshot convert" as well.

Signed-off-by: Matthias Schiffer <mschiffer@universe-factory.net>
7 years agoupgraded: link dynamically, chroot during exec
Matthias Schiffer [Sun, 23 Apr 2017 00:28:13 +0000 (02:28 +0200)]
upgraded: link dynamically, chroot during exec

The chroot ensures we don't reference anything on the rootfs and is
reverted after the upgraded exec. While we're at it, also improve error
handling a bit.

This change also required changes to sysupgrade, as the dynamically linked
version is expected at a different location, and libraries need to be made
available.

Signed-off-by: Matthias Schiffer <mschiffer@universe-factory.net>
7 years agosystem: always support staged sysupgrade
Matthias Schiffer [Fri, 21 Apr 2017 18:06:59 +0000 (20:06 +0200)]
system: always support staged sysupgrade

In preparation for switching all targets to the staged sysupgrade
mechanism, upgraded is always built, and the "nandupgrade" ubus method is
renamed to "sysupgrade".

To make the migration easier, support for the old name "nandupgrade" and
the "upgrade" method that will become unused with the staged sysupgrade is
retained for now.

Signed-off-by: Matthias Schiffer <mschiffer@universe-factory.net>
7 years agoprocd/rcS: Use /dev/null as stdin
Michal Sojka [Sun, 30 Apr 2017 07:51:20 +0000 (09:51 +0200)]
procd/rcS: Use /dev/null as stdin

This change ensures that /etc/init.d/* scripts are started with
/dev/null as stdin. This is useful in cases where an init.d script
reads (e.g. by mistake) from stdin, which a user can perceive as if
some characters typed into shell on serial console are "eaten" by
something else (i.e. by the init.d script running on background). This
is very annoying, because each character needs to be pressed several
times before it appears on the screen.

Signed-off-by: Michal Sojka <sojkam1@fel.cvut.cz>
7 years agoservice/instance: add an auto start option
John Crispin [Wed, 5 Apr 2017 06:58:22 +0000 (08:58 +0200)]
service/instance: add an auto start option

this allows us to register services with procd but not auto start them. An
additional ubus call is required to start the service.

Signed-off-by: John Crispin <john@phrozen.org>
7 years agoprocd: Log initscript output prefixed with script name
Michal Sojka [Sat, 11 Mar 2017 00:48:16 +0000 (01:48 +0100)]
procd: Log initscript output prefixed with script name

It helps with debugging of initscript problems.

Signed-off-by: Michal Sojka <sojkam1@fel.cvut.cz>
7 years agoprocd: Don't use syslog before its initialization
Michal Sojka [Sun, 12 Mar 2017 01:11:39 +0000 (02:11 +0100)]
procd: Don't use syslog before its initialization

When procd starts a rcS script, it captures its stdout and stderr and
logs them via syslog(). The problem with that is that the rest of
procd code uses ulog rather than syslog() directly and ulog_open()
doesn't call openlog() immediately, but only after something is logged
with ulog(). This lazy calling of openlog() can result in the
following unwanted behavior:

1) When rcS's stdout/err is logged via syslog(), the log identifier is
   not set yet (due to openlog() not called) and so the log message
   lacks information about source.

2) procd can also log stdout/err from services. When a message from a
   service needs to be logged, ulog_open() is called to change the log
   identifier to match the service name/PID. After logging the service
   messages, ulog_open() is called again the change the identifier
   back to "procd". The lazy call to openlog() means that the messages
   logged directly with syslog() will be logged with the
   identification of the previously logged service and not of the rcS
   script that produced the message.

Both problems are fixed by replacing direct call to syslog() with
ULOG_NOTE, which automatically calls openlog() if needed.

Signed-off-by: Michal Sojka <sojkam1@fel.cvut.cz>
7 years agoprocd: Add missing \n in debug message
Michal Sojka [Sat, 11 Mar 2017 00:48:14 +0000 (01:48 +0100)]
procd: Add missing \n in debug message

Signed-off-by: Michal Sojka <sojkam1@fel.cvut.cz>
7 years agoprocd: service gets deleted when its last instance is freed
Alin Năstac [Mon, 27 Feb 2017 09:08:34 +0000 (10:08 +0100)]
procd: service gets deleted when its last instance is freed

This fixes the following regression introduced in commit
961dc692aff7457f874bce61f8e766514edcf794:
 1) reboot using the following configuration
root@OpenWrt:~# uci show system.ntp
system.ntp=timeserver
system.ntp.enable_server='0'
system.ntp.use_dhcp='1'
system.ntp.dhcp_interface='wan'
root@OpenWrt:~# uci show network.wan
network.wan=interface
network.wan.proto='dhcp'
network.wan.ifname='eth4'
network.wan.reqopts='1 3 6 15 33 42 51 121 249'
 2) if obtained DHCP lease has an option 42 sysntpd service will have an
 instance
 3) run "ifup wan"
 4) although the same DHCP lease was obtained, sysntpd would be stopped

Because sysntpd service is deleted when last instance is freed, its triggers
will also be released. Without these triggers in place, sysntpd will not be
reloaded when a new DHCP lease containing option 42 will be received.

Signed-off-by: Alin Nastac <alin.nastac@gmail.com>
7 years agoprocd: update modprobe path
Nathan Hintz [Mon, 20 Feb 2017 20:39:11 +0000 (20:39 +0000)]
procd: update modprobe path

Commit 81aeba9b7f619ee1af1a64f355ae8001fa147d03 in LEDE source.git moved
modprobe to the "/sbin" directory.  Update procd with the new path.

Signed-off-by: Nathan Hintz <nlhintz@hotmail.com>
7 years agoprocd: add cancel_timeout on rc scripts when a runtime_timeout is specified
Jurgen Van Ham [Fri, 10 Feb 2017 06:55:23 +0000 (07:55 +0100)]
procd: add cancel_timeout on rc scripts when a runtime_timeout is specified

Enable procd to restrict the execution time of a rc scripts during shutdown, even
when a script ignores the SIGTERM signal by insisting after 10s with a SIGKILL.

Signed-off-by: Jurgen Van Ham <juvanham.tc@gmail.com>
7 years agoprocd: stop service using SIGKILL if SIGTERM failed to do so
Alin Năstac [Thu, 9 Feb 2017 10:02:53 +0000 (11:02 +0100)]
procd: stop service using SIGKILL if SIGTERM failed to do so

SIGKILL is sent if instance process is still running after
<term_timeout> seconds after SIGTERM has been sent. To prevent
another daemon process being launched before old process dies,
the instance is kept until SIGCHLD confirms that service has
been stopped.

Signed-off-by: Alin Nastac <alin.nastac@gmail.com>
7 years agoadd missing includes
Felix Fietkau [Sat, 11 Feb 2017 14:43:36 +0000 (15:43 +0100)]
add missing includes

Including sys/sysmacros.h is now necessary for makedev() on glibc 2.25.

Signed-off-by: Felix Fietkau <nbd@nbd.name>
7 years agoujail: fix signal forwarding
John Crispin [Wed, 8 Feb 2017 11:02:10 +0000 (12:02 +0100)]
ujail: fix signal forwarding

Signed-off-by: John Crispin <john@phrozen.org>
7 years agoinit: fix /tmp permissions on zram
Matthias Schiffer [Thu, 26 Jan 2017 11:56:24 +0000 (12:56 +0100)]
init: fix /tmp permissions on zram

mkfs.ext4 will create the filesystem with 755, we need to chmod to 1777
explicitly.

Signed-off-by: Matthias Schiffer <mschiffer@universe-factory.net>
7 years agoujail: add basic /dev files
Etienne CHAMPETIER [Fri, 30 Dec 2016 02:08:58 +0000 (18:08 -0800)]
ujail: add basic /dev files

This adds
/dev/full
/dev/null
/dev/urandom
/dev/zero
in every jail (not having them only allow subtle bugs)

Signed-off-by: Etienne CHAMPETIER <champetier.etienne@gmail.com>
7 years agoservice: add reload_signal property
Jo-Philipp Wich [Tue, 13 Dec 2016 16:27:13 +0000 (17:27 +0100)]
service: add reload_signal property

Introduce a new optional property "reload_signal" which - if set - instructs
procd to not terminate and restart supervised processes upon changes, but to
send them a kill() signal instead.

This is useful for services which fully support native config reload upon
receipt of a signal.

Signed-off-by: Jo-Philipp Wich <jo@mein.io>
7 years agohotplug: fix uninitialized variable
Jo-Philipp Wich [Tue, 13 Dec 2016 15:26:03 +0000 (16:26 +0100)]
hotplug: fix uninitialized variable

Commit e999ab7 (hotplug: Check chown return value) introduced a new variable
"ret" which is not explicitely initialized, leading to the following compile
error:

    hotplug.c:155:18: error: 'ret' may be used uninitialized in this function [-Werror=maybe-uninitialized]
        if (!g || ret < 0)
                      ^
    cc1: all warnings being treated as errors

Explicitely initialize it to zero to avoid that problem.

Signed-off-by: Jo-Philipp Wich <jo@mein.io>
7 years agoservice: add service.signal ubus call
Jo-Philipp Wich [Tue, 13 Dec 2016 15:21:29 +0000 (16:21 +0100)]
service: add service.signal ubus call

Add a service.signal call to allow sending kill() signals to a service.

The default signal sent to services is SIGHUP and may be overridden by a
numerical signal value using the signal parameter.

The optional instance argument allows restricting the signal delivery to one
specific instance. If omitted, the signal is sent to all instances.

Acked-by: John Crispin <john@phrozen.org>
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
7 years agotrace: use the cloned environment pointer
Felix Fietkau [Mon, 5 Dec 2016 17:16:47 +0000 (18:16 +0100)]
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>
7 years agoprocd: Fix memory leaks found by cppcheck
Rosen Penev [Sun, 4 Dec 2016 04:39:42 +0000 (20:39 -0800)]
procd: Fix memory leaks found by cppcheck

Signed-off by: Rosen Penev <rosenp@gmail.com>