Files
kernel/include/linux/user_namespace.h
T

220 lines
6.0 KiB
C
Raw Normal View History

/* SPDX-License-Identifier: GPL-2.0 */
2007-07-15 23:40:59 -07:00
#ifndef _LINUX_USER_NAMESPACE_H
#define _LINUX_USER_NAMESPACE_H
#include <linux/kref.h>
#include <linux/nsproxy.h>
#include <linux/ns_common.h>
2007-07-15 23:40:59 -07:00
#include <linux/sched.h>
#include <linux/workqueue.h>
#include <linux/rwsem.h>
#include <linux/sysctl.h>
2007-07-15 23:41:01 -07:00
#include <linux/err.h>
2007-07-15 23:40:59 -07:00
2017-10-25 00:04:41 +02:00
#define UID_GID_MAP_MAX_BASE_EXTENTS 5
#define UID_GID_MAP_MAX_EXTENTS 340
2017-10-25 00:04:40 +02:00
struct uid_gid_extent {
u32 first;
u32 lower_first;
u32 count;
};
2017-10-25 00:04:41 +02:00
struct uid_gid_map { /* 64 bytes -- 1 cache line */
u32 nr_extents;
2017-10-25 00:04:40 +02:00
union {
2017-10-25 00:04:41 +02:00
struct uid_gid_extent extent[UID_GID_MAP_MAX_BASE_EXTENTS];
2017-10-25 00:04:40 +02:00
struct {
struct uid_gid_extent *forward;
struct uid_gid_extent *reverse;
};
};
};
#define USERNS_SETGROUPS_ALLOWED 1UL
#define USERNS_INIT_FLAGS USERNS_SETGROUPS_ALLOWED
struct ucounts;
enum ucount_type {
UCOUNT_USER_NAMESPACES,
UCOUNT_PID_NAMESPACES,
UCOUNT_UTS_NAMESPACES,
UCOUNT_IPC_NAMESPACES,
UCOUNT_NET_NAMESPACES,
UCOUNT_MNT_NAMESPACES,
UCOUNT_CGROUP_NAMESPACES,
2019-11-12 01:26:52 +00:00
UCOUNT_TIME_NAMESPACES,
#ifdef CONFIG_INOTIFY_USER
UCOUNT_INOTIFY_INSTANCES,
UCOUNT_INOTIFY_WATCHES,
2021-03-04 13:29:20 +02:00
#endif
#ifdef CONFIG_FANOTIFY
UCOUNT_FANOTIFY_GROUPS,
UCOUNT_FANOTIFY_MARKS,
#endif
2021-04-22 14:27:11 +02:00
UCOUNT_RLIMIT_NPROC,
UCOUNT_RLIMIT_MSGQUEUE,
UCOUNT_RLIMIT_SIGPENDING,
UCOUNT_RLIMIT_MEMLOCK,
UCOUNT_COUNTS,
};
2021-04-22 14:27:11 +02:00
#define MAX_PER_NAMESPACE_UCOUNTS UCOUNT_RLIMIT_NPROC
2007-07-15 23:40:59 -07:00
struct user_namespace {
struct uid_gid_map uid_map;
struct uid_gid_map gid_map;
struct uid_gid_map projid_map;
struct user_namespace *parent;
int level;
kuid_t owner;
kgid_t group;
struct ns_common ns;
unsigned long flags;
/* parent_could_setfcap: true if the creator if this ns had CAP_SETFCAP
* in its effective capability set at the child ns creation time. */
bool parent_could_setfcap;
2019-06-26 21:02:32 +01:00
#ifdef CONFIG_KEYS
/* List of joinable keyrings in this namespace. Modification access of
* these pointers is controlled by keyring_sem. Once
* user_keyring_register is set, it won't be changed, so it can be
* accessed directly with READ_ONCE().
*/
2019-06-26 21:02:32 +01:00
struct list_head keyring_name_list;
struct key *user_keyring_register;
struct rw_semaphore keyring_sem;
2019-06-26 21:02:32 +01:00
#endif
/* Register of per-UID persistent keyrings for this namespace */
#ifdef CONFIG_PERSISTENT_KEYRINGS
struct key *persistent_keyring_register;
#endif
struct work_struct work;
2016-07-30 13:58:49 -05:00
#ifdef CONFIG_SYSCTL
struct ctl_table_set set;
struct ctl_table_header *sysctls;
#endif
struct ucounts *ucounts;
2021-04-22 14:27:08 +02:00
long ucount_max[UCOUNT_COUNTS];
} __randomize_layout;
struct ucounts {
struct hlist_node node;
struct user_namespace *ns;
kuid_t uid;
2021-04-22 14:27:10 +02:00
atomic_t count;
2021-04-22 14:27:08 +02:00
atomic_long_t ucount[UCOUNT_COUNTS];
2007-07-15 23:40:59 -07:00
};
extern struct user_namespace init_user_ns;
2021-04-22 14:27:09 +02:00
extern struct ucounts init_ucounts;
bool setup_userns_sysctls(struct user_namespace *ns);
void retire_userns_sysctls(struct user_namespace *ns);
struct ucounts *inc_ucount(struct user_namespace *ns, kuid_t uid, enum ucount_type type);
void dec_ucount(struct ucounts *ucounts, enum ucount_type type);
2021-04-22 14:27:09 +02:00
struct ucounts *alloc_ucounts(struct user_namespace *ns, kuid_t uid);
2021-04-22 14:27:10 +02:00
struct ucounts * __must_check get_ucounts(struct ucounts *ucounts);
2021-04-22 14:27:09 +02:00
void put_ucounts(struct ucounts *ucounts);
2007-07-15 23:40:59 -07:00
2021-04-22 14:27:11 +02:00
static inline long get_ucounts_value(struct ucounts *ucounts, enum ucount_type type)
{
return atomic_long_read(&ucounts->ucount[type]);
}
long inc_rlimit_ucounts(struct ucounts *ucounts, enum ucount_type type, long v);
bool dec_rlimit_ucounts(struct ucounts *ucounts, enum ucount_type type, long v);
2021-10-16 15:59:49 -05:00
long inc_rlimit_get_ucounts(struct ucounts *ucounts, enum ucount_type type);
void dec_rlimit_put_ucounts(struct ucounts *ucounts, enum ucount_type type);
2021-04-22 14:27:11 +02:00
bool is_ucounts_overlimit(struct ucounts *ucounts, enum ucount_type type, unsigned long max);
static inline void set_rlimit_ucount_max(struct user_namespace *ns,
enum ucount_type type, unsigned long max)
{
ns->ucount_max[type] = max <= LONG_MAX ? max : LONG_MAX;
}
2007-07-15 23:40:59 -07:00
#ifdef CONFIG_USER_NS
static inline struct user_namespace *get_user_ns(struct user_namespace *ns)
{
if (ns)
2020-08-03 13:16:37 +03:00
refcount_inc(&ns->ns.count);
2007-07-15 23:40:59 -07:00
return ns;
}
2008-10-15 16:38:45 -05:00
extern int create_user_ns(struct cred *new);
extern int unshare_userns(unsigned long unshare_flags, struct cred **new_cred);
extern void __put_user_ns(struct user_namespace *ns);
2007-07-15 23:40:59 -07:00
static inline void put_user_ns(struct user_namespace *ns)
{
2020-08-03 13:16:37 +03:00
if (ns && refcount_dec_and_test(&ns->ns.count))
__put_user_ns(ns);
2007-07-15 23:40:59 -07:00
}
struct seq_operations;
2014-08-08 14:21:22 -07:00
extern const struct seq_operations proc_uid_seq_operations;
extern const struct seq_operations proc_gid_seq_operations;
extern const struct seq_operations proc_projid_seq_operations;
extern ssize_t proc_uid_map_write(struct file *, const char __user *, size_t, loff_t *);
extern ssize_t proc_gid_map_write(struct file *, const char __user *, size_t, loff_t *);
extern ssize_t proc_projid_map_write(struct file *, const char __user *, size_t, loff_t *);
extern ssize_t proc_setgroups_write(struct file *, const char __user *, size_t, loff_t *);
extern int proc_setgroups_show(struct seq_file *m, void *v);
extern bool userns_may_setgroups(const struct user_namespace *ns);
extern bool in_userns(const struct user_namespace *ancestor,
const struct user_namespace *child);
extern bool current_in_userns(const struct user_namespace *target_ns);
struct ns_common *ns_get_owner(struct ns_common *ns);
2007-07-15 23:40:59 -07:00
#else
static inline struct user_namespace *get_user_ns(struct user_namespace *ns)
{
return &init_user_ns;
}
2008-10-15 16:38:45 -05:00
static inline int create_user_ns(struct cred *new)
2007-07-15 23:40:59 -07:00
{
2008-10-15 16:38:45 -05:00
return -EINVAL;
2007-07-15 23:40:59 -07:00
}
static inline int unshare_userns(unsigned long unshare_flags,
struct cred **new_cred)
{
if (unshare_flags & CLONE_NEWUSER)
return -EINVAL;
return 0;
}
2007-07-15 23:40:59 -07:00
static inline void put_user_ns(struct user_namespace *ns)
{
}
static inline bool userns_may_setgroups(const struct user_namespace *ns)
{
return true;
}
static inline bool in_userns(const struct user_namespace *ancestor,
const struct user_namespace *child)
{
return true;
}
static inline bool current_in_userns(const struct user_namespace *target_ns)
{
return true;
}
static inline struct ns_common *ns_get_owner(struct ns_common *ns)
{
return ERR_PTR(-EPERM);
}
#endif
2007-07-15 23:40:59 -07:00
#endif /* _LINUX_USER_H */