mirror of
git://github.com/lxc/lxc
synced 2025-08-31 16:57:57 +00:00
conf: fix lxc.cap.keep behavior
Fixes: ##3993
Fixes: 20ab75789e
("conf: simplify and port caps to new list type")
Signed-off-by: Christian Brauner <christian.brauner@ubuntu.com>
This commit is contained in:
@@ -178,26 +178,6 @@ int prepare_cgroup_fd(const struct cgroup_ops *ops, struct cgroup_fd *fd, bool l
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Taken over modified from the kernel sources. */
|
||||
#define NBITS 32 /* bits in uint32_t */
|
||||
#define DIV_ROUND_UP(n, d) (((n) + (d)-1) / (d))
|
||||
#define BITS_TO_LONGS(nr) DIV_ROUND_UP(nr, NBITS)
|
||||
|
||||
static void set_bit(unsigned bit, uint32_t *bitarr)
|
||||
{
|
||||
bitarr[bit / NBITS] |= (1 << (bit % NBITS));
|
||||
}
|
||||
|
||||
static void clear_bit(unsigned bit, uint32_t *bitarr)
|
||||
{
|
||||
bitarr[bit / NBITS] &= ~(1 << (bit % NBITS));
|
||||
}
|
||||
|
||||
static bool is_set(unsigned bit, uint32_t *bitarr)
|
||||
{
|
||||
return (bitarr[bit / NBITS] & (1 << (bit % NBITS))) != 0;
|
||||
}
|
||||
|
||||
/* Create cpumask from cpulist aka turn:
|
||||
*
|
||||
* 0,2-3
|
||||
|
@@ -3154,7 +3154,7 @@ bool has_cap(int cap, struct lxc_conf *conf)
|
||||
return !cap_in_list;
|
||||
}
|
||||
|
||||
static int setup_caps(struct lxc_conf *conf)
|
||||
static int capabilities_deny(struct lxc_conf *conf)
|
||||
{
|
||||
struct cap_entry *cap;
|
||||
|
||||
@@ -3164,7 +3164,7 @@ static int setup_caps(struct lxc_conf *conf)
|
||||
ret = prctl(PR_CAPBSET_DROP, prctl_arg(cap->cap), prctl_arg(0),
|
||||
prctl_arg(0), prctl_arg(0));
|
||||
if (ret < 0)
|
||||
return log_error_errno(-1, errno, "Failed to remove %s capability", cap->cap_name);
|
||||
return syserror("Failed to remove %s capability", cap->cap_name);
|
||||
|
||||
DEBUG("Dropped %s (%d) capability", cap->cap_name, cap->cap);
|
||||
}
|
||||
@@ -3173,10 +3173,12 @@ static int setup_caps(struct lxc_conf *conf)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int dropcaps_except(struct lxc_conf *conf)
|
||||
static int capabilities_allow(struct lxc_conf *conf)
|
||||
{
|
||||
__do_free __u32 *keep_bits = NULL;
|
||||
int numcaps;
|
||||
struct cap_entry *cap;
|
||||
size_t nr_u32;
|
||||
|
||||
numcaps = lxc_caps_last_cap() + 1;
|
||||
if (numcaps <= 0 || numcaps > 200)
|
||||
@@ -3184,20 +3186,31 @@ static int dropcaps_except(struct lxc_conf *conf)
|
||||
|
||||
TRACE("Found %d capabilities", numcaps);
|
||||
|
||||
list_for_each_entry(cap, &conf->caps.list, head) {
|
||||
int ret;
|
||||
nr_u32 = BITS_TO_LONGS(numcaps);
|
||||
keep_bits = zalloc(nr_u32 * sizeof(__u32));
|
||||
if (!keep_bits)
|
||||
return ret_errno(ENOMEM);
|
||||
|
||||
list_for_each_entry(cap, &conf->caps.list, head) {
|
||||
if (cap->cap >= numcaps)
|
||||
continue;
|
||||
|
||||
ret = prctl(PR_CAPBSET_DROP, prctl_arg(cap->cap), prctl_arg(0),
|
||||
set_bit(cap->cap, keep_bits);
|
||||
DEBUG("Keeping %s (%d) capability", cap->cap_name, cap->cap);
|
||||
}
|
||||
|
||||
for (int cap_bit = 0; cap_bit < numcaps; cap_bit++) {
|
||||
int ret;
|
||||
|
||||
if (is_set(cap_bit, keep_bits))
|
||||
continue;
|
||||
|
||||
ret = prctl(PR_CAPBSET_DROP, prctl_arg(cap_bit), prctl_arg(0),
|
||||
prctl_arg(0), prctl_arg(0));
|
||||
if (ret < 0)
|
||||
return log_error_errno(-1, errno,
|
||||
"Failed to remove capability %s (%d)",
|
||||
cap->cap_name, cap->cap);
|
||||
return syserror("Failed to remove capability %d", cap_bit);
|
||||
|
||||
DEBUG("Keep capability %s (%d)", cap->cap_name, cap->cap);
|
||||
TRACE("Dropped capability %d", cap_bit);
|
||||
}
|
||||
|
||||
DEBUG("Capabilities have been setup");
|
||||
@@ -4259,11 +4272,11 @@ static int setcup_capabilities(struct lxc_conf *conf)
|
||||
int ret;
|
||||
|
||||
if (conf->caps.keep)
|
||||
ret = dropcaps_except(conf);
|
||||
ret = capabilities_allow(conf);
|
||||
else
|
||||
ret = setup_caps(conf);
|
||||
ret = capabilities_deny(conf);
|
||||
if (ret < 0)
|
||||
return log_error(-1, "Failed to %s capabilities", conf->caps.keep ? "keep" : "drop");
|
||||
return syserror_ret(ret, "Failed to %s capabilities", conf->caps.keep ? "allow" : "deny");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@@ -765,4 +765,24 @@ static inline bool has_exact_flags(__u32 flags, __u32 mask)
|
||||
|
||||
typedef long long unsigned int llu;
|
||||
|
||||
/* Taken over modified from the kernel sources. */
|
||||
#define NBITS 32 /* bits in uint32_t */
|
||||
#define DIV_ROUND_UP(n, d) (((n) + (d)-1) / (d))
|
||||
#define BITS_TO_LONGS(nr) DIV_ROUND_UP(nr, NBITS)
|
||||
|
||||
static inline void set_bit(unsigned bit, uint32_t *bitarr)
|
||||
{
|
||||
bitarr[bit / NBITS] |= (1 << (bit % NBITS));
|
||||
}
|
||||
|
||||
static inline void clear_bit(unsigned bit, uint32_t *bitarr)
|
||||
{
|
||||
bitarr[bit / NBITS] &= ~(1 << (bit % NBITS));
|
||||
}
|
||||
|
||||
static inline bool is_set(unsigned bit, uint32_t *bitarr)
|
||||
{
|
||||
return (bitarr[bit / NBITS] & (1 << (bit % NBITS))) != 0;
|
||||
}
|
||||
|
||||
#endif /* __LXC_MACRO_H */
|
||||
|
@@ -53,11 +53,6 @@
|
||||
#define pam_cgfs_debug(format, ...)
|
||||
#endif /* DEBUG */
|
||||
|
||||
/* Taken over modified from the kernel sources. */
|
||||
#define NBITS 32 /* bits in uint32_t */
|
||||
#define DIV_ROUND_UP(n, d) (((n) + (d)-1) / (d))
|
||||
#define BITS_TO_LONGS(nr) DIV_ROUND_UP(nr, NBITS)
|
||||
|
||||
static enum cg_mount_mode {
|
||||
CGROUP_UNKNOWN = -1,
|
||||
CGROUP_MIXED = 0,
|
||||
@@ -70,18 +65,10 @@ static enum cg_mount_mode {
|
||||
static void append_line(char **dest, size_t oldlen, char *new, size_t newlen);
|
||||
static int append_null_to_list(void ***list);
|
||||
static void batch_realloc(char **mem, size_t oldlen, size_t newlen);
|
||||
static inline void clear_bit(unsigned bit, uint32_t *bitarr)
|
||||
{
|
||||
bitarr[bit / NBITS] &= ~(1 << (bit % NBITS));
|
||||
}
|
||||
static char *copy_to_eol(char *s);
|
||||
static char *get_mountpoint(char *line);
|
||||
static bool get_uid_gid(const char *user, uid_t *uid, gid_t *gid);
|
||||
static int handle_login(const char *user, uid_t uid, gid_t gid);
|
||||
static inline bool is_set(unsigned bit, uint32_t *bitarr)
|
||||
{
|
||||
return (bitarr[bit / NBITS] & (1 << (bit % NBITS))) != 0;
|
||||
}
|
||||
static bool is_lxcfs(const char *line);
|
||||
static bool is_cgv1(char *line);
|
||||
static bool is_cgv2(char *line);
|
||||
@@ -92,10 +79,6 @@ static void must_append_string(char ***list, char *entry);
|
||||
static void mysyslog(int err, const char *format, ...) __attribute__((sentinel));
|
||||
static char *read_file(char *fnam);
|
||||
static int recursive_rmdir(char *dirname);
|
||||
static inline void set_bit(unsigned bit, uint32_t *bitarr)
|
||||
{
|
||||
bitarr[bit / NBITS] |= (1 << (bit % NBITS));
|
||||
}
|
||||
static bool string_in_list(char **list, const char *entry);
|
||||
static char *string_join(const char *sep, const char **parts, bool use_as_prefix);
|
||||
static void trim(char *s);
|
||||
|
Reference in New Issue
Block a user