Commit 025ed0f3 by Serge Hallyn

make heavier use of process_lock (v2)

pthread_mutex_lock() will only return an error if it was set to PTHREAD_MUTEX_ERRORCHECK and we are recursively calling it (and would otherwise have deadlocked). If that's the case then log a message for future debugging and exit. Trying to "recover" is nonsense at that point. process_lock() was held over too long a time in lxcapi_start() in the daemonize case. (note the non-daemonized case still needs a check to enforce that it must NOT be called while threaded). Add process_lock() at least across all open/close/socket() calls. Anything done after a fork() doesn't need the locks as it is no longer threaded - so some open/close/dups()s are not locked for that reason. However, some common functions are called from both threaded and non-threaded contexts. So after doing a fork(), do a possibly-extraneous process_unlock() to make sure that, if we were forked while pthread mutex was held, we aren't deadlocked by nobody. Tested that lp:~serge-hallyn/+junk/lxc-test still works with this patch. Signed-off-by: 's avatarSerge Hallyn <serge.hallyn@ubuntu.com> Tested-by: 's avatarS.Çağlar Onur <caglar@10ur.org> Acked-by: 's avatarStéphane Graber <stgraber@ubuntu.com>
parent beb6d93e
...@@ -30,6 +30,7 @@ ...@@ -30,6 +30,7 @@
#include <sys/un.h> #include <sys/un.h>
#include "log.h" #include "log.h"
#include "lxclock.h"
lxc_log_define(lxc_af_unix, lxc); lxc_log_define(lxc_af_unix, lxc);
...@@ -42,7 +43,9 @@ int lxc_af_unix_open(const char *path, int type, int flags) ...@@ -42,7 +43,9 @@ int lxc_af_unix_open(const char *path, int type, int flags)
if (flags & O_TRUNC) if (flags & O_TRUNC)
unlink(path); unlink(path);
process_lock();
fd = socket(PF_UNIX, type, 0); fd = socket(PF_UNIX, type, 0);
process_unlock();
if (fd < 0) if (fd < 0)
return -1; return -1;
...@@ -57,7 +60,9 @@ int lxc_af_unix_open(const char *path, int type, int flags) ...@@ -57,7 +60,9 @@ int lxc_af_unix_open(const char *path, int type, int flags)
if (path[0]) { if (path[0]) {
len = strlen(path); len = strlen(path);
if (len >= sizeof(addr.sun_path)) { if (len >= sizeof(addr.sun_path)) {
process_lock();
close(fd); close(fd);
process_unlock();
errno = ENAMETOOLONG; errno = ENAMETOOLONG;
return -1; return -1;
} }
...@@ -66,14 +71,18 @@ int lxc_af_unix_open(const char *path, int type, int flags) ...@@ -66,14 +71,18 @@ int lxc_af_unix_open(const char *path, int type, int flags)
if (bind(fd, (struct sockaddr *)&addr, sizeof(addr))) { if (bind(fd, (struct sockaddr *)&addr, sizeof(addr))) {
int tmp = errno; int tmp = errno;
process_lock();
close(fd); close(fd);
process_unlock();
errno = tmp; errno = tmp;
return -1; return -1;
} }
if (type == SOCK_STREAM && listen(fd, 100)) { if (type == SOCK_STREAM && listen(fd, 100)) {
int tmp = errno; int tmp = errno;
process_lock();
close(fd); close(fd);
process_unlock();
errno = tmp; errno = tmp;
return -1; return -1;
} }
...@@ -90,7 +99,9 @@ int lxc_af_unix_close(int fd) ...@@ -90,7 +99,9 @@ int lxc_af_unix_close(int fd)
addr.sun_path[0]) addr.sun_path[0])
unlink(addr.sun_path); unlink(addr.sun_path);
process_lock();
close(fd); close(fd);
process_unlock();
return 0; return 0;
} }
...@@ -100,7 +111,9 @@ int lxc_af_unix_connect(const char *path) ...@@ -100,7 +111,9 @@ int lxc_af_unix_connect(const char *path)
int fd; int fd;
struct sockaddr_un addr; struct sockaddr_un addr;
process_lock();
fd = socket(PF_UNIX, SOCK_STREAM, 0); fd = socket(PF_UNIX, SOCK_STREAM, 0);
process_unlock();
if (fd < 0) if (fd < 0)
return -1; return -1;
...@@ -113,7 +126,9 @@ int lxc_af_unix_connect(const char *path) ...@@ -113,7 +126,9 @@ int lxc_af_unix_connect(const char *path)
if (connect(fd, (struct sockaddr *)&addr, sizeof(addr))) { if (connect(fd, (struct sockaddr *)&addr, sizeof(addr))) {
int tmp = errno; int tmp = errno;
process_lock();
close(fd); close(fd);
process_unlock();
errno = tmp; errno = tmp;
return -1; return -1;
} }
......
...@@ -28,6 +28,7 @@ ...@@ -28,6 +28,7 @@
#include "log.h" #include "log.h"
#include "apparmor.h" #include "apparmor.h"
#include "lxclock.h"
lxc_log_define(lxc_apparmor, lxc); lxc_log_define(lxc_apparmor, lxc);
...@@ -53,7 +54,9 @@ extern char *aa_get_profile(pid_t pid) ...@@ -53,7 +54,9 @@ extern char *aa_get_profile(pid_t pid)
return NULL; return NULL;
} }
again: again:
process_lock();
f = fopen(path, "r"); f = fopen(path, "r");
process_unlock();
if (!f) { if (!f) {
SYSERROR("opening %s\n", path); SYSERROR("opening %s\n", path);
if (buf) if (buf)
...@@ -65,11 +68,15 @@ again: ...@@ -65,11 +68,15 @@ again:
memset(buf, 0, sz); memset(buf, 0, sz);
if (!buf) { if (!buf) {
ERROR("out of memory"); ERROR("out of memory");
process_lock();
fclose(f); fclose(f);
process_unlock();
return NULL; return NULL;
} }
ret = fread(buf, 1, sz - 1, f); ret = fread(buf, 1, sz - 1, f);
process_lock();
fclose(f); fclose(f);
process_unlock();
if (ret >= sz) if (ret >= sz)
goto again; goto again;
if (ret < 0) { if (ret < 0) {
...@@ -108,11 +115,15 @@ static int check_apparmor_enabled(void) ...@@ -108,11 +115,15 @@ static int check_apparmor_enabled(void)
ret = stat(AA_MOUNT_RESTR, &statbuf); ret = stat(AA_MOUNT_RESTR, &statbuf);
if (ret != 0) if (ret != 0)
return 0; return 0;
process_lock();
fin = fopen(AA_ENABLED_FILE, "r"); fin = fopen(AA_ENABLED_FILE, "r");
process_unlock();
if (!fin) if (!fin)
return 0; return 0;
ret = fscanf(fin, "%c", &e); ret = fscanf(fin, "%c", &e);
process_lock();
fclose(fin); fclose(fin);
process_unlock();
if (ret == 1 && e == 'Y') if (ret == 1 && e == 'Y')
return 1; return 1;
return 0; return 0;
......
...@@ -50,6 +50,7 @@ ...@@ -50,6 +50,7 @@
#include "utils.h" #include "utils.h"
#include "commands.h" #include "commands.h"
#include "cgroup.h" #include "cgroup.h"
#include "lxclock.h"
#if HAVE_SYS_PERSONALITY_H #if HAVE_SYS_PERSONALITY_H
#include <sys/personality.h> #include <sys/personality.h>
...@@ -78,7 +79,9 @@ struct lxc_proc_context_info *lxc_proc_get_context_info(pid_t pid) ...@@ -78,7 +79,9 @@ struct lxc_proc_context_info *lxc_proc_get_context_info(pid_t pid)
/* read capabilities */ /* read capabilities */
snprintf(proc_fn, MAXPATHLEN, "/proc/%d/status", pid); snprintf(proc_fn, MAXPATHLEN, "/proc/%d/status", pid);
process_lock();
proc_file = fopen(proc_fn, "r"); proc_file = fopen(proc_fn, "r");
process_unlock();
if (!proc_file) { if (!proc_file) {
SYSERROR("Could not open %s", proc_fn); SYSERROR("Could not open %s", proc_fn);
goto out_error; goto out_error;
...@@ -95,7 +98,9 @@ struct lxc_proc_context_info *lxc_proc_get_context_info(pid_t pid) ...@@ -95,7 +98,9 @@ struct lxc_proc_context_info *lxc_proc_get_context_info(pid_t pid)
if (line) if (line)
free(line); free(line);
process_lock();
fclose(proc_file); fclose(proc_file);
process_unlock();
if (!found) { if (!found) {
SYSERROR("Could not read capability bounding set from %s", proc_fn); SYSERROR("Could not read capability bounding set from %s", proc_fn);
...@@ -106,14 +111,18 @@ struct lxc_proc_context_info *lxc_proc_get_context_info(pid_t pid) ...@@ -106,14 +111,18 @@ struct lxc_proc_context_info *lxc_proc_get_context_info(pid_t pid)
/* read personality */ /* read personality */
snprintf(proc_fn, MAXPATHLEN, "/proc/%d/personality", pid); snprintf(proc_fn, MAXPATHLEN, "/proc/%d/personality", pid);
process_lock();
proc_file = fopen(proc_fn, "r"); proc_file = fopen(proc_fn, "r");
process_unlock();
if (!proc_file) { if (!proc_file) {
SYSERROR("Could not open %s", proc_fn); SYSERROR("Could not open %s", proc_fn);
goto out_error; goto out_error;
} }
ret = fscanf(proc_file, "%lx", &info->personality); ret = fscanf(proc_file, "%lx", &info->personality);
process_lock();
fclose(proc_file); fclose(proc_file);
process_unlock();
if (ret == EOF || ret == 0) { if (ret == EOF || ret == 0) {
SYSERROR("Could not read personality from %s", proc_fn); SYSERROR("Could not read personality from %s", proc_fn);
...@@ -162,15 +171,19 @@ int lxc_attach_to_ns(pid_t pid, int which) ...@@ -162,15 +171,19 @@ int lxc_attach_to_ns(pid_t pid, int which)
} }
snprintf(path, MAXPATHLEN, "/proc/%d/ns/%s", pid, ns[i]); snprintf(path, MAXPATHLEN, "/proc/%d/ns/%s", pid, ns[i]);
process_lock();
fd[i] = open(path, O_RDONLY | O_CLOEXEC); fd[i] = open(path, O_RDONLY | O_CLOEXEC);
process_unlock();
if (fd[i] < 0) { if (fd[i] < 0) {
saved_errno = errno; saved_errno = errno;
/* close all already opened file descriptors before /* close all already opened file descriptors before
* we return an error, so we don't leak them * we return an error, so we don't leak them
*/ */
process_lock();
for (j = 0; j < i; j++) for (j = 0; j < i; j++)
close(fd[j]); close(fd[j]);
process_unlock();
errno = saved_errno; errno = saved_errno;
SYSERROR("failed to open '%s'", path); SYSERROR("failed to open '%s'", path);
...@@ -190,7 +203,9 @@ int lxc_attach_to_ns(pid_t pid, int which) ...@@ -190,7 +203,9 @@ int lxc_attach_to_ns(pid_t pid, int which)
return -1; return -1;
} }
process_lock();
close(fd[i]); close(fd[i]);
process_unlock();
} }
return 0; return 0;
...@@ -378,14 +393,18 @@ char *lxc_attach_getpwshell(uid_t uid) ...@@ -378,14 +393,18 @@ char *lxc_attach_getpwshell(uid_t uid)
* getent program, and we need to capture its * getent program, and we need to capture its
* output, so we use a pipe for that purpose * output, so we use a pipe for that purpose
*/ */
process_lock();
ret = pipe(pipes); ret = pipe(pipes);
process_unlock();
if (ret < 0) if (ret < 0)
return NULL; return NULL;
pid = fork(); pid = fork();
if (pid < 0) { if (pid < 0) {
process_lock();
close(pipes[0]); close(pipes[0]);
close(pipes[1]); close(pipes[1]);
process_unlock();
return NULL; return NULL;
} }
...@@ -397,9 +416,13 @@ char *lxc_attach_getpwshell(uid_t uid) ...@@ -397,9 +416,13 @@ char *lxc_attach_getpwshell(uid_t uid)
int found = 0; int found = 0;
int status; int status;
process_lock();
close(pipes[1]); close(pipes[1]);
process_unlock();
process_lock();
pipe_f = fdopen(pipes[0], "r"); pipe_f = fdopen(pipes[0], "r");
process_unlock();
while (getline(&line, &line_bufsz, pipe_f) != -1) { while (getline(&line, &line_bufsz, pipe_f) != -1) {
char *token; char *token;
char *saveptr = NULL; char *saveptr = NULL;
...@@ -456,7 +479,9 @@ char *lxc_attach_getpwshell(uid_t uid) ...@@ -456,7 +479,9 @@ char *lxc_attach_getpwshell(uid_t uid)
} }
free(line); free(line);
process_lock();
fclose(pipe_f); fclose(pipe_f);
process_unlock();
again: again:
if (waitpid(pid, &status, 0) < 0) { if (waitpid(pid, &status, 0) < 0) {
if (errno == EINTR) if (errno == EINTR)
...@@ -489,6 +514,7 @@ char *lxc_attach_getpwshell(uid_t uid) ...@@ -489,6 +514,7 @@ char *lxc_attach_getpwshell(uid_t uid)
NULL NULL
}; };
process_unlock(); // we're no longer sharing
close(pipes[0]); close(pipes[0]);
/* we want to capture stdout */ /* we want to capture stdout */
...@@ -651,7 +677,9 @@ int lxc_attach(const char* name, const char* lxcpath, lxc_attach_exec_t exec_fun ...@@ -651,7 +677,9 @@ int lxc_attach(const char* name, const char* lxcpath, lxc_attach_exec_t exec_fun
* close socket close socket * close socket close socket
* run program * run program
*/ */
process_lock();
ret = socketpair(PF_LOCAL, SOCK_STREAM | SOCK_CLOEXEC, 0, ipc_sockets); ret = socketpair(PF_LOCAL, SOCK_STREAM | SOCK_CLOEXEC, 0, ipc_sockets);
process_unlock();
if (ret < 0) { if (ret < 0) {
SYSERROR("could not set up required IPC mechanism for attaching"); SYSERROR("could not set up required IPC mechanism for attaching");
free(cwd); free(cwd);
...@@ -689,7 +717,9 @@ int lxc_attach(const char* name, const char* lxcpath, lxc_attach_exec_t exec_fun ...@@ -689,7 +717,9 @@ int lxc_attach(const char* name, const char* lxcpath, lxc_attach_exec_t exec_fun
/* inital thread, we close the socket that is for the /* inital thread, we close the socket that is for the
* subprocesses * subprocesses
*/ */
process_lock();
close(ipc_sockets[1]); close(ipc_sockets[1]);
process_unlock();
free(cwd); free(cwd);
/* get pid from intermediate process */ /* get pid from intermediate process */
...@@ -761,7 +791,9 @@ int lxc_attach(const char* name, const char* lxcpath, lxc_attach_exec_t exec_fun ...@@ -761,7 +791,9 @@ int lxc_attach(const char* name, const char* lxcpath, lxc_attach_exec_t exec_fun
/* now shut down communication with child, we're done */ /* now shut down communication with child, we're done */
shutdown(ipc_sockets[0], SHUT_RDWR); shutdown(ipc_sockets[0], SHUT_RDWR);
process_lock();
close(ipc_sockets[0]); close(ipc_sockets[0]);
process_unlock();
free(init_ctx->aa_profile); free(init_ctx->aa_profile);
free(init_ctx); free(init_ctx);
...@@ -778,7 +810,9 @@ int lxc_attach(const char* name, const char* lxcpath, lxc_attach_exec_t exec_fun ...@@ -778,7 +810,9 @@ int lxc_attach(const char* name, const char* lxcpath, lxc_attach_exec_t exec_fun
* otherwise the pid we're waiting for may never exit * otherwise the pid we're waiting for may never exit
*/ */
shutdown(ipc_sockets[0], SHUT_RDWR); shutdown(ipc_sockets[0], SHUT_RDWR);
process_lock();
close(ipc_sockets[0]); close(ipc_sockets[0]);
process_unlock();
if (to_cleanup_pid) if (to_cleanup_pid)
(void) wait_for_pid(to_cleanup_pid); (void) wait_for_pid(to_cleanup_pid);
free(init_ctx->aa_profile); free(init_ctx->aa_profile);
...@@ -786,6 +820,7 @@ int lxc_attach(const char* name, const char* lxcpath, lxc_attach_exec_t exec_fun ...@@ -786,6 +820,7 @@ int lxc_attach(const char* name, const char* lxcpath, lxc_attach_exec_t exec_fun
return -1; return -1;
} }
process_unlock(); // we're no longer sharing
/* first subprocess begins here, we close the socket that is for the /* first subprocess begins here, we close the socket that is for the
* initial thread * initial thread
*/ */
......
...@@ -70,6 +70,8 @@ static int do_rsync(const char *src, const char *dest) ...@@ -70,6 +70,8 @@ static int do_rsync(const char *src, const char *dest)
return -1; return -1;
if (pid > 0) if (pid > 0)
return wait_for_pid(pid); return wait_for_pid(pid);
process_unlock(); // we're no longer sharing
l = strlen(src) + 2; l = strlen(src) + 2;
s = malloc(l); s = malloc(l);
if (!s) if (!s)
...@@ -93,11 +95,15 @@ static int blk_getsize(struct bdev *bdev, unsigned long *size) ...@@ -93,11 +95,15 @@ static int blk_getsize(struct bdev *bdev, unsigned long *size)
if (strcmp(bdev->type, "loop") == 0) if (strcmp(bdev->type, "loop") == 0)
path = bdev->src + 5; path = bdev->src + 5;
process_lock();
fd = open(path, O_RDONLY); fd = open(path, O_RDONLY);
process_unlock();
if (fd < 0) if (fd < 0)
return -1; return -1;
ret = ioctl(fd, BLKGETSIZE64, size); ret = ioctl(fd, BLKGETSIZE64, size);
process_lock();
close(fd); close(fd);
process_unlock();
return ret; return ret;
} }
...@@ -194,6 +200,7 @@ static int do_mkfs(const char *path, const char *fstype) ...@@ -194,6 +200,7 @@ static int do_mkfs(const char *path, const char *fstype)
if (pid > 0) if (pid > 0)
return wait_for_pid(pid); return wait_for_pid(pid);
process_unlock(); // we're no longer sharing
// If the file is not a block device, we don't want mkfs to ask // If the file is not a block device, we don't want mkfs to ask
// us about whether to proceed. // us about whether to proceed.
close(0); close(0);
...@@ -252,16 +259,23 @@ static int detect_fs(struct bdev *bdev, char *type, int len) ...@@ -252,16 +259,23 @@ static int detect_fs(struct bdev *bdev, char *type, int len)
if (strcmp(bdev->type, "loop") == 0) if (strcmp(bdev->type, "loop") == 0)
srcdev = bdev->src + 5; srcdev = bdev->src + 5;
if (pipe(p) < 0) process_lock();
ret = pipe(p);
process_unlock();
if (ret < 0)
return -1; return -1;
if ((pid = fork()) < 0) if ((pid = fork()) < 0)
return -1; return -1;
if (pid > 0) { if (pid > 0) {
int status; int status;
process_lock();
close(p[1]); close(p[1]);
process_unlock();
memset(type, 0, len); memset(type, 0, len);
ret = read(p[0], type, len-1); ret = read(p[0], type, len-1);
process_lock();
close(p[0]); close(p[0]);
process_unlock();
if (ret < 0) { if (ret < 0) {
SYSERROR("error reading from pipe"); SYSERROR("error reading from pipe");
wait(&status); wait(&status);
...@@ -277,6 +291,7 @@ static int detect_fs(struct bdev *bdev, char *type, int len) ...@@ -277,6 +291,7 @@ static int detect_fs(struct bdev *bdev, char *type, int len)
return ret; return ret;
} }
process_unlock(); // we're no longer sharing
if (unshare(CLONE_NEWNS) < 0) if (unshare(CLONE_NEWNS) < 0)
exit(1); exit(1);
...@@ -488,7 +503,10 @@ static int zfs_list_entry(const char *path, char *output, size_t inlen) ...@@ -488,7 +503,10 @@ static int zfs_list_entry(const char *path, char *output, size_t inlen)
FILE *f; FILE *f;
int found=0; int found=0;
if ((f = popen("zfs list 2> /dev/null", "r")) == NULL) { process_lock();
f = popen("zfs list 2> /dev/null", "r");
process_unlock();
if (f == NULL) {
SYSERROR("popen failed"); SYSERROR("popen failed");
return 0; return 0;
} }
...@@ -498,7 +516,9 @@ static int zfs_list_entry(const char *path, char *output, size_t inlen) ...@@ -498,7 +516,9 @@ static int zfs_list_entry(const char *path, char *output, size_t inlen)
break; break;
} }
} }
process_lock();
(void) pclose(f); (void) pclose(f);
process_unlock();
return found; return found;
} }
...@@ -566,6 +586,8 @@ static int zfs_clone(const char *opath, const char *npath, const char *oname, ...@@ -566,6 +586,8 @@ static int zfs_clone(const char *opath, const char *npath, const char *oname,
return -1; return -1;
if (!pid) { if (!pid) {
char dev[MAXPATHLEN]; char dev[MAXPATHLEN];
process_unlock(); // we're no longer sharing
ret = snprintf(dev, MAXPATHLEN, "%s/%s", zfsroot, nname); ret = snprintf(dev, MAXPATHLEN, "%s/%s", zfsroot, nname);
if (ret < 0 || ret >= MAXPATHLEN) if (ret < 0 || ret >= MAXPATHLEN)
exit(1); exit(1);
...@@ -589,6 +611,7 @@ static int zfs_clone(const char *opath, const char *npath, const char *oname, ...@@ -589,6 +611,7 @@ static int zfs_clone(const char *opath, const char *npath, const char *oname,
if ((pid = fork()) < 0) if ((pid = fork()) < 0)
return -1; return -1;
if (!pid) { if (!pid) {
process_unlock(); // we're no longer sharing
execlp("zfs", "zfs", "destroy", path1, NULL); execlp("zfs", "zfs", "destroy", path1, NULL);
exit(1); exit(1);
} }
...@@ -599,6 +622,7 @@ static int zfs_clone(const char *opath, const char *npath, const char *oname, ...@@ -599,6 +622,7 @@ static int zfs_clone(const char *opath, const char *npath, const char *oname,
if ((pid = fork()) < 0) if ((pid = fork()) < 0)
return -1; return -1;
if (!pid) { if (!pid) {
process_unlock(); // we're no longer sharing
execlp("zfs", "zfs", "snapshot", path1, NULL); execlp("zfs", "zfs", "snapshot", path1, NULL);
exit(1); exit(1);
} }
...@@ -609,6 +633,7 @@ static int zfs_clone(const char *opath, const char *npath, const char *oname, ...@@ -609,6 +633,7 @@ static int zfs_clone(const char *opath, const char *npath, const char *oname,
if ((pid = fork()) < 0) if ((pid = fork()) < 0)
return -1; return -1;
if (!pid) { if (!pid) {
process_unlock(); // we're no longer sharing
execlp("zfs", "zfs", "clone", option, path1, path2, NULL); execlp("zfs", "zfs", "clone", option, path1, path2, NULL);
exit(1); exit(1);
} }
...@@ -659,6 +684,7 @@ static int zfs_destroy(struct bdev *orig) ...@@ -659,6 +684,7 @@ static int zfs_destroy(struct bdev *orig)
if (pid) if (pid)
return wait_for_pid(pid); return wait_for_pid(pid);
process_unlock(); // we're no longer sharing
if (!zfs_list_entry(orig->src, output, MAXPATHLEN)) { if (!zfs_list_entry(orig->src, output, MAXPATHLEN)) {
ERROR("Error: zfs entry for %s not found", orig->src); ERROR("Error: zfs entry for %s not found", orig->src);
return -1; return -1;
...@@ -703,6 +729,7 @@ static int zfs_create(struct bdev *bdev, const char *dest, const char *n, ...@@ -703,6 +729,7 @@ static int zfs_create(struct bdev *bdev, const char *dest, const char *n,
if (pid) if (pid)
return wait_for_pid(pid); return wait_for_pid(pid);
process_unlock(); // we're no longer sharing
char dev[MAXPATHLEN]; char dev[MAXPATHLEN];
ret = snprintf(dev, MAXPATHLEN, "%s/%s", zfsroot, n); ret = snprintf(dev, MAXPATHLEN, "%s/%s", zfsroot, n);
if (ret < 0 || ret >= MAXPATHLEN) if (ret < 0 || ret >= MAXPATHLEN)
...@@ -750,11 +777,15 @@ static int lvm_detect(const char *path) ...@@ -750,11 +777,15 @@ static int lvm_detect(const char *path)
ERROR("lvm uuid pathname too long"); ERROR("lvm uuid pathname too long");
return 0; return 0;
} }
process_lock();
fout = fopen(devp, "r"); fout = fopen(devp, "r");
process_unlock();
if (!fout) if (!fout)
return 0; return 0;
ret = fread(buf, 1, 4, fout); ret = fread(buf, 1, 4, fout);
process_lock();
fclose(fout); fclose(fout);
process_unlock();
if (ret != 4 || strncmp(buf, "LVM-", 4) != 0) if (ret != 4 || strncmp(buf, "LVM-", 4) != 0)
return 0; return 0;
return 1; return 1;
...@@ -797,6 +828,7 @@ static int do_lvm_create(const char *path, unsigned long size) ...@@ -797,6 +828,7 @@ static int do_lvm_create(const char *path, unsigned long size)
if (pid > 0) if (pid > 0)
return wait_for_pid(pid); return wait_for_pid(pid);
process_unlock(); // we're no longer sharing
// lvcreate default size is in M, not bytes. // lvcreate default size is in M, not bytes.
ret = snprintf(sz, 24, "%lu", size/1000000); ret = snprintf(sz, 24, "%lu", size/1000000);
if (ret < 0 || ret >= 24) if (ret < 0 || ret >= 24)
...@@ -832,6 +864,8 @@ static int lvm_snapshot(const char *orig, const char *path, unsigned long size) ...@@ -832,6 +864,8 @@ static int lvm_snapshot(const char *orig, const char *path, unsigned long size)
} }
if (pid > 0) if (pid > 0)
return wait_for_pid(pid); return wait_for_pid(pid);
process_unlock(); // we're no longer sharing
// lvcreate default size is in M, not bytes. // lvcreate default size is in M, not bytes.
ret = snprintf(sz, 24, "%lu", size/1000000); ret = snprintf(sz, 24, "%lu", size/1000000);
if (ret < 0 || ret >= 24) if (ret < 0 || ret >= 24)
...@@ -952,6 +986,7 @@ static int lvm_destroy(struct bdev *orig) ...@@ -952,6 +986,7 @@ static int lvm_destroy(struct bdev *orig)
if ((pid = fork()) < 0) if ((pid = fork()) < 0)
return -1; return -1;
if (!pid) { if (!pid) {
process_unlock(); // we're no longer sharing
execlp("lvremove", "lvremove", "-f", orig->src, NULL); execlp("lvremove", "lvremove", "-f", orig->src, NULL);
exit(1); exit(1);
} }
...@@ -1052,13 +1087,17 @@ static bool is_btrfs_fs(const char *path) ...@@ -1052,13 +1087,17 @@ static bool is_btrfs_fs(const char *path)
struct btrfs_ioctl_space_args sargs; struct btrfs_ioctl_space_args sargs;
// make sure this is a btrfs filesystem // make sure this is a btrfs filesystem
process_lock();
fd = open(path, O_RDONLY); fd = open(path, O_RDONLY);
process_unlock();
if (fd < 0) if (fd < 0)
return false; return false;
sargs.space_slots = 0; sargs.space_slots = 0;
sargs.total_spaces = 0; sargs.total_spaces = 0;
ret = ioctl(fd, BTRFS_IOC_SPACE_INFO, &sargs); ret = ioctl(fd, BTRFS_IOC_SPACE_INFO, &sargs);
process_lock();
close(fd); close(fd);
process_unlock();
if (ret < 0) if (ret < 0)
return false; return false;
...@@ -1155,7 +1194,10 @@ static int btrfs_subvolume_create(const char *path) ...@@ -1155,7 +1194,10 @@ static int btrfs_subvolume_create(const char *path)
} }
*p = '\0'; *p = '\0';
if ((fd = open(newfull, O_RDONLY)) < 0) { process_lock();
fd = open(newfull, O_RDONLY);
process_unlock();
if (fd < 0) {
ERROR("Error opening %s", newfull); ERROR("Error opening %s", newfull);
free(newfull); free(newfull);
return -1; return -1;
...@@ -1168,7 +1210,9 @@ static int btrfs_subvolume_create(const char *path) ...@@ -1168,7 +1210,9 @@ static int btrfs_subvolume_create(const char *path)
INFO("btrfs: snapshot create ioctl returned %d", ret); INFO("btrfs: snapshot create ioctl returned %d", ret);
free(newfull); free(newfull);
process_lock();
close(fd); close(fd);
process_unlock();
return ret; return ret;
} }
...@@ -1190,12 +1234,14 @@ static int btrfs_snapshot(const char *orig, const char *new) ...@@ -1190,12 +1234,14 @@ static int btrfs_snapshot(const char *orig, const char *new)
} }
newname = basename(newfull); newname = basename(newfull);
newdir = dirname(newfull); newdir = dirname(newfull);
process_lock();
fd = open(orig, O_RDONLY); fd = open(orig, O_RDONLY);
fddst = open(newdir, O_RDONLY);
process_unlock();
if (fd < 0) { if (fd < 0) {
SYSERROR("Error opening original rootfs %s", orig); SYSERROR("Error opening original rootfs %s", orig);
goto out; goto out;
} }
fddst = open(newdir, O_RDONLY);
if (fddst < 0) { if (fddst < 0) {
SYSERROR("Error opening new container dir %s", newdir); SYSERROR("Error opening new container dir %s", newdir);
goto out; goto out;
...@@ -1209,10 +1255,12 @@ static int btrfs_snapshot(const char *orig, const char *new) ...@@ -1209,10 +1255,12 @@ static int btrfs_snapshot(const char *orig, const char *new)
INFO("btrfs: snapshot create ioctl returned %d", ret); INFO("btrfs: snapshot create ioctl returned %d", ret);
out: out:
process_lock();
if (fddst != -1) if (fddst != -1)
close(fddst); close(fddst);
if (fd != -1) if (fd != -1)
close(fd); close(fd);
process_unlock();
if (newfull) if (newfull)
free(newfull); free(newfull);
return ret; return ret;
...@@ -1282,7 +1330,10 @@ static int btrfs_destroy(struct bdev *orig) ...@@ -1282,7 +1330,10 @@ static int btrfs_destroy(struct bdev *orig)
} }
*p = '\0'; *p = '\0';
if ((fd = open(newfull, O_RDONLY)) < 0) { process_lock();
fd = open(newfull, O_RDONLY);
process_unlock();
if (fd < 0) {
ERROR("Error opening %s", newfull); ERROR("Error opening %s", newfull);
free(newfull); free(newfull);
return -1; return -1;
...@@ -1295,7 +1346,9 @@ static int btrfs_destroy(struct bdev *orig) ...@@ -1295,7 +1346,9 @@ static int btrfs_destroy(struct bdev *orig)
INFO("btrfs: snapshot create ioctl returned %d", ret); INFO("btrfs: snapshot create ioctl returned %d", ret);
free(newfull); free(newfull);
process_lock();
close(fd); close(fd);
process_unlock();
return ret; return ret;
} }
...@@ -1335,7 +1388,10 @@ static int find_free_loopdev(int *retfd, char *namep) ...@@ -1335,7 +1388,10 @@ static int find_free_loopdev(int *retfd, char *namep)
DIR *dir; DIR *dir;
int fd = -1; int fd = -1;
if (!(dir = opendir("/dev"))) { process_lock();
dir = opendir("/dev");
process_unlock();
if (!dir) {
SYSERROR("Error opening /dev"); SYSERROR("Error opening /dev");
return -1; return -1;
} }
...@@ -1345,10 +1401,15 @@ static int find_free_loopdev(int *retfd, char *namep) ...@@ -1345,10 +1401,15 @@ static int find_free_loopdev(int *retfd, char *namep)
break; break;
if (strncmp(direntp->d_name, "loop", 4) != 0) if (strncmp(direntp->d_name, "loop", 4) != 0)
continue; continue;
if ((fd = openat(dirfd(dir), direntp->d_name, O_RDWR)) < 0) process_lock();
fd = openat(dirfd(dir), direntp->d_name, O_RDWR);
process_unlock();
if (fd < 0)
continue; continue;
if (ioctl(fd, LOOP_GET_STATUS64, &lo) == 0 || errno != ENXIO) { if (ioctl(fd, LOOP_GET_STATUS64, &lo) == 0 || errno != ENXIO) {
process_lock();
close(fd); close(fd);
process_unlock();
fd = -1; fd = -1;
continue; continue;
} }
...@@ -1356,7 +1417,9 @@ static int find_free_loopdev(int *retfd, char *namep) ...@@ -1356,7 +1417,9 @@ static int find_free_loopdev(int *retfd, char *namep)
snprintf(namep, 100, "/dev/%s", direntp->d_name); snprintf(namep, 100, "/dev/%s", direntp->d_name);
break; break;
} }
process_lock();
closedir(dir); closedir(dir);
process_unlock();
if (fd == -1) { if (fd == -1) {
ERROR("No loop device found"); ERROR("No loop device found");
return -1; return -1;
...@@ -1379,7 +1442,10 @@ static int loop_mount(struct bdev *bdev) ...@@ -1379,7 +1442,10 @@ static int loop_mount(struct bdev *bdev)
if (find_free_loopdev(&lfd, loname) < 0) if (find_free_loopdev(&lfd, loname) < 0)
return -22; return -22;
if ((ffd = open(bdev->src + 5, O_RDWR)) < 0) { process_lock();
ffd = open(bdev->src + 5, O_RDWR);
process_unlock();
if (ffd < 0) {
SYSERROR("Error opening backing file %s\n", bdev->src); SYSERROR("Error opening backing file %s\n", bdev->src);
goto out; goto out;
} }
...@@ -1402,12 +1468,14 @@ static int loop_mount(struct bdev *bdev) ...@@ -1402,12 +1468,14 @@ static int loop_mount(struct bdev *bdev)
bdev->lofd = lfd; bdev->lofd = lfd;
out: out:
process_lock();
if (ffd > -1) if (ffd > -1)
close(ffd); close(ffd);
if (ret < 0) { if (ret < 0) {
close(lfd); close(lfd);
bdev->lofd = -1; bdev->lofd = -1;
} }
process_unlock();
return ret; return ret;
} }
...@@ -1421,7 +1489,9 @@ static int loop_umount(struct bdev *bdev) ...@@ -1421,7 +1489,9 @@ static int loop_umount(struct bdev *bdev)
return -22; return -22;
ret = umount(bdev->dest); ret = umount(bdev->dest);
if (bdev->lofd >= 0) { if (bdev->lofd >= 0) {
process_lock();
close(bdev->lofd); close(bdev->lofd);
process_unlock();
bdev->lofd = -1; bdev->lofd = -1;
} }
return ret; return ret;
...@@ -1429,9 +1499,11 @@ static int loop_umount(struct bdev *bdev) ...@@ -1429,9 +1499,11 @@ static int loop_umount(struct bdev *bdev)
static int do_loop_create(const char *path, unsigned long size, const char *fstype) static int do_loop_create(const char *path, unsigned long size, const char *fstype)
{ {
int fd; int fd, ret;
// create the new loopback file. // create the new loopback file.
process_lock();
fd = creat(path, S_IRUSR|S_IWUSR); fd = creat(path, S_IRUSR|S_IWUSR);
process_unlock();
if (fd < 0) if (fd < 0)
return -1; return -1;
if (lseek(fd, size, SEEK_SET) < 0) { if (lseek(fd, size, SEEK_SET) < 0) {
...@@ -1444,7 +1516,10 @@ static int do_loop_create(const char *path, unsigned long size, const char *fsty ...@@ -1444,7 +1516,10 @@ static int do_loop_create(const char *path, unsigned long size, const char *fsty
close(fd); close(fd);
return -1; return -1;
} }
if (close(fd) < 0) { process_lock();
ret = close(fd);
process_unlock();
if (ret < 0) {
SYSERROR("Error closing new loop file"); SYSERROR("Error closing new loop file");
return -1; return -1;
} }
...@@ -1975,6 +2050,7 @@ struct bdev *bdev_copy(const char *src, const char *oldname, const char *cname, ...@@ -1975,6 +2050,7 @@ struct bdev *bdev_copy(const char *src, const char *oldname, const char *cname,
return new; return new;
} }
process_unlock(); // we're no longer sharing
if (unshare(CLONE_NEWNS) < 0) { if (unshare(CLONE_NEWNS) < 0) {
SYSERROR("unshare CLONE_NEWNS"); SYSERROR("unshare CLONE_NEWNS");
exit(1); exit(1);
......
...@@ -31,6 +31,7 @@ ...@@ -31,6 +31,7 @@
#include "config.h" #include "config.h"
#include "log.h" #include "log.h"
#include "lxclock.h"
lxc_log_define(lxc_caps, lxc); lxc_log_define(lxc_caps, lxc);
...@@ -191,7 +192,9 @@ static int _real_caps_last_cap(void) ...@@ -191,7 +192,9 @@ static int _real_caps_last_cap(void)
/* try to get the maximum capability over the kernel /* try to get the maximum capability over the kernel
* interface introduced in v3.2 */ * interface introduced in v3.2 */
process_lock();
fd = open("/proc/sys/kernel/cap_last_cap", O_RDONLY); fd = open("/proc/sys/kernel/cap_last_cap", O_RDONLY);
process_unlock();
if (fd >= 0) { if (fd >= 0) {
char buf[32]; char buf[32];
char *ptr; char *ptr;
...@@ -205,7 +208,9 @@ static int _real_caps_last_cap(void) ...@@ -205,7 +208,9 @@ static int _real_caps_last_cap(void)
result = -1; result = -1;
} }
process_lock();
close(fd); close(fd);
process_unlock();
} }
/* try to get it manually by trying to get the status of /* try to get it manually by trying to get the status of
......
...@@ -45,6 +45,7 @@ ...@@ -45,6 +45,7 @@
#include "conf.h" #include "conf.h"
#include "utils.h" #include "utils.h"
#include "bdev.h" #include "bdev.h"
#include "lxclock.h"
#include <lxc/log.h> #include <lxc/log.h>
#include <lxc/cgroup.h> #include <lxc/cgroup.h>
...@@ -148,7 +149,9 @@ struct cgroup_meta_data *lxc_cgroup_load_meta2(const char **subsystem_whitelist) ...@@ -148,7 +149,9 @@ struct cgroup_meta_data *lxc_cgroup_load_meta2(const char **subsystem_whitelist)
meta_data->ref = 1; meta_data->ref = 1;
/* Step 1: determine all kernel subsystems */ /* Step 1: determine all kernel subsystems */
process_lock();
proc_cgroups = fopen_cloexec("/proc/cgroups", "r"); proc_cgroups = fopen_cloexec("/proc/cgroups", "r");
process_unlock();
if (!proc_cgroups) if (!proc_cgroups)
goto out_error; goto out_error;
...@@ -186,18 +189,22 @@ struct cgroup_meta_data *lxc_cgroup_load_meta2(const char **subsystem_whitelist) ...@@ -186,18 +189,22 @@ struct cgroup_meta_data *lxc_cgroup_load_meta2(const char **subsystem_whitelist)
kernel_subsystems_count++; kernel_subsystems_count++;
} }
process_lock();
fclose(proc_cgroups); fclose(proc_cgroups);
process_unlock();
proc_cgroups = NULL; proc_cgroups = NULL;
/* Step 2: determine all hierarchies (by reading /proc/self/cgroup), /* Step 2: determine all hierarchies (by reading /proc/self/cgroup),
* since mount points don't specify hierarchy number and * since mount points don't specify hierarchy number and
* /proc/cgroups does not contain named hierarchies * /proc/cgroups does not contain named hierarchies
*/ */
process_lock();
proc_self_cgroup = fopen_cloexec("/proc/self/cgroup", "r"); proc_self_cgroup = fopen_cloexec("/proc/self/cgroup", "r");
/* if for some reason (because of setns() and pid namespace for example), /* if for some reason (because of setns() and pid namespace for example),
* /proc/self is not valid, we try /proc/1/cgroup... */ * /proc/self is not valid, we try /proc/1/cgroup... */
if (!proc_self_cgroup) if (!proc_self_cgroup)
proc_self_cgroup = fopen_cloexec("/proc/1/cgroup", "r"); proc_self_cgroup = fopen_cloexec("/proc/1/cgroup", "r");
process_unlock();
if (!proc_self_cgroup) if (!proc_self_cgroup)
goto out_error; goto out_error;
...@@ -274,15 +281,19 @@ struct cgroup_meta_data *lxc_cgroup_load_meta2(const char **subsystem_whitelist) ...@@ -274,15 +281,19 @@ struct cgroup_meta_data *lxc_cgroup_load_meta2(const char **subsystem_whitelist)
} }
} }
process_lock();
fclose(proc_self_cgroup); fclose(proc_self_cgroup);
process_unlock();
proc_self_cgroup = NULL; proc_self_cgroup = NULL;
/* Step 3: determine all mount points of each hierarchy */ /* Step 3: determine all mount points of each hierarchy */
process_lock();
proc_self_mountinfo = fopen_cloexec("/proc/self/mountinfo", "r"); proc_self_mountinfo = fopen_cloexec("/proc/self/mountinfo", "r");
/* if for some reason (because of setns() and pid namespace for example), /* if for some reason (because of setns() and pid namespace for example),
* /proc/self is not valid, we try /proc/1/cgroup... */ * /proc/self is not valid, we try /proc/1/cgroup... */
if (!proc_self_mountinfo) if (!proc_self_mountinfo)
proc_self_mountinfo = fopen_cloexec("/proc/1/mountinfo", "r"); proc_self_mountinfo = fopen_cloexec("/proc/1/mountinfo", "r");
process_unlock();
if (!proc_self_mountinfo) if (!proc_self_mountinfo)
goto out_error; goto out_error;
...@@ -395,12 +406,14 @@ struct cgroup_meta_data *lxc_cgroup_load_meta2(const char **subsystem_whitelist) ...@@ -395,12 +406,14 @@ struct cgroup_meta_data *lxc_cgroup_load_meta2(const char **subsystem_whitelist)
out_error: out_error:
saved_errno = errno; saved_errno = errno;
process_lock();
if (proc_cgroups) if (proc_cgroups)
fclose(proc_cgroups); fclose(proc_cgroups);
if (proc_self_cgroup) if (proc_self_cgroup)
fclose(proc_self_cgroup); fclose(proc_self_cgroup);
if (proc_self_mountinfo) if (proc_self_mountinfo)
fclose(proc_self_mountinfo); fclose(proc_self_mountinfo);
process_unlock();
free(line); free(line);
free(tokens); free(tokens);
lxc_free_array((void **)kernel_subsystems, free); lxc_free_array((void **)kernel_subsystems, free);
...@@ -1367,7 +1380,9 @@ struct cgroup_process_info *lxc_cgroup_process_info_getx(const char *proc_pid_cg ...@@ -1367,7 +1380,9 @@ struct cgroup_process_info *lxc_cgroup_process_info_getx(const char *proc_pid_cg
struct cgroup_process_info **cptr = &result; struct cgroup_process_info **cptr = &result;
struct cgroup_process_info *entry = NULL; struct cgroup_process_info *entry = NULL;
process_lock();
proc_pid_cgroup = fopen_cloexec(proc_pid_cgroup_str, "r"); proc_pid_cgroup = fopen_cloexec(proc_pid_cgroup_str, "r");
process_unlock();
if (!proc_pid_cgroup) if (!proc_pid_cgroup)
return NULL; return NULL;
...@@ -1437,14 +1452,18 @@ struct cgroup_process_info *lxc_cgroup_process_info_getx(const char *proc_pid_cg ...@@ -1437,14 +1452,18 @@ struct cgroup_process_info *lxc_cgroup_process_info_getx(const char *proc_pid_cg
entry = NULL; entry = NULL;
} }
process_lock();
fclose(proc_pid_cgroup); fclose(proc_pid_cgroup);
process_unlock();
free(line); free(line);
return result; return result;
out_error: out_error:
saved_errno = errno; saved_errno = errno;
process_lock();
if (proc_pid_cgroup) if (proc_pid_cgroup)
fclose(proc_pid_cgroup); fclose(proc_pid_cgroup);
process_unlock();
lxc_cgroup_process_info_free(result); lxc_cgroup_process_info_free(result);
lxc_cgroup_process_info_free(entry); lxc_cgroup_process_info_free(entry);
free(line); free(line);
...@@ -1702,7 +1721,9 @@ bool cgroup_devices_has_allow_or_deny(struct lxc_handler *h, char *v, bool for_a ...@@ -1702,7 +1721,9 @@ bool cgroup_devices_has_allow_or_deny(struct lxc_handler *h, char *v, bool for_a
return false; return false;
} }
process_lock();
devices_list = fopen_cloexec(path, "r"); devices_list = fopen_cloexec(path, "r");
process_unlock();
if (!devices_list) { if (!devices_list) {
free(path); free(path);
return false; return false;
...@@ -1722,7 +1743,9 @@ bool cgroup_devices_has_allow_or_deny(struct lxc_handler *h, char *v, bool for_a ...@@ -1722,7 +1743,9 @@ bool cgroup_devices_has_allow_or_deny(struct lxc_handler *h, char *v, bool for_a
} }
out: out:
process_lock();
fclose(devices_list); fclose(devices_list);
process_unlock();
free(line); free(line);
free(path); free(path);
return ret; return ret;
...@@ -1744,7 +1767,9 @@ int cgroup_recursive_task_count(const char *cgroup_path) ...@@ -1744,7 +1767,9 @@ int cgroup_recursive_task_count(const char *cgroup_path)
if (!dent_buf) if (!dent_buf)
return -1; return -1;
process_lock();
d = opendir(cgroup_path); d = opendir(cgroup_path);
process_unlock();
if (!d) if (!d)
return 0; return 0;
...@@ -1761,13 +1786,17 @@ int cgroup_recursive_task_count(const char *cgroup_path) ...@@ -1761,13 +1786,17 @@ int cgroup_recursive_task_count(const char *cgroup_path)
continue; continue;
sub_path = lxc_string_join("/", parts, false); sub_path = lxc_string_join("/", parts, false);
if (!sub_path) { if (!sub_path) {
process_lock();
closedir(d); closedir(d);
process_unlock();
free(dent_buf); free(dent_buf);
return -1; return -1;
} }
r = stat(sub_path, &st); r = stat(sub_path, &st);
if (r < 0) { if (r < 0) {
process_lock();
closedir(d); closedir(d);
process_unlock();
free(dent_buf); free(dent_buf);
free(sub_path); free(sub_path);
return -1; return -1;
...@@ -1783,7 +1812,9 @@ int cgroup_recursive_task_count(const char *cgroup_path) ...@@ -1783,7 +1812,9 @@ int cgroup_recursive_task_count(const char *cgroup_path)
} }
free(sub_path); free(sub_path);
} }
process_lock();
closedir(d); closedir(d);
process_unlock();
free(dent_buf); free(dent_buf);
return n; return n;
...@@ -1796,7 +1827,9 @@ int count_lines(const char *fn) ...@@ -1796,7 +1827,9 @@ int count_lines(const char *fn)
size_t sz = 0; size_t sz = 0;
int n = 0; int n = 0;
process_lock();
f = fopen_cloexec(fn, "r"); f = fopen_cloexec(fn, "r");
process_unlock();
if (!f) if (!f)
return -1; return -1;
...@@ -1804,7 +1837,9 @@ int count_lines(const char *fn) ...@@ -1804,7 +1837,9 @@ int count_lines(const char *fn)
n++; n++;
} }
free(line); free(line);
process_lock();
fclose(f); fclose(f);
process_unlock();
return n; return n;
} }
......
...@@ -46,6 +46,7 @@ ...@@ -46,6 +46,7 @@
#include "mainloop.h" #include "mainloop.h"
#include "af_unix.h" #include "af_unix.h"
#include "config.h" #include "config.h"
#include "lxclock.h"
/* /*
* This file provides the different functions for clients to * This file provides the different functions for clients to
...@@ -716,7 +717,9 @@ static void lxc_cmd_fd_cleanup(int fd, struct lxc_handler *handler, ...@@ -716,7 +717,9 @@ static void lxc_cmd_fd_cleanup(int fd, struct lxc_handler *handler,
{ {
lxc_console_free(handler->conf, fd); lxc_console_free(handler->conf, fd);
lxc_mainloop_del_handler(descr, fd); lxc_mainloop_del_handler(descr, fd);
process_lock();
close(fd); close(fd);
process_unlock();
} }
static int lxc_cmd_handler(int fd, void *data, struct lxc_epoll_descr *descr) static int lxc_cmd_handler(int fd, void *data, struct lxc_epoll_descr *descr)
...@@ -787,7 +790,9 @@ static int lxc_cmd_accept(int fd, void *data, struct lxc_epoll_descr *descr) ...@@ -787,7 +790,9 @@ static int lxc_cmd_accept(int fd, void *data, struct lxc_epoll_descr *descr)
{ {
int opt = 1, ret = -1, connection; int opt = 1, ret = -1, connection;
process_lock();
connection = accept(fd, NULL, 0); connection = accept(fd, NULL, 0);
process_unlock();
if (connection < 0) { if (connection < 0) {
SYSERROR("failed to accept connection"); SYSERROR("failed to accept connection");
return -1; return -1;
...@@ -814,7 +819,9 @@ out: ...@@ -814,7 +819,9 @@ out:
return ret; return ret;
out_close: out_close:
process_lock();
close(connection); close(connection);
process_unlock();
goto out; goto out;
} }
...@@ -843,7 +850,9 @@ int lxc_cmd_init(const char *name, struct lxc_handler *handler, ...@@ -843,7 +850,9 @@ int lxc_cmd_init(const char *name, struct lxc_handler *handler,
if (fcntl(fd, F_SETFD, FD_CLOEXEC)) { if (fcntl(fd, F_SETFD, FD_CLOEXEC)) {
SYSERROR("failed to set sigfd to close-on-exec"); SYSERROR("failed to set sigfd to close-on-exec");
process_lock();
close(fd); close(fd);
process_unlock();
return -1; return -1;
} }
...@@ -860,7 +869,9 @@ int lxc_cmd_mainloop_add(const char *name, ...@@ -860,7 +869,9 @@ int lxc_cmd_mainloop_add(const char *name,
ret = lxc_mainloop_add_handler(descr, fd, lxc_cmd_accept, handler); ret = lxc_mainloop_add_handler(descr, fd, lxc_cmd_accept, handler);
if (ret) { if (ret) {
ERROR("failed to add handler for command socket"); ERROR("failed to add handler for command socket");
process_lock();
close(fd); close(fd);
process_unlock();
} }
return ret; return ret;
......
...@@ -73,6 +73,7 @@ ...@@ -73,6 +73,7 @@
#include "caps.h" /* for lxc_caps_last_cap() */ #include "caps.h" /* for lxc_caps_last_cap() */
#include "bdev.h" #include "bdev.h"
#include "cgroup.h" #include "cgroup.h"
#include "lxclock.h"
#if HAVE_APPARMOR #if HAVE_APPARMOR
#include <apparmor.h> #include <apparmor.h>
...@@ -296,11 +297,15 @@ static char *mkifname(char *template) ...@@ -296,11 +297,15 @@ static char *mkifname(char *template)
getifaddrs(&ifaddr); getifaddrs(&ifaddr);
/* Initialize the random number generator */ /* Initialize the random number generator */
process_lock();
urandom = fopen ("/dev/urandom", "r"); urandom = fopen ("/dev/urandom", "r");
process_unlock();
if (urandom != NULL) { if (urandom != NULL) {
if (fread (&seed, sizeof(seed), 1, urandom) <= 0) if (fread (&seed, sizeof(seed), 1, urandom) <= 0)
seed = time(0); seed = time(0);
process_lock();
fclose(urandom); fclose(urandom);
process_unlock();
} }
else else
seed = time(0); seed = time(0);
...@@ -350,7 +355,9 @@ static int run_buffer(char *buffer) ...@@ -350,7 +355,9 @@ static int run_buffer(char *buffer)
char *output; char *output;
int ret; int ret;
process_lock();
f = popen(buffer, "r"); f = popen(buffer, "r");
process_unlock();
if (!f) { if (!f) {
SYSERROR("popen failed"); SYSERROR("popen failed");
return -1; return -1;
...@@ -359,7 +366,9 @@ static int run_buffer(char *buffer) ...@@ -359,7 +366,9 @@ static int run_buffer(char *buffer)
output = malloc(LXC_LOG_BUFFER_SIZE); output = malloc(LXC_LOG_BUFFER_SIZE);
if (!output) { if (!output) {
ERROR("failed to allocate memory for script output"); ERROR("failed to allocate memory for script output");
process_lock();
pclose(f); pclose(f);
process_unlock();
return -1; return -1;
} }
...@@ -368,7 +377,9 @@ static int run_buffer(char *buffer) ...@@ -368,7 +377,9 @@ static int run_buffer(char *buffer)
free(output); free(output);
process_lock();
ret = pclose(f); ret = pclose(f);
process_unlock();
if (ret == -1) { if (ret == -1) {
SYSERROR("Script exited on error"); SYSERROR("Script exited on error");
return -1; return -1;
...@@ -573,7 +584,9 @@ static int setup_lodev(const char *rootfs, int fd, struct loop_info64 *loinfo) ...@@ -573,7 +584,9 @@ static int setup_lodev(const char *rootfs, int fd, struct loop_info64 *loinfo)
int rfd; int rfd;
int ret = -1; int ret = -1;
process_lock();
rfd = open(rootfs, O_RDWR); rfd = open(rootfs, O_RDWR);
process_unlock();
if (rfd < 0) { if (rfd < 0) {
SYSERROR("failed to open '%s'", rootfs); SYSERROR("failed to open '%s'", rootfs);
return -1; return -1;
...@@ -595,7 +608,9 @@ static int setup_lodev(const char *rootfs, int fd, struct loop_info64 *loinfo) ...@@ -595,7 +608,9 @@ static int setup_lodev(const char *rootfs, int fd, struct loop_info64 *loinfo)
ret = 0; ret = 0;
out: out:
process_lock();
close(rfd); close(rfd);
process_unlock();
return ret; return ret;
} }
...@@ -608,7 +623,9 @@ static int mount_rootfs_file(const char *rootfs, const char *target) ...@@ -608,7 +623,9 @@ static int mount_rootfs_file(const char *rootfs, const char *target)
DIR *dir; DIR *dir;
char path[MAXPATHLEN]; char path[MAXPATHLEN];
process_lock();
dir = opendir("/dev"); dir = opendir("/dev");
process_unlock();
if (!dir) { if (!dir) {
SYSERROR("failed to open '/dev'"); SYSERROR("failed to open '/dev'");
return -1; return -1;
...@@ -632,19 +649,25 @@ static int mount_rootfs_file(const char *rootfs, const char *target) ...@@ -632,19 +649,25 @@ static int mount_rootfs_file(const char *rootfs, const char *target)
if (rc < 0 || rc >= MAXPATHLEN) if (rc < 0 || rc >= MAXPATHLEN)
continue; continue;
process_lock();
fd = open(path, O_RDWR); fd = open(path, O_RDWR);
process_unlock();
if (fd < 0) if (fd < 0)
continue; continue;
if (ioctl(fd, LOOP_GET_STATUS64, &loinfo) == 0) { if (ioctl(fd, LOOP_GET_STATUS64, &loinfo) == 0) {
process_lock();
close(fd); close(fd);
process_unlock();
continue; continue;
} }
if (errno != ENXIO) { if (errno != ENXIO) {
WARN("unexpected error for ioctl on '%s': %m", WARN("unexpected error for ioctl on '%s': %m",
direntp->d_name); direntp->d_name);
process_lock();
close(fd); close(fd);
process_unlock();
continue; continue;
} }
...@@ -653,13 +676,17 @@ static int mount_rootfs_file(const char *rootfs, const char *target) ...@@ -653,13 +676,17 @@ static int mount_rootfs_file(const char *rootfs, const char *target)
ret = setup_lodev(rootfs, fd, &loinfo); ret = setup_lodev(rootfs, fd, &loinfo);
if (!ret) if (!ret)
ret = mount_unknow_fs(path, target, 0); ret = mount_unknow_fs(path, target, 0);
process_lock();
close(fd); close(fd);
process_unlock();
break; break;
} }
process_lock();
if (closedir(dir)) if (closedir(dir))
WARN("failed to close directory"); WARN("failed to close directory");
process_unlock();
return ret; return ret;
} }
...@@ -705,7 +732,9 @@ int pin_rootfs(const char *rootfs) ...@@ -705,7 +732,9 @@ int pin_rootfs(const char *rootfs)
if (ret >= MAXPATHLEN) if (ret >= MAXPATHLEN)
return -1; return -1;
process_lock();
fd = open(absrootfspin, O_CREAT | O_RDWR, S_IWUSR|S_IRUSR); fd = open(absrootfspin, O_CREAT | O_RDWR, S_IWUSR|S_IRUSR);
process_unlock();
if (fd < 0) if (fd < 0)
return fd; return fd;
(void)unlink(absrootfspin); (void)unlink(absrootfspin);
...@@ -881,13 +910,17 @@ static int setup_tty(const struct lxc_rootfs *rootfs, ...@@ -881,13 +910,17 @@ static int setup_tty(const struct lxc_rootfs *rootfs,
ERROR("pathname too long for ttys"); ERROR("pathname too long for ttys");
return -1; return -1;
} }
process_lock();
ret = creat(lxcpath, 0660); ret = creat(lxcpath, 0660);
process_unlock();
if (ret==-1 && errno != EEXIST) { if (ret==-1 && errno != EEXIST) {
SYSERROR("error creating %s\n", lxcpath); SYSERROR("error creating %s\n", lxcpath);
return -1; return -1;
} }
process_lock();
if (ret >= 0) if (ret >= 0)
close(ret); close(ret);
process_unlock();
ret = unlink(path); ret = unlink(path);
if (ret && errno != ENOENT) { if (ret && errno != ENOENT) {
SYSERROR("error unlinking %s\n", path); SYSERROR("error unlinking %s\n", path);
...@@ -913,12 +946,17 @@ static int setup_tty(const struct lxc_rootfs *rootfs, ...@@ -913,12 +946,17 @@ static int setup_tty(const struct lxc_rootfs *rootfs,
} else { } else {
/* If we populated /dev, then we need to create /dev/ttyN */ /* If we populated /dev, then we need to create /dev/ttyN */
if (access(path, F_OK)) { if (access(path, F_OK)) {
process_lock();
ret = creat(path, 0660); ret = creat(path, 0660);
process_unlock();
if (ret==-1) { if (ret==-1) {
SYSERROR("error creating %s\n", path); SYSERROR("error creating %s\n", path);
/* this isn't fatal, continue */ /* this isn't fatal, continue */
} else } else {
process_lock();
close(ret); close(ret);
process_unlock();
}
} }
if (mount(pty_info->name, path, "none", MS_BIND, 0)) { if (mount(pty_info->name, path, "none", MS_BIND, 0)) {
WARN("failed to mount '%s'->'%s'", WARN("failed to mount '%s'->'%s'",
...@@ -1226,7 +1264,9 @@ int detect_shared_rootfs(void) ...@@ -1226,7 +1264,9 @@ int detect_shared_rootfs(void)
int i; int i;
char *p2; char *p2;
process_lock();
f = fopen("/proc/self/mountinfo", "r"); f = fopen("/proc/self/mountinfo", "r");
process_unlock();
if (!f) if (!f)
return 0; return 0;
while ((p = fgets(buf, LINELEN, f))) { while ((p = fgets(buf, LINELEN, f))) {
...@@ -1244,12 +1284,16 @@ int detect_shared_rootfs(void) ...@@ -1244,12 +1284,16 @@ int detect_shared_rootfs(void)
// this is '/'. is it shared? // this is '/'. is it shared?
p = index(p2+1, ' '); p = index(p2+1, ' ');
if (p && strstr(p, "shared:")) { if (p && strstr(p, "shared:")) {
process_lock();
fclose(f); fclose(f);
process_unlock();
return 1; return 1;
} }
} }
} }
process_lock();
fclose(f); fclose(f);
process_unlock();
return 0; return 0;
} }
...@@ -1505,13 +1549,17 @@ static int setup_ttydir_console(const struct lxc_rootfs *rootfs, ...@@ -1505,13 +1549,17 @@ static int setup_ttydir_console(const struct lxc_rootfs *rootfs,
return -1; return -1;
} }
process_lock();
ret = creat(lxcpath, 0660); ret = creat(lxcpath, 0660);
process_unlock();
if (ret==-1 && errno != EEXIST) { if (ret==-1 && errno != EEXIST) {
SYSERROR("error %d creating %s\n", errno, lxcpath); SYSERROR("error %d creating %s\n", errno, lxcpath);
return -1; return -1;
} }
process_lock();
if (ret >= 0) if (ret >= 0)
close(ret); close(ret);
process_unlock();
if (console->master < 0) { if (console->master < 0) {
INFO("no console"); INFO("no console");
...@@ -1827,7 +1875,9 @@ static int setup_mount(const struct lxc_rootfs *rootfs, const char *fstab, ...@@ -1827,7 +1875,9 @@ static int setup_mount(const struct lxc_rootfs *rootfs, const char *fstab,
if (!fstab) if (!fstab)
return 0; return 0;
process_lock();
file = setmntent(fstab, "r"); file = setmntent(fstab, "r");
process_unlock();
if (!file) { if (!file) {
SYSERROR("failed to use '%s'", fstab); SYSERROR("failed to use '%s'", fstab);
return -1; return -1;
...@@ -1835,7 +1885,9 @@ static int setup_mount(const struct lxc_rootfs *rootfs, const char *fstab, ...@@ -1835,7 +1885,9 @@ static int setup_mount(const struct lxc_rootfs *rootfs, const char *fstab,
ret = mount_file_entries(rootfs, file, lxc_name); ret = mount_file_entries(rootfs, file, lxc_name);
process_lock();
endmntent(file); endmntent(file);
process_unlock();
return ret; return ret;
} }
...@@ -1847,7 +1899,9 @@ static int setup_mount_entries(const struct lxc_rootfs *rootfs, struct lxc_list ...@@ -1847,7 +1899,9 @@ static int setup_mount_entries(const struct lxc_rootfs *rootfs, struct lxc_list
char *mount_entry; char *mount_entry;
int ret; int ret;
process_lock();
file = tmpfile(); file = tmpfile();
process_unlock();
if (!file) { if (!file) {
ERROR("tmpfile error: %m"); ERROR("tmpfile error: %m");
return -1; return -1;
...@@ -1862,7 +1916,9 @@ static int setup_mount_entries(const struct lxc_rootfs *rootfs, struct lxc_list ...@@ -1862,7 +1916,9 @@ static int setup_mount_entries(const struct lxc_rootfs *rootfs, struct lxc_list
ret = mount_file_entries(rootfs, file, lxc_name); ret = mount_file_entries(rootfs, file, lxc_name);
process_lock();
fclose(file); fclose(file);
process_unlock();
return ret; return ret;
} }
...@@ -2007,14 +2063,18 @@ static int setup_hw_addr(char *hwaddr, const char *ifname) ...@@ -2007,14 +2063,18 @@ static int setup_hw_addr(char *hwaddr, const char *ifname)
memcpy(ifr.ifr_name, ifname, IFNAMSIZ); memcpy(ifr.ifr_name, ifname, IFNAMSIZ);
memcpy((char *) &ifr.ifr_hwaddr, (char *) &sockaddr, sizeof(sockaddr)); memcpy((char *) &ifr.ifr_hwaddr, (char *) &sockaddr, sizeof(sockaddr));
process_lock();
fd = socket(AF_INET, SOCK_DGRAM, 0); fd = socket(AF_INET, SOCK_DGRAM, 0);
process_unlock();
if (fd < 0) { if (fd < 0) {
ERROR("socket failure : %s", strerror(errno)); ERROR("socket failure : %s", strerror(errno));
return -1; return -1;
} }
ret = ioctl(fd, SIOCSIFHWADDR, &ifr); ret = ioctl(fd, SIOCSIFHWADDR, &ifr);
process_lock();
close(fd); close(fd);
process_unlock();
if (ret) if (ret)
ERROR("ioctl failure : %s", strerror(errno)); ERROR("ioctl failure : %s", strerror(errno));
...@@ -2261,20 +2321,26 @@ static int setup_private_host_hw_addr(char *veth1) ...@@ -2261,20 +2321,26 @@ static int setup_private_host_hw_addr(char *veth1)
int err; int err;
int sockfd; int sockfd;
process_lock();
sockfd = socket(AF_INET, SOCK_DGRAM, 0); sockfd = socket(AF_INET, SOCK_DGRAM, 0);
process_unlock();
if (sockfd < 0) if (sockfd < 0)
return -errno; return -errno;
snprintf((char *)ifr.ifr_name, IFNAMSIZ, "%s", veth1); snprintf((char *)ifr.ifr_name, IFNAMSIZ, "%s", veth1);
err = ioctl(sockfd, SIOCGIFHWADDR, &ifr); err = ioctl(sockfd, SIOCGIFHWADDR, &ifr);
if (err < 0) { if (err < 0) {
process_lock();
close(sockfd); close(sockfd);
process_unlock();
return -errno; return -errno;
} }
ifr.ifr_hwaddr.sa_data[0] = 0xfe; ifr.ifr_hwaddr.sa_data[0] = 0xfe;
err = ioctl(sockfd, SIOCSIFHWADDR, &ifr); err = ioctl(sockfd, SIOCSIFHWADDR, &ifr);
process_lock();
close(sockfd); close(sockfd);
process_unlock();
if (err < 0) if (err < 0)
return -errno; return -errno;
...@@ -2716,7 +2782,9 @@ static int write_id_mapping(enum idtype idtype, pid_t pid, const char *buf, ...@@ -2716,7 +2782,9 @@ static int write_id_mapping(enum idtype idtype, pid_t pid, const char *buf,
fprintf(stderr, "%s: path name too long", __func__); fprintf(stderr, "%s: path name too long", __func__);
return -E2BIG; return -E2BIG;
} }
process_lock();
f = fopen(path, "w"); f = fopen(path, "w");
process_unlock();
if (!f) { if (!f) {
perror("open"); perror("open");
return -EINVAL; return -EINVAL;
...@@ -2724,7 +2792,9 @@ static int write_id_mapping(enum idtype idtype, pid_t pid, const char *buf, ...@@ -2724,7 +2792,9 @@ static int write_id_mapping(enum idtype idtype, pid_t pid, const char *buf,
ret = fwrite(buf, buf_size, 1, f); ret = fwrite(buf, buf_size, 1, f);
if (ret < 0) if (ret < 0)
SYSERROR("writing id mapping"); SYSERROR("writing id mapping");
process_lock();
closeret = fclose(f); closeret = fclose(f);
process_unlock();
if (closeret) if (closeret)
SYSERROR("writing id mapping"); SYSERROR("writing id mapping");
return ret < 0 ? ret : closeret; return ret < 0 ? ret : closeret;
...@@ -2822,7 +2892,7 @@ int lxc_find_gateway_addresses(struct lxc_handler *handler) ...@@ -2822,7 +2892,7 @@ int lxc_find_gateway_addresses(struct lxc_handler *handler)
int lxc_create_tty(const char *name, struct lxc_conf *conf) int lxc_create_tty(const char *name, struct lxc_conf *conf)
{ {
struct lxc_tty_info *tty_info = &conf->tty_info; struct lxc_tty_info *tty_info = &conf->tty_info;
int i; int i, ret;
/* no tty in the configuration */ /* no tty in the configuration */
if (!conf->tty) if (!conf->tty)
...@@ -2839,8 +2909,11 @@ int lxc_create_tty(const char *name, struct lxc_conf *conf) ...@@ -2839,8 +2909,11 @@ int lxc_create_tty(const char *name, struct lxc_conf *conf)
struct lxc_pty_info *pty_info = &tty_info->pty_info[i]; struct lxc_pty_info *pty_info = &tty_info->pty_info[i];
if (openpty(&pty_info->master, &pty_info->slave, process_lock();
pty_info->name, NULL, NULL)) { ret = openpty(&pty_info->master, &pty_info->slave,
pty_info->name, NULL, NULL);
process_unlock();
if (ret) {
SYSERROR("failed to create pty #%d", i); SYSERROR("failed to create pty #%d", i);
tty_info->nbtty = i; tty_info->nbtty = i;
lxc_delete_tty(tty_info); lxc_delete_tty(tty_info);
...@@ -2871,8 +2944,10 @@ void lxc_delete_tty(struct lxc_tty_info *tty_info) ...@@ -2871,8 +2944,10 @@ void lxc_delete_tty(struct lxc_tty_info *tty_info)
for (i = 0; i < tty_info->nbtty; i++) { for (i = 0; i < tty_info->nbtty; i++) {
struct lxc_pty_info *pty_info = &tty_info->pty_info[i]; struct lxc_pty_info *pty_info = &tty_info->pty_info[i];
process_lock();
close(pty_info->master); close(pty_info->master);
close(pty_info->slave); close(pty_info->slave);
process_unlock();
} }
free(tty_info->pty_info); free(tty_info->pty_info);
......
...@@ -100,16 +100,16 @@ static void lxc_console_winch(struct lxc_tty_state *ts) ...@@ -100,16 +100,16 @@ static void lxc_console_winch(struct lxc_tty_state *ts)
void lxc_console_sigwinch(int sig) void lxc_console_sigwinch(int sig)
{ {
if (process_lock() == 0) { struct lxc_list *it;
struct lxc_list *it; struct lxc_tty_state *ts;
struct lxc_tty_state *ts;
lxc_list_for_each(it, &lxc_ttys) { process_lock();
ts = it->elem;
lxc_console_winch(ts); lxc_list_for_each(it, &lxc_ttys) {
} ts = it->elem;
process_unlock(); lxc_console_winch(ts);
} }
process_unlock();
} }
static int lxc_console_cb_sigwinch_fd(int fd, void *cbdata, static int lxc_console_cb_sigwinch_fd(int fd, void *cbdata,
...@@ -204,8 +204,11 @@ out: ...@@ -204,8 +204,11 @@ out:
*/ */
static void lxc_console_sigwinch_fini(struct lxc_tty_state *ts) static void lxc_console_sigwinch_fini(struct lxc_tty_state *ts)
{ {
if (ts->sigfd >= 0) if (ts->sigfd >= 0) {
process_lock();
close(ts->sigfd); close(ts->sigfd);
process_unlock();
}
lxc_list_del(&ts->node); lxc_list_del(&ts->node);
sigprocmask(SIG_SETMASK, &ts->oldmask, NULL); sigprocmask(SIG_SETMASK, &ts->oldmask, NULL);
free(ts); free(ts);
...@@ -227,7 +230,9 @@ static int lxc_console_cb_con(int fd, void *data, ...@@ -227,7 +230,9 @@ static int lxc_console_cb_con(int fd, void *data,
if (!r) { if (!r) {
INFO("console client on fd %d has exited", fd); INFO("console client on fd %d has exited", fd);
lxc_mainloop_del_handler(descr, fd); lxc_mainloop_del_handler(descr, fd);
process_lock();
close(fd); close(fd);
process_unlock();
return 0; return 0;
} }
...@@ -343,8 +348,10 @@ static void lxc_console_peer_proxy_free(struct lxc_console *console) ...@@ -343,8 +348,10 @@ static void lxc_console_peer_proxy_free(struct lxc_console *console)
lxc_console_sigwinch_fini(console->tty_state); lxc_console_sigwinch_fini(console->tty_state);
console->tty_state = NULL; console->tty_state = NULL;
} }
process_lock();
close(console->peerpty.master); close(console->peerpty.master);
close(console->peerpty.slave); close(console->peerpty.slave);
process_unlock();
console->peerpty.master = -1; console->peerpty.master = -1;
console->peerpty.slave = -1; console->peerpty.slave = -1;
console->peerpty.busy = -1; console->peerpty.busy = -1;
...@@ -356,6 +363,7 @@ static int lxc_console_peer_proxy_alloc(struct lxc_console *console, int sockfd) ...@@ -356,6 +363,7 @@ static int lxc_console_peer_proxy_alloc(struct lxc_console *console, int sockfd)
{ {
struct termios oldtermio; struct termios oldtermio;
struct lxc_tty_state *ts; struct lxc_tty_state *ts;
int ret;
if (console->master < 0) { if (console->master < 0) {
ERROR("console not set up"); ERROR("console not set up");
...@@ -373,8 +381,11 @@ static int lxc_console_peer_proxy_alloc(struct lxc_console *console, int sockfd) ...@@ -373,8 +381,11 @@ static int lxc_console_peer_proxy_alloc(struct lxc_console *console, int sockfd)
/* this is the proxy pty that will be given to the client, and that /* this is the proxy pty that will be given to the client, and that
* the real pty master will send to / recv from * the real pty master will send to / recv from
*/ */
if (openpty(&console->peerpty.master, &console->peerpty.slave, process_lock();
console->peerpty.name, NULL, NULL)) { ret = openpty(&console->peerpty.master, &console->peerpty.slave,
console->peerpty.name, NULL, NULL);
process_unlock();
if (ret) {
SYSERROR("failed to create proxy pty"); SYSERROR("failed to create proxy pty");
return -1; return -1;
} }
...@@ -488,19 +499,23 @@ static void lxc_console_peer_default(struct lxc_console *console) ...@@ -488,19 +499,23 @@ static void lxc_console_peer_default(struct lxc_console *console)
*/ */
if (!path && !access("/dev/tty", F_OK)) { if (!path && !access("/dev/tty", F_OK)) {
int fd; int fd;
process_lock();
fd = open("/dev/tty", O_RDWR); fd = open("/dev/tty", O_RDWR);
if (fd >= 0) { if (fd >= 0) {
close(fd); close(fd);
path = "/dev/tty"; path = "/dev/tty";
} }
process_unlock();
} }
if (!path) if (!path)
goto out; goto out;
DEBUG("opening %s for console peer", path); DEBUG("opening %s for console peer", path);
process_lock();
console->peer = lxc_unpriv(open(path, O_CLOEXEC | O_RDWR | O_CREAT | console->peer = lxc_unpriv(open(path, O_CLOEXEC | O_RDWR | O_CREAT |
O_APPEND, 0600)); O_APPEND, 0600));
process_unlock();
if (console->peer < 0) if (console->peer < 0)
goto out; goto out;
...@@ -531,7 +546,9 @@ err2: ...@@ -531,7 +546,9 @@ err2:
free(console->tios); free(console->tios);
console->tios = NULL; console->tios = NULL;
err1: err1:
process_lock();
close(console->peer); close(console->peer);
process_unlock();
console->peer = -1; console->peer = -1;
out: out:
DEBUG("no console peer"); DEBUG("no console peer");
...@@ -545,24 +562,24 @@ void lxc_console_delete(struct lxc_console *console) ...@@ -545,24 +562,24 @@ void lxc_console_delete(struct lxc_console *console)
free(console->tios); free(console->tios);
console->tios = NULL; console->tios = NULL;
process_lock();
close(console->peer); close(console->peer);
console->peer = -1; close(console->master);
close(console->slave);
if (console->log_fd >= 0) { if (console->log_fd >= 0)
close(console->log_fd); close(console->log_fd);
console->log_fd = -1; process_unlock();
}
close(console->master); console->peer = -1;
console->master = -1; console->master = -1;
close(console->slave);
console->slave = -1; console->slave = -1;
console->log_fd = -1;
} }
int lxc_console_create(struct lxc_conf *conf) int lxc_console_create(struct lxc_conf *conf)
{ {
struct lxc_console *console = &conf->console; struct lxc_console *console = &conf->console;
int ret;
if (conf->is_execute) { if (conf->is_execute) {
INFO("no console for lxc-execute."); INFO("no console for lxc-execute.");
...@@ -575,8 +592,11 @@ int lxc_console_create(struct lxc_conf *conf) ...@@ -575,8 +592,11 @@ int lxc_console_create(struct lxc_conf *conf)
if (console->path && !strcmp(console->path, "none")) if (console->path && !strcmp(console->path, "none"))
return 0; return 0;
if (openpty(&console->master, &console->slave, process_lock();
console->name, NULL, NULL)) { ret = openpty(&console->master, &console->slave,
console->name, NULL, NULL);
process_unlock();
if (ret) {
SYSERROR("failed to allocate a pty"); SYSERROR("failed to allocate a pty");
return -1; return -1;
} }
...@@ -594,9 +614,11 @@ int lxc_console_create(struct lxc_conf *conf) ...@@ -594,9 +614,11 @@ int lxc_console_create(struct lxc_conf *conf)
lxc_console_peer_default(console); lxc_console_peer_default(console);
if (console->log_path) { if (console->log_path) {
process_lock();
console->log_fd = lxc_unpriv(open(console->log_path, console->log_fd = lxc_unpriv(open(console->log_path,
O_CLOEXEC | O_RDWR | O_CLOEXEC | O_RDWR |
O_CREAT | O_APPEND, 0600)); O_CREAT | O_APPEND, 0600));
process_unlock();
if (console->log_fd < 0) { if (console->log_fd < 0) {
SYSERROR("failed to open '%s'", console->log_path); SYSERROR("failed to open '%s'", console->log_path);
goto err; goto err;
...@@ -693,6 +715,7 @@ int lxc_console(struct lxc_container *c, int ttynum, ...@@ -693,6 +715,7 @@ int lxc_console(struct lxc_container *c, int ttynum,
process_lock(); process_lock();
ttyfd = lxc_cmd_console(c->name, &ttynum, &masterfd, c->config_path); ttyfd = lxc_cmd_console(c->name, &ttynum, &masterfd, c->config_path);
process_unlock();
if (ttyfd < 0) { if (ttyfd < 0) {
ret = ttyfd; ret = ttyfd;
goto err1; goto err1;
...@@ -747,9 +770,9 @@ int lxc_console(struct lxc_container *c, int ttynum, ...@@ -747,9 +770,9 @@ int lxc_console(struct lxc_container *c, int ttynum,
goto err4; goto err4;
} }
process_unlock();
ret = lxc_mainloop(&descr, -1);
process_lock(); process_lock();
ret = lxc_mainloop(&descr, -1);
process_unlock();
if (ret) { if (ret) {
ERROR("mainloop returned an error"); ERROR("mainloop returned an error");
goto err4; goto err4;
...@@ -762,11 +785,12 @@ err4: ...@@ -762,11 +785,12 @@ err4:
err3: err3:
lxc_console_sigwinch_fini(ts); lxc_console_sigwinch_fini(ts);
err2: err2:
process_lock();
close(masterfd); close(masterfd);
close(ttyfd); close(ttyfd);
process_unlock();
err1: err1:
tcsetattr(stdinfd, TCSAFLUSH, &oldtios); tcsetattr(stdinfd, TCSAFLUSH, &oldtios);
process_unlock();
return ret; return ret;
} }
...@@ -34,6 +34,7 @@ ...@@ -34,6 +34,7 @@
#include "error.h" #include "error.h"
#include "state.h" #include "state.h"
#include "monitor.h" #include "monitor.h"
#include "lxclock.h"
#include <lxc/log.h> #include <lxc/log.h>
#include <lxc/cgroup.h> #include <lxc/cgroup.h>
...@@ -52,7 +53,9 @@ static int do_unfreeze(const char *nsgroup, int freeze, const char *name, const ...@@ -52,7 +53,9 @@ static int do_unfreeze(const char *nsgroup, int freeze, const char *name, const
return -1; return -1;
} }
process_lock();
fd = open(freezer, O_RDWR); fd = open(freezer, O_RDWR);
process_unlock();
if (fd < 0) { if (fd < 0) {
SYSERROR("failed to open freezer at '%s'", nsgroup); SYSERROR("failed to open freezer at '%s'", nsgroup);
return -1; return -1;
...@@ -114,7 +117,9 @@ static int do_unfreeze(const char *nsgroup, int freeze, const char *name, const ...@@ -114,7 +117,9 @@ static int do_unfreeze(const char *nsgroup, int freeze, const char *name, const
} }
out: out:
process_lock();
close(fd); close(fd);
process_unlock();
return ret; return ret;
} }
......
...@@ -36,6 +36,7 @@ ...@@ -36,6 +36,7 @@
#include "log.h" #include "log.h"
#include "caps.h" #include "caps.h"
#include "utils.h" #include "utils.h"
#include "lxclock.h"
#define LXC_LOG_PREFIX_SIZE 32 #define LXC_LOG_PREFIX_SIZE 32
#define LXC_LOG_BUFFER_SIZE 512 #define LXC_LOG_BUFFER_SIZE 512
...@@ -159,8 +160,10 @@ static int log_open(const char *name) ...@@ -159,8 +160,10 @@ static int log_open(const char *name)
int fd; int fd;
int newfd; int newfd;
process_lock();
fd = lxc_unpriv(open(name, O_CREAT | O_WRONLY | fd = lxc_unpriv(open(name, O_CREAT | O_WRONLY |
O_APPEND | O_CLOEXEC, 0666)); O_APPEND | O_CLOEXEC, 0666));
process_unlock();
if (fd == -1) { if (fd == -1) {
ERROR("failed to open log file \"%s\" : %s", name, ERROR("failed to open log file \"%s\" : %s", name,
strerror(errno)); strerror(errno));
...@@ -174,7 +177,9 @@ static int log_open(const char *name) ...@@ -174,7 +177,9 @@ static int log_open(const char *name)
if (newfd == -1) if (newfd == -1)
ERROR("failed to dup log fd %d : %s", fd, strerror(errno)); ERROR("failed to dup log fd %d : %s", fd, strerror(errno));
process_lock();
close(fd); close(fd);
process_unlock();
return newfd; return newfd;
} }
...@@ -241,7 +246,9 @@ static int __lxc_log_set_file(const char *fname, int create_dirs) ...@@ -241,7 +246,9 @@ static int __lxc_log_set_file(const char *fname, int create_dirs)
{ {
if (lxc_log_fd != -1) { if (lxc_log_fd != -1) {
// we are overriding the default. // we are overriding the default.
process_lock();
close(lxc_log_fd); close(lxc_log_fd);
process_unlock();
free(log_fname); free(log_fname);
} }
......
...@@ -271,13 +271,14 @@ void lxc_putlock(struct lxc_lock *l) ...@@ -271,13 +271,14 @@ void lxc_putlock(struct lxc_lock *l)
free(l); free(l);
} }
int process_lock(void) void process_lock(void)
{ {
int ret; int ret;
ret = pthread_mutex_lock(&thread_mutex);
if (ret != 0) if ((ret = pthread_mutex_lock(&thread_mutex)) != 0) {
ERROR("pthread_mutex_lock returned:%d %s", ret, strerror(ret)); ERROR("pthread_mutex_lock returned:%d %s", ret, strerror(ret));
return ret; exit(1);
}
} }
void process_unlock(void) void process_unlock(void)
......
...@@ -85,7 +85,7 @@ extern int lxcunlock(struct lxc_lock *lock); ...@@ -85,7 +85,7 @@ extern int lxcunlock(struct lxc_lock *lock);
extern void lxc_putlock(struct lxc_lock *l); extern void lxc_putlock(struct lxc_lock *l);
extern int process_lock(void); extern void process_lock(void);
extern void process_unlock(void); extern void process_unlock(void);
struct lxc_container; struct lxc_container;
extern int container_mem_lock(struct lxc_container *c); extern int container_mem_lock(struct lxc_container *c);
......
...@@ -62,6 +62,7 @@ static int timerfd_settime (int __ufd, int __flags, ...@@ -62,6 +62,7 @@ static int timerfd_settime (int __ufd, int __flags,
#include "mainloop.h" #include "mainloop.h"
#include "lxc.h" #include "lxc.h"
#include "log.h" #include "log.h"
#include "lxclock.h"
#ifndef __USE_GNU #ifndef __USE_GNU
#define __USE_GNU #define __USE_GNU
...@@ -342,7 +343,9 @@ run_ok: ...@@ -342,7 +343,9 @@ run_ok:
memset(utmp_data, 0, sizeof(struct lxc_utmp)); memset(utmp_data, 0, sizeof(struct lxc_utmp));
process_lock();
fd = inotify_init(); fd = inotify_init();
process_unlock();
if (fd < 0) { if (fd < 0) {
SYSERROR("failed to inotify_init"); SYSERROR("failed to inotify_init");
goto out; goto out;
...@@ -376,7 +379,9 @@ run_ok: ...@@ -376,7 +379,9 @@ run_ok:
return 0; return 0;
out_close: out_close:
process_lock();
close(fd); close(fd);
process_unlock();
out: out:
free(utmp_data); free(utmp_data);
return -1; return -1;
...@@ -426,7 +431,9 @@ int lxc_utmp_add_timer(struct lxc_epoll_descr *descr, ...@@ -426,7 +431,9 @@ int lxc_utmp_add_timer(struct lxc_epoll_descr *descr,
struct itimerspec timeout; struct itimerspec timeout;
struct lxc_utmp *utmp_data = (struct lxc_utmp *)data; struct lxc_utmp *utmp_data = (struct lxc_utmp *)data;
process_lock();
fd = timerfd_create(CLOCK_MONOTONIC, TFD_NONBLOCK | TFD_CLOEXEC); fd = timerfd_create(CLOCK_MONOTONIC, TFD_NONBLOCK | TFD_CLOEXEC);
process_unlock();
if (fd < 0) { if (fd < 0) {
SYSERROR("failed to create timer"); SYSERROR("failed to create timer");
return -1; return -1;
...@@ -450,7 +457,9 @@ int lxc_utmp_add_timer(struct lxc_epoll_descr *descr, ...@@ -450,7 +457,9 @@ int lxc_utmp_add_timer(struct lxc_epoll_descr *descr,
if (lxc_mainloop_add_handler(descr, fd, callback, utmp_data)) { if (lxc_mainloop_add_handler(descr, fd, callback, utmp_data)) {
SYSERROR("failed to add utmp timer to mainloop"); SYSERROR("failed to add utmp timer to mainloop");
process_lock();
close(fd); close(fd);
process_unlock();
return -1; return -1;
} }
...@@ -471,7 +480,9 @@ int lxc_utmp_del_timer(struct lxc_epoll_descr *descr, ...@@ -471,7 +480,9 @@ int lxc_utmp_del_timer(struct lxc_epoll_descr *descr,
SYSERROR("failed to del utmp timer from mainloop"); SYSERROR("failed to del utmp timer from mainloop");
/* shutdown timer_fd */ /* shutdown timer_fd */
process_lock();
close(utmp_data->timer_fd); close(utmp_data->timer_fd);
process_unlock();
utmp_data->timer_fd = -1; utmp_data->timer_fd = -1;
if (result < 0) if (result < 0)
......
...@@ -29,6 +29,7 @@ ...@@ -29,6 +29,7 @@
#include <sys/epoll.h> #include <sys/epoll.h>
#include "mainloop.h" #include "mainloop.h"
#include "lxclock.h"
struct mainloop_handler { struct mainloop_handler {
lxc_mainloop_callback_t callback; lxc_mainloop_callback_t callback;
...@@ -132,12 +133,16 @@ int lxc_mainloop_del_handler(struct lxc_epoll_descr *descr, int fd) ...@@ -132,12 +133,16 @@ int lxc_mainloop_del_handler(struct lxc_epoll_descr *descr, int fd)
int lxc_mainloop_open(struct lxc_epoll_descr *descr) int lxc_mainloop_open(struct lxc_epoll_descr *descr)
{ {
/* hint value passed to epoll create */ /* hint value passed to epoll create */
process_lock();
descr->epfd = epoll_create(2); descr->epfd = epoll_create(2);
process_unlock();
if (descr->epfd < 0) if (descr->epfd < 0)
return -1; return -1;
if (fcntl(descr->epfd, F_SETFD, FD_CLOEXEC)) { if (fcntl(descr->epfd, F_SETFD, FD_CLOEXEC)) {
process_lock();
close(descr->epfd); close(descr->epfd);
process_unlock();
return -1; return -1;
} }
...@@ -148,6 +153,7 @@ int lxc_mainloop_open(struct lxc_epoll_descr *descr) ...@@ -148,6 +153,7 @@ int lxc_mainloop_open(struct lxc_epoll_descr *descr)
int lxc_mainloop_close(struct lxc_epoll_descr *descr) int lxc_mainloop_close(struct lxc_epoll_descr *descr)
{ {
struct lxc_list *iterator, *next; struct lxc_list *iterator, *next;
int ret;
iterator = descr->handlers.next; iterator = descr->handlers.next;
while (iterator != &descr->handlers) { while (iterator != &descr->handlers) {
...@@ -159,6 +165,9 @@ int lxc_mainloop_close(struct lxc_epoll_descr *descr) ...@@ -159,6 +165,9 @@ int lxc_mainloop_close(struct lxc_epoll_descr *descr)
iterator = next; iterator = next;
} }
return close(descr->epfd); process_lock();
ret = close(descr->epfd);
process_unlock();
return ret;
} }
...@@ -90,7 +90,9 @@ static void lxc_monitor_fifo_send(struct lxc_msg *msg, const char *lxcpath) ...@@ -90,7 +90,9 @@ static void lxc_monitor_fifo_send(struct lxc_msg *msg, const char *lxcpath)
if (ret < 0) if (ret < 0)
return; return;
process_lock();
fd = open(fifo_path, O_WRONLY); fd = open(fifo_path, O_WRONLY);
process_unlock();
if (fd < 0) { if (fd < 0) {
/* it is normal for this open to fail when there is no monitor /* it is normal for this open to fail when there is no monitor
* running, so we don't log it * running, so we don't log it
...@@ -100,12 +102,16 @@ static void lxc_monitor_fifo_send(struct lxc_msg *msg, const char *lxcpath) ...@@ -100,12 +102,16 @@ static void lxc_monitor_fifo_send(struct lxc_msg *msg, const char *lxcpath)
ret = write(fd, msg, sizeof(*msg)); ret = write(fd, msg, sizeof(*msg));
if (ret != sizeof(*msg)) { if (ret != sizeof(*msg)) {
process_lock();
close(fd); close(fd);
process_unlock();
SYSERROR("failed to write monitor fifo %s", fifo_path); SYSERROR("failed to write monitor fifo %s", fifo_path);
return; return;
} }
process_lock();
close(fd); close(fd);
process_unlock();
} }
void lxc_monitor_send_state(const char *name, lxc_state_t state, const char *lxcpath) void lxc_monitor_send_state(const char *name, lxc_state_t state, const char *lxcpath)
...@@ -122,7 +128,12 @@ void lxc_monitor_send_state(const char *name, lxc_state_t state, const char *lxc ...@@ -122,7 +128,12 @@ void lxc_monitor_send_state(const char *name, lxc_state_t state, const char *lxc
/* routines used by monitor subscribers (lxc-monitor) */ /* routines used by monitor subscribers (lxc-monitor) */
int lxc_monitor_close(int fd) int lxc_monitor_close(int fd)
{ {
return close(fd); int ret;
process_lock();
ret = close(fd);
process_unlock();
return ret;
} }
/* Note we don't use SHA-1 here as we don't want to depend on HAVE_GNUTLS. /* Note we don't use SHA-1 here as we don't want to depend on HAVE_GNUTLS.
...@@ -187,7 +198,9 @@ int lxc_monitor_open(const char *lxcpath) ...@@ -187,7 +198,9 @@ int lxc_monitor_open(const char *lxcpath)
if (lxc_monitor_sock_name(lxcpath, &addr) < 0) if (lxc_monitor_sock_name(lxcpath, &addr) < 0)
return -1; return -1;
process_lock();
fd = socket(PF_UNIX, SOCK_STREAM, 0); fd = socket(PF_UNIX, SOCK_STREAM, 0);
process_unlock();
if (fd < 0) { if (fd < 0) {
ERROR("socket : %s", strerror(errno)); ERROR("socket : %s", strerror(errno));
return -1; return -1;
...@@ -207,7 +220,9 @@ int lxc_monitor_open(const char *lxcpath) ...@@ -207,7 +220,9 @@ int lxc_monitor_open(const char *lxcpath)
} }
return fd; return fd;
err1: err1:
process_lock();
close(fd); close(fd);
process_unlock();
return ret; return ret;
} }
...@@ -293,6 +308,7 @@ int lxc_monitord_spawn(const char *lxcpath) ...@@ -293,6 +308,7 @@ int lxc_monitord_spawn(const char *lxcpath)
return 0; return 0;
} }
process_unlock(); // we're no longer sharing
if (pipe(pipefd) < 0) { if (pipe(pipefd) < 0) {
SYSERROR("failed to create pipe"); SYSERROR("failed to create pipe");
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
......
...@@ -48,6 +48,7 @@ ...@@ -48,6 +48,7 @@
#include "nl.h" #include "nl.h"
#include "network.h" #include "network.h"
#include "conf.h" #include "conf.h"
#include "lxclock.h"
#ifndef IFLA_LINKMODE #ifndef IFLA_LINKMODE
# define IFLA_LINKMODE 17 # define IFLA_LINKMODE 17
...@@ -569,14 +570,18 @@ static int proc_sys_net_write(const char *path, const char *value) ...@@ -569,14 +570,18 @@ static int proc_sys_net_write(const char *path, const char *value)
{ {
int fd, err = 0; int fd, err = 0;
process_lock();
fd = open(path, O_WRONLY); fd = open(path, O_WRONLY);
process_unlock();
if (fd < 0) if (fd < 0)
return -errno; return -errno;
if (write(fd, value, strlen(value)) < 0) if (write(fd, value, strlen(value)) < 0)
err = -errno; err = -errno;
process_lock();
close(fd); close(fd);
process_unlock();
return err; return err;
} }
...@@ -994,14 +999,18 @@ int lxc_bridge_attach(const char *bridge, const char *ifname) ...@@ -994,14 +999,18 @@ int lxc_bridge_attach(const char *bridge, const char *ifname)
if (!index) if (!index)
return -EINVAL; return -EINVAL;
process_lock();
fd = socket(AF_INET, SOCK_STREAM, 0); fd = socket(AF_INET, SOCK_STREAM, 0);
process_unlock();
if (fd < 0) if (fd < 0)
return -errno; return -errno;
strncpy(ifr.ifr_name, bridge, IFNAMSIZ); strncpy(ifr.ifr_name, bridge, IFNAMSIZ);
ifr.ifr_ifindex = index; ifr.ifr_ifindex = index;
err = ioctl(fd, SIOCBRADDIF, &ifr); err = ioctl(fd, SIOCBRADDIF, &ifr);
process_lock();
close(fd); close(fd);
process_unlock();
if (err) if (err)
err = -errno; err = -errno;
......
...@@ -31,6 +31,7 @@ ...@@ -31,6 +31,7 @@
#include <linux/rtnetlink.h> #include <linux/rtnetlink.h>
#include "nl.h" #include "nl.h"
#include "lxclock.h"
#define NLMSG_TAIL(nmsg) \ #define NLMSG_TAIL(nmsg) \
((struct rtattr *) (((void *) (nmsg)) + NLMSG_ALIGN((nmsg)->nlmsg_len))) ((struct rtattr *) (((void *) (nmsg)) + NLMSG_ALIGN((nmsg)->nlmsg_len)))
...@@ -222,7 +223,9 @@ extern int netlink_open(struct nl_handler *handler, int protocol) ...@@ -222,7 +223,9 @@ extern int netlink_open(struct nl_handler *handler, int protocol)
memset(handler, 0, sizeof(*handler)); memset(handler, 0, sizeof(*handler));
process_lock();
handler->fd = socket(AF_NETLINK, SOCK_RAW, protocol); handler->fd = socket(AF_NETLINK, SOCK_RAW, protocol);
process_unlock();
if (handler->fd < 0) if (handler->fd < 0)
return -errno; return -errno;
...@@ -260,7 +263,9 @@ extern int netlink_open(struct nl_handler *handler, int protocol) ...@@ -260,7 +263,9 @@ extern int netlink_open(struct nl_handler *handler, int protocol)
extern int netlink_close(struct nl_handler *handler) extern int netlink_close(struct nl_handler *handler)
{ {
process_lock();
close(handler->fd); close(handler->fd);
process_unlock();
handler->fd = -1; handler->fd = -1;
return 0; return 0;
} }
......
...@@ -31,6 +31,7 @@ ...@@ -31,6 +31,7 @@
#include "parse.h" #include "parse.h"
#include "config.h" #include "config.h"
#include "utils.h" #include "utils.h"
#include "lxclock.h"
#include <lxc/log.h> #include <lxc/log.h>
/* Workaround for the broken signature of alphasort() in bionic. /* Workaround for the broken signature of alphasort() in bionic.
...@@ -90,7 +91,9 @@ int lxc_file_for_each_line(const char *file, lxc_file_cb callback, void *data) ...@@ -90,7 +91,9 @@ int lxc_file_for_each_line(const char *file, lxc_file_cb callback, void *data)
char *line = NULL; char *line = NULL;
size_t len = 0; size_t len = 0;
process_lock();
f = fopen(file, "r"); f = fopen(file, "r");
process_unlock();
if (!f) { if (!f) {
SYSERROR("failed to open %s", file); SYSERROR("failed to open %s", file);
return -1; return -1;
...@@ -104,7 +107,9 @@ int lxc_file_for_each_line(const char *file, lxc_file_cb callback, void *data) ...@@ -104,7 +107,9 @@ int lxc_file_for_each_line(const char *file, lxc_file_cb callback, void *data)
if (line) if (line)
free(line); free(line);
process_lock();
fclose(f); fclose(f);
process_unlock();
return err; return err;
} }
......
...@@ -29,6 +29,7 @@ ...@@ -29,6 +29,7 @@
#include <seccomp.h> #include <seccomp.h>
#include "config.h" #include "config.h"
#include "lxcseccomp.h" #include "lxcseccomp.h"
#include "lxclock.h"
#include "log.h" #include "log.h"
...@@ -114,13 +115,17 @@ int lxc_read_seccomp_config(struct lxc_conf *conf) ...@@ -114,13 +115,17 @@ int lxc_read_seccomp_config(struct lxc_conf *conf)
return -1; return -1;
} }
process_lock();
f = fopen(conf->seccomp, "r"); f = fopen(conf->seccomp, "r");
process_unlock();
if (!f) { if (!f) {
SYSERROR("failed to open seccomp policy file %s\n", conf->seccomp); SYSERROR("failed to open seccomp policy file %s\n", conf->seccomp);
return -1; return -1;
} }
ret = parse_config(f, conf); ret = parse_config(f, conf);
process_lock();
fclose(f); fclose(f);
process_unlock();
return ret; return ret;
} }
......
...@@ -71,6 +71,7 @@ ...@@ -71,6 +71,7 @@
#include "apparmor.h" #include "apparmor.h"
#include "lxcseccomp.h" #include "lxcseccomp.h"
#include "caps.h" #include "caps.h"
#include "lxclock.h"
lxc_log_define(lxc_start, lxc); lxc_log_define(lxc_start, lxc);
...@@ -86,7 +87,9 @@ int lxc_check_inherited(struct lxc_conf *conf, int fd_to_ignore) ...@@ -86,7 +87,9 @@ int lxc_check_inherited(struct lxc_conf *conf, int fd_to_ignore)
DIR *dir; DIR *dir;
restart: restart:
process_lock();
dir = opendir("/proc/self/fd"); dir = opendir("/proc/self/fd");
process_unlock();
if (!dir) { if (!dir) {
WARN("failed to open directory: %m"); WARN("failed to open directory: %m");
return -1; return -1;
...@@ -113,15 +116,19 @@ restart: ...@@ -113,15 +116,19 @@ restart:
continue; continue;
if (conf->close_all_fds) { if (conf->close_all_fds) {
process_lock();
close(fd); close(fd);
closedir(dir); closedir(dir);
process_unlock();
INFO("closed inherited fd %d", fd); INFO("closed inherited fd %d", fd);
goto restart; goto restart;
} }
WARN("inherited fd %d", fd); WARN("inherited fd %d", fd);
} }
process_lock();
closedir(dir); /* cannot fail */ closedir(dir); /* cannot fail */
process_unlock();
return 0; return 0;
} }
...@@ -258,7 +265,9 @@ int lxc_poll(const char *name, struct lxc_handler *handler) ...@@ -258,7 +265,9 @@ int lxc_poll(const char *name, struct lxc_handler *handler)
out_mainloop_open: out_mainloop_open:
lxc_mainloop_close(&descr); lxc_mainloop_close(&descr);
out_sigfd: out_sigfd:
process_lock();
close(sigfd); close(sigfd);
process_unlock();
return -1; return -1;
} }
...@@ -353,7 +362,9 @@ out_delete_tty: ...@@ -353,7 +362,9 @@ out_delete_tty:
out_aborting: out_aborting:
lxc_set_state(name, handler, ABORTING); lxc_set_state(name, handler, ABORTING);
out_close_maincmd_fd: out_close_maincmd_fd:
process_lock();
close(conf->maincmd_fd); close(conf->maincmd_fd);
process_unlock();
conf->maincmd_fd = -1; conf->maincmd_fd = -1;
out_free_name: out_free_name:
free(handler->name); free(handler->name);
...@@ -380,7 +391,9 @@ static void lxc_fini(const char *name, struct lxc_handler *handler) ...@@ -380,7 +391,9 @@ static void lxc_fini(const char *name, struct lxc_handler *handler)
lxc_console_delete(&handler->conf->console); lxc_console_delete(&handler->conf->console);
lxc_delete_tty(&handler->conf->tty_info); lxc_delete_tty(&handler->conf->tty_info);
process_lock();
close(handler->conf->maincmd_fd); close(handler->conf->maincmd_fd);
process_unlock();
handler->conf->maincmd_fd = -1; handler->conf->maincmd_fd = -1;
free(handler->name); free(handler->name);
if (handler->cgroup) { if (handler->cgroup) {
...@@ -421,20 +434,25 @@ static int container_reboot_supported(void *arg) ...@@ -421,20 +434,25 @@ static int container_reboot_supported(void *arg)
static int must_drop_cap_sys_boot(struct lxc_conf *conf) static int must_drop_cap_sys_boot(struct lxc_conf *conf)
{ {
FILE *f = fopen("/proc/sys/kernel/ctrl-alt-del", "r"); FILE *f;
int ret, cmd, v, flags; int ret, cmd, v, flags;
long stack_size = 4096; long stack_size = 4096;
void *stack = alloca(stack_size); void *stack = alloca(stack_size);
int status; int status;
pid_t pid; pid_t pid;
process_lock();
f = fopen("/proc/sys/kernel/ctrl-alt-del", "r");
process_unlock();
if (!f) { if (!f) {
DEBUG("failed to open /proc/sys/kernel/ctrl-alt-del"); DEBUG("failed to open /proc/sys/kernel/ctrl-alt-del");
return 1; return 1;
} }
ret = fscanf(f, "%d", &v); ret = fscanf(f, "%d", &v);
process_lock();
fclose(f); fclose(f);
process_unlock();
if (ret != 1) { if (ret != 1) {
DEBUG("Failed to read /proc/sys/kernel/ctrl-alt-del"); DEBUG("Failed to read /proc/sys/kernel/ctrl-alt-del");
return 1; return 1;
...@@ -489,8 +507,11 @@ static int do_start(void *data) ...@@ -489,8 +507,11 @@ static int do_start(void *data)
lxc_sync_fini_parent(handler); lxc_sync_fini_parent(handler);
/* don't leak the pinfd to the container */ /* don't leak the pinfd to the container */
if (handler->pinfd >= 0) if (handler->pinfd >= 0) {
process_lock();
close(handler->pinfd); close(handler->pinfd);
process_unlock();
}
/* Tell the parent task it can begin to configure the /* Tell the parent task it can begin to configure the
* container and wait for it to finish * container and wait for it to finish
...@@ -560,7 +581,9 @@ static int do_start(void *data) ...@@ -560,7 +581,9 @@ static int do_start(void *data)
goto out_warn_father; goto out_warn_father;
} }
process_lock();
close(handler->sigfd); close(handler->sigfd);
process_unlock();
/* after this call, we are in error because this /* after this call, we are in error because this
* ops should not return as it execs */ * ops should not return as it execs */
...@@ -780,7 +803,9 @@ out_abort: ...@@ -780,7 +803,9 @@ out_abort:
lxc_abort(name, handler); lxc_abort(name, handler);
lxc_sync_fini(handler); lxc_sync_fini(handler);
if (handler->pinfd >= 0) { if (handler->pinfd >= 0) {
process_lock();
close(handler->pinfd); close(handler->pinfd);
process_unlock();
handler->pinfd = -1; handler->pinfd = -1;
} }
...@@ -852,7 +877,9 @@ int __lxc_start(const char *name, struct lxc_conf *conf, ...@@ -852,7 +877,9 @@ int __lxc_start(const char *name, struct lxc_conf *conf,
lxc_rename_phys_nics_on_shutdown(handler->conf); lxc_rename_phys_nics_on_shutdown(handler->conf);
if (handler->pinfd >= 0) { if (handler->pinfd >= 0) {
process_lock();
close(handler->pinfd); close(handler->pinfd);
process_unlock();
handler->pinfd = -1; handler->pinfd = -1;
} }
......
...@@ -39,6 +39,7 @@ ...@@ -39,6 +39,7 @@
#include <lxc/monitor.h> #include <lxc/monitor.h>
#include "commands.h" #include "commands.h"
#include "config.h" #include "config.h"
#include "lxclock.h"
lxc_log_define(lxc_state, lxc); lxc_log_define(lxc_state, lxc);
...@@ -83,14 +84,18 @@ static lxc_state_t freezer_state(const char *name, const char *lxcpath) ...@@ -83,14 +84,18 @@ static lxc_state_t freezer_state(const char *name, const char *lxcpath)
if (ret < 0 || ret >= MAXPATHLEN) if (ret < 0 || ret >= MAXPATHLEN)
goto out; goto out;
process_lock();
file = fopen(freezer, "r"); file = fopen(freezer, "r");
process_unlock();
if (!file) { if (!file) {
ret = -1; ret = -1;
goto out; goto out;
} }
ret = fscanf(file, "%s", status); ret = fscanf(file, "%s", status);
process_lock();
fclose(file); fclose(file);
process_unlock();
if (ret == EOF) { if (ret == EOF) {
SYSERROR("failed to read %s", freezer); SYSERROR("failed to read %s", freezer);
......
...@@ -29,6 +29,7 @@ ...@@ -29,6 +29,7 @@
#include "log.h" #include "log.h"
#include "start.h" #include "start.h"
#include "lxclock.h"
lxc_log_define(lxc_sync, lxc); lxc_log_define(lxc_sync, lxc);
...@@ -99,7 +100,12 @@ int lxc_sync_wake_child(struct lxc_handler *handler, int sequence) ...@@ -99,7 +100,12 @@ int lxc_sync_wake_child(struct lxc_handler *handler, int sequence)
int lxc_sync_init(struct lxc_handler *handler) int lxc_sync_init(struct lxc_handler *handler)
{ {
if (socketpair(AF_LOCAL, SOCK_STREAM, 0, handler->sv)) { int ret;
process_lock();
ret = socketpair(AF_LOCAL, SOCK_STREAM, 0, handler->sv);
process_unlock();
if (ret) {
SYSERROR("failed to create synchronization socketpair"); SYSERROR("failed to create synchronization socketpair");
return -1; return -1;
} }
...@@ -113,7 +119,9 @@ int lxc_sync_init(struct lxc_handler *handler) ...@@ -113,7 +119,9 @@ int lxc_sync_init(struct lxc_handler *handler)
void lxc_sync_fini_child(struct lxc_handler *handler) void lxc_sync_fini_child(struct lxc_handler *handler)
{ {
if (handler->sv[0] != -1) { if (handler->sv[0] != -1) {
process_lock();
close(handler->sv[0]); close(handler->sv[0]);
process_unlock();
handler->sv[0] = -1; handler->sv[0] = -1;
} }
} }
...@@ -121,7 +129,9 @@ void lxc_sync_fini_child(struct lxc_handler *handler) ...@@ -121,7 +129,9 @@ void lxc_sync_fini_child(struct lxc_handler *handler)
void lxc_sync_fini_parent(struct lxc_handler *handler) void lxc_sync_fini_parent(struct lxc_handler *handler)
{ {
if (handler->sv[1] != -1) { if (handler->sv[1] != -1) {
process_lock();
close(handler->sv[1]); close(handler->sv[1]);
process_unlock();
handler->sv[1] = -1; handler->sv[1] = -1;
} }
} }
......
...@@ -47,6 +47,7 @@ ...@@ -47,6 +47,7 @@
#include "utils.h" #include "utils.h"
#include "log.h" #include "log.h"
#include "lxclock.h"
lxc_log_define(lxc_utils, lxc); lxc_log_define(lxc_utils, lxc);
...@@ -57,7 +58,9 @@ static int _recursive_rmdir_onedev(char *dirname, dev_t pdev) ...@@ -57,7 +58,9 @@ static int _recursive_rmdir_onedev(char *dirname, dev_t pdev)
int ret, failed=0; int ret, failed=0;
char pathname[MAXPATHLEN]; char pathname[MAXPATHLEN];
process_lock();
dir = opendir(dirname); dir = opendir(dirname);
process_unlock();
if (!dir) { if (!dir) {
ERROR("%s: failed to open %s", __func__, dirname); ERROR("%s: failed to open %s", __func__, dirname);
return 0; return 0;
...@@ -104,7 +107,10 @@ static int _recursive_rmdir_onedev(char *dirname, dev_t pdev) ...@@ -104,7 +107,10 @@ static int _recursive_rmdir_onedev(char *dirname, dev_t pdev)
failed=1; failed=1;
} }
if (closedir(dir)) { process_lock();
ret = closedir(dir);
process_unlock();
if (ret) {
ERROR("%s: failed to close directory %s", __func__, dirname); ERROR("%s: failed to close directory %s", __func__, dirname);
failed=1; failed=1;
} }
...@@ -253,7 +259,9 @@ const char *lxc_global_config_value(const char *option_name) ...@@ -253,7 +259,9 @@ const char *lxc_global_config_value(const char *option_name)
if (values[i]) if (values[i])
return values[i]; return values[i];
process_lock();
fin = fopen_cloexec(LXC_GLOBAL_CONF, "r"); fin = fopen_cloexec(LXC_GLOBAL_CONF, "r");
process_unlock();
if (fin) { if (fin) {
while (fgets(buf, 1024, fin)) { while (fgets(buf, 1024, fin)) {
if (buf[0] == '#') if (buf[0] == '#')
...@@ -299,8 +307,10 @@ const char *lxc_global_config_value(const char *option_name) ...@@ -299,8 +307,10 @@ const char *lxc_global_config_value(const char *option_name)
errno = 0; errno = 0;
out: out:
process_lock();
if (fin) if (fin)
fclose(fin); fclose(fin);
process_unlock();
return values[i]; return values[i];
} }
...@@ -397,6 +407,15 @@ ssize_t lxc_read_nointr_expect(int fd, void* buf, size_t count, const void* expe ...@@ -397,6 +407,15 @@ ssize_t lxc_read_nointr_expect(int fd, void* buf, size_t count, const void* expe
return ret; return ret;
} }
static inline int lock_fclose(FILE *f)
{
int ret;
process_lock();
ret = fclose(f);
process_unlock();
return ret;
}
#if HAVE_LIBGNUTLS #if HAVE_LIBGNUTLS
#include <gnutls/gnutls.h> #include <gnutls/gnutls.h>
#include <gnutls/crypto.h> #include <gnutls/crypto.h>
...@@ -409,37 +428,40 @@ int sha1sum_file(char *fnam, unsigned char *digest) ...@@ -409,37 +428,40 @@ int sha1sum_file(char *fnam, unsigned char *digest)
if (!fnam) if (!fnam)
return -1; return -1;
if ((f = fopen_cloexec(fnam, "r")) < 0) { process_lock();
f = fopen_cloexec(fnam, "r");
process_unlock();
if (f < 0) {
SYSERROR("Error opening template"); SYSERROR("Error opening template");
return -1; return -1;
} }
if (fseek(f, 0, SEEK_END) < 0) { if (fseek(f, 0, SEEK_END) < 0) {
SYSERROR("Error seeking to end of template"); SYSERROR("Error seeking to end of template");
fclose(f); lock_fclose(f);
return -1; return -1;
} }
if ((flen = ftell(f)) < 0) { if ((flen = ftell(f)) < 0) {
SYSERROR("Error telling size of template"); SYSERROR("Error telling size of template");
fclose(f); lock_fclose(f);
return -1; return -1;
} }
if (fseek(f, 0, SEEK_SET) < 0) { if (fseek(f, 0, SEEK_SET) < 0) {
SYSERROR("Error seeking to start of template"); SYSERROR("Error seeking to start of template");
fclose(f); lock_fclose(f);
return -1; return -1;
} }
if ((buf = malloc(flen+1)) == NULL) { if ((buf = malloc(flen+1)) == NULL) {
SYSERROR("Out of memory"); SYSERROR("Out of memory");
fclose(f); lock_fclose(f);
return -1; return -1;
} }
if (fread(buf, 1, flen, f) != flen) { if (fread(buf, 1, flen, f) != flen) {
SYSERROR("Failure reading template"); SYSERROR("Failure reading template");
free(buf); free(buf);
fclose(f); lock_fclose(f);
return -1; return -1;
} }
if (fclose(f) < 0) { if (lock_fclose(f) < 0) {
SYSERROR("Failre closing template"); SYSERROR("Failre closing template");
free(buf); free(buf);
return -1; return -1;
...@@ -496,6 +518,10 @@ const char** lxc_va_arg_list_to_argv_const(va_list ap, size_t skip) ...@@ -496,6 +518,10 @@ const char** lxc_va_arg_list_to_argv_const(va_list ap, size_t skip)
return (const char**)lxc_va_arg_list_to_argv(ap, skip, 0); return (const char**)lxc_va_arg_list_to_argv(ap, skip, 0);
} }
/*
* fopen_cloexec: must be called with process_lock() held
* if it is needed.
*/
FILE *fopen_cloexec(const char *path, const char *mode) FILE *fopen_cloexec(const char *path, const char *mode)
{ {
int open_mode = 0; int open_mode = 0;
...@@ -847,7 +873,9 @@ int lxc_write_to_file(const char *filename, const void* buf, size_t count, bool ...@@ -847,7 +873,9 @@ int lxc_write_to_file(const char *filename, const void* buf, size_t count, bool
int fd, saved_errno; int fd, saved_errno;
ssize_t ret; ssize_t ret;
process_lock();
fd = open(filename, O_WRONLY | O_TRUNC | O_CREAT | O_CLOEXEC, 0666); fd = open(filename, O_WRONLY | O_TRUNC | O_CREAT | O_CLOEXEC, 0666);
process_unlock();
if (fd < 0) if (fd < 0)
return -1; return -1;
ret = lxc_write_nointr(fd, buf, count); ret = lxc_write_nointr(fd, buf, count);
...@@ -860,12 +888,16 @@ int lxc_write_to_file(const char *filename, const void* buf, size_t count, bool ...@@ -860,12 +888,16 @@ int lxc_write_to_file(const char *filename, const void* buf, size_t count, bool
if (ret != 1) if (ret != 1)
goto out_error; goto out_error;
} }
process_lock();
close(fd); close(fd);
process_unlock();
return 0; return 0;
out_error: out_error:
saved_errno = errno; saved_errno = errno;
process_lock();
close(fd); close(fd);
process_unlock();
errno = saved_errno; errno = saved_errno;
return -1; return -1;
} }
...@@ -875,7 +907,9 @@ int lxc_read_from_file(const char *filename, void* buf, size_t count) ...@@ -875,7 +907,9 @@ int lxc_read_from_file(const char *filename, void* buf, size_t count)
int fd = -1, saved_errno; int fd = -1, saved_errno;
ssize_t ret; ssize_t ret;
process_lock();
fd = open(filename, O_RDONLY | O_CLOEXEC); fd = open(filename, O_RDONLY | O_CLOEXEC);
process_unlock();
if (fd < 0) if (fd < 0)
return -1; return -1;
...@@ -895,7 +929,9 @@ int lxc_read_from_file(const char *filename, void* buf, size_t count) ...@@ -895,7 +929,9 @@ int lxc_read_from_file(const char *filename, void* buf, size_t count)
ERROR("read %s: %s", filename, strerror(errno)); ERROR("read %s: %s", filename, strerror(errno));
saved_errno = errno; saved_errno = errno;
process_lock();
close(fd); close(fd);
process_unlock();
errno = saved_errno; errno = saved_errno;
return ret; return ret;
} }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment