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
e3cca068
Commit
e3cca068
authored
Jan 07, 2017
by
Serge Hallyn
Committed by
GitHub
Jan 07, 2017
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #1373 from brauner/2016-01-02/fix_execute_and_improve_setgroups
start: fix execute and improve setgroups() calls
parents
4484e6f8
87bf0db0
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
105 additions
and
27 deletions
+105
-27
caps.c
src/lxc/caps.c
+29
-5
caps.h
src/lxc/caps.h
+12
-0
start.c
src/lxc/start.c
+30
-22
utils.c
src/lxc/utils.c
+30
-0
utils.h
src/lxc/utils.h
+4
-0
No files found.
src/lxc/caps.c
View file @
e3cca068
...
@@ -22,20 +22,21 @@
...
@@ -22,20 +22,21 @@
*/
*/
#define _GNU_SOURCE
#define _GNU_SOURCE
#include <unistd.h>
#include "config.h"
#include <errno.h>
#include <limits.h>
#include <fcntl.h>
#include <fcntl.h>
#include <stdlib.h>
#include <stdlib.h>
#include <
limits
.h>
#include <
unistd
.h>
#include <sys/prctl.h>
#include <sys/prctl.h>
#include <errno.h>
#include "c
onfig
.h"
#include "c
aps
.h"
#include "log.h"
#include "log.h"
lxc_log_define
(
lxc_caps
,
lxc
);
lxc_log_define
(
lxc_caps
,
lxc
);
#if HAVE_SYS_CAPABILITY_H
#if HAVE_SYS_CAPABILITY_H
#include <sys/capability.h>
#ifndef PR_CAPBSET_READ
#ifndef PR_CAPBSET_READ
#define PR_CAPBSET_READ 23
#define PR_CAPBSET_READ 23
...
@@ -208,4 +209,27 @@ int lxc_caps_last_cap(void)
...
@@ -208,4 +209,27 @@ int lxc_caps_last_cap(void)
return
last_cap
;
return
last_cap
;
}
}
bool
lxc_cap_is_set
(
cap_value_t
cap
,
cap_flag_t
flag
)
{
int
ret
;
cap_t
caps
;
cap_flag_value_t
flagval
;
caps
=
cap_get_proc
();
if
(
!
caps
)
{
ERROR
(
"Failed to perform cap_get_proc(): %s."
,
strerror
(
errno
));
return
false
;
}
ret
=
cap_get_flag
(
caps
,
cap
,
flag
,
&
flagval
);
if
(
ret
<
0
)
{
ERROR
(
"Failed to perform cap_get_flag(): %s."
,
strerror
(
errno
));
cap_free
(
caps
);
return
false
;
}
cap_free
(
caps
);
return
flagval
==
CAP_SET
;
}
#endif
#endif
src/lxc/caps.h
View file @
e3cca068
...
@@ -20,17 +20,23 @@
...
@@ -20,17 +20,23 @@
* License along with this library; if not, write to the Free Software
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
*/
#include "config.h"
#include "config.h"
#include <stdbool.h>
#ifndef __LXC_CAPS_H
#ifndef __LXC_CAPS_H
#define __LXC_CAPS_H
#define __LXC_CAPS_H
#if HAVE_SYS_CAPABILITY_H
#if HAVE_SYS_CAPABILITY_H
#include <sys/capability.h>
extern
int
lxc_caps_down
(
void
);
extern
int
lxc_caps_down
(
void
);
extern
int
lxc_caps_up
(
void
);
extern
int
lxc_caps_up
(
void
);
extern
int
lxc_caps_init
(
void
);
extern
int
lxc_caps_init
(
void
);
extern
int
lxc_caps_last_cap
(
void
);
extern
int
lxc_caps_last_cap
(
void
);
extern
bool
lxc_cap_is_set
(
cap_value_t
cap
,
cap_flag_t
flag
);
#else
#else
static
inline
int
lxc_caps_down
(
void
)
{
static
inline
int
lxc_caps_down
(
void
)
{
return
0
;
return
0
;
...
@@ -45,6 +51,12 @@ static inline int lxc_caps_init(void) {
...
@@ -45,6 +51,12 @@ static inline int lxc_caps_init(void) {
static
inline
int
lxc_caps_last_cap
(
void
)
{
static
inline
int
lxc_caps_last_cap
(
void
)
{
return
0
;
return
0
;
}
}
typedef
int
cap_value_t
;
typedef
int
cap_flag_t
;
static
inline
bool
lxc_cap_is_set
(
cap_value_t
cap
,
cap_flag_t
flag
)
{
return
true
;
}
#endif
#endif
#define lxc_priv(__lxc_function) \
#define lxc_priv(__lxc_function) \
...
...
src/lxc/start.c
View file @
e3cca068
...
@@ -769,32 +769,17 @@ static int do_start(void *data)
...
@@ -769,32 +769,17 @@ static int do_start(void *data)
goto
out_warn_father
;
goto
out_warn_father
;
/* If we are in a new user namespace, become root there to have
/* If we are in a new user namespace, become root there to have
* privilege over our namespace. When using lxc-execute we default to
* privilege over our namespace.
* root, but this can be overriden using the lxc.init_uid and
* lxc.init_gid configuration options.
*/
*/
if
(
!
lxc_list_empty
(
&
handler
->
conf
->
id_map
))
{
if
(
!
lxc_list_empty
(
&
handler
->
conf
->
id_map
))
{
gid_t
new_gid
=
0
;
if
(
lxc_switch_uid_gid
(
0
,
0
)
<
0
)
if
(
handler
->
conf
->
is_execute
&&
handler
->
conf
->
init_gid
)
new_gid
=
handler
->
conf
->
init_gid
;
uid_t
new_uid
=
0
;
if
(
handler
->
conf
->
is_execute
&&
handler
->
conf
->
init_uid
)
new_uid
=
handler
->
conf
->
init_uid
;
NOTICE
(
"Switching to uid=%d and gid=%d in new user namespace."
,
new_uid
,
new_gid
);
if
(
setgid
(
new_gid
))
{
SYSERROR
(
"Failed to setgid()."
);
goto
out_warn_father
;
}
if
(
setuid
(
new_uid
))
{
SYSERROR
(
"Failed to setuid()."
);
goto
out_warn_father
;
goto
out_warn_father
;
}
if
(
setgroups
(
0
,
NULL
))
{
/* Drop groups only after we switched to a valid gid in the new
SYSERROR
(
"Failed to setgroups()."
);
* user namespace.
*/
if
(
lxc_setgroups
(
0
,
NULL
)
<
0
)
goto
out_warn_father
;
goto
out_warn_father
;
}
}
}
if
(
access
(
handler
->
lxcpath
,
X_OK
))
{
if
(
access
(
handler
->
lxcpath
,
X_OK
))
{
...
@@ -900,6 +885,29 @@ static int do_start(void *data)
...
@@ -900,6 +885,29 @@ static int do_start(void *data)
goto
out_warn_father
;
goto
out_warn_father
;
}
}
/* The container has been setup. We can now switch to an unprivileged
* uid/gid.
*/
if
(
handler
->
conf
->
is_execute
)
{
bool
have_cap_setgid
;
uid_t
new_uid
=
handler
->
conf
->
init_uid
;
gid_t
new_gid
=
handler
->
conf
->
init_gid
;
/* If we are in a new user namespace we already dropped all
* groups when we switched to root in the new user namespace
* further above. Only drop groups if we can, so ensure that we
* have necessary privilege.
*/
have_cap_setgid
=
lxc_cap_is_set
(
CAP_SETGID
,
CAP_EFFECTIVE
);
if
(
lxc_list_empty
(
&
handler
->
conf
->
id_map
)
&&
have_cap_setgid
)
{
if
(
lxc_setgroups
(
0
,
NULL
)
<
0
)
goto
out_warn_father
;
}
if
(
lxc_switch_uid_gid
(
new_uid
,
new_gid
)
<
0
)
goto
out_warn_father
;
}
/* The clearenv() and putenv() calls have been moved here to allow us to
/* The clearenv() and putenv() calls have been moved here to allow us to
* use environment variables passed to the various hooks, such as the
* use environment variables passed to the various hooks, such as the
* start hook above. Not all of the variables like CONFIG_PATH or ROOTFS
* start hook above. Not all of the variables like CONFIG_PATH or ROOTFS
...
...
src/lxc/utils.c
View file @
e3cca068
...
@@ -26,6 +26,7 @@
...
@@ -26,6 +26,7 @@
#include <dirent.h>
#include <dirent.h>
#include <errno.h>
#include <errno.h>
#include <fcntl.h>
#include <fcntl.h>
#include <grp.h>
#include <libgen.h>
#include <libgen.h>
#include <stddef.h>
#include <stddef.h>
#include <stdio.h>
#include <stdio.h>
...
@@ -2053,3 +2054,32 @@ int lxc_safe_long(const char *numstr, long int *converted)
...
@@ -2053,3 +2054,32 @@ int lxc_safe_long(const char *numstr, long int *converted)
*
converted
=
sli
;
*
converted
=
sli
;
return
0
;
return
0
;
}
}
int
lxc_switch_uid_gid
(
uid_t
uid
,
gid_t
gid
)
{
if
(
setgid
(
gid
)
<
0
)
{
SYSERROR
(
"Failed to switch to gid %d."
,
gid
);
return
-
errno
;
}
NOTICE
(
"Switched to gid %d."
,
gid
);
if
(
setuid
(
uid
)
<
0
)
{
SYSERROR
(
"Failed to switch to uid %d."
,
uid
);
return
-
errno
;
}
NOTICE
(
"Switched to uid %d."
,
uid
);
return
0
;
}
/* Simple covenience function which enables uniform logging. */
int
lxc_setgroups
(
int
size
,
gid_t
list
[])
{
if
(
setgroups
(
size
,
list
)
<
0
)
{
SYSERROR
(
"Failed to setgroups()."
);
return
-
errno
;
}
NOTICE
(
"Dropped additional groups."
);
return
0
;
}
src/lxc/utils.h
View file @
e3cca068
...
@@ -327,4 +327,8 @@ int lxc_safe_uint(const char *numstr, unsigned int *converted);
...
@@ -327,4 +327,8 @@ int lxc_safe_uint(const char *numstr, unsigned int *converted);
int
lxc_safe_int
(
const
char
*
numstr
,
int
*
converted
);
int
lxc_safe_int
(
const
char
*
numstr
,
int
*
converted
);
int
lxc_safe_long
(
const
char
*
numstr
,
long
int
*
converted
);
int
lxc_safe_long
(
const
char
*
numstr
,
long
int
*
converted
);
/* Switch to a new uid and gid. */
int
lxc_switch_uid_gid
(
uid_t
uid
,
gid_t
gid
);
int
lxc_setgroups
(
int
size
,
gid_t
list
[]);
#endif
/* __LXC_UTILS_H */
#endif
/* __LXC_UTILS_H */
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