]> git.proxmox.com Git - mirror_lxc.git/blame - src/lxc/utils.c
Fix unprivileged containers started by root
[mirror_lxc.git] / src / lxc / utils.c
CommitLineData
e3642c43
DL
1/*
2 * lxc: linux Container library
3 *
4 * (C) Copyright IBM Corp. 2007, 2008
5 *
6 * Authors:
9afe19d6 7 * Daniel Lezcano <daniel.lezcano at free.fr>
e3642c43
DL
8 *
9 * This library is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU Lesser General Public
11 * License as published by the Free Software Foundation; either
12 * version 2.1 of the License, or (at your option) any later version.
13 *
14 * This library is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * Lesser General Public License for more details.
18 *
19 * You should have received a copy of the GNU Lesser General Public
20 * License along with this library; if not, write to the Free Software
250b1eec 21 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
e3642c43
DL
22 */
23
052616eb
ÇO
24#include "config.h"
25
e3642c43
DL
26#include <errno.h>
27#include <unistd.h>
d983b93c
MN
28#include <stdlib.h>
29#include <stddef.h>
61a1d519 30#include <string.h>
e3642c43
DL
31#include <sys/types.h>
32#include <sys/stat.h>
33#include <sys/mman.h>
d983b93c 34#include <sys/param.h>
6e4bb2e0 35#include <sys/mount.h>
d983b93c
MN
36#include <dirent.h>
37#include <fcntl.h>
1b09f2c0 38#include <libgen.h>
9be53773
SH
39#include <sys/types.h>
40#include <sys/wait.h>
502657d5 41#include <assert.h>
e3642c43 42
3ce74686 43#include "utils.h"
e3642c43 44#include "log.h"
025ed0f3 45#include "lxclock.h"
e3642c43 46
052616eb
ÇO
47#define MAX_STACKDEPTH 25
48
e3642c43
DL
49lxc_log_define(lxc_utils, lxc);
50
60bf62d4
SH
51static int _recursive_rmdir_onedev(char *dirname, dev_t pdev)
52{
53 struct dirent dirent, *direntp;
54 DIR *dir;
55 int ret, failed=0;
56 char pathname[MAXPATHLEN];
57
58 dir = opendir(dirname);
59 if (!dir) {
60 ERROR("%s: failed to open %s", __func__, dirname);
4355ab5f 61 return -1;
60bf62d4
SH
62 }
63
64 while (!readdir_r(dir, &dirent, &direntp)) {
65 struct stat mystat;
66 int rc;
67
68 if (!direntp)
69 break;
70
71 if (!strcmp(direntp->d_name, ".") ||
72 !strcmp(direntp->d_name, ".."))
73 continue;
74
75 rc = snprintf(pathname, MAXPATHLEN, "%s/%s", dirname, direntp->d_name);
76 if (rc < 0 || rc >= MAXPATHLEN) {
77 ERROR("pathname too long");
78 failed=1;
79 continue;
80 }
81 ret = lstat(pathname, &mystat);
82 if (ret) {
83 ERROR("%s: failed to stat %s", __func__, pathname);
84 failed=1;
85 continue;
86 }
87 if (mystat.st_dev != pdev)
88 continue;
89 if (S_ISDIR(mystat.st_mode)) {
4355ab5f 90 if (_recursive_rmdir_onedev(pathname, pdev) < 0)
60bf62d4
SH
91 failed=1;
92 } else {
93 if (unlink(pathname) < 0) {
94 ERROR("%s: failed to delete %s", __func__, pathname);
95 failed=1;
96 }
97 }
98 }
99
100 if (rmdir(dirname) < 0) {
101 ERROR("%s: failed to delete %s", __func__, dirname);
102 failed=1;
103 }
104
025ed0f3 105 ret = closedir(dir);
025ed0f3 106 if (ret) {
60bf62d4
SH
107 ERROR("%s: failed to close directory %s", __func__, dirname);
108 failed=1;
109 }
110
4355ab5f 111 return failed ? -1 : 0;
60bf62d4
SH
112}
113
4355ab5f 114/* returns 0 on success, -1 if there were any failures */
60bf62d4
SH
115extern int lxc_rmdir_onedev(char *path)
116{
117 struct stat mystat;
118
119 if (lstat(path, &mystat) < 0) {
120 ERROR("%s: failed to stat %s", __func__, path);
4355ab5f 121 return -1;
60bf62d4
SH
122 }
123
124 return _recursive_rmdir_onedev(path, mystat.st_dev);
125}
126
6e4bb2e0
MN
127static int mount_fs(const char *source, const char *target, const char *type)
128{
129 /* the umount may fail */
130 if (umount(target))
131 WARN("failed to unmount %s : %s", target, strerror(errno));
132
133 if (mount(source, target, type, 0, NULL)) {
134 ERROR("failed to mount %s : %s", target, strerror(errno));
135 return -1;
136 }
137
138 DEBUG("'%s' mounted on '%s'", source, target);
139
140 return 0;
141}
142
ea0da529 143extern void lxc_setup_fs(void)
6e4bb2e0
MN
144{
145 if (mount_fs("proc", "/proc", "proc"))
ea0da529 146 INFO("failed to remount proc");
6e4bb2e0 147
721d262c 148 /* if we can't mount /dev/shm, continue anyway */
6e4bb2e0 149 if (mount_fs("shmfs", "/dev/shm", "tmpfs"))
3283db09 150 INFO("failed to mount /dev/shm");
6e4bb2e0
MN
151
152 /* If we were able to mount /dev/shm, then /dev exists */
b91b1cd7 153 /* Sure, but it's read-only per config :) */
6e4bb2e0 154 if (access("/dev/mqueue", F_OK) && mkdir("/dev/mqueue", 0666)) {
b91b1cd7 155 DEBUG("failed to create '/dev/mqueue'");
ea0da529 156 return;
6e4bb2e0
MN
157 }
158
5d4d3ebb 159 /* continue even without posix message queue support */
6e4bb2e0 160 if (mount_fs("mqueue", "/dev/mqueue", "mqueue"))
5d4d3ebb 161 INFO("failed to mount /dev/mqueue");
6e4bb2e0 162}
9ddaf3bf
JHS
163
164/* borrowed from iproute2 */
7c11d57a 165extern int get_u16(unsigned short *val, const char *arg, int base)
9ddaf3bf
JHS
166{
167 unsigned long res;
168 char *ptr;
169
170 if (!arg || !*arg)
171 return -1;
172
09bbd745 173 errno = 0;
9ddaf3bf 174 res = strtoul(arg, &ptr, base);
09bbd745 175 if (!ptr || ptr == arg || *ptr || res > 0xFFFF || errno != 0)
9ddaf3bf
JHS
176 return -1;
177
178 *val = res;
179
180 return 0;
181}
182
3ce74686 183extern int mkdir_p(const char *dir, mode_t mode)
1b09f2c0 184{
3ce74686
SH
185 const char *tmp = dir;
186 const char *orig = dir;
860fc865
RW
187 char *makeme;
188
189 do {
190 dir = tmp + strspn(tmp, "/");
191 tmp = dir + strcspn(dir, "/");
d74325c4 192 makeme = strndup(orig, dir - orig);
860fc865
RW
193 if (*makeme) {
194 if (mkdir(makeme, mode) && errno != EEXIST) {
959aee9c 195 SYSERROR("failed to create directory '%s'", makeme);
d74325c4 196 free(makeme);
860fc865
RW
197 return -1;
198 }
199 }
d74325c4 200 free(makeme);
860fc865 201 } while(tmp != dir);
1b09f2c0 202
98663823 203 return 0;
1b09f2c0 204}
2a59a681 205
89cd7793
QH
206extern void remove_trailing_slashes(char *p)
207{
208 int l = strlen(p);
209 while (--l >= 0 && (p[l] == '/' || p[l] == '\n'))
210 p[l] = '\0';
211}
212
d0386d66 213static char *copy_global_config_value(char *p)
2a59a681
SH
214{
215 int len = strlen(p);
216 char *retbuf;
217
218 if (len < 1)
219 return NULL;
220 if (p[len-1] == '\n') {
221 p[len-1] = '\0';
222 len--;
223 }
224 retbuf = malloc(len+1);
225 if (!retbuf)
226 return NULL;
227 strcpy(retbuf, p);
228 return retbuf;
229}
230
31a95fec 231#define DEFAULT_VG "lxc"
055af165 232#define DEFAULT_THIN_POOL "lxc"
31a95fec 233#define DEFAULT_ZFSROOT "lxc"
67e571de 234
593e8478 235const char *lxc_global_config_value(const char *option_name)
31a95fec 236{
74a3920a 237 static const char * const options[][2] = {
2e59ba02
SG
238 { "lxc.bdev.lvm.vg", DEFAULT_VG },
239 { "lxc.bdev.lvm.thin_pool", DEFAULT_THIN_POOL },
240 { "lxc.bdev.zfs.root", DEFAULT_ZFSROOT },
241 { "lxc.lxcpath", NULL },
242 { "lxc.default_config", NULL },
243 { "lxc.cgroup.pattern", DEFAULT_CGROUP_PATTERN },
244 { "lxc.cgroup.use", NULL },
d0386d66
CS
245 { NULL, NULL },
246 };
4878dac4 247
93c379f0 248 /* placed in the thread local storage pool for non-bionic targets */
babbea4b
ÇO
249#ifdef HAVE_TLS
250 static __thread const char *values[sizeof(options) / sizeof(options[0])] = { 0 };
251#else
91664352 252 static const char *values[sizeof(options) / sizeof(options[0])] = { 0 };
babbea4b 253#endif
4878dac4 254 char *user_config_path = NULL;
9e8be781 255 char *user_default_config_path = NULL;
4878dac4 256 char *user_lxc_path = NULL;
4878dac4
SG
257
258 if (geteuid() > 0) {
6ed46d9e
AM
259 const char *user_home = getenv("HOME");
260 if (!user_home)
e99facec 261 user_home = "/";
4878dac4
SG
262
263 user_config_path = malloc(sizeof(char) * (22 + strlen(user_home)));
9e8be781 264 user_default_config_path = malloc(sizeof(char) * (26 + strlen(user_home)));
4878dac4
SG
265 user_lxc_path = malloc(sizeof(char) * (19 + strlen(user_home)));
266
267 sprintf(user_config_path, "%s/.config/lxc/lxc.conf", user_home);
9e8be781 268 sprintf(user_default_config_path, "%s/.config/lxc/default.conf", user_home);
4878dac4 269 sprintf(user_lxc_path, "%s/.local/share/lxc/", user_home);
4878dac4
SG
270 }
271 else {
272 user_config_path = strdup(LXC_GLOBAL_CONF);
9e8be781 273 user_default_config_path = strdup(LXC_DEFAULT_CONFIG);
4878dac4
SG
274 user_lxc_path = strdup(LXCPATH);
275 }
276
74a3920a 277 const char * const (*ptr)[2];
d0386d66
CS
278 size_t i;
279 char buf[1024], *p, *p2;
280 FILE *fin = NULL;
281
282 for (i = 0, ptr = options; (*ptr)[0]; ptr++, i++) {
283 if (!strcmp(option_name, (*ptr)[0]))
284 break;
285 }
286 if (!(*ptr)[0]) {
4878dac4 287 free(user_config_path);
9e8be781 288 free(user_default_config_path);
4878dac4 289 free(user_lxc_path);
d0386d66
CS
290 errno = EINVAL;
291 return NULL;
292 }
052616eb 293
052616eb 294 if (values[i]) {
4878dac4 295 free(user_config_path);
9e8be781 296 free(user_default_config_path);
4878dac4 297 free(user_lxc_path);
babbea4b 298 return values[i];
052616eb 299 }
31a95fec 300
4878dac4
SG
301 fin = fopen_cloexec(user_config_path, "r");
302 free(user_config_path);
31a95fec
SH
303 if (fin) {
304 while (fgets(buf, 1024, fin)) {
305 if (buf[0] == '#')
306 continue;
d0386d66 307 p = strstr(buf, option_name);
31a95fec
SH
308 if (!p)
309 continue;
d0386d66
CS
310 /* see if there was just white space in front
311 * of the option name
312 */
313 for (p2 = buf; p2 < p; p2++) {
314 if (*p2 != ' ' && *p2 != '\t')
315 break;
316 }
317 if (p2 < p)
318 continue;
31a95fec
SH
319 p = strchr(p, '=');
320 if (!p)
321 continue;
d0386d66
CS
322 /* see if there was just white space after
323 * the option name
324 */
325 for (p2 += strlen(option_name); p2 < p; p2++) {
326 if (*p2 != ' ' && *p2 != '\t')
327 break;
328 }
329 if (p2 < p)
330 continue;
31a95fec
SH
331 p++;
332 while (*p && (*p == ' ' || *p == '\t')) p++;
333 if (!*p)
334 continue;
f407c5e4 335
9e8be781 336 free(user_default_config_path);
f407c5e4
SG
337
338 if (strcmp(option_name, "lxc.lxcpath") == 0) {
339 free(user_lxc_path);
340 user_lxc_path = copy_global_config_value(p);
341 remove_trailing_slashes(user_lxc_path);
342 values[i] = user_lxc_path;
343 goto out;
344 }
345
346 values[i] = copy_global_config_value(p);
4878dac4 347 free(user_lxc_path);
31a95fec
SH
348 goto out;
349 }
350 }
d0386d66 351 /* could not find value, use default */
9e8be781 352 if (strcmp(option_name, "lxc.lxcpath") == 0) {
f407c5e4 353 remove_trailing_slashes(user_lxc_path);
4878dac4 354 values[i] = user_lxc_path;
9e8be781
SG
355 free(user_default_config_path);
356 }
357 else if (strcmp(option_name, "lxc.default_config") == 0) {
358 values[i] = user_default_config_path;
359 free(user_lxc_path);
360 }
4878dac4 361 else {
9e8be781 362 free(user_default_config_path);
4878dac4
SG
363 free(user_lxc_path);
364 values[i] = (*ptr)[1];
365 }
d0386d66
CS
366 /* special case: if default value is NULL,
367 * and there is no config, don't view that
368 * as an error... */
369 if (!values[i])
370 errno = 0;
31a95fec
SH
371
372out:
373 if (fin)
374 fclose(fin);
41f68357 375
babbea4b 376 return values[i];
31a95fec
SH
377}
378
44b9ae4b 379char *get_rundir()
9e60f51d 380{
97a696c6
SG
381 char *rundir;
382 const char *homedir;
9e60f51d 383
d6470e71 384 if (geteuid() == 0) {
c580b8d2 385 rundir = strdup(RUNTIME_PATH);
d6470e71
SG
386 return rundir;
387 }
97a696c6
SG
388
389 rundir = getenv("XDG_RUNTIME_DIR");
44b9ae4b
SG
390 if (rundir) {
391 rundir = strdup(rundir);
392 return rundir;
393 }
97a696c6 394
44b9ae4b
SG
395 INFO("XDG_RUNTIME_DIR isn't set in the environment.");
396 homedir = getenv("HOME");
397 if (!homedir) {
398 ERROR("HOME isn't set in the environment.");
399 return NULL;
97a696c6
SG
400 }
401
44b9ae4b
SG
402 rundir = malloc(sizeof(char) * (17 + strlen(homedir)));
403 sprintf(rundir, "%s/.cache/lxc/run/", homedir);
404
9e60f51d
DE
405 return rundir;
406}
407
9be53773
SH
408int wait_for_pid(pid_t pid)
409{
410 int status, ret;
411
412again:
413 ret = waitpid(pid, &status, 0);
414 if (ret == -1) {
71b9b8ed 415 if (errno == EINTR)
9be53773
SH
416 goto again;
417 return -1;
418 }
419 if (ret != pid)
420 goto again;
421 if (!WIFEXITED(status) || WEXITSTATUS(status) != 0)
422 return -1;
423 return 0;
424}
c797a220
CS
425
426int lxc_wait_for_pid_status(pid_t pid)
427{
428 int status, ret;
429
430again:
431 ret = waitpid(pid, &status, 0);
432 if (ret == -1) {
433 if (errno == EINTR)
434 goto again;
435 return -1;
436 }
437 if (ret != pid)
438 goto again;
439 return status;
440}
92f023dc 441
650468bb 442ssize_t lxc_write_nointr(int fd, const void* buf, size_t count)
92f023dc 443{
650468bb 444 ssize_t ret;
92f023dc
CS
445again:
446 ret = write(fd, buf, count);
447 if (ret < 0 && errno == EINTR)
448 goto again;
449 return ret;
450}
451
650468bb 452ssize_t lxc_read_nointr(int fd, void* buf, size_t count)
92f023dc 453{
650468bb 454 ssize_t ret;
92f023dc
CS
455again:
456 ret = read(fd, buf, count);
457 if (ret < 0 && errno == EINTR)
458 goto again;
459 return ret;
460}
461
650468bb 462ssize_t lxc_read_nointr_expect(int fd, void* buf, size_t count, const void* expected_buf)
92f023dc 463{
650468bb 464 ssize_t ret;
92f023dc
CS
465 ret = lxc_read_nointr(fd, buf, count);
466 if (ret <= 0)
467 return ret;
650468bb 468 if ((size_t)ret != count)
92f023dc
CS
469 return -1;
470 if (expected_buf && memcmp(buf, expected_buf, count) != 0) {
471 errno = EINVAL;
472 return -1;
473 }
474 return ret;
475}
3ce74686
SH
476
477#if HAVE_LIBGNUTLS
478#include <gnutls/gnutls.h>
479#include <gnutls/crypto.h>
41246cee
DE
480
481__attribute__((constructor))
482static void gnutls_lxc_init(void)
483{
484 gnutls_global_init();
485}
486
3ce74686
SH
487int sha1sum_file(char *fnam, unsigned char *digest)
488{
489 char *buf;
490 int ret;
491 FILE *f;
492 long flen;
493
494 if (!fnam)
495 return -1;
025ed0f3 496 f = fopen_cloexec(fnam, "r");
7be677a8 497 if (!f) {
3ce74686
SH
498 SYSERROR("Error opening template");
499 return -1;
500 }
501 if (fseek(f, 0, SEEK_END) < 0) {
502 SYSERROR("Error seeking to end of template");
dd1d77f9 503 fclose(f);
3ce74686
SH
504 return -1;
505 }
506 if ((flen = ftell(f)) < 0) {
507 SYSERROR("Error telling size of template");
dd1d77f9 508 fclose(f);
3ce74686
SH
509 return -1;
510 }
511 if (fseek(f, 0, SEEK_SET) < 0) {
512 SYSERROR("Error seeking to start of template");
dd1d77f9 513 fclose(f);
3ce74686
SH
514 return -1;
515 }
516 if ((buf = malloc(flen+1)) == NULL) {
517 SYSERROR("Out of memory");
dd1d77f9 518 fclose(f);
3ce74686
SH
519 return -1;
520 }
521 if (fread(buf, 1, flen, f) != flen) {
522 SYSERROR("Failure reading template");
523 free(buf);
dd1d77f9 524 fclose(f);
3ce74686
SH
525 return -1;
526 }
dd1d77f9 527 if (fclose(f) < 0) {
3ce74686
SH
528 SYSERROR("Failre closing template");
529 free(buf);
530 return -1;
531 }
532 buf[flen] = '\0';
533 ret = gnutls_hash_fast(GNUTLS_DIG_SHA1, buf, flen, (void *)digest);
534 free(buf);
535 return ret;
536}
537#endif
61a1d519
CS
538
539char** lxc_va_arg_list_to_argv(va_list ap, size_t skip, int do_strdup)
540{
541 va_list ap2;
542 size_t count = 1 + skip;
543 char **result;
544
545 /* first determine size of argument list, we don't want to reallocate
546 * constantly...
547 */
548 va_copy(ap2, ap);
549 while (1) {
550 char* arg = va_arg(ap2, char*);
551 if (!arg)
552 break;
553 count++;
554 }
555 va_end(ap2);
556
557 result = calloc(count, sizeof(char*));
558 if (!result)
559 return NULL;
560 count = skip;
561 while (1) {
562 char* arg = va_arg(ap, char*);
563 if (!arg)
564 break;
565 arg = do_strdup ? strdup(arg) : arg;
566 if (!arg)
567 goto oom;
568 result[count++] = arg;
569 }
570
571 /* calloc has already set last element to NULL*/
572 return result;
573
574oom:
575 free(result);
576 return NULL;
577}
578
579const char** lxc_va_arg_list_to_argv_const(va_list ap, size_t skip)
580{
581 return (const char**)lxc_va_arg_list_to_argv(ap, skip, 0);
582}
db27c8d7
CS
583
584FILE *fopen_cloexec(const char *path, const char *mode)
585{
586 int open_mode = 0;
587 int step = 0;
588 int fd;
589 int saved_errno = 0;
590 FILE *ret;
591
592 if (!strncmp(mode, "r+", 2)) {
593 open_mode = O_RDWR;
594 step = 2;
595 } else if (!strncmp(mode, "r", 1)) {
596 open_mode = O_RDONLY;
597 step = 1;
598 } else if (!strncmp(mode, "w+", 2)) {
599 open_mode = O_RDWR | O_TRUNC | O_CREAT;
600 step = 2;
601 } else if (!strncmp(mode, "w", 1)) {
602 open_mode = O_WRONLY | O_TRUNC | O_CREAT;
603 step = 1;
604 } else if (!strncmp(mode, "a+", 2)) {
605 open_mode = O_RDWR | O_CREAT | O_APPEND;
606 step = 2;
607 } else if (!strncmp(mode, "a", 1)) {
608 open_mode = O_WRONLY | O_CREAT | O_APPEND;
609 step = 1;
610 }
611 for (; mode[step]; step++)
612 if (mode[step] == 'x')
613 open_mode |= O_EXCL;
614 open_mode |= O_CLOEXEC;
615
82371fdd 616 fd = open(path, open_mode, 0666);
db27c8d7
CS
617 if (fd < 0)
618 return NULL;
619
620 ret = fdopen(fd, mode);
621 saved_errno = errno;
622 if (!ret)
623 close(fd);
624 errno = saved_errno;
625 return ret;
626}
502657d5 627
ebec9176
AM
628extern struct lxc_popen_FILE *lxc_popen(const char *command)
629{
630 struct lxc_popen_FILE *fp = NULL;
631 int parent_end = -1, child_end = -1;
632 int pipe_fds[2];
633 pid_t child_pid;
634
635 int r = pipe2(pipe_fds, O_CLOEXEC);
636
637 if (r < 0) {
638 ERROR("pipe2 failure");
639 return NULL;
640 }
641
642 parent_end = pipe_fds[0];
643 child_end = pipe_fds[1];
644
645 child_pid = fork();
646
647 if (child_pid == 0) {
648 /* child */
649 int child_std_end = STDOUT_FILENO;
650
651 if (child_end != child_std_end) {
652 /* dup2() doesn't dup close-on-exec flag */
653 dup2(child_end, child_std_end);
654
655 /* it's safe not to close child_end here
656 * as it's marked close-on-exec anyway
657 */
658 } else {
659 /*
660 * The descriptor is already the one we will use.
661 * But it must not be marked close-on-exec.
662 * Undo the effects.
663 */
57d2be54
SG
664 if (fcntl(child_end, F_SETFD, 0) != 0) {
665 SYSERROR("Failed to remove FD_CLOEXEC from fd.");
666 exit(127);
667 }
ebec9176
AM
668 }
669
670 /*
671 * Unblock signals.
672 * This is the main/only reason
673 * why we do our lousy popen() emulation.
674 */
675 {
676 sigset_t mask;
677 sigfillset(&mask);
678 sigprocmask(SIG_UNBLOCK, &mask, NULL);
679 }
680
681 execl("/bin/sh", "sh", "-c", command, (char *) NULL);
682 exit(127);
683 }
684
685 /* parent */
686
687 close(child_end);
688 child_end = -1;
689
690 if (child_pid < 0) {
691 ERROR("fork failure");
692 goto error;
693 }
694
695 fp = calloc(1, sizeof(*fp));
696 if (!fp) {
697 ERROR("failed to allocate memory");
698 goto error;
699 }
700
701 fp->f = fdopen(parent_end, "r");
702 if (!fp->f) {
703 ERROR("fdopen failure");
704 goto error;
705 }
706
707 fp->child_pid = child_pid;
708
709 return fp;
710
711error:
712
713 if (fp) {
714 if (fp->f) {
715 fclose(fp->f);
716 parent_end = -1; /* so we do not close it second time */
717 }
718
719 free(fp);
720 }
721
ebec9176
AM
722 if (parent_end != -1)
723 close(parent_end);
724
725 return NULL;
726}
727
ebec9176
AM
728extern int lxc_pclose(struct lxc_popen_FILE *fp)
729{
730 FILE *f = NULL;
731 pid_t child_pid = 0;
732 int wstatus = 0;
733 pid_t wait_pid;
734
735 if (fp) {
736 f = fp->f;
737 child_pid = fp->child_pid;
738 /* free memory (we still need to close file stream) */
739 free(fp);
740 fp = NULL;
741 }
742
743 if (!f || fclose(f)) {
744 ERROR("fclose failure");
745 return -1;
746 }
747
748 do {
749 wait_pid = waitpid(child_pid, &wstatus, 0);
750 } while (wait_pid == -1 && errno == EINTR);
751
752 if (wait_pid == -1) {
753 ERROR("waitpid failure");
754 return -1;
755 }
756
757 return wstatus;
758}
759
502657d5
CS
760char *lxc_string_replace(const char *needle, const char *replacement, const char *haystack)
761{
762 ssize_t len = -1, saved_len = -1;
763 char *result = NULL;
764 size_t replacement_len = strlen(replacement);
765 size_t needle_len = strlen(needle);
766
767 /* should be executed exactly twice */
768 while (len == -1 || result == NULL) {
769 char *p;
770 char *last_p;
771 ssize_t part_len;
772
773 if (len != -1) {
774 result = calloc(1, len + 1);
775 if (!result)
776 return NULL;
777 saved_len = len;
778 }
779
780 len = 0;
781
782 for (last_p = (char *)haystack, p = strstr(last_p, needle); p; last_p = p, p = strstr(last_p, needle)) {
783 part_len = (ssize_t)(p - last_p);
784 if (result && part_len > 0)
785 memcpy(&result[len], last_p, part_len);
786 len += part_len;
787 if (result && replacement_len > 0)
788 memcpy(&result[len], replacement, replacement_len);
789 len += replacement_len;
790 p += needle_len;
791 }
792 part_len = strlen(last_p);
793 if (result && part_len > 0)
794 memcpy(&result[len], last_p, part_len);
795 len += part_len;
796 }
797
798 /* make sure we did the same thing twice,
799 * once for calculating length, the other
800 * time for copying data */
801 assert(saved_len == len);
802 /* make sure we didn't overwrite any buffer,
803 * due to calloc the string should be 0-terminated */
804 assert(result[len] == '\0');
805
806 return result;
807}
808
809bool lxc_string_in_array(const char *needle, const char **haystack)
810{
811 for (; haystack && *haystack; haystack++)
812 if (!strcmp(needle, *haystack))
813 return true;
814 return false;
815}
816
817char *lxc_string_join(const char *sep, const char **parts, bool use_as_prefix)
818{
819 char *result;
820 char **p;
821 size_t sep_len = strlen(sep);
822 size_t result_len = use_as_prefix * sep_len;
823
824 /* calculate new string length */
825 for (p = (char **)parts; *p; p++)
826 result_len += (p > (char **)parts) * sep_len + strlen(*p);
827
828 result = calloc(result_len + 1, 1);
829 if (!result)
830 return NULL;
831
832 if (use_as_prefix)
833 strcpy(result, sep);
834 for (p = (char **)parts; *p; p++) {
835 if (p > (char **)parts)
836 strcat(result, sep);
837 strcat(result, *p);
838 }
839
840 return result;
841}
842
843char **lxc_normalize_path(const char *path)
844{
845 char **components;
846 char **p;
847 size_t components_len = 0;
848 size_t pos = 0;
849
850 components = lxc_string_split(path, '/');
851 if (!components)
852 return NULL;
853 for (p = components; *p; p++)
854 components_len++;
855
856 /* resolve '.' and '..' */
857 for (pos = 0; pos < components_len; ) {
858 if (!strcmp(components[pos], ".") || (!strcmp(components[pos], "..") && pos == 0)) {
859 /* eat this element */
860 free(components[pos]);
861 memmove(&components[pos], &components[pos+1], sizeof(char *) * (components_len - pos));
862 components_len--;
863 } else if (!strcmp(components[pos], "..")) {
864 /* eat this and the previous element */
865 free(components[pos - 1]);
866 free(components[pos]);
867 memmove(&components[pos-1], &components[pos+1], sizeof(char *) * (components_len - pos));
868 components_len -= 2;
869 pos--;
870 } else {
871 pos++;
872 }
873 }
874
875 return components;
876}
877
24b51482
CS
878char *lxc_append_paths(const char *first, const char *second)
879{
880 size_t len = strlen(first) + strlen(second) + 1;
881 const char *pattern = "%s%s";
882 char *result = NULL;
883
884 if (second[0] != '/') {
885 len += 1;
886 pattern = "%s/%s";
887 }
888
889 result = calloc(1, len);
890 if (!result)
891 return NULL;
892
893 snprintf(result, len, pattern, first, second);
894 return result;
895}
896
502657d5
CS
897bool lxc_string_in_list(const char *needle, const char *haystack, char _sep)
898{
899 char *token, *str, *saveptr = NULL;
900 char sep[2] = { _sep, '\0' };
901
902 if (!haystack || !needle)
903 return 0;
904
905 str = alloca(strlen(haystack)+1);
906 strcpy(str, haystack);
907 for (; (token = strtok_r(str, sep, &saveptr)); str = NULL) {
908 if (strcmp(needle, token) == 0)
909 return 1;
910 }
911
912 return 0;
913}
914
915char **lxc_string_split(const char *string, char _sep)
916{
917 char *token, *str, *saveptr = NULL;
918 char sep[2] = { _sep, '\0' };
919 char **result = NULL;
920 size_t result_capacity = 0;
921 size_t result_count = 0;
922 int r, saved_errno;
923
924 if (!string)
925 return calloc(1, sizeof(char *));
926
927 str = alloca(strlen(string)+1);
928 strcpy(str, string);
929 for (; (token = strtok_r(str, sep, &saveptr)); str = NULL) {
930 r = lxc_grow_array((void ***)&result, &result_capacity, result_count + 1, 16);
931 if (r < 0)
932 goto error_out;
933 result[result_count] = strdup(token);
934 if (!result[result_count])
935 goto error_out;
936 result_count++;
937 }
938
939 /* if we allocated too much, reduce it */
940 return realloc(result, (result_count + 1) * sizeof(char *));
941error_out:
942 saved_errno = errno;
943 lxc_free_array((void **)result, free);
944 errno = saved_errno;
945 return NULL;
946}
947
948char **lxc_string_split_and_trim(const char *string, char _sep)
949{
950 char *token, *str, *saveptr = NULL;
951 char sep[2] = { _sep, '\0' };
952 char **result = NULL;
953 size_t result_capacity = 0;
954 size_t result_count = 0;
955 int r, saved_errno;
956 size_t i = 0;
957
958 if (!string)
959 return calloc(1, sizeof(char *));
960
961 str = alloca(strlen(string)+1);
962 strcpy(str, string);
963 for (; (token = strtok_r(str, sep, &saveptr)); str = NULL) {
964 while (token[0] == ' ' || token[0] == '\t')
965 token++;
966 i = strlen(token);
967 while (i > 0 && (token[i - 1] == ' ' || token[i - 1] == '\t')) {
968 token[i - 1] = '\0';
969 i--;
970 }
971 r = lxc_grow_array((void ***)&result, &result_capacity, result_count + 1, 16);
972 if (r < 0)
973 goto error_out;
974 result[result_count] = strdup(token);
975 if (!result[result_count])
976 goto error_out;
977 result_count++;
978 }
979
980 /* if we allocated too much, reduce it */
981 return realloc(result, (result_count + 1) * sizeof(char *));
982error_out:
983 saved_errno = errno;
984 lxc_free_array((void **)result, free);
985 errno = saved_errno;
986 return NULL;
987}
988
989void lxc_free_array(void **array, lxc_free_fn element_free_fn)
990{
991 void **p;
992 for (p = array; p && *p; p++)
993 element_free_fn(*p);
994 free((void*)array);
995}
996
997int lxc_grow_array(void ***array, size_t* capacity, size_t new_size, size_t capacity_increment)
998{
999 size_t new_capacity;
1000 void **new_array;
1001
1002 /* first time around, catch some trivial mistakes of the user
1003 * only initializing one of these */
1004 if (!*array || !*capacity) {
1005 *array = NULL;
1006 *capacity = 0;
1007 }
1008
1009 new_capacity = *capacity;
1010 while (new_size + 1 > new_capacity)
1011 new_capacity += capacity_increment;
1012 if (new_capacity != *capacity) {
1013 /* we have to reallocate */
1014 new_array = realloc(*array, new_capacity * sizeof(void *));
1015 if (!new_array)
1016 return -1;
1017 memset(&new_array[*capacity], 0, (new_capacity - (*capacity)) * sizeof(void *));
1018 *array = new_array;
1019 *capacity = new_capacity;
1020 }
1021
1022 /* array has sufficient elements */
1023 return 0;
1024}
1025
1026size_t lxc_array_len(void **array)
1027{
1028 void **p;
1029 size_t result = 0;
1030
1031 for (p = array; p && *p; p++)
1032 result++;
1033
1034 return result;
1035}
1036
0e95426b
CS
1037int lxc_write_to_file(const char *filename, const void* buf, size_t count, bool add_newline)
1038{
1039 int fd, saved_errno;
1040 ssize_t ret;
1041
1042 fd = open(filename, O_WRONLY | O_TRUNC | O_CREAT | O_CLOEXEC, 0666);
1043 if (fd < 0)
1044 return -1;
1045 ret = lxc_write_nointr(fd, buf, count);
1046 if (ret < 0)
799f29ab 1047 goto out_error;
0e95426b
CS
1048 if ((size_t)ret != count)
1049 goto out_error;
1050 if (add_newline) {
1051 ret = lxc_write_nointr(fd, "\n", 1);
1052 if (ret != 1)
1053 goto out_error;
1054 }
1055 close(fd);
1056 return 0;
1057
1058out_error:
1059 saved_errno = errno;
1060 close(fd);
1061 errno = saved_errno;
1062 return -1;
1063}
1064
1065int lxc_read_from_file(const char *filename, void* buf, size_t count)
1066{
1067 int fd = -1, saved_errno;
1068 ssize_t ret;
1069
1070 fd = open(filename, O_RDONLY | O_CLOEXEC);
1071 if (fd < 0)
1072 return -1;
1073
1074 if (!buf || !count) {
1075 char buf2[100];
1076 size_t count2 = 0;
1077 while ((ret = read(fd, buf2, 100)) > 0)
1078 count2 += ret;
1079 if (ret >= 0)
1080 ret = count2;
1081 } else {
1082 memset(buf, 0, count);
1083 ret = read(fd, buf, count);
1084 }
1085
1086 if (ret < 0)
1087 ERROR("read %s: %s", filename, strerror(errno));
1088
1089 saved_errno = errno;
1090 close(fd);
1091 errno = saved_errno;
1092 return ret;
1093}
799f29ab
ÇO
1094
1095void **lxc_append_null_to_array(void **array, size_t count)
1096{
1097 void **temp;
1098
1099 /* Append NULL to the array */
1100 if (count) {
1101 temp = realloc(array, (count + 1) * sizeof(*array));
1102 if (!temp) {
1103 int i;
1104 for (i = 0; i < count; i++)
1105 free(array[i]);
1106 free(array);
1107 return NULL;
1108 }
1109 array = temp;
1110 array[count] = NULL;
1111 }
1112 return array;
1113}
508c263e
SH
1114
1115int randseed(bool srand_it)
1116{
1117 /*
1118 srand pre-seed function based on /dev/urandom
1119 */
1120 unsigned int seed=time(NULL)+getpid();
1121
1122 FILE *f;
1123 f = fopen("/dev/urandom", "r");
1124 if (f) {
1125 int ret = fread(&seed, sizeof(seed), 1, f);
1126 if (ret != 1)
1127 DEBUG("unable to fread /dev/urandom, %s, fallback to time+pid rand seed", strerror(errno));
1128 fclose(f);
1129 }
1130
1131 if (srand_it)
1132 srand(seed);
1133
1134 return seed;
1135}
5d897655
SH
1136
1137uid_t get_ns_uid(uid_t orig)
1138{
1139 char *line = NULL;
1140 size_t sz = 0;
1141 uid_t nsid, hostid, range;
1142 FILE *f = fopen("/proc/self/uid_map", "r");
1143 if (!f)
1144 return 0;
1145
1146 while (getline(&line, &sz, f) != -1) {
1147 if (sscanf(line, "%u %u %u", &nsid, &hostid, &range) != 3)
1148 continue;
1149 if (hostid <= orig && hostid + range > orig) {
1150 nsid += orig - hostid;
1151 goto found;
1152 }
1153 }
1154
1155 nsid = 0;
1156found:
1157 fclose(f);
1158 free(line);
1159 return nsid;
1160}
c476bdce
SH
1161
1162bool dir_exists(const char *path)
1163{
1164 struct stat sb;
1165 int ret;
1166
1167 ret = stat(path, &sb);
1168 if (ret < 0)
1169 // could be something other than eexist, just say no
1170 return false;
1171 return S_ISDIR(sb.st_mode);
1172}
93c379f0
ÇO
1173
1174/* Note we don't use SHA-1 here as we don't want to depend on HAVE_GNUTLS.
1175 * FNV has good anti collision properties and we're not worried
1176 * about pre-image resistance or one-way-ness, we're just trying to make
1177 * the name unique in the 108 bytes of space we have.
1178 */
1179uint64_t fnv_64a_buf(void *buf, size_t len, uint64_t hval)
1180{
1181 unsigned char *bp;
1182
1183 for(bp = buf; bp < (unsigned char *)buf + len; bp++)
1184 {
1185 /* xor the bottom with the current octet */
1186 hval ^= (uint64_t)*bp;
1187
1188 /* gcc optimised:
1189 * multiply by the 64 bit FNV magic prime mod 2^64
1190 */
1191 hval += (hval << 1) + (hval << 4) + (hval << 5) +
1192 (hval << 7) + (hval << 8) + (hval << 40);
1193 }
1194
1195 return hval;
1196}
2c6f3fc9
SH
1197
1198/*
1199 * Detect whether / is mounted MS_SHARED. The only way I know of to
1200 * check that is through /proc/self/mountinfo.
1201 * I'm only checking for /. If the container rootfs or mount location
1202 * is MS_SHARED, but not '/', then you're out of luck - figuring that
1203 * out would be too much work to be worth it.
1204 */
1205#define LINELEN 4096
1206int detect_shared_rootfs(void)
1207{
1208 char buf[LINELEN], *p;
1209 FILE *f;
1210 int i;
1211 char *p2;
1212
1213 f = fopen("/proc/self/mountinfo", "r");
1214 if (!f)
1215 return 0;
1216 while (fgets(buf, LINELEN, f)) {
1217 for (p = buf, i=0; p && i < 4; i++)
1218 p = index(p+1, ' ');
1219 if (!p)
1220 continue;
1221 p2 = index(p+1, ' ');
1222 if (!p2)
1223 continue;
1224 *p2 = '\0';
1225 if (strcmp(p+1, "/") == 0) {
1226 // this is '/'. is it shared?
1227 p = index(p2+1, ' ');
1228 if (p && strstr(p, "shared:")) {
1229 fclose(f);
1230 return 1;
1231 }
1232 }
1233 }
1234 fclose(f);
1235 return 0;
1236}
0e6e3a41
SG
1237
1238bool on_path(char *cmd) {
1239 char *path = NULL;
1240 char *entry = NULL;
1241 char *saveptr = NULL;
1242 char cmdpath[MAXPATHLEN];
1243 int ret;
1244
1245 path = getenv("PATH");
1246 if (!path)
1247 return false;
1248
1249 path = strdup(path);
1250 if (!path)
1251 return false;
1252
1253 entry = strtok_r(path, ":", &saveptr);
1254 while (entry) {
1255 ret = snprintf(cmdpath, MAXPATHLEN, "%s/%s", entry, cmd);
1256
1257 if (ret < 0 || ret >= MAXPATHLEN)
1258 goto next_loop;
1259
1260 if (access(cmdpath, X_OK) == 0) {
1261 free(path);
1262 return true;
1263 }
1264
1265next_loop:
1266 entry = strtok(NULL, ":");
1267 }
1268
1269 free(path);
1270 return false;
1271}