2 * Copyright (C) 2015 John Crispin <blogic@openwrt.org>
3 * Copyright (C) 2015 Etienne Champetier <champetier.etienne@gmail.com>
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU Lesser General Public License version 2.1
7 * as published by the Free Software Foundation
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
21 #include <linux/limits.h>
28 #include <libubox/avl.h>
29 #include <libubox/avl-cmp.h>
43 struct avl_tree mounts;
45 int add_mount(const char *path, int readonly, int error)
49 if (avl_find(&mounts, path))
53 m = calloc(1, sizeof(struct mount));
55 m->avl.key = m->path = strdup(path);
56 m->readonly = readonly;
59 avl_insert(&mounts, &m->avl);
60 DEBUG("adding mount %s ro(%d) err(%d)\n", m->path, m->readonly, m->error != 0);
64 int mount_all(const char *jailroot) {
68 avl_for_each_element(&libraries, l, avl)
69 add_mount(l->path, 1, -1);
71 avl_for_each_element(&mounts, m, avl)
72 if (mount_bind(jailroot, m->path, m->readonly, m->error))
78 void mount_list_init(void) {
79 avl_init(&mounts, avl_strcmp, false, NULL);
82 static int add_script_interp(const char *path, const char *map, int size)
85 while (start < size && map[start] != '/') {
89 ERROR("bad script interp (%s)", path);
93 while (stop < size && map[stop] > 0x20 && map[stop] <= 0x7e) {
96 if (stop >= size || (stop-start) > PATH_MAX) {
97 ERROR("bad script interp (%s)", path);
101 strncpy(buf, map+start, stop-start);
102 return add_path_and_deps(buf, 1, -1, 0);
105 int add_path_and_deps(const char *path, int readonly, int error, int lib)
107 assert(path != NULL);
109 if (lib == 0 && path[0] != '/') {
110 ERROR("%s is not an absolute path\n", path);
116 if (path[0] == '/') {
117 if (avl_find(&mounts, path))
119 fd = open(path, O_RDONLY);
122 add_mount(path, readonly, error);
124 if (avl_find(&libraries, path))
127 fd = lib_open(&fullpath, path);
131 alloc_library(fullpath, path);
137 if (fstat(fd, &s) == -1) {
138 ERROR("fstat(%s) failed: %s\n", path, strerror(errno));
143 if (!S_ISREG(s.st_mode)) {
148 /* too small to be an ELF or a script -> "normal" file */
154 map = mmap(NULL, s.st_size, PROT_READ, MAP_PRIVATE, fd, 0);
155 if (map == MAP_FAILED) {
156 ERROR("failed to mmap %s\n", path);
161 if (map[0] == '#' && map[1] == '!') {
162 ret = add_script_interp(path, map, s.st_size);
166 if (map[0] == ELFMAG0 && map[1] == ELFMAG1 && map[2] == ELFMAG2 && map[3] == ELFMAG3) {
167 ret = elf_load_deps(path, map);
177 munmap(map, s.st_size);