summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMatthias Schiffer <mschiffer@universe-factory.net>2015-11-28 14:58:01 +0100
committerMatthias Schiffer <mschiffer@universe-factory.net>2015-11-30 09:53:36 +0100
commit13590ca98ac2fd4939b683adbfdd63392b559f3f (patch)
tree37a267d3ac4ca067fea1d2a1789c1a055ed7b707
parent890ac34c460fbb753bd4303b201d11aebd27a570 (diff)
downloadunitd-13590ca98ac2fd4939b683adbfdd63392b559f3f.tar
unitd-13590ca98ac2fd4939b683adbfdd63392b559f3f.zip
Strip down procd to the necessary code, update copyright
-rw-r--r--CMakeLists.txt89
-rw-r--r--early.c (renamed from initd/early.c)38
-rw-r--r--initd/init.c121
-rw-r--r--initd/init.h32
-rw-r--r--initd/mkdev.c125
-rw-r--r--initd/preinit.c122
-rw-r--r--initd/zram.c128
-rw-r--r--inittab.c1
-rw-r--r--jail/capabilities.c116
-rw-r--r--jail/capabilities.h14
-rw-r--r--jail/elf.c355
-rw-r--r--jail/elf.h38
-rw-r--r--jail/jail.c459
-rw-r--r--jail/log.h27
-rw-r--r--jail/preload.c80
-rw-r--r--jail/seccomp-bpf.h89
-rw-r--r--jail/seccomp.c142
-rw-r--r--jail/seccomp.h19
-rw-r--r--libc-compat.h10
-rw-r--r--log.h1
-rwxr-xr-xmake_capabilities_h.sh10
-rwxr-xr-xmake_syscall_h.sh18
-rw-r--r--plug/coldplug.c69
-rw-r--r--plug/hotplug.c610
-rw-r--r--plug/hotplug.h25
-rw-r--r--plug/udevtrigger.c264
-rw-r--r--preload.h56
-rw-r--r--procd.c24
-rw-r--r--procd.h3
-rw-r--r--rcS.c1
-rw-r--r--rcS.h1
-rw-r--r--service/instance.c1
-rw-r--r--service/instance.h1
-rw-r--r--service/service.c57
-rw-r--r--service/service.h17
-rw-r--r--service/setlbf.c6
-rw-r--r--service/trigger.c1
-rw-r--r--service/validate.c163
-rw-r--r--service/watch.c1
-rw-r--r--signal.c1
-rw-r--r--state.c17
-rw-r--r--system.c1
-rw-r--r--trace/preload.c80
-rw-r--r--trace/trace.c225
-rw-r--r--ubus.c1
-rw-r--r--upgraded/CMakeLists.txt17
-rw-r--r--upgraded/upgraded.c80
-rw-r--r--utils/askfirst.c1
-rw-r--r--utils/utils.c1
-rw-r--r--utils/utils.h1
-rw-r--r--watchdog.c1
-rw-r--r--watchdog.h1
52 files changed, 45 insertions, 3716 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index d749c25..30b1410 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -6,21 +6,10 @@ ADD_DEFINITIONS(-Os -ggdb -Wall -Werror --std=gnu99 -Wmissing-declarations)
SET(CMAKE_SHARED_LIBRARY_LINK_C_FLAGS "")
-IF(APPLE)
- INCLUDE_DIRECTORIES(/opt/local/include)
- LINK_DIRECTORIES(/opt/local/lib)
-ENDIF()
-
-
-ADD_LIBRARY(setlbf SHARED service/setlbf.c)
-INSTALL(TARGETS setlbf
- LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
-)
-
-SET(SOURCES procd.c signal.c watchdog.c state.c inittab.c rcS.c ubus.c system.c
- service/service.c service/instance.c service/validate.c service/trigger.c service/watch.c
- plug/coldplug.c plug/hotplug.c utils/utils.c)
+SET(SOURCES procd.c signal.c watchdog.c state.c inittab.c rcS.c ubus.c system.c early.c
+ service/service.c service/instance.c service/trigger.c service/watch.c
+ utils/utils.c)
SET(LIBS ubox ubus json-c blobmsg_json json_script)
@@ -28,84 +17,14 @@ IF(DEBUG)
ADD_DEFINITIONS(-DDEBUG -g3)
ENDIF()
-IF(ZRAM_TMPFS)
- ADD_DEFINITIONS(-DZRAM_TMPFS)
- SET(SOURCES_ZRAM initd/zram.c)
-ENDIF()
-
-IF(BUILD_UPGRADED)
- add_subdirectory(upgraded)
-ENDIF()
-
-ADD_EXECUTABLE(procd ${SOURCES})
-TARGET_LINK_LIBRARIES(procd ${LIBS})
-INSTALL(TARGETS procd
- RUNTIME DESTINATION ${CMAKE_INSTALL_SBINDIR}
-)
-
-
-ADD_EXECUTABLE(init initd/init.c initd/early.c initd/preinit.c initd/mkdev.c watchdog.c
- utils/utils.c ${SOURCES_ZRAM})
+ADD_EXECUTABLE(init ${SOURCES})
TARGET_LINK_LIBRARIES(init ${LIBS})
INSTALL(TARGETS init
RUNTIME DESTINATION ${CMAKE_INSTALL_SBINDIR}
)
-ADD_EXECUTABLE(udevtrigger plug/udevtrigger.c)
-INSTALL(TARGETS udevtrigger
- RUNTIME DESTINATION ${CMAKE_INSTALL_SBINDIR}
-)
-
-
ADD_EXECUTABLE(askfirst utils/askfirst.c)
INSTALL(TARGETS askfirst
RUNTIME DESTINATION ${CMAKE_INSTALL_SBINDIR}
)
-
-ADD_CUSTOM_COMMAND(
- OUTPUT syscall-names.h
- COMMAND ./make_syscall_h.sh ${CMAKE_C_COMPILER} > ./syscall-names.h
- DEPENDS ./make_syscall_h.sh
-)
-ADD_CUSTOM_TARGET(syscall-names-h DEPENDS syscall-names.h)
-
-ADD_CUSTOM_COMMAND(
- OUTPUT capabilities-names.h
- COMMAND ./make_capabilities_h.sh ${CMAKE_C_COMPILER} > ./capabilities-names.h
- DEPENDS ./make_capabilities_h.sh
-)
-ADD_CUSTOM_TARGET(capabilities-names-h DEPENDS capabilities-names.h)
-
-IF(SECCOMP_SUPPORT)
-ADD_LIBRARY(preload-seccomp SHARED jail/preload.c jail/seccomp.c)
-TARGET_LINK_LIBRARIES(preload-seccomp dl ubox blobmsg_json)
-INSTALL(TARGETS preload-seccomp
- LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
-)
-ADD_DEPENDENCIES(preload-seccomp syscall-names-h)
-endif()
-
-IF(JAIL_SUPPORT)
-ADD_EXECUTABLE(ujail jail/jail.c jail/elf.c jail/capabilities.c)
-TARGET_LINK_LIBRARIES(ujail ubox blobmsg_json)
-INSTALL(TARGETS ujail
- RUNTIME DESTINATION ${CMAKE_INSTALL_SBINDIR}
-)
-ADD_DEPENDENCIES(ujail capabilities-names-h)
-endif()
-
-IF(UTRACE_SUPPORT)
-ADD_EXECUTABLE(utrace trace/trace.c)
-TARGET_LINK_LIBRARIES(utrace ubox ${json} blobmsg_json)
-INSTALL(TARGETS utrace
- RUNTIME DESTINATION ${CMAKE_INSTALL_SBINDIR}
-)
-ADD_DEPENDENCIES(utrace syscall-names-h)
-
-ADD_LIBRARY(preload-trace SHARED trace/preload.c)
-TARGET_LINK_LIBRARIES(preload-trace dl)
-INSTALL(TARGETS preload-trace
- LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
-)
-endif()
diff --git a/initd/early.c b/early.c
index e87774f..92ec6bd 100644
--- a/initd/early.c
+++ b/early.c
@@ -1,6 +1,7 @@
/*
* Copyright (C) 2013 Felix Fietkau <nbd@openwrt.org>
* Copyright (C) 2013 John Crispin <blogic@openwrt.org>
+ * Copyright (C) 2015 Matthias Schiffer <mschiffer@universe-factory.net>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License version 2.1
@@ -21,15 +22,7 @@
#include <unistd.h>
#include <stdlib.h>
-#include "init.h"
-#include "../libc-compat.h"
-
-static void
-early_dev(void)
-{
- mkdev("*", 0600);
- mknod("/dev/null", 0666, makedev(1, 3));
-}
+#include "procd.h"
static void
early_console(const char *dev)
@@ -64,26 +57,13 @@ early_mounts(void)
unsigned int oldumask = umask(0);
mount("proc", "/proc", "proc", MS_NOATIME | MS_NODEV | MS_NOEXEC | MS_NOSUID, 0);
- mount("sysfs", "/sys", "sysfs", MS_NOATIME | MS_NODEV | MS_NOEXEC | MS_NOSUID, 0);
- mount("cgroup", "/sys/fs/cgroup", "cgroup", MS_NODEV | MS_NOEXEC | MS_NOSUID, 0);
- mount("tmpfs", "/dev", "tmpfs", MS_NOATIME | MS_NOSUID, "mode=0755,size=512K");
- ignore(symlink("/tmp/shm", "/dev/shm"));
+ mount("sys", "/sys", "sysfs", MS_NOATIME | MS_NODEV | MS_NOEXEC | MS_NOSUID, 0);
+ mount("cgroup", "/sys/fs/cgroup", "cgroup", MS_NODEV | MS_NOEXEC | MS_NOSUID, "none");
+ mount("dev", "/dev", "devtmpfs", MS_NOATIME | MS_NOSUID, "mode=0755,size=512K");
mkdir("/dev/pts", 0755);
mount("devpts", "/dev/pts", "devpts", MS_NOATIME | MS_NOEXEC | MS_NOSUID, "mode=600");
- early_dev();
+ mount("tmpfs", "/tmp", "tmpfs", MS_NOSUID | MS_NODEV | MS_NOATIME, 0);
- early_console("/dev/console");
- if (mount_zram_on_tmp()) {
- mount("tmpfs", "/tmp", "tmpfs", MS_NOSUID | MS_NODEV | MS_NOATIME, 0);
- mkdir("/tmp/shm", 01777);
- } else {
- mkdir("/tmp/shm", 01777);
- mount("tmpfs", "/tmp/shm", "tmpfs", MS_NOSUID | MS_NODEV | MS_NOATIME,
- "mode=01777");
- }
- mkdir("/tmp/run", 0777);
- mkdir("/tmp/lock", 0777);
- mkdir("/tmp/state", 0777);
umask(oldumask);
}
@@ -94,12 +74,10 @@ early_env(void)
}
void
-early(void)
+procd_early(void)
{
- if (getpid() != 1)
- return;
-
early_mounts();
+ early_console("/dev/console");
early_env();
LOG("Console is alive\n");
diff --git a/initd/init.c b/initd/init.c
deleted file mode 100644
index 9818c4f..0000000
--- a/initd/init.c
+++ /dev/null
@@ -1,121 +0,0 @@
-/*
- * Copyright (C) 2013 Felix Fietkau <nbd@openwrt.org>
- * Copyright (C) 2013 John Crispin <blogic@openwrt.org>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU Lesser General Public License version 2.1
- * as published by the Free Software Foundation
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- */
-
-#include <sys/wait.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <sys/reboot.h>
-
-#include <libubox/uloop.h>
-#include <libubus.h>
-
-#include <limits.h>
-#include <stdlib.h>
-#include <fcntl.h>
-#include <getopt.h>
-#include <libgen.h>
-#include <regex.h>
-#include <unistd.h>
-#include <stdio.h>
-
-#include "../utils/utils.h"
-#include "init.h"
-#include "../watchdog.h"
-
-unsigned int debug = 0;
-
-static void
-signal_shutdown(int signal, siginfo_t *siginfo, void *data)
-{
- fprintf(stderr, "reboot\n");
- fflush(stderr);
- sync();
- sleep(2);
- reboot(RB_AUTOBOOT);
- while (1)
- ;
-}
-
-static struct sigaction sa_shutdown = {
- .sa_sigaction = signal_shutdown,
- .sa_flags = SA_SIGINFO
-};
-
-static void
-cmdline(void)
-{
- char line[20];
- char* res;
- long r;
-
- res = get_cmdline_val("init_debug", line, sizeof(line));
- if (res != NULL) {
- r = strtol(line, NULL, 10);
- if ((r != LONG_MIN) && (r != LONG_MAX))
- debug = (int) r;
- }
-}
-
-int
-main(int argc, char **argv)
-{
- pid_t pid;
-
- ulog_open(ULOG_KMSG, LOG_DAEMON, "init");
-
- sigaction(SIGTERM, &sa_shutdown, NULL);
- sigaction(SIGUSR1, &sa_shutdown, NULL);
- sigaction(SIGUSR2, &sa_shutdown, NULL);
-
- early();
- cmdline();
- watchdog_init(1);
-
- pid = fork();
- if (!pid) {
- char *kmod[] = { "/sbin/kmodloader", "/etc/modules-boot.d/", NULL };
-
- if (debug < 3) {
- int fd = open("/dev/null", O_RDWR);
-
- if (fd > -1) {
- dup2(fd, STDIN_FILENO);
- dup2(fd, STDOUT_FILENO);
- dup2(fd, STDERR_FILENO);
- if (fd > STDERR_FILENO)
- close(fd);
- }
- }
- execvp(kmod[0], kmod);
- ERROR("Failed to start kmodloader\n");
- exit(-1);
- }
- if (pid <= 0) {
- ERROR("Failed to start kmodloader instance\n");
- } else {
- int i;
-
- for (i = 0; i < 120; i++) {
- if (waitpid(pid, NULL, WNOHANG) > 0)
- break;
- sleep(1);
- watchdog_ping();
- }
- }
- uloop_init();
- preinit();
- uloop_run();
-
- return 0;
-}
diff --git a/initd/init.h b/initd/init.h
deleted file mode 100644
index 274645b..0000000
--- a/initd/init.h
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * Copyright (C) 2013 John Crispin <blogic@openwrt.org>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU Lesser General Public License version 2.1
- * as published by the Free Software Foundation
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- */
-
-#ifndef _INIT_H__
-#define _INIT_H__
-
-#include <errno.h>
-
-#include "../log.h"
-
-void preinit(void);
-void early(void);
-int mkdev(const char *progname, int progmode);
-
-#ifdef ZRAM_TMPFS
-int mount_zram_on_tmp(void);
-#else
-static inline int mount_zram_on_tmp(void) {
- return -ENOSYS;
-}
-#endif
-#endif
diff --git a/initd/mkdev.c b/initd/mkdev.c
deleted file mode 100644
index e6d3d0c..0000000
--- a/initd/mkdev.c
+++ /dev/null
@@ -1,125 +0,0 @@
-/*
- * Copyright (C) 2013 Felix Fietkau <nbd@openwrt.org>
- * Copyright (C) 2013 John Crispin <blogic@openwrt.org>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU Lesser General Public License version 2.1
- * as published by the Free Software Foundation
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- */
-
-#define _DEFAULT_SOURCE
-
-#include <sys/stat.h>
-#include <sys/types.h>
-
-#include <stdio.h>
-#include <string.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <stdbool.h>
-#include <dirent.h>
-#include <limits.h>
-#include <fnmatch.h>
-
-#include "init.h"
-
-static char **patterns;
-static int n_patterns;
-static char buf[PATH_MAX];
-static char buf2[PATH_MAX];
-static unsigned int mode = 0600;
-
-static bool find_pattern(const char *name)
-{
- int i;
-
- for (i = 0; i < n_patterns; i++)
- if (!fnmatch(patterns[i], name, 0))
- return true;
-
- return false;
-}
-
-static void make_dev(const char *path, bool block, int major, int minor)
-{
- unsigned int oldumask = umask(0);
- unsigned int _mode = mode | (block ? S_IFBLK : S_IFCHR);
-
- DEBUG(4, "Creating %s device %s(%d,%d)\n",
- block ? "block" : "character",
- path, major, minor);
-
- mknod(path, _mode, makedev(major, minor));
- umask(oldumask);
-}
-
-static void find_devs(bool block)
-{
- char *path = block ? "/sys/dev/block" : "/sys/dev/char";
- struct dirent *dp;
- DIR *dir;
-
- dir = opendir(path);
- if (!dir)
- return;
-
- path = buf2 + sprintf(buf2, "%s/", path);
- while ((dp = readdir(dir)) != NULL) {
- char *c;
- int major = 0, minor = 0;
- int len;
-
- if (dp->d_type != DT_LNK)
- continue;
-
- if (sscanf(dp->d_name, "%d:%d", &major, &minor) != 2)
- continue;
-
- strcpy(path, dp->d_name);
- len = readlink(buf2, buf, sizeof(buf));
- if (len <= 0)
- continue;
-
- buf[len] = 0;
- if (!find_pattern(buf))
- continue;
-
- c = strrchr(buf, '/');
- if (!c)
- continue;
-
- c++;
- make_dev(c, block, major, minor);
- }
- closedir(dir);
-}
-
-static char *add_pattern(const char *name)
-{
- char *str = malloc(strlen(name) + 2);
-
- str[0] = '*';
- strcpy(str + 1, name);
- return str;
-}
-
-int mkdev(const char *name, int _mode)
-{
- char *pattern;
-
- if (chdir("/dev"))
- return 1;
-
- pattern = add_pattern(name);
- patterns = &pattern;
- mode = _mode;
- n_patterns = 1;
- find_devs(true);
- find_devs(false);
- return chdir("/");
-}
diff --git a/initd/preinit.c b/initd/preinit.c
deleted file mode 100644
index f38d8ef..0000000
--- a/initd/preinit.c
+++ /dev/null
@@ -1,122 +0,0 @@
-/*
- * Copyright (C) 2013 Felix Fietkau <nbd@openwrt.org>
- * Copyright (C) 2013 John Crispin <blogic@openwrt.org>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU Lesser General Public License version 2.1
- * as published by the Free Software Foundation
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- */
-
-#include <sys/stat.h>
-#include <sys/types.h>
-#include <sys/mount.h>
-
-#include <libubox/uloop.h>
-#include <libubox/utils.h>
-#include <libubus.h>
-
-#include <stdio.h>
-
-#include <unistd.h>
-
-#include "init.h"
-#include "../watchdog.h"
-
-static struct uloop_process preinit_proc;
-static struct uloop_process plugd_proc;
-
-static void
-check_dbglvl(void)
-{
- FILE *fp = fopen("/tmp/debug_level", "r");
- int lvl = 0;
-
- if (!fp)
- return;
- if (fscanf(fp, "%d", &lvl) == EOF)
- ERROR("failed to read debug level\n");
- fclose(fp);
- unlink("/tmp/debug_level");
-
- if (lvl > 0 && lvl < 5)
- debug = lvl;
-}
-
-static void
-spawn_procd(struct uloop_process *proc, int ret)
-{
- char *wdt_fd = watchdog_fd();
- char *argv[] = { "/sbin/procd", NULL};
- struct stat s;
- char dbg[2];
-
- if (plugd_proc.pid > 0)
- kill(plugd_proc.pid, SIGKILL);
-
- if (!stat("/tmp/sysupgrade", &s))
- while (true)
- sleep(1);
-
- unsetenv("INITRAMFS");
- unsetenv("PREINIT");
- DEBUG(2, "Exec to real procd now\n");
- if (wdt_fd)
- setenv("WDTFD", wdt_fd, 1);
- check_dbglvl();
- if (debug > 0) {
- snprintf(dbg, 2, "%d", debug);
- setenv("DBGLVL", dbg, 1);
- }
-
- execvp(argv[0], argv);
-}
-
-static void
-plugd_proc_cb(struct uloop_process *proc, int ret)
-{
- proc->pid = 0;
-}
-
-void
-preinit(void)
-{
- char *init[] = { "/bin/sh", "/etc/preinit", NULL };
- char *plug[] = { "/sbin/procd", "-h", "/etc/hotplug-preinit.json", NULL };
-
- LOG("- preinit -\n");
-
- plugd_proc.cb = plugd_proc_cb;
- plugd_proc.pid = fork();
- if (!plugd_proc.pid) {
- execvp(plug[0], plug);
- ERROR("Failed to start plugd\n");
- exit(-1);
- }
- if (plugd_proc.pid <= 0) {
- ERROR("Failed to start new plugd instance\n");
- return;
- }
- uloop_process_add(&plugd_proc);
-
- setenv("PREINIT", "1", 1);
-
- preinit_proc.cb = spawn_procd;
- preinit_proc.pid = fork();
- if (!preinit_proc.pid) {
- execvp(init[0], init);
- ERROR("Failed to start preinit\n");
- exit(-1);
- }
- if (preinit_proc.pid <= 0) {
- ERROR("Failed to start new preinit instance\n");
- return;
- }
- uloop_process_add(&preinit_proc);
-
- DEBUG(4, "Launched preinit instance, pid=%d\n", (int) preinit_proc.pid);
-}
diff --git a/initd/zram.c b/initd/zram.c
deleted file mode 100644
index 49480af..0000000
--- a/initd/zram.c
+++ /dev/null
@@ -1,128 +0,0 @@
-#include <stdio.h>
-#include <unistd.h>
-#include <stdlib.h>
-#include <string.h>
-#include <errno.h>
-#include <fcntl.h>
-
-#include <sys/utsname.h>
-#include <sys/mount.h>
-#include <sys/types.h>
-#include <sys/wait.h>
-#include <sys/stat.h>
-
-#include "../log.h"
-
-#include "init.h"
-
-#define KB(x) (x * 1024)
-
-#define ZRAM_MOD_PATH "/lib/modules/%s/zram.ko"
-#define EXT4_MOD_PATH "/lib/modules/%s/ext4.ko"
-
-static long
-proc_meminfo(void)
-{
- FILE *fp;
- char line[256];
- char *key;
- long val = KB(16);
-
- fp = fopen("/proc/meminfo", "r");
- if (fp == NULL) {
- ERROR("Can't open /proc/meminfo: %s\n", strerror(errno));
- return errno;
- }
-
- while (fgets(line, sizeof(line), fp)) {
- key = strtok(line, ":");
- if (strcasecmp(key, "MemTotal"))
- continue;
- val = atol(strtok(NULL, " kB\n"));
- break;
- }
- fclose(fp);
-
- if (val > KB(32))
- val = KB(32);
-
- return val;
-}
-
-static int
-early_insmod(char *module)
-{
- pid_t pid = fork();
-
- if (!pid) {
- char *modprobe[] = { "/usr/sbin/modprobe", NULL, NULL };
- char *path;
- struct utsname ver;
-
- uname(&ver);
- path = alloca(sizeof(module) + strlen(ver.release) + 1);
- sprintf(path, module, ver.release);
- modprobe[1] = path;
- execvp(modprobe[0], modprobe);
- ERROR("Can't exec /usr/sbin/modprobe\n");
- exit(-1);
- }
-
- if (pid <= 0) {
- ERROR("Can't exec /usr/sbin/modprobe\n");
- return -1;
- } else {
- waitpid(pid, NULL, 0);
- }
-
- return 0;
-}
-
-
-int
-mount_zram_on_tmp(void)
-{
- char *mkfs[] = { "/usr/sbin/mkfs.ext4", "-b", "4096", "-F", "-L", "TEMP", "-m", "0", "/dev/zram0", NULL };
- FILE *fp;
- long zramsize;
- pid_t pid;
- int ret;
-
- if (early_insmod(ZRAM_MOD_PATH) || early_insmod(EXT4_MOD_PATH)) {
- ERROR("failed to insmod zram support\n");
- return -1;
- }
-
- mkdev("*", 0600);
-
- zramsize = proc_meminfo() / 2;
- fp = fopen("/sys/block/zram0/disksize", "r+");
- if (fp == NULL) {
- ERROR("Can't open /sys/block/zram0/disksize: %s\n", strerror(errno));
- return errno;
- }
- fprintf(fp, "%ld", KB(zramsize));
- fclose(fp);
-
- pid = fork();
- if (!pid) {
- execvp(mkfs[0], mkfs);
- ERROR("Can't exec /sbin/mkfs.ext4\n");
- exit(-1);
- } else if (pid <= 0) {
- ERROR("Can't exec /sbin/mkfs.ext4\n");
- return -1;
- } else {
- waitpid(pid, NULL, 0);
- }
-
- ret = mount("/dev/zram0", "/tmp", "ext4", MS_NOSUID | MS_NODEV | MS_NOATIME, "errors=continue,noquota");
- if (ret < 0) {
- ERROR("Can't mount /dev/zram0 on /tmp: %s\n", strerror(errno));
- return errno;
- }
-
- LOG("Using up to %ld kB of RAM as ZRAM storage on /mnt\n", zramsize);
-
- return 0;
-}
diff --git a/inittab.c b/inittab.c
index f8f0218..4675aca 100644
--- a/inittab.c
+++ b/inittab.c
@@ -1,6 +1,7 @@
/*
* Copyright (C) 2013 Felix Fietkau <nbd@openwrt.org>
* Copyright (C) 2013 John Crispin <blogic@openwrt.org>
+ * Copyright (C) 2015 Matthias Schiffer <mschiffer@universe-factory.net>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License version 2.1
diff --git a/jail/capabilities.c b/jail/capabilities.c
deleted file mode 100644
index b5ea965..0000000
--- a/jail/capabilities.c
+++ /dev/null
@@ -1,116 +0,0 @@
-/*
- * Copyright (C) 2015 Etienne CHAMPETIER <champetier.etienne@gmail.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU Lesser General Public License version 2.1
- * as published by the Free Software Foundation
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- */
-
-#define _GNU_SOURCE 1
-#include <syslog.h>
-#include <sys/prctl.h>
-
-#include <libubox/blobmsg.h>
-#include <libubox/blobmsg_json.h>
-
-#include "log.h"
-#include "../capabilities-names.h"
-#include "capabilities.h"
-
-static int find_capabilities(const char *name)
-{
- int i;
-
- for (i = 0; i <= CAP_LAST_CAP; i++)
- if (capabilities_names[i] && !strcmp(capabilities_names[i], name))
- return i;
-
- return -1;
-}
-
-int drop_capabilities(const char *file)
-{
- enum {
- CAP_KEEP,
- CAP_DROP,
- __CAP_MAX
- };
- static const struct blobmsg_policy policy[__CAP_MAX] = {
- [CAP_KEEP] = { .name = "cap.keep", .type = BLOBMSG_TYPE_ARRAY },
- [CAP_DROP] = { .name = "cap.drop", .type = BLOBMSG_TYPE_ARRAY },
- };
- struct blob_buf b = { 0 };
- struct blob_attr *tb[__CAP_MAX];
- struct blob_attr *cur;
- int rem, cap;
- char *name;
- uint64_t capdrop = 0LLU;
-
- DEBUG("dropping capabilities\n");
-
- blob_buf_init(&b, 0);
- if (!blobmsg_add_json_from_file(&b, file)) {
- ERROR("failed to load %s\n", file);
- return -1;
- }
-
- blobmsg_parse(policy, __CAP_MAX, tb, blob_data(b.head), blob_len(b.head));
- if (!tb[CAP_KEEP] && !tb[CAP_DROP]) {
- ERROR("failed to parse %s\n", file);
- return -1;
- }
-
- blobmsg_for_each_attr(cur, tb[CAP_KEEP], rem) {
- name = blobmsg_get_string(cur);
- if (!name) {
- ERROR("invalid capability name in cap.keep\n");
- return -1;
- }
- cap = find_capabilities(name);
- if (cap == -1) {
- ERROR("unknown capability %s in cap.keep\n", name);
- return -1;
- }
- capdrop |= (1LLU << cap);
- }
-
- if (capdrop == 0LLU) {
- DEBUG("cap.keep empty -> only dropping capabilities from cap.drop (blacklist)\n");
- capdrop = 0xffffffffffffffffLLU;
- } else {
- DEBUG("cap.keep has at least one capability -> dropping every capabilities not in cap.keep (whitelist)\n");
- }
-
- blobmsg_for_each_attr(cur, tb[CAP_DROP], rem) {
- name = blobmsg_get_string(cur);
- if (!name) {
- ERROR("invalid capability name in cap.drop\n");
- return -1;
- }
- cap = find_capabilities(name);
- if (cap == -1) {
- ERROR("unknown capability %s in cap.drop\n", name);
- return -1;
- }
- capdrop &= ~(1LLU << cap);
- }
-
- for (cap = 0; cap <= CAP_LAST_CAP; cap++) {
- if ( (capdrop & (1LLU << cap)) == 0) {
- DEBUG("dropping capability %s (%d)\n", capabilities_names[cap], cap);
- if (prctl(PR_CAPBSET_DROP, cap, 0, 0, 0)) {
- ERROR("prctl(PR_CAPBSET_DROP, %d) failed: %s\n", cap, strerror(errno));
- return errno;
- }
- } else {
- DEBUG("keeping capability %s (%d)\n", capabilities_names[cap], cap);
- }
- }
-
- return 0;
-}
diff --git a/jail/capabilities.h b/jail/capabilities.h
deleted file mode 100644
index e6699e9..0000000
--- a/jail/capabilities.h
+++ /dev/null
@@ -1,14 +0,0 @@
-/*
- * Copyright (C) 2015 Etienne CHAMPETIER <champetier.etienne@gmail.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU Lesser General Public License version 2.1
- * as published by the Free Software Foundation
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- */
-
-int drop_capabilities(const char *file);
diff --git a/jail/elf.c b/jail/elf.c
deleted file mode 100644
index cbb3051..0000000
--- a/jail/elf.c
+++ /dev/null
@@ -1,355 +0,0 @@
-/*
- * Copyright (C) 2015 John Crispin <blogic@openwrt.org>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU Lesser General Public License version 2.1
- * as published by the Free Software Foundation
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- */
-
-#define _GNU_SOURCE
-#include <sys/mman.h>
-
-#include <stdlib.h>
-#include <unistd.h>
-#include <stdio.h>
-#include <string.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-#include <libgen.h>
-#include <glob.h>
-#include <elf.h>
-
-#include <libubox/utils.h>
-
-#include "elf.h"
-
-struct avl_tree libraries;
-static LIST_HEAD(library_paths);
-
-void alloc_library_path(const char *path)
-{
- struct library_path *p;
- char *_path;
-
- p = calloc_a(sizeof(*p),
- &_path, strlen(path) + 1);
- if (!p)
- return;
-
- p->path = strcpy(_path, path);
-
- list_add_tail(&p->list, &library_paths);
- DEBUG("adding ld.so path %s\n", path);
-}
-
-static void alloc_library(const char *path, const char *name)
-{
- struct library *l;
- char *_name, *_path;
-
- l = calloc_a(sizeof(*l),
- &_path, strlen(path) + 1,
- &_name, strlen(name) + 1);
- if (!l)
- return;
-
- l->avl.key = l->name = strcpy(_name, name);
- l->path = strcpy(_path, path);
-
- avl_insert(&libraries, &l->avl);
- DEBUG("adding library %s/%s\n", path, name);
-}
-
-static int elf_open(char **dir, char *file)
-{
- struct library_path *p;
- char path[256];
- int fd = -1;
-
- *dir = NULL;
-
- list_for_each_entry(p, &library_paths, list) {
- if (strlen(p->path))
- snprintf(path, sizeof(path), "%s/%s", p->path, file);
- else
- strncpy(path, file, sizeof(path));
- fd = open(path, O_RDONLY);
- if (fd >= 0) {
- *dir = p->path;
- break;
- }
- }
-
- if (fd == -1)
- fd = open(file, O_RDONLY);
-
- return fd;
-}
-
-char* find_lib(char *file)
-{
- struct library *l;
- static char path[256];
- const char *p;
-
- l = avl_find_element(&libraries, file, l, avl);
- if (!l)
- return NULL;
-
- p = l->path;
- if (strstr(p, "local"))
- p = "/lib";
-
- snprintf(path, sizeof(path), "%s/%s", p, file);
-
- return path;
-}
-
-static int elf64_find_section(char *map, unsigned int type, unsigned int *offset, unsigned int *size, unsigned int *vaddr)
-{
- Elf64_Ehdr *e;
- Elf64_Phdr *ph;
- int i;
-
- e = (Elf64_Ehdr *) map;
- ph = (Elf64_Phdr *) (map + e->e_phoff);
-
- for (i = 0; i < e->e_phnum; i++) {
- if (ph[i].p_type == type) {
- *offset = ph[i].p_offset;
- if (size)
- *size = ph[i].p_filesz;
- if (vaddr)
- *vaddr = ph[i].p_vaddr;
- return 0;
- }
- }
-
- return -1;
-}
-
-static int elf32_find_section(char *map, unsigned int type, unsigned int *offset, unsigned int *size, unsigned int *vaddr)
-{
- Elf32_Ehdr *e;
- Elf32_Phdr *ph;
- int i;
-
- e = (Elf32_Ehdr *) map;
- ph = (Elf32_Phdr *) (map + e->e_phoff);
-
- for (i = 0; i < e->e_phnum; i++) {
- if (ph[i].p_type == type) {
- *offset = ph[i].p_offset;
- if (size)
- *size = ph[i].p_filesz;
- if (vaddr)
- *vaddr = ph[i].p_vaddr;
- return 0;
- }
- }
-
- return -1;
-}
-
-static int elf_find_section(char *map, unsigned int type, unsigned int *offset, unsigned int *size, unsigned int *vaddr)
-{
- int clazz = map[EI_CLASS];
-
- if (clazz == ELFCLASS32)
- return elf32_find_section(map, type, offset, size, vaddr);
- else if (clazz == ELFCLASS64)
- return elf64_find_section(map, type, offset, size, vaddr);
-
- ERROR("unknown elf format %d\n", clazz);
-
- return -1;
-}
-
-static int elf32_scan_dynamic(char *map, int dyn_offset, int dyn_size, int load_offset)
-{
- Elf32_Dyn *dynamic = (Elf32_Dyn *) (map + dyn_offset);
- char *strtab = NULL;
-
- while ((void *) dynamic < (void *) (map + dyn_offset + dyn_size)) {
- Elf32_Dyn *curr = dynamic;
-
- dynamic++;
- if (curr->d_tag != DT_STRTAB)
- continue;
-
- strtab = map + (curr->d_un.d_val - load_offset);
- break;
- }
-
- if (!strtab)
- return -1;
-
- dynamic = (Elf32_Dyn *) (map + dyn_offset);
- while ((void *) dynamic < (void *) (map + dyn_offset + dyn_size)) {
- Elf32_Dyn *curr = dynamic;
-
- dynamic++;
- if (curr->d_tag != DT_NEEDED)
- continue;
-
- if (elf_load_deps(&strtab[curr->d_un.d_val]))
- return -1;
- }
-
- return 0;
-}
-
-static int elf64_scan_dynamic(char *map, int dyn_offset, int dyn_size, int load_offset)
-{
- Elf64_Dyn *dynamic = (Elf64_Dyn *) (map + dyn_offset);
- char *strtab = NULL;
-
- while ((void *) dynamic < (void *) (map + dyn_offset + dyn_size)) {
- Elf64_Dyn *curr = dynamic;
-
- dynamic++;
- if (curr->d_tag != DT_STRTAB)
- continue;
-
- strtab = map + (curr->d_un.d_val - load_offset);
- break;
- }
-
- if (!strtab)
- return -1;
-
- dynamic = (Elf64_Dyn *) (map + dyn_offset);
- while ((void *) dynamic < (void *) (map + dyn_offset + dyn_size)) {
- Elf64_Dyn *curr = dynamic;
-
- dynamic++;
- if (curr->d_tag != DT_NEEDED)
- continue;
-
- if (elf_load_deps(&strtab[curr->d_un.d_val]))
- return -1;
- }
-
- return 0;
-}
-
-int elf_load_deps(char *library)
-{
- unsigned int dyn_offset, dyn_size;
- unsigned int load_offset, load_vaddr;
- struct stat s;
- char *map = NULL, *dir = NULL;
- int clazz, fd, ret = -1;
-
- if (avl_find(&libraries, library))
- return 0;
-
- fd = elf_open(&dir, library);
-
- if (fd < 0) {
- ERROR("failed to open %s\n", library);
- return -1;
- }
-
- if (fstat(fd, &s) == -1) {
- ERROR("failed to stat %s\n", library);
- ret = -1;
- goto err_out;
- }
-
- map = mmap(NULL, s.st_size, PROT_READ, MAP_PRIVATE, fd, 0);
- if (map == MAP_FAILED) {
- ERROR("failed to mmap %s\n", library);
- ret = -1;
- goto err_out;
- }
-
- if (elf_find_section(map, PT_LOAD, &load_offset, NULL, &load_vaddr)) {
- ERROR("failed to load the .load section from %s\n", library);
- ret = -1;
- goto err_out;
- }
-
- if (elf_find_section(map, PT_DYNAMIC, &dyn_offset, &dyn_size, NULL)) {
- ERROR("failed to load the .dynamic section from %s\n", library);
- ret = -1;
- goto err_out;
- }
-
- if (dir) {
- alloc_library(dir, library);
- } else {
- char *elf = strdup(library);
-
- alloc_library(dirname(elf), basename(library));
- free(elf);
- }
- clazz = map[EI_CLASS];
-
- if (clazz == ELFCLASS32)
- ret = elf32_scan_dynamic(map, dyn_offset, dyn_size, load_vaddr - load_offset);
- else if (clazz == ELFCLASS64)
- ret = elf64_scan_dynamic(map, dyn_offset, dyn_size, load_vaddr - load_offset);
-
-err_out:
- if (map)
- munmap(map, s.st_size);
- close(fd);
-
- return ret;
-}
-
-void load_ldso_conf(const char *conf)
-{
- FILE* fp = fopen(conf, "r");
- char line[256];
-
- if (!fp) {
- DEBUG("failed to open %s\n", conf);
- return;
- }
-
- while (!feof(fp)) {
- int len;
-
- if (!fgets(line, 256, fp))
- break;
- len = strlen(line);
- if (len < 2)
- continue;
- if (*line == '#')
- continue;
- if (line[len - 1] == '\n')
- line[len - 1] = '\0';
- if (!strncmp(line, "include ", 8)) {
- char *sep = strstr(line, " ");
- glob_t gl;
- int i;
-
- if (!sep)
- continue;;
- while (*sep == ' ')
- sep++;
- if (glob(sep, GLOB_NOESCAPE | GLOB_MARK, NULL, &gl)) {
- ERROR("glob failed on %s\n", sep);
- continue;
- }
- for (i = 0; i < gl.gl_pathc; i++)
- load_ldso_conf(gl.gl_pathv[i]);
- globfree(&gl);
- } else {
- struct stat s;
-
- if (stat(line, &s))
- continue;
- alloc_library_path(line);
- }
- }
-
- fclose(fp);
-}
diff --git a/jail/elf.h b/jail/elf.h
deleted file mode 100644
index 3ae311e..0000000
--- a/jail/elf.h
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * Copyright (C) 2015 John Crispin <blogic@openwrt.org>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU Lesser General Public License version 2.1
- * as published by the Free Software Foundation
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- */
-
-#ifndef _ELF_H__
-#include <libubox/avl.h>
-#include <libubox/avl-cmp.h>
-
-#include "log.h"
-
-struct library {
- struct avl_node avl;
- char *name;
- char *path;
-};
-
-struct library_path {
- struct list_head list;
- char *path;
-};
-
-extern struct avl_tree libraries;
-
-extern void alloc_library_path(const char *path);
-extern char* find_lib(char *file);
-extern int elf_load_deps(char *library);
-extern void load_ldso_conf(const char *conf);
-
-#endif
diff --git a/jail/jail.c b/jail/jail.c
deleted file mode 100644
index 56dc9ca..0000000
--- a/jail/jail.c
+++ /dev/null
@@ -1,459 +0,0 @@
-/*
- * Copyright (C) 2015 John Crispin <blogic@openwrt.org>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU Lesser General Public License version 2.1
- * as published by the Free Software Foundation
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- */
-
-#define _GNU_SOURCE
-#include <sys/mount.h>
-#include <sys/prctl.h>
-#include <sys/wait.h>
-
-#include <stdlib.h>
-#include <unistd.h>
-#include <values.h>
-#include <errno.h>
-#include <stdio.h>
-#include <string.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-#include <libgen.h>
-#include <sched.h>
-
-#include "elf.h"
-#include "capabilities.h"
-
-#include <libubox/list.h>
-#include <libubox/uloop.h>
-
-#define STACK_SIZE (1024 * 1024)
-#define OPT_ARGS "P:S:C:n:r:w:d:psulo"
-
-static struct {
- char *path;
- char *name;
- char **jail_argv;
- char *seccomp;
- char *capabilities;
- int namespace;
- int procfs;
- int ronly;
- int sysfs;
-} opts;
-
-struct extra {
- struct list_head list;
-
- const char *path;
- const char *name;
- int readonly;
-};
-
-static LIST_HEAD(extras);
-
-extern int pivot_root(const char *new_root, const char *put_old);
-
-int debug = 0;
-
-static char child_stack[STACK_SIZE];
-
-static int mkdir_p(char *dir, mode_t mask)
-{
- char *l = strrchr(dir, '/');
- int ret;
-
- if (!l)
- return 0;
-
- *l = '\0';
-
- if (mkdir_p(dir, mask))
- return -1;
-
- *l = '/';
-
- ret = mkdir(dir, mask);
- if (ret && errno == EEXIST)
- return 0;
-
- if (ret)
- ERROR("mkdir failed on %s: %s\n", dir, strerror(errno));
-
- return ret;
-}
-
-static int mount_bind(const char *root, const char *path, const char *name, int readonly, int error)
-{
- const char *p = path;
- struct stat s;
- char old[256];
- char new[256];
- int fd;
-
- if (strstr(p, "local"))
- p = "/lib";
-
- snprintf(old, sizeof(old), "%s/%s", path, name);
- snprintf(new, sizeof(new), "%s%s", root, p);
-
- mkdir_p(new, 0755);
-
- snprintf(new, sizeof(new), "%s%s/%s", root, p, name);
-
- if (stat(old, &s)) {
- ERROR("%s does not exist\n", old);
- return error;
- }
-
- if (S_ISDIR(s.st_mode)) {
- mkdir_p(new, 0755);
- } else {
- fd = creat(new, 0644);
- if (fd == -1) {
- ERROR("failed to create %s: %s\n", new, strerror(errno));
- return -1;
- }
- close(fd);
- }
-
- if (mount(old, new, NULL, MS_BIND, NULL)) {
- ERROR("failed to mount -B %s %s: %s\n", old, new, strerror(errno));
- return -1;
- }
-
- if (readonly && mount(NULL, new, NULL, MS_BIND | MS_REMOUNT | MS_RDONLY, NULL)) {
- ERROR("failed to remount ro %s: %s\n", new, strerror(errno));
- return -1;
- }
-
- DEBUG("mount -B %s %s\n", old, new);
-
- return 0;
-}
-
-static int build_jail_fs()
-{
- struct library *l;
- struct extra *m;
-
- if (mount("tmpfs", opts.path, "tmpfs", MS_NOATIME, "mode=0755")) {
- ERROR("tmpfs mount failed %s\n", strerror(errno));
- return -1;
- }
-
- if (chdir(opts.path)) {
- ERROR("failed to chdir() in the jail root\n");
- return -1;
- }
-
- avl_init(&libraries, avl_strcmp, false, NULL);
- alloc_library_path("/lib64");
- alloc_library_path("/lib");
- alloc_library_path("/usr/lib");
- load_ldso_conf("/etc/ld.so.conf");
-
- if (elf_load_deps(*opts.jail_argv)) {
- ERROR("failed to load dependencies\n");
- return -1;
- }
-
- if (opts.seccomp && elf_load_deps("libpreload-seccomp.so")) {
- ERROR("failed to load libpreload-seccomp.so\n");
- return -1;
- }
-
- avl_for_each_element(&libraries, l, avl)
- if (mount_bind(opts.path, l->path, l->name, 1, -1))
- return -1;
-
- list_for_each_entry(m, &extras, list)
- if (mount_bind(opts.path, m->path, m->name, m->readonly, 0))
- return -1;
-
- char *mpoint;
- if (asprintf(&mpoint, "%s/old", opts.path) < 0) {
- ERROR("failed to alloc pivot path: %s\n", strerror(errno));
- return -1;
- }
- mkdir_p(mpoint, 0755);
- if (pivot_root(opts.path, mpoint) == -1) {
- ERROR("pivot_root failed:%s\n", strerror(errno));
- free(mpoint);
- return -1;
- }
- free(mpoint);
- umount2("/old", MNT_DETACH);
- rmdir("/old");
- if (opts.procfs) {
- mkdir("/proc", 0755);
- mount("proc", "/proc", "proc", MS_NOATIME | MS_NODEV | MS_NOEXEC | MS_NOSUID, 0);
- }
- if (opts.sysfs) {
- mkdir("/sys", 0755);
- mount("sysfs", "/sys", "sysfs", MS_NOATIME | MS_NODEV | MS_NOEXEC | MS_NOSUID, 0);
- }
- if (opts.ronly)
- mount(NULL, "/", NULL, MS_RDONLY | MS_REMOUNT, 0);
-
- return 0;
-}
-
-#define MAX_ENVP 8
-static char** build_envp(const char *seccomp)
-{
- static char *envp[MAX_ENVP];
- static char preload_var[64];
- static char seccomp_var[64];
- static char debug_var[] = "LD_DEBUG=all";
- char *preload_lib = find_lib("libpreload-seccomp.so");
- int count = 0;
-
- if (seccomp && !preload_lib) {
- ERROR("failed to add preload-lib to env\n");
- return NULL;
- }
- if (seccomp) {
- snprintf(seccomp_var, sizeof(seccomp_var), "SECCOMP_FILE=%s", seccomp);
- envp[count++] = seccomp_var;
- snprintf(preload_var, sizeof(preload_var), "LD_PRELOAD=%s", preload_lib);
- envp[count++] = preload_var;
- }
- if (debug > 1)
- envp[count++] = debug_var;
-
- return envp;
-}
-
-static void usage(void)
-{
- fprintf(stderr, "ujail <options> -- <binary> <params ...>\n");
- fprintf(stderr, " -d <num>\tshow debug log (increase num to increase verbosity)\n");
- fprintf(stderr, " -S <file>\tseccomp filter config\n");
- fprintf(stderr, " -C <file>\tcapabilities drop config\n");
- fprintf(stderr, " -n <name>\tthe name of the jail\n");
- fprintf(stderr, "namespace jail options:\n");
- fprintf(stderr, " -P <path>\tpath where the jail will be staged\n");
- fprintf(stderr, " -r <file>\treadonly files that should be staged\n");
- fprintf(stderr, " -w <file>\twriteable files that should be staged\n");
- fprintf(stderr, " -p\t\tjail has /proc\n");
- fprintf(stderr, " -s\t\tjail has /sys\n");
- fprintf(stderr, " -l\t\tjail has /dev/log\n");
- fprintf(stderr, " -u\t\tjail has a ubus socket\n");
- fprintf(stderr, " -o\t\tremont jail root (/) read only\n");
- fprintf(stderr, "\nWarning: by default root inside the jail is the same\n\
-and he has the same powers as root outside the jail,\n\
-thus he can escape the jail and/or break stuff.\n\
-Please use seccomp/capabilities (-S/-C) to restrict his powers\n\n\
-If you use none of the namespace jail options,\n\
-ujail will not use namespace/build a jail,\n\
-and will only drop capabilities/apply seccomp filter.\n\n");
-}
-
-static int exec_jail()
-{
- char **envp = build_envp(opts.seccomp);
- if (!envp)
- exit(EXIT_FAILURE);
-
- if (opts.capabilities && drop_capabilities(opts.capabilities))
- exit(EXIT_FAILURE);
-
- INFO("exec-ing %s\n", *opts.jail_argv);
- execve(*opts.jail_argv, opts.jail_argv, envp);
- //we get there only if execve fails
- ERROR("failed to execve %s: %s\n", *opts.jail_argv, strerror(errno));
- exit(EXIT_FAILURE);
-}
-
-static int spawn_jail(void *arg)
-{
- if (opts.name && sethostname(opts.name, strlen(opts.name))) {
- ERROR("failed to sethostname: %s\n", strerror(errno));
- }
-
- if (build_jail_fs()) {
- ERROR("failed to build jail fs");
- exit(EXIT_FAILURE);
- }
-
- return exec_jail();
-}
-
-static int jail_running = 1;
-static int jail_return_code = 0;
-
-static void jail_process_handler(struct uloop_process *c, int ret)
-{
- if (WIFEXITED(ret)) {
- jail_return_code = WEXITSTATUS(ret);
- INFO("jail (%d) exited with exit: %d\n", c->pid, jail_return_code);
- } else {
- jail_return_code = WTERMSIG(ret);
- INFO("jail (%d) exited with signal: %d\n", c->pid, jail_return_code);
- }
- jail_running = 0;
- uloop_end();
-}
-
-static struct uloop_process jail_process = {
- .cb = jail_process_handler,
-};
-
-static void add_extra(char *name, int readonly)
-{
- struct extra *f;
-
- if (*name != '/') {
- ERROR("%s is not an absolute path\n", name);
- return;
- }
-
- f = calloc(1, sizeof(struct extra));
-
- f->name = basename(name);
- f->path = dirname(strdup(name));
- f->readonly = readonly;
-
- list_add_tail(&f->list, &extras);
-}
-
-int main(int argc, char **argv)
-{
- uid_t uid = getuid();
- char log[] = "/dev/log";
- char ubus[] = "/var/run/ubus.sock";
- int ret = EXIT_SUCCESS;
- int ch;
-
- if (uid) {
- ERROR("not root, aborting: %s\n", strerror(errno));
- return EXIT_FAILURE;
- }
-
- umask(022);
-
- while ((ch = getopt(argc, argv, OPT_ARGS)) != -1) {
- switch (ch) {
- case 'd':
- debug = atoi(optarg);
- break;
- case 'p':
- opts.namespace = 1;
- opts.procfs = 1;
- break;
- case 'o':
- opts.namespace = 1;
- opts.ronly = 1;
- break;
- case 's':
- opts.namespace = 1;
- opts.sysfs = 1;
- break;
- case 'S':
- opts.seccomp = optarg;
- add_extra(optarg, 1);
- break;
- case 'C':
- opts.capabilities = optarg;
- add_extra(optarg, 1);
- break;
- case 'P':
- opts.namespace = 1;
- opts.path = optarg;
- break;
- case 'n':
- opts.name = optarg;
- break;
- case 'r':
- opts.namespace = 1;
- add_extra(optarg, 1);
- break;
- case 'w':
- opts.namespace = 1;
- add_extra(optarg, 0);
- break;
- case 'u':
- opts.namespace = 1;
- add_extra(ubus, 0);
- break;
- case 'l':
- opts.namespace = 1;
- add_extra(log, 0);
- break;
- }
- }
-
- //no <binary> param found
- if (argc - optind < 1) {
- usage();
- return EXIT_FAILURE;
- }
- if (!(opts.namespace||opts.capabilities||opts.seccomp)) {
- ERROR("Not using namespaces, capabilities or seccomp !!!\n\n");
- usage();
- return EXIT_FAILURE;
- }
- DEBUG("Using namespaces(%d), capabilities(%d), seccomp(%d)\n",
- opts.namespace,
- opts.capabilities != 0,
- opts.seccomp != 0);
-
- opts.jail_argv = &argv[optind];
-
- if (opts.name)
- prctl(PR_SET_NAME, opts.name, NULL, NULL, NULL);
-
- if (opts.namespace && !opts.path && asprintf(&opts.path, "/tmp/%s", basename(*opts.jail_argv)) == -1) {
- ERROR("failed to asprintf root path: %s\n", strerror(errno));
- return EXIT_FAILURE;
- }
-
- if (opts.namespace && mkdir(opts.path, 0755)) {
- ERROR("unable to create root path: %s (%s)\n", opts.path, strerror(errno));
- return EXIT_FAILURE;
- }
-
- uloop_init();
- if (opts.namespace) {
- jail_process.pid = clone(spawn_jail,
- child_stack + STACK_SIZE,
- CLONE_NEWUTS | CLONE_NEWPID | CLONE_NEWNS | CLONE_NEWIPC | SIGCHLD, argv);
- } else {
- jail_process.pid = fork();
- }
-
- if (jail_process.pid > 0) {
- //parent process
- uloop_process_add(&jail_process);
- uloop_run();
- uloop_done();
- if (jail_running) {
- DEBUG("uloop interrupted, killing jail process\n");
- kill(jail_process.pid, SIGTERM);
- waitpid(jail_process.pid, NULL, 0);
- }
- } else if (jail_process.pid == 0) {
- //fork child process
- return exec_jail();
- } else {
- ERROR("failed to clone/fork: %s\n", strerror(errno));
- ret = EXIT_FAILURE;
- }
-
- if (opts.namespace && rmdir(opts.path)) {
- ERROR("Unable to remove root path: %s (%s)\n", opts.path, strerror(errno));
- ret = EXIT_FAILURE;
- }
-
- if (ret)
- return ret;
-
- return jail_return_code;
-}
diff --git a/jail/log.h b/jail/log.h
deleted file mode 100644
index b1d201e..0000000
--- a/jail/log.h
+++ /dev/null
@@ -1,27 +0,0 @@
-/*
- * Copyright (C) 2015 John Crispin <blogic@openwrt.org>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU Lesser General Public License version 2.1
- * as published by the Free Software Foundation
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- */
-
-extern int debug;
-#include <syslog.h>
-
-#define INFO(fmt, ...) do { \
- printf("jail: "fmt, ## __VA_ARGS__); \
- } while (0)
-#define ERROR(fmt, ...) do { \
- syslog(LOG_ERR, "jail: "fmt, ## __VA_ARGS__); \
- fprintf(stderr,"jail: "fmt, ## __VA_ARGS__); \
- } while (0)
-#define DEBUG(fmt, ...) do { \
- if (debug) printf("jail: "fmt, ## __VA_ARGS__); \
- } while (0)
-
diff --git a/jail/preload.c b/jail/preload.c
deleted file mode 100644
index a1cc0b6..0000000
--- a/jail/preload.c
+++ /dev/null
@@ -1,80 +0,0 @@
-/*
- * Copyright (C) 2015 John Crispin <blogic@openwrt.org>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU Lesser General Public License version 2.1
- * as published by the Free Software Foundation
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- */
-
-#define _GNU_SOURCE
-#include <sys/types.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <string.h>
-#include <dlfcn.h>
-#include <syslog.h>
-
-#include "seccomp.h"
-#include "../preload.h"
-
-static main_t __main__;
-
-static int __preload_main__(int argc, char **argv, char **envp)
-{
- char *env_file = getenv("SECCOMP_FILE");
-
- if (install_syscall_filter(*argv, env_file))
- return -1;
-
- unsetenv("LD_PRELOAD");
- unsetenv("SECCOMP_FILE");
-
- return (*__main__)(argc, argv, envp);
-}
-
-int __libc_start_main(main_t main,
- int argc,
- char **argv,
- ElfW(auxv_t) *auxvec,
- __typeof (main) init,
- void (*fini) (void),
- void (*rtld_fini) (void),
- void *stack_end)
-{
- start_main_t __start_main__;
-
- __start_main__ = dlsym(RTLD_NEXT, "__libc_start_main");
- if (!__start_main__)
- INFO("failed to find __libc_start_main %s\n", dlerror());
-
- __main__ = main;
-
- return (*__start_main__)(__preload_main__, argc, argv, auxvec,
- init, fini, rtld_fini, stack_end);
-}
-
-void __uClibc_main(main_t main,
- int argc,
- char **argv,
- void (*app_init)(void),
- void (*app_fini)(void),
- void (*rtld_fini)(void),
- void *stack_end attribute_unused)
-{
- uClibc_main __start_main__;
-
- __start_main__ = dlsym(RTLD_NEXT, "__uClibc_main");
- if (!__start_main__)
- INFO("failed to find __uClibc_main %s\n", dlerror());
-
- __main__ = main;
-
- return (*__start_main__)(__preload_main__, argc, argv,
- app_init, app_fini, rtld_fini, stack_end);
-}
diff --git a/jail/seccomp-bpf.h b/jail/seccomp-bpf.h
deleted file mode 100644
index 82c0669..0000000
--- a/jail/seccomp-bpf.h
+++ /dev/null
@@ -1,89 +0,0 @@
-/*
- * seccomp example for x86 (32-bit and 64-bit) with BPF macros
- *
- * Copyright (c) 2012 The Chromium OS Authors <chromium-os-dev@chromium.org>
- * Authors:
- * Will Drewry <wad@chromium.org>
- * Kees Cook <keescook@chromium.org>
- *
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-#ifndef _SECCOMP_BPF_H_
-#define _SECCOMP_BPF_H_
-
-#define _GNU_SOURCE 1
-#include <stdio.h>
-#include <stddef.h>
-#include <stdlib.h>
-#include <errno.h>
-#include <signal.h>
-#include <string.h>
-#include <unistd.h>
-#include <endian.h>
-
-#include <sys/prctl.h>
-#ifndef PR_SET_NO_NEW_PRIVS
-# define PR_SET_NO_NEW_PRIVS 38
-#endif
-
-#include <linux/unistd.h>
-#include <linux/audit.h>
-#include <linux/filter.h>
-
-#ifdef HAVE_LINUX_SECCOMP_H
-# include <linux/seccomp.h>
-#endif
-
-#ifndef SECCOMP_MODE_FILTER
-#define SECCOMP_MODE_FILTER 2 /* uses user-supplied filter. */
-#define SECCOMP_RET_KILL 0x00000000U /* kill the task immediately */
-#define SECCOMP_RET_TRAP 0x00030000U /* disallow and force a SIGSYS */
-#define SECCOMP_RET_ERRNO 0x00050000U /* returns an errno */
-#define SECCOMP_RET_LOG 0x00070000U
-#define SECCOMP_RET_ALLOW 0x7fff0000U /* allow */
-#define SECCOMP_RET_ERROR(x) (SECCOMP_RET_ERRNO | ((x) & 0x0000ffffU))
-#define SECCOMP_RET_LOGGER(x) (SECCOMP_RET_LOG | ((x) & 0x0000ffffU))
-
-struct seccomp_data {
- int nr;
- __u32 arch;
- __u64 instruction_pointer;
- __u64 args[6];
-};
-#endif
-
-#ifndef SYS_SECCOMP
-# define SYS_SECCOMP 1
-#endif
-
-#define syscall_nr (offsetof(struct seccomp_data, nr))
-#define arch_nr (offsetof(struct seccomp_data, arch))
-
-#if defined(__i386__)
-# define REG_SYSCALL REG_EAX
-# define ARCH_NR AUDIT_ARCH_I386
-#elif defined(__x86_64__)
-# define REG_SYSCALL REG_RAX
-# define ARCH_NR AUDIT_ARCH_X86_64
-#elif defined(__mips__)
-# define REG_SYSCALL regs[2]
-# if __BYTE_ORDER == __LITTLE_ENDIAN
-# define ARCH_NR AUDIT_ARCH_MIPSEL
-# else
-# define ARCH_NR AUDIT_ARCH_MIPS
-# endif
-#elif defined(__arm__) && (defined(__ARM_EABI__) || defined(__thumb__))
-# define REG_SYSCALL regs.uregs[7]
-# if __BYTE_ORDER == __LITTLE_ENDIAN
-# define ARCH_NR AUDIT_ARCH_ARM
-# else
-# define ARCH_NR AUDIT_ARCH_ARMEB
-# endif
-#else
-# warning "Platform does not support seccomp filter yet"
-# define REG_SYSCALL 0
-# define ARCH_NR 0
-#endif
-
-#endif /* _SECCOMP_BPF_H_ */
diff --git a/jail/seccomp.c b/jail/seccomp.c
deleted file mode 100644
index de01fc6..0000000
--- a/jail/seccomp.c
+++ /dev/null
@@ -1,142 +0,0 @@
-/*
- * seccomp example with syscall reporting
- *
- * Copyright (c) 2012 The Chromium OS Authors <chromium-os-dev@chromium.org>
- * Authors:
- * Kees Cook <keescook@chromium.org>
- * Will Drewry <wad@chromium.org>
- *
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-#define _GNU_SOURCE 1
-#include <stdio.h>
-#include <stddef.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <syslog.h>
-
-#include <libubox/utils.h>
-#include <libubox/blobmsg.h>
-#include <libubox/blobmsg_json.h>
-
-#include "seccomp-bpf.h"
-#include "seccomp.h"
-#include "../syscall-names.h"
-
-static int max_syscall = ARRAY_SIZE(syscall_names);
-
-static int find_syscall(const char *name)
-{
- int i;
-
- for (i = 0; i < max_syscall; i++)
- if (syscall_names[i] && !strcmp(syscall_names[i], name))
- return i;
-
- return -1;
-}
-
-static void set_filter(struct sock_filter *filter, __u16 code, __u8 jt, __u8 jf, __u32 k)
-{
- filter->code = code;
- filter->jt = jt;
- filter->jf = jf;
- filter->k = k;
-}
-
-int install_syscall_filter(const char *argv, const char *file)
-{
- enum {
- SECCOMP_WHITELIST,
- SECCOMP_POLICY,
- __SECCOMP_MAX
- };
- static const struct blobmsg_policy policy[__SECCOMP_MAX] = {
- [SECCOMP_WHITELIST] = { .name = "whitelist", .type = BLOBMSG_TYPE_ARRAY },
- [SECCOMP_POLICY] = { .name = "policy", .type = BLOBMSG_TYPE_INT32 },
- };
- struct blob_buf b = { 0 };
- struct blob_attr *tb[__SECCOMP_MAX];
- struct blob_attr *cur;
- int rem;
-
- struct sock_filter *filter;
- struct sock_fprog prog = { 0 };
- int sz = 5, idx = 0, default_policy = 0;
-
- INFO("%s: setting up syscall filter\n", argv);
-
- blob_buf_init(&b, 0);
- if (!blobmsg_add_json_from_file(&b, file)) {
- INFO("%s: failed to load %s\n", argv, file);
- return -1;
- }
-
- blobmsg_parse(policy, __SECCOMP_MAX, tb, blob_data(b.head), blob_len(b.head));
- if (!tb[SECCOMP_WHITELIST]) {
- INFO("%s: %s is missing the syscall table\n", argv, file);
- return -1;
- }
-
- if (tb[SECCOMP_POLICY])
- default_policy = blobmsg_get_u32(tb[SECCOMP_POLICY]);
-
- blobmsg_for_each_attr(cur, tb[SECCOMP_WHITELIST], rem)
- sz += 2;
-
- filter = calloc(sz, sizeof(struct sock_filter));
- if (!filter) {
- INFO("failed to allocate filter memory\n");
- return -1;
- }
-
- /* validate arch */
- set_filter(&filter[idx++], BPF_LD + BPF_W + BPF_ABS, 0, 0, arch_nr);
- set_filter(&filter[idx++], BPF_JMP + BPF_JEQ + BPF_K, 1, 0, ARCH_NR);
- set_filter(&filter[idx++], BPF_RET + BPF_K, 0, 0, SECCOMP_RET_KILL);
-
- /* get syscall */
- set_filter(&filter[idx++], BPF_LD + BPF_W + BPF_ABS, 0, 0, syscall_nr);
-
- blobmsg_for_each_attr(cur, tb[SECCOMP_WHITELIST], rem) {
- char *name = blobmsg_get_string(cur);
- int nr;
-
- if (!name) {
- INFO("%s: invalid syscall name\n", argv);
- continue;
- }
-
- nr = find_syscall(name);
- if (nr == -1) {
- INFO("%s: unknown syscall %s\n", argv, name);
- continue;
- }
-
- /* add whitelist */
- set_filter(&filter[idx++], BPF_JMP + BPF_JEQ + BPF_K, 0, 1, nr);
- set_filter(&filter[idx++], BPF_RET + BPF_K, 0, 0, SECCOMP_RET_ALLOW);
- }
-
- if (default_policy)
- /* return -1 and set errno */
- set_filter(&filter[idx], BPF_RET + BPF_K, 0, 0, SECCOMP_RET_LOGGER(default_policy));
- else
- /* kill the process */
- set_filter(&filter[idx], BPF_RET + BPF_K, 0, 0, SECCOMP_RET_KILL);
-
- if (prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0)) {
- INFO("%s: prctl(PR_SET_NO_NEW_PRIVS) failed: %s\n", argv, strerror(errno));
- return errno;
- }
-
- prog.len = (unsigned short) idx + 1;
- prog.filter = filter;
-
- if (prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &prog)) {
- INFO("%s: prctl(PR_SET_SECCOMP) failed: %s\n", argv, strerror(errno));
- return errno;
- }
- return 0;
-}
diff --git a/jail/seccomp.h b/jail/seccomp.h
deleted file mode 100644
index 45eede7..0000000
--- a/jail/seccomp.h
+++ /dev/null
@@ -1,19 +0,0 @@
-/*
- * Copyright (C) 2015 John Crispin <blogic@openwrt.org>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU Lesser General Public License version 2.1
- * as published by the Free Software Foundation
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- */
-
-#define INFO(fmt, ...) do { \
- syslog(LOG_INFO,"preload-seccomp: "fmt, ## __VA_ARGS__); \
- fprintf(stderr,"preload-seccomp: "fmt, ## __VA_ARGS__); \
- } while (0)
-
-int install_syscall_filter(const char *argv, const char *file);
diff --git a/libc-compat.h b/libc-compat.h
deleted file mode 100644
index 9435346..0000000
--- a/libc-compat.h
+++ /dev/null
@@ -1,10 +0,0 @@
-#ifndef __PROCD_LIBC_COMPAT_H
-#define __PROCD_LIBC_COMPAT_H
-
-#if defined(__GLIBC__) && !defined(__UCLIBC__)
-static inline int ignore(int x) {return x;}
-#else
-#define ignore(x) x
-#endif
-
-#endif
diff --git a/log.h b/log.h
index bf86f1e..c8c3929 100644
--- a/log.h
+++ b/log.h
@@ -1,6 +1,7 @@
/*
* Copyright (C) 2013 Felix Fietkau <nbd@openwrt.org>
* Copyright (C) 2013 John Crispin <blogic@openwrt.org>
+ * Copyright (C) 2015 Matthias Schiffer <mschiffer@universe-factory.net>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License version 2.1
diff --git a/make_capabilities_h.sh b/make_capabilities_h.sh
deleted file mode 100755
index 635e740..0000000
--- a/make_capabilities_h.sh
+++ /dev/null
@@ -1,10 +0,0 @@
-#!/bin/sh
-
-CC=$1
-[ -n "$TARGET_CC_NOCACHE" ] && CC=$TARGET_CC_NOCACHE
-
-echo "#include <linux/capability.h>"
-echo "static const char *capabilities_names[] = {"
-echo "#include <linux/capability.h>" | ${CC} -E -dM - | grep '#define CAP' | grep -vE '(CAP_TO|CAP_LAST_CAP)' | \
- awk '{print $3" "$2}' | sort -n | awk '{print " ["$1"]\t= \""tolower($2)"\","}'
-echo "};"
diff --git a/make_syscall_h.sh b/make_syscall_h.sh
deleted file mode 100755
index 3363bc7..0000000
--- a/make_syscall_h.sh
+++ /dev/null
@@ -1,18 +0,0 @@
-#!/bin/sh
-# syscall reporting example for seccomp
-#
-# Copyright (c) 2012 The Chromium OS Authors <chromium-os-dev@chromium.org>
-# Authors:
-# Kees Cook <keescook@chromium.org>
-#
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-CC=$1
-[ -n "$TARGET_CC_NOCACHE" ] && CC=$TARGET_CC_NOCACHE
-
-echo "#include <asm/unistd.h>"
-echo "static const char *syscall_names[] = {"
-echo "#include <sys/syscall.h>" | ${CC} -E -dM - | grep '^#define __NR_' | \
- LC_ALL=C sed -r -n -e 's/^\#define[ \t]+__NR_([a-z0-9_]+)[ \t]+([ ()+0-9a-zNR_Linux]+)(.*)/ [\2] = "\1",/p'
-echo "};"
diff --git a/plug/coldplug.c b/plug/coldplug.c
deleted file mode 100644
index 5fcb9a3..0000000
--- a/plug/coldplug.c
+++ /dev/null
@@ -1,69 +0,0 @@
-/*
- * Copyright (C) 2013 Felix Fietkau <nbd@openwrt.org>
- * Copyright (C) 2013 John Crispin <blogic@openwrt.org>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU Lesser General Public License version 2.1
- * as published by the Free Software Foundation
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- */
-
-#include <sys/stat.h>
-#include <sys/types.h>
-#include <sys/mount.h>
-
-#include <unistd.h>
-
-#include "../procd.h"
-#include "../libc-compat.h"
-
-#include "hotplug.h"
-
-static struct uloop_process udevtrigger;
-
-static void coldplug_complete(struct uloop_timeout *t)
-{
- DEBUG(4, "Coldplug complete\n");
- hotplug_last_event(NULL);
- procd_state_next();
-}
-
-static void udevtrigger_complete(struct uloop_process *proc, int ret)
-{
- DEBUG(4, "Finished udevtrigger\n");
- hotplug_last_event(coldplug_complete);
-}
-
-void procd_coldplug(void)
-{
- char *argv[] = { "udevtrigger", NULL };
- unsigned int oldumask = umask(0);
-
- umount2("/dev/pts", MNT_DETACH);
- umount2("/dev/", MNT_DETACH);
- mount("tmpfs", "/dev", "tmpfs", MS_NOSUID, "mode=0755,size=512K");
- ignore(symlink("/tmp/shm", "/dev/shm"));
- mkdir("/dev/pts", 0755);
- umask(oldumask);
- mount("devpts", "/dev/pts", "devpts", MS_NOEXEC | MS_NOSUID, 0);
- udevtrigger.cb = udevtrigger_complete;
- udevtrigger.pid = fork();
- if (!udevtrigger.pid) {
- execvp(argv[0], argv);
- ERROR("Failed to start coldplug\n");
- exit(-1);
- }
-
- if (udevtrigger.pid <= 0) {
- ERROR("Failed to start new coldplug instance\n");
- return;
- }
-
- uloop_process_add(&udevtrigger);
-
- DEBUG(4, "Launched coldplug instance, pid=%d\n", (int) udevtrigger.pid);
-}
diff --git a/plug/hotplug.c b/plug/hotplug.c
deleted file mode 100644
index b5ebd07..0000000
--- a/plug/hotplug.c
+++ /dev/null
@@ -1,610 +0,0 @@
-/*
- * Copyright (C) 2013 Felix Fietkau <nbd@openwrt.org>
- * Copyright (C) 2013 John Crispin <blogic@openwrt.org>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU Lesser General Public License version 2.1
- * as published by the Free Software Foundation
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- */
-
-#include <sys/stat.h>
-#include <sys/socket.h>
-#include <sys/types.h>
-
-#include <linux/types.h>
-#include <linux/netlink.h>
-
-#include <libubox/blobmsg_json.h>
-#include <libubox/json_script.h>
-#include <libubox/uloop.h>
-#include <json-c/json.h>
-
-#include <fcntl.h>
-#include <unistd.h>
-#include <stdlib.h>
-#include <libgen.h>
-
-#include "../procd.h"
-
-#include "hotplug.h"
-
-#define HOTPLUG_WAIT 500
-
-struct cmd_handler;
-struct cmd_queue {
- struct list_head list;
-
- struct blob_attr *msg;
- struct blob_attr *data;
- int timeout;
-
- void (*handler)(struct blob_attr *msg, struct blob_attr *data);
- void (*start)(struct blob_attr *msg, struct blob_attr *data);
- void (*complete)(struct blob_attr *msg, struct blob_attr *data, int ret);
-};
-
-struct button_timeout {
- struct list_head list;
- struct uloop_timeout timeout;
- char *name;
- int seen;
- struct blob_attr *data;
-};
-
-static LIST_HEAD(cmd_queue);
-static LIST_HEAD(button_timer);
-static struct uloop_process queue_proc;
-static struct uloop_timeout last_event;
-static struct blob_buf b, button_buf;
-static char *rule_file;
-static struct blob_buf script;
-static struct cmd_queue *current;
-
-static void queue_add(struct cmd_handler *h, struct blob_attr *msg, struct blob_attr *data);
-static void handle_button_complete(struct blob_attr *msg, struct blob_attr *data, int ret);
-
-static void button_free(struct button_timeout *b)
-{
- uloop_timeout_cancel(&b->timeout);
- list_del(&b->list);
- free(b->data);
- free(b->name);
- free(b);
-}
-
-static void button_timeout_remove(char *button)
-{
- struct button_timeout *b, *c;
-
- if (!list_empty(&button_timer)) list_for_each_entry_safe(b, c, &button_timer, list) {
- if (!strcmp(b->name, button))
- button_free(b);
- }
-}
-
-static char *hotplug_msg_find_var(struct blob_attr *msg, const char *name)
-{
- struct blob_attr *cur;
- int rem;
-
- blobmsg_for_each_attr(cur, msg, rem) {
- if (blobmsg_type(cur) != BLOBMSG_TYPE_STRING)
- continue;
-
- if (strcmp(blobmsg_name(cur), name) != 0)
- continue;
-
- return blobmsg_data(cur);
- }
-
- return NULL;
-}
-
-static void mkdir_p(char *dir)
-{
- char *l = strrchr(dir, '/');
-
- if (l) {
- *l = '\0';
- mkdir_p(dir);
- *l = '/';
- mkdir(dir, 0755);
- }
-}
-
-static void handle_makedev(struct blob_attr *msg, struct blob_attr *data)
-{
- unsigned int oldumask = umask(0);
- static struct blobmsg_policy mkdev_policy[2] = {
- { .type = BLOBMSG_TYPE_STRING },
- { .type = BLOBMSG_TYPE_STRING },
- };
- struct blob_attr *tb[2];
- char *minor = hotplug_msg_find_var(msg, "MINOR");
- char *major = hotplug_msg_find_var(msg, "MAJOR");
- char *subsystem = hotplug_msg_find_var(msg, "SUBSYSTEM");
-
- blobmsg_parse_array(mkdev_policy, 2, tb, blobmsg_data(data), blobmsg_data_len(data));
- if (tb[0] && tb[1] && minor && major && subsystem) {
- mode_t m = S_IFCHR;
- char *d = strdup(blobmsg_get_string(tb[0]));
-
- d = dirname(d);
- mkdir_p(d);
- free(d);
-
- if (!strcmp(subsystem, "block"))
- m = S_IFBLK;
- mknod(blobmsg_get_string(tb[0]),
- m | strtoul(blobmsg_data(tb[1]), NULL, 8),
- makedev(atoi(major), atoi(minor)));
- }
- umask(oldumask);
-}
-
-static void handle_rm(struct blob_attr *msg, struct blob_attr *data)
-{
- static struct blobmsg_policy rm_policy = {
- .type = BLOBMSG_TYPE_STRING,
- };
- struct blob_attr *tb;
-
- blobmsg_parse_array(&rm_policy, 1, &tb, blobmsg_data(data), blobmsg_data_len(data));
- if (tb)
- unlink(blobmsg_data(tb));
-}
-
-static void handle_exec(struct blob_attr *msg, struct blob_attr *data)
-{
- char *argv[8];
- struct blob_attr *cur;
- int rem, fd;
- int i = 0;
-
- blobmsg_for_each_attr(cur, msg, rem)
- setenv(blobmsg_name(cur), blobmsg_data(cur), 1);
-
- blobmsg_for_each_attr(cur, data, rem) {
- argv[i] = blobmsg_data(cur);
- i++;
- if (i == 7)
- break;
- }
-
- if (debug < 3) {
- fd = open("/dev/null", O_RDWR);
- if (fd > -1) {
- dup2(fd, STDIN_FILENO);
- dup2(fd, STDOUT_FILENO);
- dup2(fd, STDERR_FILENO);
- if (fd > STDERR_FILENO)
- close(fd);
- }
- }
-
- if (i > 0) {
- argv[i] = NULL;
- execvp(argv[0], &argv[0]);
- }
- exit(-1);
-}
-
-static void handle_button_start(struct blob_attr *msg, struct blob_attr *data)
-{
- char *button = hotplug_msg_find_var(msg, "BUTTON");
-
- if (button)
- button_timeout_remove(button);
-}
-
-static void handle_firmware(struct blob_attr *msg, struct blob_attr *data)
-{
- char *dir = blobmsg_get_string(blobmsg_data(data));
- char *file = hotplug_msg_find_var(msg, "FIRMWARE");
- char *dev = hotplug_msg_find_var(msg, "DEVPATH");
- struct stat s = { 0 };
- char *path, loadpath[256], syspath[256];
- int fw, src, load, len;
- static char buf[4096];
-
- DEBUG(2, "Firmware request for %s/%s\n", dir, file);
-
- if (!file || !dir || !dev) {
- ERROR("Request for unknown firmware %s/%s\n", dir, file);
- exit(-1);
- }
-
- path = alloca(strlen(dir) + strlen(file) + 2);
- sprintf(path, "%s/%s", dir, file);
-
- if (stat(path, &s)) {
- ERROR("Could not find firmware %s\n", path);
- src = -1;
- s.st_size = 0;
- goto send_to_kernel;
- }
-
- src = open(path, O_RDONLY);
- if (src < 0) {
- ERROR("Failed to open %s\n", path);
- s.st_size = 0;
- goto send_to_kernel;
- }
-
-send_to_kernel:
- snprintf(loadpath, sizeof(loadpath), "/sys/%s/loading", dev);
- load = open(loadpath, O_WRONLY);
- if (!load) {
- ERROR("Failed to open %s\n", loadpath);
- exit(-1);
- }
- if (write(load, "1", 1) == -1) {
- ERROR("Failed to write to %s\n", loadpath);
- exit(-1);
- }
- close(load);
-
- snprintf(syspath, sizeof(syspath), "/sys/%s/data", dev);
- fw = open(syspath, O_WRONLY);
- if (fw < 0) {
- ERROR("Failed to open %s\n", syspath);
- exit(-1);
- }
-
- len = s.st_size;
- while (len) {
- len = read(src, buf, sizeof(buf));
- if (len <= 0)
- break;
-
- if (write(fw, buf, len) == -1) {
- ERROR("failed to write firmware file %s/%s to %s\n", dir, file, dev);
- break;
- }
- }
-
- if (src >= 0)
- close(src);
- close(fw);
-
- load = open(loadpath, O_WRONLY);
- if (write(load, "0", 1) == -1)
- ERROR("failed to write to %s\n", loadpath);
- close(load);
-
- DEBUG(2, "Done loading %s\n", path);
-
- exit(-1);
-}
-
-enum {
- HANDLER_MKDEV = 0,
- HANDLER_RM,
- HANDLER_EXEC,
- HANDLER_BUTTON,
- HANDLER_FW,
-};
-
-static struct cmd_handler {
- char *name;
- int atomic;
- void (*handler)(struct blob_attr *msg, struct blob_attr *data);
- void (*start)(struct blob_attr *msg, struct blob_attr *data);
- void (*complete)(struct blob_attr *msg, struct blob_attr *data, int ret);
-} handlers[] = {
- [HANDLER_MKDEV] = {
- .name = "makedev",
- .atomic = 1,
- .handler = handle_makedev,
- },
- [HANDLER_RM] = {
- .name = "rm",
- .atomic = 1,
- .handler = handle_rm,
- },
- [HANDLER_EXEC] = {
- .name = "exec",
- .handler = handle_exec,
- },
- [HANDLER_BUTTON] = {
- .name = "button",
- .handler = handle_exec,
- .start = handle_button_start,
- .complete = handle_button_complete,
- },
- [HANDLER_FW] = {
- .name = "load-firmware",
- .handler = handle_firmware,
- },
-};
-
-static void queue_next(void)
-{
- struct cmd_queue *c;
-
- if (queue_proc.pending || list_empty(&cmd_queue))
- return;
-
- c = list_first_entry(&cmd_queue, struct cmd_queue, list);
-
- queue_proc.pid = fork();
- if (!queue_proc.pid) {
- uloop_done();
- c->handler(c->msg, c->data);
- exit(0);
- }
- if (c->start)
- c->start(c->msg, c->data);
- list_del(&c->list);
- if (c->complete)
- current = c;
- else
- free(c);
- if (queue_proc.pid <= 0) {
- queue_next();
- return;
- }
-
- uloop_process_add(&queue_proc);
-
- DEBUG(4, "Launched hotplug exec instance, pid=%d\n", (int) queue_proc.pid);
-}
-
-static void queue_proc_cb(struct uloop_process *c, int ret)
-{
- DEBUG(4, "Finished hotplug exec instance, pid=%d\n", (int) c->pid);
-
- if (current) {
- current->complete(current->msg, current->data, ret);
- free(current);
- current = NULL;
- }
- queue_next();
-}
-
-static void queue_add(struct cmd_handler *h, struct blob_attr *msg, struct blob_attr *data)
-{
- struct cmd_queue *c = NULL;
- struct blob_attr *_msg, *_data;
-
- c = calloc_a(sizeof(struct cmd_queue),
- &_msg, blob_pad_len(msg),
- &_data, blob_pad_len(data),
- NULL);
-
- c->msg = _msg;
- c->data = _data;
-
- if (!c)
- return;
-
- memcpy(c->msg, msg, blob_pad_len(msg));
- memcpy(c->data, data, blob_pad_len(data));
- c->handler = h->handler;
- c->complete = h->complete;
- c->start = h->start;
- list_add_tail(&c->list, &cmd_queue);
- queue_next();
-}
-
-static void handle_button_timeout(struct uloop_timeout *t)
-{
- struct button_timeout *b;
- char seen[16];
-
- b = container_of(t, struct button_timeout, timeout);
- blob_buf_init(&button_buf, 0);
- blobmsg_add_string(&button_buf, "BUTTON", b->name);
- blobmsg_add_string(&button_buf, "ACTION", "timeout");
- snprintf(seen, sizeof(seen), "%d", b->seen);
- blobmsg_add_string(&button_buf, "SEEN", seen);
- queue_add(&handlers[HANDLER_EXEC], button_buf.head, b->data);
- button_free(b);
-}
-
-static void handle_button_complete(struct blob_attr *msg, struct blob_attr *data, int ret)
-{
- char *name = hotplug_msg_find_var(msg, "BUTTON");
- struct button_timeout *b;
- int timeout = ret >> 8;
-
- if (!timeout)
- return;
-
- b = malloc(sizeof(*b));
- if (!b || !name)
- return;
-
- memset(b, 0, sizeof(*b));
-
- b->data = malloc(blob_pad_len(data));
- b->name = strdup(name);
- b->seen = timeout;
-
- memcpy(b->data, data, blob_pad_len(data));
- b->timeout.cb = handle_button_timeout;
-
- uloop_timeout_set(&b->timeout, timeout * 1000);
- list_add(&b->list, &button_timer);
-}
-
-static const char* rule_handle_var(struct json_script_ctx *ctx, const char *name, struct blob_attr *vars)
-{
- const char *str, *sep;
-
- if (!strcmp(name, "DEVICENAME") || !strcmp(name, "DEVNAME")) {
- str = json_script_find_var(ctx, vars, "DEVPATH");
- if (!str)
- return NULL;
-
- sep = strrchr(str, '/');
- if (sep)
- return sep + 1;
-
- return str;
- }
-
- return NULL;
-}
-
-static struct json_script_file *
-rule_handle_file(struct json_script_ctx *ctx, const char *name)
-{
- json_object *obj;
-
- obj = json_object_from_file((char*)name);
- if (!obj)
- return NULL;
-
- blob_buf_init(&script, 0);
- blobmsg_add_json_element(&script, "", obj);
-
- return json_script_file_from_blobmsg(name, blob_data(script.head), blob_len(script.head));
-}
-
-static void rule_handle_command(struct json_script_ctx *ctx, const char *name,
- struct blob_attr *data, struct blob_attr *vars)
-{
- struct blob_attr *cur;
- int rem, i;
-
- if (debug > 3) {
- DEBUG(4, "Command: %s", name);
- blobmsg_for_each_attr(cur, data, rem)
- DEBUG(4, " %s", (char *) blobmsg_data(cur));
- DEBUG(4, "\n");
-
- DEBUG(4, "Message:");
- blobmsg_for_each_attr(cur, vars, rem)
- DEBUG(4, " %s=%s", blobmsg_name(cur), (char *) blobmsg_data(cur));
- DEBUG(4, "\n");
- }
-
- for (i = 0; i < ARRAY_SIZE(handlers); i++)
- if (!strcmp(handlers[i].name, name)) {
- if (handlers[i].atomic)
- handlers[i].handler(vars, data);
- else
- queue_add(&handlers[i], vars, data);
- break;
- }
-
- if (last_event.cb)
- uloop_timeout_set(&last_event, HOTPLUG_WAIT);
-}
-
-static void rule_handle_error(struct json_script_ctx *ctx, const char *msg,
- struct blob_attr *context)
-{
- char *s;
-
- s = blobmsg_format_json(context, false);
- ERROR("ERROR: %s in block: %s\n", msg, s);
- free(s);
-}
-
-static struct json_script_ctx jctx = {
- .handle_var = rule_handle_var,
- .handle_error = rule_handle_error,
- .handle_command = rule_handle_command,
- .handle_file = rule_handle_file,
-};
-
-static void hotplug_handler_debug(struct blob_attr *data)
-{
- char *str;
-
- if (debug < 3)
- return;
-
- str = blobmsg_format_json(data, true);
- DEBUG(3, "%s\n", str);
- free(str);
-}
-
-static void hotplug_handler(struct uloop_fd *u, unsigned int ev)
-{
- int i = 0;
- static char buf[4096];
- int len = recv(u->fd, buf, sizeof(buf), MSG_DONTWAIT);
- void *index;
- if (len < 1)
- return;
-
- blob_buf_init(&b, 0);
- index = blobmsg_open_table(&b, NULL);
- while (i < len) {
- int l = strlen(buf + i) + 1;
- char *e = strstr(&buf[i], "=");
-
- if (e) {
- *e = '\0';
- blobmsg_add_string(&b, &buf[i], &e[1]);
- }
- i += l;
- }
- blobmsg_close_table(&b, index);
- hotplug_handler_debug(b.head);
- json_script_run(&jctx, rule_file, blob_data(b.head));
-}
-
-static struct uloop_fd hotplug_fd = {
- .cb = hotplug_handler,
-};
-
-void hotplug_last_event(uloop_timeout_handler handler)
-{
- last_event.cb = handler;
- if (handler)
- uloop_timeout_set(&last_event, HOTPLUG_WAIT);
- else
- uloop_timeout_cancel(&last_event);
-}
-
-void hotplug(char *rules)
-{
- struct sockaddr_nl nls;
- int nlbufsize = 512 * 1024;
-
- rule_file = strdup(rules);
- memset(&nls,0,sizeof(struct sockaddr_nl));
- nls.nl_family = AF_NETLINK;
- nls.nl_pid = getpid();
- nls.nl_groups = -1;
-
- if ((hotplug_fd.fd = socket(PF_NETLINK, SOCK_DGRAM | SOCK_CLOEXEC, NETLINK_KOBJECT_UEVENT)) == -1) {
- ERROR("Failed to open hotplug socket: %s\n", strerror(errno));
- exit(1);
- }
- if (bind(hotplug_fd.fd, (void *)&nls, sizeof(struct sockaddr_nl))) {
- ERROR("Failed to bind hotplug socket: %s\n", strerror(errno));
- exit(1);
- }
-
- if (setsockopt(hotplug_fd.fd, SOL_SOCKET, SO_RCVBUFFORCE, &nlbufsize, sizeof(nlbufsize)))
- ERROR("Failed to resize receive buffer: %s\n", strerror(errno));
-
- json_script_init(&jctx);
- queue_proc.cb = queue_proc_cb;
- uloop_fd_add(&hotplug_fd, ULOOP_READ);
-}
-
-int hotplug_run(char *rules)
-{
- uloop_init();
- hotplug(rules);
- uloop_run();
-
- return 0;
-}
-
-void hotplug_shutdown(void)
-{
- uloop_fd_delete(&hotplug_fd);
- close(hotplug_fd.fd);
-}
diff --git a/plug/hotplug.h b/plug/hotplug.h
deleted file mode 100644
index 2a44442..0000000
--- a/plug/hotplug.h
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- * Copyright (C) 2013 Felix Fietkau <nbd@openwrt.org>
- * Copyright (C) 2013 John Crispin <blogic@openwrt.org>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU Lesser General Public License version 2.1
- * as published by the Free Software Foundation
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- */
-
-#ifndef __PROCD_HOTPLUG_H
-#define __PROCD_HOTPLUG_H
-
-#include <libubox/uloop.h>
-
-void hotplug(char *rules);
-int hotplug_run(char *rules);
-void hotplug_shutdown(void);
-void hotplug_last_event(uloop_timeout_handler handler);
-
-#endif
diff --git a/plug/udevtrigger.c b/plug/udevtrigger.c
deleted file mode 100644
index 5013189..0000000
--- a/plug/udevtrigger.c
+++ /dev/null
@@ -1,264 +0,0 @@
-/*
- * Copyright (C) 2004-2006 Kay Sievers <kay@vrfy.org>
- * Copyright (C) 2006 Hannes Reinecke <hare@suse.de>
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation version 2 of the License.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- */
-
-#include <stdlib.h>
-#include <stddef.h>
-#include <stdarg.h>
-#include <stdio.h>
-#include <stdbool.h>
-#include <unistd.h>
-#include <getopt.h>
-#include <errno.h>
-#include <dirent.h>
-#include <fcntl.h>
-#include <syslog.h>
-#include <sys/stat.h>
-#include <sys/types.h>
-#include <string.h>
-
-#define PATH_SIZE 512
-
-#ifndef strlcpy
-#define strlcpy(d,s,l) (strncpy(d,s,l), (d)[(l)-1] = '\0')
-#endif
-
-#ifndef strlcat
-#define strlcat(d,s,l) strncat(d,s,(l)-strlen(d)-1)
-#endif
-
-static int verbose;
-static int dry_run;
-
-static void log_message(int priority, const char *format, ...)
-{
- va_list args;
-
- va_start(args, format);
- vsyslog(priority, format, args);
- va_end(args);
-}
-
-#undef err
-#define err(format, arg...) \
- do { \
- log_message(LOG_ERR ,"%s: " format ,__FUNCTION__ ,## arg); \
- } while (0)
-
-#undef info
-#define info(format, arg...) \
- do { \
- log_message(LOG_INFO ,"%s: " format ,__FUNCTION__ ,## arg); \
- } while (0)
-
-#ifdef DEBUG
-#undef dbg
-#define dbg(format, arg...) \
- do { \
- log_message(LOG_DEBUG ,"%s: " format ,__FUNCTION__ ,## arg); \
- } while (0)
-#else
-#define dbg(...) do {} while(0)
-#endif
-
-
-static void trigger_uevent(const char *devpath)
-{
- char filename[PATH_SIZE];
- int fd;
-
- strlcpy(filename, "/sys", sizeof(filename));
- strlcat(filename, devpath, sizeof(filename));
- strlcat(filename, "/uevent", sizeof(filename));
-
- if (verbose)
- printf("%s\n", devpath);
-
- if (dry_run)
- return;
-
- fd = open(filename, O_WRONLY);
- if (fd < 0) {
- dbg("error on opening %s: %s\n", filename, strerror(errno));
- return;
- }
-
- if (write(fd, "add", 3) < 0)
- info("error on triggering %s: %s\n", filename, strerror(errno));
-
- close(fd);
-}
-
-static int sysfs_resolve_link(char *devpath, size_t size)
-{
- char link_path[PATH_SIZE];
- char link_target[PATH_SIZE];
- int len;
- int i;
- int back;
-
- strlcpy(link_path, "/sys", sizeof(link_path));
- strlcat(link_path, devpath, sizeof(link_path));
- len = readlink(link_path, link_target, sizeof(link_target));
- if (len <= 0)
- return -1;
- link_target[len] = '\0';
- dbg("path link '%s' points to '%s'", devpath, link_target);
-
- for (back = 0; strncmp(&link_target[back * 3], "../", 3) == 0; back++)
- ;
- dbg("base '%s', tail '%s', back %i", devpath, &link_target[back * 3], back);
- for (i = 0; i <= back; i++) {
- char *pos = strrchr(devpath, '/');
-
- if (pos == NULL)
- return -1;
- pos[0] = '\0';
- }
- dbg("after moving back '%s'", devpath);
- strlcat(devpath, "/", size);
- strlcat(devpath, &link_target[back * 3], size);
- return 0;
-}
-
-static bool device_has_attribute(const char *path, const char *attr,
- mode_t mode)
-{
- char filename[PATH_SIZE];
- struct stat statbuf;
-
- strlcpy(filename, path, sizeof(filename));
- strlcat(filename, attr, sizeof(filename));
-
- if (stat(filename, &statbuf) < 0)
- return false;
-
- if (!(statbuf.st_mode & mode))
- return false;
-
- return true;
-}
-
-static int device_list_insert(const char *path)
-{
- char devpath[PATH_SIZE];
- struct stat statbuf;
-
- dbg("add '%s'" , path);
-
- /* we only have a device, if we have a dev and an uevent file */
- if (!device_has_attribute(path, "/dev", S_IRUSR) ||
- !device_has_attribute(path, "/uevent", S_IWUSR))
- return -1;
-
- strlcpy(devpath, &path[4], sizeof(devpath));
-
- /* resolve possible link to real target */
- if (lstat(path, &statbuf) < 0)
- return -1;
- if (S_ISLNK(statbuf.st_mode))
- if (sysfs_resolve_link(devpath, sizeof(devpath)) != 0)
- return -1;
-
- trigger_uevent(devpath);
- return 0;
-}
-
-static void scan_subdir(const char *base, const char *subdir,
- bool insert, int depth)
-{
- DIR *dir;
- struct dirent *dent;
-
- dir = opendir(base);
- if (dir == NULL)
- return;
-
- for (dent = readdir(dir); dent != NULL; dent = readdir(dir)) {
- char dirname[PATH_SIZE];
-
- if (dent->d_name[0] == '.')
- continue;
-
- strlcpy(dirname, base, sizeof(dirname));
- strlcat(dirname, "/", sizeof(dirname));
- strlcat(dirname, dent->d_name, sizeof(dirname));
-
- if (insert) {
- int err;
-
- err = device_list_insert(dirname);
- if (err)
- continue;
- }
-
- if (subdir)
- strlcat(dirname, subdir, sizeof(base));
-
- if (depth)
- scan_subdir(dirname, NULL, true, depth - 1);
- }
-
- closedir(dir);
-}
-
-int main(int argc, char *argv[], char *envp[])
-{
- struct stat statbuf;
- int option;
-
- openlog("udevtrigger", LOG_PID | LOG_CONS, LOG_DAEMON);
-
- while (1) {
- option = getopt(argc, argv, "vnh");
- if (option == -1)
- break;
-
- switch (option) {
- case 'v':
- verbose = 1;
- break;
- case 'n':
- dry_run = 1;
- break;
- case 'h':
- printf("Usage: udevtrigger OPTIONS\n"
- " -v print the list of devices while running\n"
- " -n do not actually trigger the events\n"
- " -h print this text\n"
- "\n");
- goto exit;
- default:
- goto exit;
- }
- }
-
-
- /* if we have /sys/subsystem, forget all the old stuff */
- scan_subdir("/sys/bus", "/devices", false, 1);
- scan_subdir("/sys/class", NULL, false, 1);
-
- /* scan "block" if it isn't a "class" */
- if (stat("/sys/class/block", &statbuf) != 0)
- scan_subdir("/sys/block", NULL, true, 1);
-
-exit:
-
- closelog();
- return 0;
-}
diff --git a/preload.h b/preload.h
deleted file mode 100644
index 5e663ac..0000000
--- a/preload.h
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
- * Copyright (C) 2015 John Crispin <blogic@openwrt.org>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU Lesser General Public License version 2.1
- * as published by the Free Software Foundation
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- */
-
-#include <link.h>
-
-#ifndef __unbounded
-#define __unbounded
-#endif
-
-#ifndef attribute_unused
-#define attribute_unused __attribute__ ((unused))
-#endif
-typedef int (*main_t)(int, char **, char **);
-
-typedef int (*start_main_t)(main_t main, int, char *__unbounded *__unbounded,
- ElfW(auxv_t) *,
- __typeof (main),
- void (*fini) (void),
- void (*rtld_fini) (void),
- void *__unbounded stack_end);
-
-int __libc_start_main(main_t main,
- int argc,
- char **argv,
- ElfW(auxv_t) *auxvec,
- __typeof (main) init,
- void (*fini) (void),
- void (*rtld_fini) (void),
- void *stack_end);
-
-
-typedef void (*uClibc_main)(main_t main,
- int argc,
- char **argv,
- void (*app_init)(void),
- void (*app_fini)(void),
- void (*rtld_fini)(void),
- void *stack_end attribute_unused);
-
-void __uClibc_main(main_t main,
- int argc,
- char **argv,
- void (*app_init)(void),
- void (*app_fini)(void),
- void (*rtld_fini)(void),
- void *stack_end attribute_unused);
diff --git a/procd.c b/procd.c
index e41d98a..a82d9a5 100644
--- a/procd.c
+++ b/procd.c
@@ -1,6 +1,7 @@
/*
* Copyright (C) 2013 Felix Fietkau <nbd@openwrt.org>
* Copyright (C) 2013 John Crispin <blogic@openwrt.org>
+ * Copyright (C) 2015 Matthias Schiffer <mschiffer@universe-factory.net>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License version 2.1
@@ -23,16 +24,14 @@
#include "procd.h"
#include "watchdog.h"
-#include "plug/hotplug.h"
-unsigned int debug;
+unsigned int debug = 4;
static int usage(const char *prog)
{
ERROR("Usage: %s [options]\n"
"Options:\n"
"\t-s <path>\tPath to ubus socket\n"
- "\t-h <path>\trun as hotplug daemon\n"
"\t-d <level>\tEnable debug messages\n"
"\n", prog);
return 1;
@@ -41,19 +40,15 @@ static int usage(const char *prog)
int main(int argc, char **argv)
{
int ch;
- char *dbglvl = getenv("DBGLVL");
+ if (getpid() != 1) {
+ fprintf(stderr, "error: must run as PID 1\n");
+ return 1;
+ }
ulog_open(ULOG_KMSG, LOG_DAEMON, "procd");
- if (dbglvl) {
- debug = atoi(dbglvl);
- unsetenv("DBGLVL");
- }
-
- while ((ch = getopt(argc, argv, "d:s:h:")) != -1) {
+ while ((ch = getopt(argc, argv, "d:s:")) != -1) {
switch (ch) {
- case 'h':
- return hotplug_run(optarg);
case 's':
ubus_socket = optarg;
break;
@@ -68,10 +63,7 @@ int main(int argc, char **argv)
uloop_init();
procd_signal();
trigger_init();
- if (getpid() != 1)
- procd_connect_ubus();
- else
- procd_state_next();
+ procd_state_next();
uloop_run();
uloop_done();
diff --git a/procd.h b/procd.h
index 66d183c..eeb2889 100644
--- a/procd.h
+++ b/procd.h
@@ -1,6 +1,7 @@
/*
* Copyright (C) 2013 Felix Fietkau <nbd@openwrt.org>
* Copyright (C) 2013 John Crispin <blogic@openwrt.org>
+ * Copyright (C) 2015 Matthias Schiffer <mschiffer@universe-factory.net>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License version 2.1
@@ -29,6 +30,8 @@
extern char *ubus_socket;
extern int upgrade_running;
+void procd_early(void);
+
void procd_connect_ubus(void);
void procd_reconnect_ubus(int reconnect);
void ubus_init_service(struct ubus_context *ctx);
diff --git a/rcS.c b/rcS.c
index 1e38d39..fae30c7 100644
--- a/rcS.c
+++ b/rcS.c
@@ -2,6 +2,7 @@
* runqueue-example.c
*
* Copyright (C) 2013 Felix Fietkau <nbd@openwrt.org>
+ * Copyright (C) 2015 Matthias Schiffer <mschiffer@universe-factory.net>
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
diff --git a/rcS.h b/rcS.h
index 91d37d1..a5be019 100644
--- a/rcS.h
+++ b/rcS.h
@@ -1,6 +1,7 @@
/*
* Copyright (C) 2013 Felix Fietkau <nbd@openwrt.org>
* Copyright (C) 2013 John Crispin <blogic@openwrt.org>
+ * Copyright (C) 2015 Matthias Schiffer <mschiffer@universe-factory.net>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License version 2.1
diff --git a/service/instance.c b/service/instance.c
index 40ff021..3c98ff7 100644
--- a/service/instance.c
+++ b/service/instance.c
@@ -1,6 +1,7 @@
/*
* Copyright (C) 2013 Felix Fietkau <nbd@openwrt.org>
* Copyright (C) 2013 John Crispin <blogic@openwrt.org>
+ * Copyright (C) 2015 Matthias Schiffer <mschiffer@universe-factory.net>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License version 2.1
diff --git a/service/instance.h b/service/instance.h
index 3fb33e9..cdf0bf7 100644
--- a/service/instance.h
+++ b/service/instance.h
@@ -1,6 +1,7 @@
/*
* Copyright (C) 2013 Felix Fietkau <nbd@openwrt.org>
* Copyright (C) 2013 John Crispin <blogic@openwrt.org>
+ * Copyright (C) 2015 Matthias Schiffer <mschiffer@universe-factory.net>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License version 2.1
diff --git a/service/service.c b/service/service.c
index 2702dc3..90f4d7c 100644
--- a/service/service.c
+++ b/service/service.c
@@ -1,6 +1,7 @@
/*
* Copyright (C) 2013 Felix Fietkau <nbd@openwrt.org>
* Copyright (C) 2013 John Crispin <blogic@openwrt.org>
+ * Copyright (C) 2015 Matthias Schiffer <mschiffer@universe-factory.net>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License version 2.1
@@ -83,7 +84,6 @@ service_alloc(const char *name)
s->instances.keep_old = true;
s->name = new_name;
s->avl.key = s->name;
- INIT_LIST_HEAD(&s->validators);
return s;
}
@@ -93,7 +93,6 @@ enum {
SERVICE_SET_SCRIPT,
SERVICE_SET_INSTANCES,
SERVICE_SET_TRIGGER,
- SERVICE_SET_VALIDATE,
__SERVICE_SET_MAX
};
@@ -102,7 +101,6 @@ static const struct blobmsg_policy service_set_attrs[__SERVICE_SET_MAX] = {
[SERVICE_SET_SCRIPT] = { "script", BLOBMSG_TYPE_STRING },
[SERVICE_SET_INSTANCES] = { "instances", BLOBMSG_TYPE_TABLE },
[SERVICE_SET_TRIGGER] = { "triggers", BLOBMSG_TYPE_ARRAY },
- [SERVICE_SET_VALIDATE] = { "validate", BLOBMSG_TYPE_ARRAY },
};
static int
@@ -117,8 +115,6 @@ service_update(struct service *s, struct blob_attr **tb, bool add)
s->trigger = NULL;
}
- service_validate_del(s);
-
if (tb[SERVICE_SET_TRIGGER] && blobmsg_data_len(tb[SERVICE_SET_TRIGGER])) {
s->trigger = blob_memdup(tb[SERVICE_SET_TRIGGER]);
if (!s->trigger)
@@ -126,11 +122,6 @@ service_update(struct service *s, struct blob_attr **tb, bool add)
trigger_add(s->trigger, s);
}
- if (tb[SERVICE_SET_VALIDATE] && blobmsg_data_len(tb[SERVICE_SET_VALIDATE])) {
- blobmsg_for_each_attr(cur, tb[SERVICE_SET_VALIDATE], rem)
- service_validate_add(s, cur);
- }
-
if (tb[SERVICE_SET_INSTANCES]) {
if (!add)
vlist_update(&s->instances);
@@ -155,7 +146,6 @@ service_delete(struct service *s)
trigger_del(s);
free(s->trigger);
free(s);
- service_validate_del(s);
}
enum {
@@ -201,19 +191,6 @@ static const struct blobmsg_policy event_policy[__EVENT_MAX] = {
};
enum {
- VALIDATE_PACKAGE,
- VALIDATE_TYPE,
- VALIDATE_SERVICE,
- __VALIDATE_MAX
-};
-
-static const struct blobmsg_policy validate_policy[__VALIDATE_MAX] = {
- [VALIDATE_PACKAGE] = { .name = "package", .type = BLOBMSG_TYPE_STRING },
- [VALIDATE_TYPE] = { .name = "type", .type = BLOBMSG_TYPE_STRING },
- [VALIDATE_SERVICE] = { .name = "service", .type = BLOBMSG_TYPE_STRING },
-};
-
-enum {
DATA_NAME,
DATA_INSTANCE,
DATA_TYPE,
@@ -282,8 +259,6 @@ service_dump(struct service *s, bool verbose)
}
if (verbose && s->trigger)
blobmsg_add_blob(&b, s->trigger);
- if (verbose && !list_empty(&s->validators))
- service_validate_dump(&b, s);
blobmsg_close_table(&b, c);
}
@@ -399,34 +374,6 @@ service_handle_event(struct ubus_context *ctx, struct ubus_object *obj,
}
static int
-service_handle_validate(struct ubus_context *ctx, struct ubus_object *obj,
- struct ubus_request_data *req, const char *method,
- struct blob_attr *msg)
-{
- struct blob_attr *tb[__VALIDATE_MAX];
- char *p = NULL, *t = NULL;
-
- if (!msg)
- return UBUS_STATUS_INVALID_ARGUMENT;
-
- blobmsg_parse(validate_policy, __VALIDATE_MAX, tb, blob_data(msg), blob_len(msg));
- if (tb[VALIDATE_SERVICE]) {
- return 0;
- }
- if (tb[VALIDATE_PACKAGE])
- p = blobmsg_get_string(tb[VALIDATE_PACKAGE]);
-
- if (tb[VALIDATE_TYPE])
- t = blobmsg_get_string(tb[VALIDATE_TYPE]);
-
- blob_buf_init(&b, 0);
- service_validate_dump_all(&b, p, t);
- ubus_send_reply(ctx, req, b.head);
-
- return 0;
-}
-
-static int
service_get_data(struct ubus_context *ctx, struct ubus_object *obj,
struct ubus_request_data *req, const char *method,
struct blob_attr *msg)
@@ -493,7 +440,6 @@ static struct ubus_method main_object_methods[] = {
UBUS_METHOD("update_start", service_handle_update, service_attrs),
UBUS_METHOD("update_complete", service_handle_update, service_attrs),
UBUS_METHOD("event", service_handle_event, event_policy),
- UBUS_METHOD("validate", service_handle_validate, validate_policy),
UBUS_METHOD("get_data", service_get_data, get_data_policy),
};
@@ -557,6 +503,5 @@ void
service_init(void)
{
avl_init(&services, avl_strcmp, false, NULL);
- service_validate_init();
}
diff --git a/service/service.h b/service/service.h
index 892a147..e346058 100644
--- a/service/service.h
+++ b/service/service.h
@@ -1,6 +1,7 @@
/*
* Copyright (C) 2013 Felix Fietkau <nbd@openwrt.org>
* Copyright (C) 2013 John Crispin <blogic@openwrt.org>
+ * Copyright (C) 2015 Matthias Schiffer <mschiffer@universe-factory.net>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License version 2.1
@@ -27,31 +28,15 @@ struct vrule {
char *rule;
};
-struct validate {
- struct avl_node avl;
- struct list_head list;
-
- char *package;
- char *type;
-
- struct avl_tree rules;
-};
-
struct service {
struct avl_node avl;
const char *name;
struct blob_attr *trigger;
struct vlist_tree instances;
- struct list_head validators;
};
-void service_validate_add(struct service *s, struct blob_attr *attr);
-void service_validate_dump(struct blob_buf *b, struct service *s);
-void service_validate_dump_all(struct blob_buf *b, char *p, char *s);
int service_start_early(char *name, char *cmdline);
-void service_validate_del(struct service *s);
-void service_validate_init(void);
void service_init(void);
void service_event(const char *type, const char *service, const char *instance);
diff --git a/service/setlbf.c b/service/setlbf.c
deleted file mode 100644
index 94c251e..0000000
--- a/service/setlbf.c
+++ /dev/null
@@ -1,6 +0,0 @@
-#include <stdio.h>
-
-static void __attribute__((constructor)) setlbf(void)
-{
- setbuf(stdout, NULL);
-}
diff --git a/service/trigger.c b/service/trigger.c
index 97a06bb..9c7115c 100644
--- a/service/trigger.c
+++ b/service/trigger.c
@@ -1,6 +1,7 @@
/*
* Copyright (C) 2013 Felix Fietkau <nbd@openwrt.org>
* Copyright (C) 2013 John Crispin <blogic@openwrt.org>
+ * Copyright (C) 2015 Matthias Schiffer <mschiffer@universe-factory.net>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License version 2.1
diff --git a/service/validate.c b/service/validate.c
deleted file mode 100644
index 6a449f4..0000000
--- a/service/validate.c
+++ /dev/null
@@ -1,163 +0,0 @@
-/*
- * Copyright (C) 2013 John Crispin <blogic@openwrt.org>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU Lesser General Public License version 2.1
- * as published by the Free Software Foundation
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- */
-
-#include <libubox/blobmsg_json.h>
-#include <libubox/avl-cmp.h>
-#include <json-c/json.h>
-
-#include "../procd.h"
-
-#include "service.h"
-
-enum {
- SERVICE_VAL_PACKAGE,
- SERVICE_VAL_TYPE,
- SERVICE_VAL_DATA,
- __SERVICE_VAL_MAX
-};
-
-static const struct blobmsg_policy service_validate_attrs[__SERVICE_VAL_MAX] = {
- [SERVICE_VAL_PACKAGE] = { "package", BLOBMSG_TYPE_STRING },
- [SERVICE_VAL_TYPE] = { "type", BLOBMSG_TYPE_STRING },
- [SERVICE_VAL_DATA] = { "data", BLOBMSG_TYPE_TABLE },
-};
-
-static struct avl_tree validators;
-
-void
-service_validate_dump_all(struct blob_buf *b, char *p, char *s)
-{
- struct json_object *r = json_object_new_object();
- struct validate *v;
-
- if (!r)
- return;
-
- avl_for_each_element(&validators, v, avl) {
- struct json_object *o, *t;
- struct vrule *vr;
-
- if (p && strcmp(p, v->package))
- continue;
-
- if (s && strcmp(s, v->type))
- continue;
-
- json_object_object_get_ex(r, v->package, &o);
- if (!o) {
- o = json_object_new_object();
- json_object_object_add(r, v->package, o);
- }
- json_object_object_get_ex(o, v->type, &t);
- if (!t) {
- t = json_object_new_object();
- json_object_object_add(o, v->type, t);
- }
- avl_for_each_element(&v->rules, vr, avl)
- json_object_object_add(t, vr->option, json_object_new_string(vr->rule));
- }
- blobmsg_add_object(b, r);
- json_object_put(r);
-}
-
-void
-service_validate_dump(struct blob_buf *b, struct service *s)
-{
- struct validate *v;
- void *i = blobmsg_open_array(b, "validate");
-
- list_for_each_entry(v, &s->validators, list) {
- struct vrule *vr;
- void *k, *j = blobmsg_open_table(b, "validate");
-
- blobmsg_add_string(b, "package", v->package);
- blobmsg_add_string(b, "type", v->type);
- k = blobmsg_open_table(b, "rules");
- avl_for_each_element(&v->rules, vr, avl)
- blobmsg_add_string(b, vr->option, vr->rule);
- blobmsg_close_table(b, k);
- blobmsg_close_table(b, j);
- }
- blobmsg_close_array(b, i);
-}
-
-void
-service_validate_del(struct service *s)
-{
- struct validate *v, *n;
-
- if (list_empty(&s->validators))
- return;
-
- list_for_each_entry_safe(v, n, &s->validators, list) {
- struct vrule *vr, *a;
-
- avl_remove_all_elements(&v->rules, vr, avl, a)
- free(vr);
-
- avl_delete(&validators, &v->avl);
- list_del(&v->list);
- free(v);
- }
-}
-
-void
-service_validate_add(struct service *s, struct blob_attr *msg)
-{
- struct blob_attr *tb[__SERVICE_VAL_MAX];
- struct validate *v;
- char *type, *package;
- struct blob_attr *cur;
- int rem;
-
- blobmsg_parse(service_validate_attrs, __SERVICE_VAL_MAX, tb, blobmsg_data(msg), blobmsg_data_len(msg));
- if (!tb[SERVICE_VAL_PACKAGE] || !tb[SERVICE_VAL_TYPE] || !tb[SERVICE_VAL_DATA])
- return;
-
- v = calloc_a(sizeof(*v), &package, blobmsg_data_len(tb[SERVICE_VAL_PACKAGE]) + 1,
- &type, blobmsg_data_len(tb[SERVICE_VAL_TYPE]) + 1);
- if (!v)
- return;
-
- v->type = type;
- v->avl.key = v->package = package;
- strcpy(v->package, blobmsg_get_string(tb[SERVICE_VAL_PACKAGE]));
- strcpy(v->type, blobmsg_get_string(tb[SERVICE_VAL_TYPE]));
-
- list_add(&v->list, &s->validators);
- if (avl_insert(&validators, &v->avl)) {
- free(v);
- return;
- }
- avl_init(&v->rules, avl_strcmp, false, NULL);
-
- blobmsg_for_each_attr(cur, tb[SERVICE_VAL_DATA], rem) {
- char *option;
- char *rule;
- struct vrule *vr = calloc_a(sizeof(*vr), &option, strlen(blobmsg_name(cur)) + 1,
- &rule, strlen(blobmsg_get_string(cur)) + 1);
-
- vr->avl.key = vr->option = option;
- vr->rule = rule;
- strcpy(vr->option, blobmsg_name(cur));
- strcpy(vr->rule, blobmsg_get_string(cur));
- if (avl_insert(&v->rules, &vr->avl))
- free(vr);
- }
-}
-
-void
-service_validate_init(void)
-{
- avl_init(&validators, avl_strcmp, true, NULL);
-}
diff --git a/service/watch.c b/service/watch.c
index 349b484..cc0b2ee 100644
--- a/service/watch.c
+++ b/service/watch.c
@@ -1,6 +1,7 @@
/*
* Copyright (C) 2013 Felix Fietkau <nbd@openwrt.org>
* Copyright (C) 2013 John Crispin <blogic@openwrt.org>
+ * Copyright (C) 2015 Matthias Schiffer <mschiffer@universe-factory.net>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License version 2.1
diff --git a/signal.c b/signal.c
index 16824f7..60b8f82 100644
--- a/signal.c
+++ b/signal.c
@@ -1,6 +1,7 @@
/*
* Copyright (C) 2013 Felix Fietkau <nbd@openwrt.org>
* Copyright (C) 2013 John Crispin <blogic@openwrt.org>
+ * Copyright (C) 2015 Matthias Schiffer <mschiffer@universe-factory.net>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License version 2.1
diff --git a/state.c b/state.c
index 1ed70f5..1faa7a0 100644
--- a/state.c
+++ b/state.c
@@ -1,6 +1,7 @@
/*
* Copyright (C) 2013 Felix Fietkau <nbd@openwrt.org>
* Copyright (C) 2013 John Crispin <blogic@openwrt.org>
+ * Copyright (C) 2015 Matthias Schiffer <mschiffer@universe-factory.net>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License version 2.1
@@ -22,7 +23,6 @@
#include "procd.h"
#include "syslog.h"
-#include "plug/hotplug.h"
#include "watchdog.h"
#include "service/service.h"
#include "utils/utils.h"
@@ -30,7 +30,6 @@
enum {
STATE_NONE = 0,
STATE_EARLY,
- STATE_UBUS,
STATE_INIT,
STATE_RUNNING,
STATE_SHUTDOWN,
@@ -99,17 +98,9 @@ static void state_enter(void)
switch (state) {
case STATE_EARLY:
- LOG("- early -\n");
watchdog_init(0);
- hotplug("/etc/hotplug.json");
- procd_coldplug();
- break;
-
- case STATE_UBUS:
- // try to reopen incase the wdt was not available before coldplug
- watchdog_init(0);
- set_stdio("console");
- LOG("- ubus -\n");
+ LOG("- early -\n");
+ procd_early();
procd_connect_ubus();
service_init();
service_start_early("ubus", ubus_cmd);
@@ -185,7 +176,7 @@ void procd_state_next(void)
void procd_state_ubus_connect(void)
{
- if (state == STATE_UBUS)
+ if (state == STATE_EARLY)
procd_state_next();
}
diff --git a/system.c b/system.c
index fb7fbe4..5f0b9bb 100644
--- a/system.c
+++ b/system.c
@@ -1,6 +1,7 @@
/*
* Copyright (C) 2013 Felix Fietkau <nbd@openwrt.org>
* Copyright (C) 2013 John Crispin <blogic@openwrt.org>
+ * Copyright (C) 2015 Matthias Schiffer <mschiffer@universe-factory.net>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License version 2.1
diff --git a/trace/preload.c b/trace/preload.c
deleted file mode 100644
index 99dd906..0000000
--- a/trace/preload.c
+++ /dev/null
@@ -1,80 +0,0 @@
-/*
- * Copyright (C) 2015 John Crispin <blogic@openwrt.org>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU Lesser General Public License version 2.1
- * as published by the Free Software Foundation
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- */
-
-#define _GNU_SOURCE
-#include <sys/ptrace.h>
-#include <sys/types.h>
-#include <signal.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <string.h>
-#include <dlfcn.h>
-
-#include "../preload.h"
-
-#define ERROR(fmt, ...) do { \
- fprintf(stderr,"perload-jail: "fmt, ## __VA_ARGS__); \
- } while (0)
-
-static main_t __main__;
-
-static int __preload_main__(int argc, char **argv, char **envp)
-{
- unsetenv("LD_PRELOAD");
- ptrace(PTRACE_TRACEME);
- kill(getpid(), SIGSTOP);
-
- return (*__main__)(argc, argv, envp);
-}
-
-int __libc_start_main(main_t main,
- int argc,
- char **argv,
- ElfW(auxv_t) *auxvec,
- __typeof (main) init,
- void (*fini) (void),
- void (*rtld_fini) (void),
- void *stack_end)
-{
- start_main_t __start_main__;
-
- __start_main__ = dlsym(RTLD_NEXT, "__libc_start_main");
- if (!__start_main__)
- ERROR("failed to find __libc_start_main %s\n", dlerror());
-
- __main__ = main;
-
- return (*__start_main__)(__preload_main__, argc, argv, auxvec,
- init, fini, rtld_fini, stack_end);
-}
-
-void __uClibc_main(main_t main,
- int argc,
- char **argv,
- void (*app_init)(void),
- void (*app_fini)(void),
- void (*rtld_fini)(void),
- void *stack_end attribute_unused)
-{
- uClibc_main __start_main__;
-
- __start_main__ = dlsym(RTLD_NEXT, "__uClibc_main");
- if (!__start_main__)
- ERROR("failed to find __uClibc_main %s\n", dlerror());
-
- __main__ = main;
-
- return (*__start_main__)(__preload_main__, argc, argv,
- app_init, app_fini, rtld_fini, stack_end);
-}
diff --git a/trace/trace.c b/trace/trace.c
deleted file mode 100644
index b0005b8..0000000
--- a/trace/trace.c
+++ /dev/null
@@ -1,225 +0,0 @@
-/*
- * Copyright (C) 2015 John Crispin <blogic@openwrt.org>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU Lesser General Public License version 2.1
- * as published by the Free Software Foundation
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- */
-
-#define _GNU_SOURCE
-#include <stddef.h>
-#include <sys/ptrace.h>
-#include <sys/types.h>
-#include <sys/user.h>
-#include <sys/wait.h>
-#include <unistd.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <errno.h>
-#include <string.h>
-#include <syslog.h>
-
-#include <libubox/uloop.h>
-#include <libubox/blobmsg.h>
-#include <libubox/blobmsg_json.h>
-
-#include "../syscall-names.h"
-
-#define _offsetof(a, b) __builtin_offsetof(a,b)
-#define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0]))
-
-#ifdef __amd64__
-#define reg_syscall_nr _offsetof(struct user, regs.orig_rax)
-#elif defined(__i386__)
-#define reg_syscall_nr _offsetof(struct user, regs.orig_eax)
-#elif defined(__mips)
-# ifndef EF_REG2
-# define EF_REG2 8
-# endif
-#define reg_syscall_nr (EF_REG2 / 4)
-#elif defined(__arm__)
-#define reg_syscall_nr _offsetof(struct user, regs.uregs[7])
-#else
-#error tracing is not supported on this architecture
-#endif
-
-#define INFO(fmt, ...) do { \
- fprintf(stderr, "utrace: "fmt, ## __VA_ARGS__); \
-} while (0)
-
-#define ERROR(fmt, ...) do { \
- syslog(LOG_ERR, "utrace: "fmt, ## __VA_ARGS__); \
- fprintf(stderr, "utrace: "fmt, ## __VA_ARGS__); \
-} while (0)
-
-static struct uloop_process tracer;
-static int *syscall_count;
-static struct blob_buf b;
-static int syscall_max;
-static int in_syscall;
-static int debug;
-
-static int max_syscall = ARRAY_SIZE(syscall_names);
-
-static void set_syscall(const char *name, int val)
-{
- int i;
-
- for (i = 0; i < max_syscall; i++)
- if (syscall_names[i] && !strcmp(syscall_names[i], name)) {
- syscall_count[i] = val;
- return;
- }
-}
-
-static void print_syscalls(int policy, const char *json)
-{
- void *c;
- int i;
-
- set_syscall("rt_sigaction", 1);
- set_syscall("sigreturn", 1);
- set_syscall("rt_sigreturn", 1);
- set_syscall("exit_group", 1);
- set_syscall("exit", 1);
-
- blob_buf_init(&b, 0);
- c = blobmsg_open_array(&b, "whitelist");
-
- for (i = 0; i < ARRAY_SIZE(syscall_names); i++) {
- if (!syscall_count[i])
- continue;
- if (syscall_names[i]) {
- if (debug)
- printf("syscall %d (%s) was called %d times\n",
- i, syscall_names[i], syscall_count[i]);
- blobmsg_add_string(&b, NULL, syscall_names[i]);
- } else {
- ERROR("no name found for syscall(%d)\n", i);
- }
- }
- blobmsg_close_array(&b, c);
- blobmsg_add_u32(&b, "policy", policy);
- if (json) {
- FILE *fp = fopen(json, "w");
- if (fp) {
- fprintf(fp, "%s", blobmsg_format_json_indent(b.head, true, 0));
- fclose(fp);
- INFO("saving syscall trace to %s\n", json);
- } else {
- ERROR("failed to open %s\n", json);
- }
- } else {
- printf("%s\n",
- blobmsg_format_json_indent(b.head, true, 0));
- }
-
-}
-
-static void tracer_cb(struct uloop_process *c, int ret)
-{
- if (WIFSTOPPED(ret) && WSTOPSIG(ret) & 0x80) {
- if (!in_syscall) {
- int syscall = ptrace(PTRACE_PEEKUSER, c->pid, reg_syscall_nr);
-
- if (syscall < syscall_max) {
- syscall_count[syscall]++;
- if (debug)
- fprintf(stderr, "%s()\n", syscall_names[syscall]);
- } else if (debug) {
- fprintf(stderr, "syscal(%d)\n", syscall);
- }
- }
- in_syscall = !in_syscall;
- } else if (WIFEXITED(ret)) {
- uloop_end();
- return;
- }
- ptrace(PTRACE_SYSCALL, c->pid, 0, 0);
- uloop_process_add(&tracer);
-}
-
-int main(int argc, char **argv, char **envp)
-{
- char *json = NULL;
- int status, ch, policy = EPERM;
- pid_t child;
-
- while ((ch = getopt(argc, argv, "f:p:")) != -1) {
- switch (ch) {
- case 'f':
- json = optarg;
- break;
- case 'p':
- policy = atoi(optarg);
- break;
- }
- }
-
- argc -= optind;
- argv += optind;
-
- if (!argc)
- return -1;
-
- if (getenv("TRACE_DEBUG"))
- debug = 1;
- unsetenv("TRACE_DEBUG");
-
- child = fork();
-
- if (child == 0) {
- char **_argv = calloc(argc + 1, sizeof(char *));
- char **_envp;
- char preload[] = "LD_PRELOAD=/lib/libpreload-trace.so";
- int envc = 1;
- int ret;
-
- memcpy(_argv, argv, argc * sizeof(char *));
-
- while (envp[envc++])
- ;
-
- _envp = calloc(envc, sizeof(char *));
- memcpy(&_envp[1], _envp, envc * sizeof(char *));
- *envp = preload;
-
- ret = execve(_argv[0], _argv, envp);
- ERROR("failed to exec %s: %s\n", _argv[0], strerror(errno));
- return ret;
- }
-
- if (child < 0)
- return -1;
-
- syscall_max = ARRAY_SIZE(syscall_names);
- syscall_count = calloc(syscall_max, sizeof(int));
- waitpid(child, &status, 0);
- if (!WIFSTOPPED(status)) {
- ERROR("failed to start %s\n", *argv);
- return -1;
- }
-
- ptrace(PTRACE_SETOPTIONS, child, 0, PTRACE_O_TRACESYSGOOD);
- ptrace(PTRACE_SYSCALL, child, 0, 0);
-
- uloop_init();
- tracer.pid = child;
- tracer.cb = tracer_cb;
- uloop_process_add(&tracer);
- uloop_run();
- uloop_done();
-
- if (!json)
- if (asprintf(&json, "/tmp/%s.%u.json", basename(*argv), child) < 0)
- ERROR("failed to allocate output path: %s\n", strerror(errno));
-
- print_syscalls(policy, json);
-
- return 0;
-}
diff --git a/ubus.c b/ubus.c
index 211a1ec..386a7d4 100644
--- a/ubus.c
+++ b/ubus.c
@@ -1,6 +1,7 @@
/*
* Copyright (C) 2013 Felix Fietkau <nbd@openwrt.org>
* Copyright (C) 2013 John Crispin <blogic@openwrt.org>
+ * Copyright (C) 2015 Matthias Schiffer <mschiffer@universe-factory.net>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License version 2.1
diff --git a/upgraded/CMakeLists.txt b/upgraded/CMakeLists.txt
deleted file mode 100644
index 093dba2..0000000
--- a/upgraded/CMakeLists.txt
+++ /dev/null
@@ -1,17 +0,0 @@
-cmake_minimum_required(VERSION 2.6)
-
-PROJECT(upgraded C)
-ADD_DEFINITIONS(-Os -ggdb -Wall -Werror --std=gnu99 -Wmissing-declarations)
-set(CMAKE_EXE_LINKER_FLAGS "-static -fPIC")
-set(CMAKE_FIND_LIBRARY_SUFFIXES .a)
-set(CMAKE_EXE_LINK_DYNAMIC_C_FLAGS)
-set(CMAKE_EXE_LINK_DYNAMIC_CXX_FLAGS)
-set(CMAKE_SHARED_LIBRARY_C_FLAGS)
-set(CMAKE_SHARED_LIBRARY_CXX_FLAGS)
-set(CMAKE_SHARED_LIBRARY_LINK_C_FLAGS)
-set(CMAKE_SHARED_LIBRARY_LINK_CXX_FLAGS)
-ADD_EXECUTABLE(upgraded upgraded.c ../watchdog.c)
-TARGET_LINK_LIBRARIES(upgraded ubox rt -lc -lgcc_pic)
-INSTALL(TARGETS upgraded
- RUNTIME DESTINATION sbin
-)
diff --git a/upgraded/upgraded.c b/upgraded/upgraded.c
deleted file mode 100644
index d7433e7..0000000
--- a/upgraded/upgraded.c
+++ /dev/null
@@ -1,80 +0,0 @@
-/*
- * Copyright (C) 2013 Felix Fietkau <nbd@openwrt.org>
- * Copyright (C) 2013 John Crispin <blogic@openwrt.org>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU Lesser General Public License version 2.1
- * as published by the Free Software Foundation
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- */
-
-#include <sys/reboot.h>
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-#include <errno.h>
-
-#include <libubox/uloop.h>
-
-#include "../watchdog.h"
-
-static struct uloop_process upgrade_proc;
-unsigned int debug = 2;
-
-static void upgrade_proc_cb(struct uloop_process *proc, int ret)
-{
- if (ret)
- fprintf(stderr, "sysupgrade aborted with return code: %d\n", ret);
- uloop_end();
-}
-
-static void sysupgarde(char *folder)
-{
- char *args[] = { "/sbin/sysupgrade", "nand", NULL, NULL };
-
- args[2] = folder;
- upgrade_proc.cb = upgrade_proc_cb;
- upgrade_proc.pid = fork();
- if (!upgrade_proc.pid) {
- execvp(args[0], args);
- fprintf(stderr, "Failed to fork sysupgrade\n");
- exit(-1);
- }
- if (upgrade_proc.pid <= 0) {
- fprintf(stderr, "Failed to start sysupgarde\n");
- uloop_end();
- }
-}
-
-int main(int argc, char **argv)
-{
- pid_t p = getpid();
-
- if (p != 1) {
- fprintf(stderr, "this tool needs to run as pid 1\n");
- return -1;
- }
- if (chdir("/tmp") == -1) {
- fprintf(stderr, "failed to chdir to /tmp: %s\n", strerror(errno));
- return -1;
- }
- if (argc != 2) {
- fprintf(stderr, "sysupgrade stage 2 failed, no folder specified\n");
- return -1;
- }
-
- uloop_init();
- watchdog_init(0);
- sysupgarde(argv[1]);
- uloop_run();
-
- reboot(RB_AUTOBOOT);
-
- return 0;
-}
diff --git a/utils/askfirst.c b/utils/askfirst.c
index 69de76f..cdd2883 100644
--- a/utils/askfirst.c
+++ b/utils/askfirst.c
@@ -1,6 +1,7 @@
/*
* Copyright (C) 2013 Felix Fietkau <nbd@openwrt.org>
* Copyright (C) 2013 John Crispin <blogic@openwrt.org>
+ * Copyright (C) 2015 Matthias Schiffer <mschiffer@universe-factory.net>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License version 2.1
diff --git a/utils/utils.c b/utils/utils.c
index c0d1cd5..8dbbbd2 100644
--- a/utils/utils.c
+++ b/utils/utils.c
@@ -1,6 +1,7 @@
/*
* Copyright (C) 2013 Felix Fietkau <nbd@openwrt.org>
* Copyright (C) 2013 John Crispin <blogic@openwrt.org>
+ * Copyright (C) 2015 Matthias Schiffer <mschiffer@universe-factory.net>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License version 2.1
diff --git a/utils/utils.h b/utils/utils.h
index 8b384fc..c371678 100644
--- a/utils/utils.h
+++ b/utils/utils.h
@@ -1,6 +1,7 @@
/*
* Copyright (C) 2013 Felix Fietkau <nbd@openwrt.org>
* Copyright (C) 2013 John Crispin <blogic@openwrt.org>
+ * Copyright (C) 2015 Matthias Schiffer <mschiffer@universe-factory.net>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License version 2.1
diff --git a/watchdog.c b/watchdog.c
index 592ae7e..0eae9c8 100644
--- a/watchdog.c
+++ b/watchdog.c
@@ -1,6 +1,7 @@
/*
* Copyright (C) 2013 Felix Fietkau <nbd@openwrt.org>
* Copyright (C) 2013 John Crispin <blogic@openwrt.org>
+ * Copyright (C) 2015 Matthias Schiffer <mschiffer@universe-factory.net>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License version 2.1
diff --git a/watchdog.h b/watchdog.h
index 015fa93..8d64895 100644
--- a/watchdog.h
+++ b/watchdog.h
@@ -1,6 +1,7 @@
/*
* Copyright (C) 2013 Felix Fietkau <nbd@openwrt.org>
* Copyright (C) 2013 John Crispin <blogic@openwrt.org>
+ * Copyright (C) 2015 Matthias Schiffer <mschiffer@universe-factory.net>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License version 2.1