Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
L
lxc
Project
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Chen Yisong
lxc
Commits
e96a536c
Unverified
Commit
e96a536c
authored
Feb 19, 2018
by
Christian Brauner
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
start: do_start()
Signed-off-by:
Christian Brauner
<
christian.brauner@ubuntu.com
>
parent
0e4f9d51
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
82 additions
and
53 deletions
+82
-53
start.c
src/lxc/start.c
+82
-53
No files found.
src/lxc/start.c
View file @
e96a536c
...
@@ -1024,13 +1024,13 @@ static int lxc_set_death_signal(int signal)
...
@@ -1024,13 +1024,13 @@ static int lxc_set_death_signal(int signal)
static
int
do_start
(
void
*
data
)
static
int
do_start
(
void
*
data
)
{
{
int
ret
;
int
ret
;
struct
lxc_list
*
iterator
;
char
path
[
PATH_MAX
];
char
path
[
PATH_MAX
];
struct
lxc_handler
*
handler
=
data
;
bool
have_cap_setgid
;
bool
have_cap_setgid
;
uid_t
new_uid
;
uid_t
new_uid
;
gid_t
new_gid
;
gid_t
new_gid
;
struct
lxc_list
*
iterator
;
int
devnull_fd
=
-
1
;
int
devnull_fd
=
-
1
;
struct
lxc_handler
*
handler
=
data
;
lxc_sync_fini_parent
(
handler
);
lxc_sync_fini_parent
(
handler
);
...
@@ -1067,19 +1067,21 @@ static int do_start(void *data)
...
@@ -1067,19 +1067,21 @@ static int do_start(void *data)
(
CLONE_NEWNET
|
CLONE_NEWUSER
))
{
(
CLONE_NEWNET
|
CLONE_NEWUSER
))
{
ret
=
unshare
(
CLONE_NEWNET
);
ret
=
unshare
(
CLONE_NEWNET
);
if
(
ret
<
0
)
{
if
(
ret
<
0
)
{
SYSERROR
(
"Failed to unshare CLONE_NEWNET
.
"
);
SYSERROR
(
"Failed to unshare CLONE_NEWNET"
);
goto
out_warn_father
;
goto
out_warn_father
;
}
}
INFO
(
"Unshared CLONE_NEWNET
.
"
);
INFO
(
"Unshared CLONE_NEWNET"
);
}
}
/* Tell the parent task it can begin to configure the container and wait
/* Tell the parent task it can begin to configure the container and wait
* for it to finish.
* for it to finish.
*/
*/
if
(
lxc_sync_barrier_parent
(
handler
,
LXC_SYNC_CONFIGURE
))
ret
=
lxc_sync_barrier_parent
(
handler
,
LXC_SYNC_CONFIGURE
);
if
(
ret
<
0
)
return
-
1
;
return
-
1
;
if
(
lxc_network_recv_veth_names_from_parent
(
handler
)
<
0
)
{
ret
=
lxc_network_recv_veth_names_from_parent
(
handler
);
if
(
ret
<
0
)
{
ERROR
(
"Failed to receive veth names from parent"
);
ERROR
(
"Failed to receive veth names from parent"
);
goto
out_warn_father
;
goto
out_warn_father
;
}
}
...
@@ -1120,12 +1122,14 @@ static int do_start(void *data)
...
@@ -1120,12 +1122,14 @@ static int do_start(void *data)
}
}
}
}
if
(
access
(
handler
->
lxcpath
,
X_OK
))
{
ret
=
access
(
handler
->
lxcpath
,
X_OK
);
if
(
ret
!=
0
)
{
print_top_failing_dir
(
handler
->
lxcpath
);
print_top_failing_dir
(
handler
->
lxcpath
);
goto
out_warn_father
;
goto
out_warn_father
;
}
}
ret
=
snprintf
(
path
,
sizeof
(
path
),
"%s/dev/null"
,
handler
->
conf
->
rootfs
.
mount
);
ret
=
snprintf
(
path
,
sizeof
(
path
),
"%s/dev/null"
,
handler
->
conf
->
rootfs
.
mount
);
if
(
ret
<
0
||
ret
>=
sizeof
(
path
))
if
(
ret
<
0
||
ret
>=
sizeof
(
path
))
goto
out_warn_father
;
goto
out_warn_father
;
...
@@ -1139,17 +1143,22 @@ static int do_start(void *data)
...
@@ -1139,17 +1143,22 @@ static int do_start(void *data)
* means that migration won't work, but at least we won't spew output
* means that migration won't work, but at least we won't spew output
* where it isn't wanted.
* where it isn't wanted.
*/
*/
if
(
handler
->
backgrounded
&&
!
handler
->
conf
->
autodev
&&
access
(
path
,
F_OK
)
<
0
)
{
if
(
handler
->
backgrounded
&&
!
handler
->
conf
->
autodev
)
{
devnull_fd
=
open_devnull
();
ret
=
access
(
path
,
F_OK
);
if
(
ret
!=
0
)
{
devnull_fd
=
open_devnull
();
if
(
devnull_fd
<
0
)
if
(
devnull_fd
<
0
)
goto
out_warn_father
;
goto
out_warn_father
;
WARN
(
"Using /dev/null from the host for container init's "
WARN
(
"Using /dev/null from the host for container "
"standard file descriptors. Migration will not work."
);
"init's standard file descriptors. Migration will "
"not work"
);
}
}
}
/* Ask father to setup cgroups and wait for him to finish. */
/* Ask father to setup cgroups and wait for him to finish. */
if
(
lxc_sync_barrier_parent
(
handler
,
LXC_SYNC_CGROUP
))
ret
=
lxc_sync_barrier_parent
(
handler
,
LXC_SYNC_CGROUP
);
if
(
ret
<
0
)
goto
out_error
;
goto
out_error
;
/* Unshare cgroup namespace after we have setup our cgroups. If we do it
/* Unshare cgroup namespace after we have setup our cgroups. If we do it
...
@@ -1165,11 +1174,12 @@ static int do_start(void *data)
...
@@ -1165,11 +1174,12 @@ static int do_start(void *data)
* 8:cpuset:/
* 8:cpuset:/
*/
*/
if
(
handler
->
clone_flags
&
CLONE_NEWCGROUP
)
{
if
(
handler
->
clone_flags
&
CLONE_NEWCGROUP
)
{
if
(
unshare
(
CLONE_NEWCGROUP
)
<
0
)
{
ret
=
unshare
(
CLONE_NEWCGROUP
);
INFO
(
"Failed to unshare CLONE_NEWCGROUP."
);
if
(
ret
<
0
)
{
INFO
(
"Failed to unshare CLONE_NEWCGROUP"
);
goto
out_warn_father
;
goto
out_warn_father
;
}
}
INFO
(
"Unshared CLONE_NEWCGROUP
.
"
);
INFO
(
"Unshared CLONE_NEWCGROUP"
);
}
}
/* Add the requested environment variables to the current environment to
/* Add the requested environment variables to the current environment to
...
@@ -1177,8 +1187,10 @@ static int do_start(void *data)
...
@@ -1177,8 +1187,10 @@ static int do_start(void *data)
* above.
* above.
*/
*/
lxc_list_for_each
(
iterator
,
&
handler
->
conf
->
environment
)
{
lxc_list_for_each
(
iterator
,
&
handler
->
conf
->
environment
)
{
if
(
putenv
((
char
*
)
iterator
->
elem
))
{
ret
=
putenv
((
char
*
)
iterator
->
elem
);
SYSERROR
(
"Failed to set environment variable: %s."
,
(
char
*
)
iterator
->
elem
);
if
(
ret
<
0
)
{
SYSERROR
(
"Failed to set environment variable: %s"
,
(
char
*
)
iterator
->
elem
);
goto
out_warn_father
;
goto
out_warn_father
;
}
}
}
}
...
@@ -1188,23 +1200,27 @@ static int do_start(void *data)
...
@@ -1188,23 +1200,27 @@ static int do_start(void *data)
close
(
handler
->
data_sock
[
1
]);
close
(
handler
->
data_sock
[
1
]);
close
(
handler
->
data_sock
[
0
]);
close
(
handler
->
data_sock
[
0
]);
if
(
ret
<
0
)
{
if
(
ret
<
0
)
{
ERROR
(
"Failed to setup container
\"
%s
\"
.
"
,
handler
->
name
);
ERROR
(
"Failed to setup container
\"
%s
\"
"
,
handler
->
name
);
goto
out_warn_father
;
goto
out_warn_father
;
}
}
/* Set the label to change to when we exec(2) the container's init. */
/* Set the label to change to when we exec(2) the container's init. */
if
(
lsm_process_label_set
(
NULL
,
handler
->
conf
,
1
,
1
)
<
0
)
ret
=
lsm_process_label_set
(
NULL
,
handler
->
conf
,
1
,
1
);
if
(
ret
<
0
)
goto
out_warn_father
;
goto
out_warn_father
;
/* Set PR_SET_NO_NEW_PRIVS after we changed the lsm label. If we do it
/* Set PR_SET_NO_NEW_PRIVS after we changed the lsm label. If we do it
* before we aren't allowed anymore.
* before we aren't allowed anymore.
*/
*/
if
(
handler
->
conf
->
no_new_privs
)
{
if
(
handler
->
conf
->
no_new_privs
)
{
if
(
prctl
(
PR_SET_NO_NEW_PRIVS
,
1
,
0
,
0
,
0
)
<
0
)
{
ret
=
prctl
(
PR_SET_NO_NEW_PRIVS
,
1
,
0
,
0
,
0
);
SYSERROR
(
"Could not set PR_SET_NO_NEW_PRIVS to block execve() gainable privileges."
);
if
(
ret
<
0
)
{
SYSERROR
(
"Could not set PR_SET_NO_NEW_PRIVS to block "
"execve() gainable privileges"
);
goto
out_warn_father
;
goto
out_warn_father
;
}
}
DEBUG
(
"Set PR_SET_NO_NEW_PRIVS to block execve() gainable privileges."
);
DEBUG
(
"Set PR_SET_NO_NEW_PRIVS to block execve() gainable "
"privileges"
);
}
}
/* Some init's such as busybox will set sane tty settings on stdin,
/* Some init's such as busybox will set sane tty settings on stdin,
...
@@ -1220,8 +1236,7 @@ static int do_start(void *data)
...
@@ -1220,8 +1236,7 @@ static int do_start(void *data)
ret
=
lxc_console_set_stdfds
(
handler
->
conf
->
console
.
slave
);
ret
=
lxc_console_set_stdfds
(
handler
->
conf
->
console
.
slave
);
if
(
ret
<
0
)
{
if
(
ret
<
0
)
{
ERROR
(
"Failed to redirect std{in,out,err} to pty file "
ERROR
(
"Failed to redirect std{in,out,err} to pty file "
"descriptor %d"
,
"descriptor %d"
,
handler
->
conf
->
console
.
slave
);
handler
->
conf
->
console
.
slave
);
goto
out_warn_father
;
goto
out_warn_father
;
}
}
}
}
...
@@ -1229,11 +1244,14 @@ static int do_start(void *data)
...
@@ -1229,11 +1244,14 @@ static int do_start(void *data)
/* If we mounted a temporary proc, then unmount it now. */
/* If we mounted a temporary proc, then unmount it now. */
tmp_proc_unmount
(
handler
->
conf
);
tmp_proc_unmount
(
handler
->
conf
);
if
(
lxc_seccomp_load
(
handler
->
conf
)
!=
0
)
ret
=
lxc_seccomp_load
(
handler
->
conf
);
if
(
ret
<
0
)
goto
out_warn_father
;
goto
out_warn_father
;
if
(
run_lxc_hooks
(
handler
->
name
,
"start"
,
handler
->
conf
,
NULL
))
{
ret
=
run_lxc_hooks
(
handler
->
name
,
"start"
,
handler
->
conf
,
NULL
);
ERROR
(
"Failed to run lxc.hook.start for container
\"
%s
\"
."
,
handler
->
name
);
if
(
ret
<
0
)
{
ERROR
(
"Failed to run lxc.hook.start for container
\"
%s
\"
"
,
handler
->
name
);
goto
out_warn_father
;
goto
out_warn_father
;
}
}
...
@@ -1246,12 +1264,13 @@ static int do_start(void *data)
...
@@ -1246,12 +1264,13 @@ static int do_start(void *data)
goto
out_warn_father
;
goto
out_warn_father
;
}
}
if
(
handler
->
conf
->
console
.
slave
<
0
&&
handler
->
backgrounded
)
if
(
handler
->
conf
->
console
.
slave
<
0
&&
handler
->
backgrounded
)
{
if
(
set_stdfds
(
devnull_fd
)
<
0
)
{
ret
=
set_stdfds
(
devnull_fd
);
ERROR
(
"Failed to redirect std{in,out,err} to "
if
(
ret
<
0
)
{
"
\"
/dev/null
\"
"
);
ERROR
(
"Failed to redirect std{in,out,err} to
\"
/dev/null
\"
"
);
goto
out_warn_father
;
goto
out_warn_father
;
}
}
}
if
(
devnull_fd
>=
0
)
{
if
(
devnull_fd
>=
0
)
{
close
(
devnull_fd
);
close
(
devnull_fd
);
...
@@ -1260,37 +1279,46 @@ static int do_start(void *data)
...
@@ -1260,37 +1279,46 @@ static int do_start(void *data)
setsid
();
setsid
();
if
(
handler
->
conf
->
init_cwd
&&
chdir
(
handler
->
conf
->
init_cwd
))
{
if
(
handler
->
conf
->
init_cwd
)
{
SYSERROR
(
"Could not change directory to
\"
%s
\"
"
,
handler
->
conf
->
init_cwd
);
ret
=
chdir
(
handler
->
conf
->
init_cwd
);
goto
out_warn_father
;
if
(
ret
<
0
)
{
SYSERROR
(
"Could not change directory to
\"
%s
\"
"
,
handler
->
conf
->
init_cwd
);
goto
out_warn_father
;
}
}
}
if
(
lxc_sync_barrier_parent
(
handler
,
LXC_SYNC_CGROUP_LIMITS
))
ret
=
lxc_sync_barrier_parent
(
handler
,
LXC_SYNC_CGROUP_LIMITS
);
if
(
ret
<
0
)
goto
out_warn_father
;
goto
out_warn_father
;
/* Reset the environment variables the user requested in a clear
/* Reset the environment variables the user requested in a clear
* environment.
* environment.
*/
*/
if
(
clearenv
())
{
ret
=
clearenv
();
/* Don't error out though. */
if
(
ret
<
0
)
SYSERROR
(
"Failed to clear environment."
);
SYSERROR
(
"Failed to clear environment."
);
/* Don't error out though. */
}
lxc_list_for_each
(
iterator
,
&
handler
->
conf
->
environment
)
{
lxc_list_for_each
(
iterator
,
&
handler
->
conf
->
environment
)
{
if
(
putenv
((
char
*
)
iterator
->
elem
))
{
ret
=
putenv
((
char
*
)
iterator
->
elem
);
SYSERROR
(
"Failed to set environment variable: %s."
,
(
char
*
)
iterator
->
elem
);
if
(
ret
<
0
)
{
SYSERROR
(
"Failed to set environment variable: %s"
,
(
char
*
)
iterator
->
elem
);
goto
out_warn_father
;
goto
out_warn_father
;
}
}
}
}
if
(
putenv
(
"container=lxc"
))
{
ret
=
putenv
(
"container=lxc"
);
SYSERROR
(
"Failed to set environment variable: container=lxc."
);
if
(
ret
<
0
)
{
SYSERROR
(
"Failed to set environment variable: container=lxc"
);
goto
out_warn_father
;
goto
out_warn_father
;
}
}
if
(
handler
->
conf
->
pty_names
)
{
if
(
handler
->
conf
->
pty_names
)
{
if
(
putenv
(
handler
->
conf
->
pty_names
))
{
ret
=
putenv
(
handler
->
conf
->
pty_names
);
SYSERROR
(
"Failed to set environment variable for container ptys."
);
if
(
ret
<
0
)
{
SYSERROR
(
"Failed to set environment variable for container ptys"
);
goto
out_warn_father
;
goto
out_warn_father
;
}
}
}
}
...
@@ -1301,10 +1329,9 @@ static int do_start(void *data)
...
@@ -1301,10 +1329,9 @@ static int do_start(void *data)
new_uid
=
handler
->
conf
->
init_uid
;
new_uid
=
handler
->
conf
->
init_uid
;
new_gid
=
handler
->
conf
->
init_gid
;
new_gid
=
handler
->
conf
->
init_gid
;
/* If we are in a new user namespace we already dropped all
/* If we are in a new user namespace we already dropped all groups when
* groups when we switched to root in the new user namespace
* we switched to root in the new user namespace further above. Only
* further above. Only drop groups if we can, so ensure that we
* drop groups if we can, so ensure that we have necessary privilege.
* have necessary privilege.
*/
*/
#if HAVE_LIBCAP
#if HAVE_LIBCAP
have_cap_setgid
=
lxc_proc_cap_is_set
(
CAP_SETGID
,
CAP_EFFECTIVE
);
have_cap_setgid
=
lxc_proc_cap_is_set
(
CAP_SETGID
,
CAP_EFFECTIVE
);
...
@@ -1312,11 +1339,13 @@ static int do_start(void *data)
...
@@ -1312,11 +1339,13 @@ static int do_start(void *data)
have_cap_setgid
=
false
;
have_cap_setgid
=
false
;
#endif
#endif
if
(
lxc_list_empty
(
&
handler
->
conf
->
id_map
)
&&
have_cap_setgid
)
{
if
(
lxc_list_empty
(
&
handler
->
conf
->
id_map
)
&&
have_cap_setgid
)
{
if
(
lxc_setgroups
(
0
,
NULL
)
<
0
)
ret
=
lxc_setgroups
(
0
,
NULL
);
if
(
ret
<
0
)
goto
out_warn_father
;
goto
out_warn_father
;
}
}
if
(
lxc_switch_uid_gid
(
new_uid
,
new_gid
)
<
0
)
ret
=
lxc_switch_uid_gid
(
new_uid
,
new_gid
);
if
(
ret
<
0
)
goto
out_warn_father
;
goto
out_warn_father
;
/* After this call, we are in error because this ops should not return
/* After this call, we are in error because this ops should not return
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment