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
return !cap_in_list;
}
-static int setup_caps(struct lxc_conf *conf)
+static int capabilities_deny(struct lxc_conf *conf)
{
struct cap_entry *cap;
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);
}
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)
TRACE("Found %d capabilities", numcaps);
+ 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;
+
+ 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 (cap->cap >= numcaps)
+ if (is_set(cap_bit, keep_bits))
continue;
- ret = prctl(PR_CAPBSET_DROP, prctl_arg(cap->cap), prctl_arg(0),
+ 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");
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;
}
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 */
#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,
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);
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);