mirror of
https://github.com/torvalds/linux.git
synced 2024-11-26 22:21:42 +00:00
Cache user_ns in struct cred
If !CONFIG_USERNS, have current_user_ns() defined to (&init_user_ns). Get rid of _current_user_ns. This requires nsown_capable() to be defined in capability.c rather than as static inline in capability.h, so do that. Request_key needs init_user_ns defined at current_user_ns if !CONFIG_USERNS, so forward-declare that in cred.h if !CONFIG_USERNS at current_user_ns() define. Compile-tested with and without CONFIG_USERNS. Signed-off-by: Serge E. Hallyn <serge.hallyn@canonical.com> [ This makes a huge performance difference for acl_permission_check(), up to 30%. And that is one of the hottest kernel functions for loads that are pathname-lookup heavy. ] Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
This commit is contained in:
parent
381e7863d9
commit
47a150edc2
@ -546,18 +546,7 @@ extern bool has_capability_noaudit(struct task_struct *t, int cap);
|
|||||||
extern bool capable(int cap);
|
extern bool capable(int cap);
|
||||||
extern bool ns_capable(struct user_namespace *ns, int cap);
|
extern bool ns_capable(struct user_namespace *ns, int cap);
|
||||||
extern bool task_ns_capable(struct task_struct *t, int cap);
|
extern bool task_ns_capable(struct task_struct *t, int cap);
|
||||||
|
extern bool nsown_capable(int cap);
|
||||||
/**
|
|
||||||
* nsown_capable - Check superior capability to one's own user_ns
|
|
||||||
* @cap: The capability in question
|
|
||||||
*
|
|
||||||
* Return true if the current task has the given superior capability
|
|
||||||
* targeted at its own user namespace.
|
|
||||||
*/
|
|
||||||
static inline bool nsown_capable(int cap)
|
|
||||||
{
|
|
||||||
return ns_capable(current_user_ns(), cap);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* audit system wants to get cap info from files as well */
|
/* audit system wants to get cap info from files as well */
|
||||||
extern int get_vfs_caps_from_disk(const struct dentry *dentry, struct cpu_vfs_cap_data *cpu_caps);
|
extern int get_vfs_caps_from_disk(const struct dentry *dentry, struct cpu_vfs_cap_data *cpu_caps);
|
||||||
|
@ -146,6 +146,7 @@ struct cred {
|
|||||||
void *security; /* subjective LSM security */
|
void *security; /* subjective LSM security */
|
||||||
#endif
|
#endif
|
||||||
struct user_struct *user; /* real user ID subscription */
|
struct user_struct *user; /* real user ID subscription */
|
||||||
|
struct user_namespace *user_ns; /* cached user->user_ns */
|
||||||
struct group_info *group_info; /* supplementary groups for euid/fsgid */
|
struct group_info *group_info; /* supplementary groups for euid/fsgid */
|
||||||
struct rcu_head rcu; /* RCU deletion hook */
|
struct rcu_head rcu; /* RCU deletion hook */
|
||||||
};
|
};
|
||||||
@ -354,10 +355,15 @@ static inline void put_cred(const struct cred *_cred)
|
|||||||
#define current_fsgid() (current_cred_xxx(fsgid))
|
#define current_fsgid() (current_cred_xxx(fsgid))
|
||||||
#define current_cap() (current_cred_xxx(cap_effective))
|
#define current_cap() (current_cred_xxx(cap_effective))
|
||||||
#define current_user() (current_cred_xxx(user))
|
#define current_user() (current_cred_xxx(user))
|
||||||
#define _current_user_ns() (current_cred_xxx(user)->user_ns)
|
|
||||||
#define current_security() (current_cred_xxx(security))
|
#define current_security() (current_cred_xxx(security))
|
||||||
|
|
||||||
extern struct user_namespace *current_user_ns(void);
|
#ifdef CONFIG_USER_NS
|
||||||
|
#define current_user_ns() (current_cred_xxx(user_ns))
|
||||||
|
#else
|
||||||
|
extern struct user_namespace init_user_ns;
|
||||||
|
#define current_user_ns() (&init_user_ns)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
#define current_uid_gid(_uid, _gid) \
|
#define current_uid_gid(_uid, _gid) \
|
||||||
do { \
|
do { \
|
||||||
|
@ -399,3 +399,15 @@ bool task_ns_capable(struct task_struct *t, int cap)
|
|||||||
return ns_capable(task_cred_xxx(t, user)->user_ns, cap);
|
return ns_capable(task_cred_xxx(t, user)->user_ns, cap);
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(task_ns_capable);
|
EXPORT_SYMBOL(task_ns_capable);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* nsown_capable - Check superior capability to one's own user_ns
|
||||||
|
* @cap: The capability in question
|
||||||
|
*
|
||||||
|
* Return true if the current task has the given superior capability
|
||||||
|
* targeted at its own user namespace.
|
||||||
|
*/
|
||||||
|
bool nsown_capable(int cap)
|
||||||
|
{
|
||||||
|
return ns_capable(current_user_ns(), cap);
|
||||||
|
}
|
||||||
|
@ -54,6 +54,7 @@ struct cred init_cred = {
|
|||||||
.cap_effective = CAP_INIT_EFF_SET,
|
.cap_effective = CAP_INIT_EFF_SET,
|
||||||
.cap_bset = CAP_INIT_BSET,
|
.cap_bset = CAP_INIT_BSET,
|
||||||
.user = INIT_USER,
|
.user = INIT_USER,
|
||||||
|
.user_ns = &init_user_ns,
|
||||||
.group_info = &init_groups,
|
.group_info = &init_groups,
|
||||||
#ifdef CONFIG_KEYS
|
#ifdef CONFIG_KEYS
|
||||||
.tgcred = &init_tgcred,
|
.tgcred = &init_tgcred,
|
||||||
@ -410,6 +411,11 @@ int copy_creds(struct task_struct *p, unsigned long clone_flags)
|
|||||||
goto error_put;
|
goto error_put;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* cache user_ns in cred. Doesn't need a refcount because it will
|
||||||
|
* stay pinned by cred->user
|
||||||
|
*/
|
||||||
|
new->user_ns = new->user->user_ns;
|
||||||
|
|
||||||
#ifdef CONFIG_KEYS
|
#ifdef CONFIG_KEYS
|
||||||
/* new threads get their own thread keyrings if their parent already
|
/* new threads get their own thread keyrings if their parent already
|
||||||
* had one */
|
* had one */
|
||||||
@ -741,12 +747,6 @@ int set_create_files_as(struct cred *new, struct inode *inode)
|
|||||||
}
|
}
|
||||||
EXPORT_SYMBOL(set_create_files_as);
|
EXPORT_SYMBOL(set_create_files_as);
|
||||||
|
|
||||||
struct user_namespace *current_user_ns(void)
|
|
||||||
{
|
|
||||||
return _current_user_ns();
|
|
||||||
}
|
|
||||||
EXPORT_SYMBOL(current_user_ns);
|
|
||||||
|
|
||||||
#ifdef CONFIG_DEBUG_CREDENTIALS
|
#ifdef CONFIG_DEBUG_CREDENTIALS
|
||||||
|
|
||||||
bool creds_are_invalid(const struct cred *cred)
|
bool creds_are_invalid(const struct cred *cred)
|
||||||
|
Loading…
Reference in New Issue
Block a user