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
23cf184d
Unverified
Commit
23cf184d
authored
May 16, 2018
by
Serge Hallyn
Committed by
GitHub
May 16, 2018
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #2332 from brauner/2018-05-16/use_ambient_capabilities
capabilities: raise ambient capabilities
parents
02d6227d
611ddd34
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
198 additions
and
35 deletions
+198
-35
caps.c
src/lxc/caps.c
+130
-0
caps.h
src/lxc/caps.h
+55
-34
start.c
src/lxc/start.c
+13
-1
No files found.
src/lxc/caps.c
View file @
23cf184d
...
...
@@ -42,6 +42,27 @@ lxc_log_define(lxc_caps, lxc);
#define PR_CAPBSET_READ 23
#endif
/* Control the ambient capability set */
#ifndef PR_CAP_AMBIENT
#define PR_CAP_AMBIENT 47
#endif
#ifndef PR_CAP_AMBIENT_IS_SET
#define PR_CAP_AMBIENT_IS_SET 1
#endif
#ifndef PR_CAP_AMBIENT_RAISE
#define PR_CAP_AMBIENT_RAISE 2
#endif
#ifndef PR_CAP_AMBIENT_LOWER
#define PR_CAP_AMBIENT_LOWER 3
#endif
#ifndef PR_CAP_AMBIENT_CLEAR_ALL
#define PR_CAP_AMBIENT_CLEAR_ALL 4
#endif
int
lxc_caps_down
(
void
)
{
cap_t
caps
;
...
...
@@ -126,6 +147,115 @@ out:
return
0
;
}
int
lxc_ambient_caps_up
(
void
)
{
int
ret
;
cap_t
caps
;
cap_value_t
cap
;
int
last_cap
=
CAP_LAST_CAP
;
char
*
cap_names
=
NULL
;
/* When we are run as root, we don't want to play with the capabilities. */
if
(
!
getuid
())
return
0
;
caps
=
cap_get_proc
();
if
(
!
caps
)
{
SYSERROR
(
"Failed to retrieve capabilities"
);
return
-
1
;
}
for
(
cap
=
0
;
cap
<=
CAP_LAST_CAP
;
cap
++
)
{
cap_flag_value_t
flag
;
ret
=
cap_get_flag
(
caps
,
cap
,
CAP_PERMITTED
,
&
flag
);
if
(
ret
<
0
)
{
if
(
errno
==
EINVAL
)
{
last_cap
=
(
cap
-
1
);
INFO
(
"Last supported cap was %d"
,
last_cap
);
break
;
}
SYSERROR
(
"Failed to retrieve capability flag"
);
goto
out
;
}
ret
=
cap_set_flag
(
caps
,
CAP_INHERITABLE
,
1
,
&
cap
,
flag
);
if
(
ret
<
0
)
{
SYSERROR
(
"Failed to set capability flag"
);
goto
out
;
}
}
ret
=
cap_set_proc
(
caps
);
if
(
ret
<
0
)
{
SYSERROR
(
"Failed to set capabilities"
);
goto
out
;
}
for
(
cap
=
0
;
cap
<=
last_cap
;
cap
++
)
{
ret
=
prctl
(
PR_CAP_AMBIENT
,
PR_CAP_AMBIENT_RAISE
,
cap
,
0
,
0
);
if
(
ret
<
0
)
{
WARN
(
"%s - Failed to raise ambient capability %d"
,
strerror
(
errno
),
cap
);
goto
out
;
}
}
cap_names
=
cap_to_text
(
caps
,
NULL
);
if
(
!
cap_names
)
goto
out
;
TRACE
(
"Raised %s in inheritable and ambient capability set"
,
cap_names
);
out:
cap_free
(
cap_names
);
cap_free
(
caps
);
return
0
;
}
int
lxc_ambient_caps_down
(
void
)
{
int
ret
;
cap_t
caps
;
cap_value_t
cap
;
/* When we are run as root, we don't want to play with the capabilities. */
if
(
!
getuid
())
return
0
;
ret
=
prctl
(
PR_CAP_AMBIENT
,
PR_CAP_AMBIENT_CLEAR_ALL
,
0
,
0
,
0
);
if
(
ret
<
0
)
{
SYSERROR
(
"Failed to clear ambient capability set"
);
return
-
1
;
}
caps
=
cap_get_proc
();
if
(
!
caps
)
{
SYSERROR
(
"Failed to retrieve capabilities"
);
return
-
1
;
}
for
(
cap
=
0
;
cap
<=
CAP_LAST_CAP
;
cap
++
)
{
ret
=
cap_set_flag
(
caps
,
CAP_INHERITABLE
,
1
,
&
cap
,
CAP_CLEAR
);
if
(
ret
<
0
)
{
SYSERROR
(
"Failed to remove capability from inheritable set"
);
goto
out
;
}
}
ret
=
cap_set_proc
(
caps
);
if
(
ret
<
0
)
{
SYSERROR
(
"Failed to set capabilities"
);
goto
out
;
}
out:
cap_free
(
caps
);
return
0
;
}
int
lxc_caps_init
(
void
)
{
uid_t
uid
=
getuid
();
...
...
src/lxc/caps.h
View file @
23cf184d
...
...
@@ -27,70 +27,91 @@
#include "config.h"
#include <stdbool.h>
#if HAVE_LIBCAP
#include <linux/types.h>
/* workaround for libcap < 2.17 bug */
#include <sys/capability.h>
extern
int
lxc_caps_down
(
void
);
extern
int
lxc_caps_up
(
void
);
extern
int
lxc_ambient_caps_up
(
void
);
extern
int
lxc_ambient_caps_down
(
void
);
extern
int
lxc_caps_init
(
void
);
extern
int
lxc_caps_last_cap
(
void
);
extern
bool
lxc_proc_cap_is_set
(
cap_value_t
cap
,
cap_flag_t
flag
);
extern
bool
lxc_file_cap_is_set
(
const
char
*
path
,
cap_value_t
cap
,
cap_flag_t
flag
);
extern
bool
lxc_file_cap_is_set
(
const
char
*
path
,
cap_value_t
cap
,
cap_flag_t
flag
);
#else
static
inline
int
lxc_caps_down
(
void
)
{
static
inline
int
lxc_caps_down
(
void
)
{
return
0
;
}
static
inline
int
lxc_caps_up
(
void
)
{
static
inline
int
lxc_caps_up
(
void
)
{
return
0
;
}
static
inline
int
lxc_caps_init
(
void
)
{
static
inline
int
lxc_ambient_caps_up
(
void
)
{
return
0
;
}
static
inline
int
lxc_ambient_caps_down
(
void
)
{
return
0
;
}
static
inline
int
lxc_caps_init
(
void
)
{
return
0
;
}
static
inline
int
lxc_caps_last_cap
(
void
)
{
static
inline
int
lxc_caps_last_cap
(
void
)
{
return
0
;
}
typedef
int
cap_value_t
;
typedef
int
cap_flag_t
;
static
inline
bool
lxc_proc_cap_is_set
(
cap_value_t
cap
,
cap_flag_t
flag
)
{
static
inline
bool
lxc_proc_cap_is_set
(
cap_value_t
cap
,
cap_flag_t
flag
)
{
return
false
;
}
static
inline
bool
lxc_file_cap_is_set
(
const
char
*
path
,
cap_value_t
cap
,
cap_flag_t
flag
)
{
static
inline
bool
lxc_file_cap_is_set
(
const
char
*
path
,
cap_value_t
cap
,
cap_flag_t
flag
)
{
return
false
;
}
#endif
#define lxc_priv(__lxc_function) \
({ \
__label__ out; \
int __ret, __ret2, ___errno = 0; \
__ret = lxc_caps_up(); \
if (__ret) \
goto out; \
__ret = __lxc_function; \
if (__ret) \
___errno = errno; \
__ret2 = lxc_caps_down(); \
out: __ret ? errno = ___errno,__ret : __ret2; \
#define lxc_priv(__lxc_function) \
({ \
__label__ out; \
int __ret, __ret2, ___errno = 0; \
__ret = lxc_caps_up(); \
if (__ret) \
goto out; \
__ret = __lxc_function; \
if (__ret) \
___errno = errno; \
__ret2 = lxc_caps_down(); \
out: \
__ret ? errno = ___errno, __ret : __ret2; \
})
#define lxc_unpriv(__lxc_function) \
({ \
__label__ out; \
int __ret, __ret2, ___errno = 0; \
__ret = lxc_caps_down(); \
if (__ret) \
goto out; \
__ret = __lxc_function; \
if (__ret) \
___errno = errno; \
__ret2 = lxc_caps_up(); \
out: __ret ? errno = ___errno,__ret : __ret2; \
#define lxc_unpriv(__lxc_function) \
({ \
__label__ out; \
int __ret, __ret2, ___errno = 0; \
__ret = lxc_caps_down(); \
if (__ret) \
goto out; \
__ret = __lxc_function; \
if (__ret) \
___errno = errno; \
__ret2 = lxc_caps_up(); \
out: \
__ret ? errno = ___errno, __ret : __ret2; \
})
#endif
src/lxc/start.c
View file @
23cf184d
...
...
@@ -1049,6 +1049,12 @@ static int do_start(void *data)
goto
out_warn_father
;
}
ret
=
lxc_ambient_caps_up
();
if
(
ret
<
0
)
{
SYSERROR
(
"Failed to raise ambient capabilities"
);
goto
out_warn_father
;
}
ret
=
sigprocmask
(
SIG_SETMASK
,
&
handler
->
oldmask
,
NULL
);
if
(
ret
<
0
)
{
SYSERROR
(
"Failed to set signal mask"
);
...
...
@@ -1081,7 +1087,7 @@ static int do_start(void *data)
*/
ret
=
lxc_sync_barrier_parent
(
handler
,
LXC_SYNC_CONFIGURE
);
if
(
ret
<
0
)
return
-
1
;
goto
out_error
;
ret
=
lxc_network_recv_veth_names_from_parent
(
handler
);
if
(
ret
<
0
)
{
...
...
@@ -1348,6 +1354,12 @@ static int do_start(void *data)
if
(
ret
<
0
)
goto
out_warn_father
;
ret
=
lxc_ambient_caps_down
();
if
(
ret
<
0
)
{
SYSERROR
(
"Failed to clear ambient capabilities"
);
goto
out_warn_father
;
}
/* After this call, we are in error because this ops should not return
* as it execs.
*/
...
...
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