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)\n", 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)\n", 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
|O_CLOEXEC
);
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
);