caps: add lxc_{proc,file}_cap_is_set()

Add two new helpers that allow to determine whether a given proc or file has a capability in the given set and move lxc_cap_is_set() to static function that both call internally. Closes #296. Signed-off-by: 's avatarChristian Brauner <christian.brauner@ubuntu.com>
parent 4bc3b759
......@@ -209,27 +209,56 @@ int lxc_caps_last_cap(void)
return last_cap;
}
bool lxc_cap_is_set(cap_value_t cap, cap_flag_t flag)
static bool lxc_cap_is_set(cap_t caps, cap_value_t cap, cap_flag_t flag)
{
int ret;
cap_t caps;
cap_flag_value_t flagval;
caps = cap_get_proc();
ret = cap_get_flag(caps, cap, flag, &flagval);
if (ret < 0) {
ERROR("Failed to perform cap_get_flag(): %s.", strerror(errno));
return false;
}
return flagval == CAP_SET;
}
bool lxc_file_cap_is_set(const char *path, cap_value_t cap, cap_flag_t flag)
{
bool cap_is_set;
cap_t caps;
caps = cap_get_file(path);
if (!caps) {
ERROR("Failed to perform cap_get_proc(): %s.", strerror(errno));
/* This is undocumented in the manpage but the source code show
* that cap_get_file() may return NULL when successful for the
* case where it didn't detect any file capabilities. In this
* case errno will be set to ENODATA.
*/
if (errno != ENODATA)
ERROR("Failed to perform cap_get_file(): %s.\n", 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);
cap_is_set = lxc_cap_is_set(caps, cap, flag);
cap_free(caps);
return cap_is_set;
}
bool lxc_proc_cap_is_set(cap_value_t cap, cap_flag_t flag)
{
bool cap_is_set;
cap_t caps;
caps = cap_get_proc();
if (!caps) {
ERROR("Failed to perform cap_get_proc(): %s.\n", strerror(errno));
return false;
}
cap_is_set = lxc_cap_is_set(caps, cap, flag);
cap_free(caps);
return flagval == CAP_SET;
return cap_is_set;
}
#endif
......@@ -36,7 +36,8 @@ extern int lxc_caps_init(void);
extern int lxc_caps_last_cap(void);
extern bool lxc_cap_is_set(cap_value_t cap, cap_flag_t flag);
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);
#else
static inline int lxc_caps_down(void) {
return 0;
......@@ -54,7 +55,11 @@ static inline int lxc_caps_last_cap(void) {
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) {
static inline bool lxc_proc_cap_is_set(cap_value_t cap, cap_flag_t flag) {
return true;
}
static inline bool lxc_file_cap_is_set(const char *path, cap_value_t cap, cap_flag_t flag) {
return true;
}
#endif
......
......@@ -899,7 +899,7 @@ static int do_start(void *data)
* have necessary privilege.
*/
#if HAVE_LIBCAP
have_cap_setgid = lxc_cap_is_set(CAP_SETGID, CAP_EFFECTIVE);
have_cap_setgid = lxc_proc_cap_is_set(CAP_SETGID, CAP_EFFECTIVE);
#else
have_cap_setgid = false;
#endif
......
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