POSIX specifies [1]:
"If the value of n is zero on a call to snprintf(), nothing shall be written,
the number of bytes that would have been written had n been sufficiently large
excluding the terminating null shall be returned, and s may be a null pointer."
But in case there are any non-sane libcs out there that do actually dereference
the buffer when when 0 is passed as length to snprintf() let's give them a
dummy buffer.
First, I forgot to actually replace strncpy() with strlcpy(). Second, we don't
want to \0-terminate since this is an abstract unix socket and this is not
required. Instead, let's simply use memcpy() which is more correct and also
silences gcc-8.
Signed-off-by: Christian Brauner <christian.brauner@ubuntu.com>
Starting with commit 55956b59df33 ("vfs: Allow userns root to call mknod on owned filesystems.")
Linux will allow mknod() in user namespaces for userns root if CAP_MKNOD is
available.
However, these device nodes are useless since
which will cause an EPERM because the device node is located on an fs
owned by non-init-userns and thus doesn't grant access to device nodes due to
SB_I_NODEV.
This commit enables LXC to deal with such kernels.
Signed-off-by: Christian Brauner <christian.brauner@ubuntu.com>
These files have never been used and as such have no dependencies in the
codebase whatsoever. So remove them. If we need them we can simply pull them
out of the git history.
Signed-off-by: Christian Brauner <christian.brauner@ubuntu.com>
Tycho Andersen [Wed, 9 May 2018 01:29:06 +0000 (01:29 +0000)]
execute: account for -o path option count
This always works fine... until your exec() fails and you try to go and
free it, you've overwritten the allocator's metadata (and potentially other
stuff) and it fails.
This is already done in do_lxcapi_start{l}() so a) no need to do it again here
and b) this would close the state socket pair sockets, corrup the fd, and lead
to EBADF.
Signed-off-by: Christian Brauner <christian.brauner@ubuntu.com>
Tycho Andersen [Thu, 3 May 2018 18:32:19 +0000 (18:32 +0000)]
fix logic for execute log file
The problem here is that lxc-init runs *inside* the container. So if a
person has the log file set to /home/$USER/foo, lxc-init ends up making a
directory /home/$USER/foo inside the container to put the log file in. What
we really want are the logs to be propagated from inside the container to
the outside. We accomplish this by passing an fd without O_CLOEXEC, and
telling lxc-init to log to that file.
Kaarle Ritvanen [Sun, 15 Apr 2018 11:50:28 +0000 (14:50 +0300)]
do_lxcapi_create: set umask
Always use 022 as the umask when creating the rootfs directory and
executing the template. A too loose umask may cause security issues.
A too strict umask may cause programs to fail inside the container.
Signed-off-by: Kaarle Ritvanen <kaarle.ritvanen@datakunkku.fi>
We should always default to mounting devpts with gid=5 but we should fallback
to mounting without gid=5. This let's us cover use-cases such as container
started with only a single mapping e.g.:
lxc.idmap = u 1000 1000 1
lxc.idmap = g 1000 1000 1
Closes #2257.
Signed-off-by: Christian Brauner <christian.brauner@ubuntu.com>
The problem here is that these two clauses were ordered backwards: we first
check if the signal came from not the init pid, and if it did, then we give
a notice and return. The comment notes that this is intended to protect
against SIGCHLD, but we don't in fact know if the signal is a SIGCHLD yet,
because that's tested in the next hunk.
The symptom is that if I e.g. send SIGTERM from the outside world to the
container init, it ignores it and gives this notice. If we re-order these
clauses, it forwards non SIGCHLD signals, and ignores SIGCHLD signals from
things that aren't the real container process.
Tycho Andersen [Thu, 15 Mar 2018 15:29:27 +0000 (15:29 +0000)]
fix handler use-after-free
The problem here is that __lxc_start frees the handler, so any use
afterwards is invalid. Since we don't have access to the actual struct
lxc_container object in __lxc_start, let's pass a pointer to error_num in
so it can be returned.
Unfortunately, I'm a little too paranoid to change the return type of
lxc_start, since it returns failure if some of the cleanup fails, which
may be useful in some cases. So let's keep this out of band.
Closes #2218
Closes #2219
Reported-by: Felix Abecassis <fabecassis@nvidia.com> Signed-off-by: Tycho Andersen <tycho@tycho.ws>
Igor Galić [Wed, 14 Mar 2018 15:53:24 +0000 (16:53 +0100)]
conf: fix clang warning when building w/o libcap
when compiling lxc with clang-5.0 parse_cap()'s main loop will produce a
warning about a tautological comparision (#2215).
By moving the result of computation into a variable (end) this is no
longer a constant expression. clang-5.0 does not do dataflow analysis at
this point, so it is, to quote someone from #llvm, "morally equivalent"
to casting `(int)i`.
in addition, we also clean up the #if HAVE_LIBCAP to no longer need
its #else branch!
Signed-off-by: Igor Galić <igor.galic@automatic-server.com>
Tycho Andersen [Mon, 12 Mar 2018 15:39:37 +0000 (09:39 -0600)]
usernsexec: init log fd
lxc-usernsexec uses some functions (e.g. lxc_map_ids()), which are part of
the lxc library and thus use the WARN etc. macros to emit log messages.
However, it doesn't initialize the log in any way, so these messages go
into the ether.
lxc-usernsexec currently has no log parameters, so let's just log these to
stderr. Someone can do something fancier later if they want.
Serge Hallyn [Tue, 27 Feb 2018 18:05:30 +0000 (12:05 -0600)]
lxc_init: don't mount filesystems
We have an extensive set of container config options to do this
for us, and doing this unconditionally breaks several use cases.
For instance, if we want to bind mount a /dev/shm using the
container configuration, then lxc-execute, then lxc-init will
rudely unmount the /dev/shm and remount it as a private tmpfs.
I was thinking about the locking here yesterday and it dawned on me that we
actually don't need this at all:
- possible contention between traversing list to send states to state clients
and adding new state clients to the list:
It is the command handler that adds new state clients to the state client
list. The command handler and the code that actually sends out the container
states run in the same process so there's not contention and thus no locking
needed.
- adding state clients to the list from multiple threads:
The command handler itself is single-threaded so only one thread's request can
be served at the same time so no locking is needed.
- sending out the state to state clients via the command handler itself:
The state client also adds and removes state clients from the state client
list so there's no locking needed.
Signed-off-by: Christian Brauner <christian.brauner@ubuntu.com>