Skip to content

Commit

Permalink
Merge branch 'for-linus' of git://selinuxproject.org/~jmorris/linux-s…
Browse files Browse the repository at this point in the history
…ecurity

* 'for-linus' of git://selinuxproject.org/~jmorris/linux-security:
  capabilities: remove __cap_full_set definition
  security: remove the security_netlink_recv hook as it is equivalent to capable()
  ptrace: do not audit capability check when outputing /proc/pid/stat
  capabilities: remove task_ns_* functions
  capabitlies: ns_capable can use the cap helpers rather than lsm call
  capabilities: style only - move capable below ns_capable
  capabilites: introduce new has_ns_capabilities_noaudit
  capabilities: call has_ns_capability from has_capability
  capabilities: remove all _real_ interfaces
  capabilities: introduce security_capable_noaudit
  capabilities: reverse arguments to security_capable
  capabilities: remove the task from capable LSM hook entirely
  selinux: sparse fix: fix several warnings in the security server cod
  selinux: sparse fix: fix warnings in netlink code
  selinux: sparse fix: eliminate warnings for selinuxfs
  selinux: sparse fix: declare selinux_disable() in security.h
  selinux: sparse fix: move selinux_complete_init
  selinux: sparse fix: make selinux_secmark_refcount static
  SELinux: Fix RCU deref check warning in sel_netport_insert()

Manually fix up a semantic mis-merge wrt security_netlink_recv():

 - the interface was removed in commit fd77846 ("security: remove
   the security_netlink_recv hook as it is equivalent to capable()")

 - a new user of it appeared in commit a38f790 ("crypto: Add
   userspace configuration API")

causing no automatic merge conflict, but Eric Paris pointed out the
issue.
  • Loading branch information
torvalds committed Jan 15, 2012
2 parents 892d208 + f423e5b commit c49c41a
Show file tree
Hide file tree
Showing 24 changed files with 120 additions and 189 deletions.
2 changes: 1 addition & 1 deletion crypto/crypto_user.c
Original file line number Diff line number Diff line change
Expand Up @@ -382,7 +382,7 @@ static int crypto_user_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
type -= CRYPTO_MSG_BASE;
link = &crypto_dispatch[type];

if (security_netlink_recv(skb, CAP_NET_ADMIN))
if (!capable(CAP_NET_ADMIN))
return -EPERM;

if ((type == (CRYPTO_MSG_GETALG - CRYPTO_MSG_BASE) &&
Expand Down
2 changes: 1 addition & 1 deletion drivers/pci/pci-sysfs.c
Original file line number Diff line number Diff line change
Expand Up @@ -432,7 +432,7 @@ pci_read_config(struct file *filp, struct kobject *kobj,
u8 *data = (u8*) buf;

/* Several chips lock up trying to read undefined config space */
if (security_capable(&init_user_ns, filp->f_cred, CAP_SYS_ADMIN) == 0) {
if (security_capable(filp->f_cred, &init_user_ns, CAP_SYS_ADMIN) == 0) {
size = dev->cfg_size;
} else if (dev->hdr_type == PCI_HEADER_TYPE_CARDBUS) {
size = 128;
Expand Down
2 changes: 1 addition & 1 deletion drivers/scsi/scsi_netlink.c
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@ scsi_nl_rcv_msg(struct sk_buff *skb)
goto next_msg;
}

if (security_netlink_recv(skb, CAP_SYS_ADMIN)) {
if (!capable(CAP_SYS_ADMIN)) {
err = -EPERM;
goto next_msg;
}
Expand Down
2 changes: 1 addition & 1 deletion fs/proc/array.c
Original file line number Diff line number Diff line change
Expand Up @@ -380,7 +380,7 @@ static int do_task_stat(struct seq_file *m, struct pid_namespace *ns,

state = *get_task_state(task);
vsize = eip = esp = 0;
permitted = ptrace_may_access(task, PTRACE_MODE_READ);
permitted = ptrace_may_access(task, PTRACE_MODE_READ | PTRACE_MODE_NOAUDIT);
mm = get_task_mm(task);
if (mm) {
vsize = task_vsize(mm);
Expand Down
4 changes: 2 additions & 2 deletions include/linux/capability.h
Original file line number Diff line number Diff line change
Expand Up @@ -380,7 +380,6 @@ struct user_namespace;
struct user_namespace *current_user_ns(void);

extern const kernel_cap_t __cap_empty_set;
extern const kernel_cap_t __cap_full_set;
extern const kernel_cap_t __cap_init_eff_set;

/*
Expand Down Expand Up @@ -544,9 +543,10 @@ extern bool has_capability(struct task_struct *t, int cap);
extern bool has_ns_capability(struct task_struct *t,
struct user_namespace *ns, int cap);
extern bool has_capability_noaudit(struct task_struct *t, int cap);
extern bool has_ns_capability_noaudit(struct task_struct *t,
struct user_namespace *ns, int cap);
extern bool capable(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 nsown_capable(int cap);

/* audit system wants to get cap info from files as well */
Expand Down
6 changes: 4 additions & 2 deletions include/linux/cred.h
Original file line number Diff line number Diff line change
Expand Up @@ -358,10 +358,12 @@ static inline void put_cred(const struct cred *_cred)
#define current_security() (current_cred_xxx(security))

#ifdef CONFIG_USER_NS
#define current_user_ns() (current_cred_xxx(user_ns))
#define current_user_ns() (current_cred_xxx(user_ns))
#define task_user_ns(task) (task_cred_xxx((task), user_ns))
#else
extern struct user_namespace init_user_ns;
#define current_user_ns() (&init_user_ns)
#define current_user_ns() (&init_user_ns)
#define task_user_ns(task) (&init_user_ns)
#endif


Expand Down
5 changes: 3 additions & 2 deletions include/linux/ptrace.h
Original file line number Diff line number Diff line change
Expand Up @@ -127,8 +127,9 @@ extern void __ptrace_link(struct task_struct *child,
struct task_struct *new_parent);
extern void __ptrace_unlink(struct task_struct *child);
extern void exit_ptrace(struct task_struct *tracer);
#define PTRACE_MODE_READ 1
#define PTRACE_MODE_ATTACH 2
#define PTRACE_MODE_READ 0x01
#define PTRACE_MODE_ATTACH 0x02
#define PTRACE_MODE_NOAUDIT 0x04
/* Returns 0 on success, -errno on denial. */
extern int __ptrace_may_access(struct task_struct *task, unsigned int mode);
/* Returns true on success, false on denial. */
Expand Down
60 changes: 13 additions & 47 deletions include/linux/security.h
Original file line number Diff line number Diff line change
Expand Up @@ -54,8 +54,8 @@ struct user_namespace;
* These functions are in security/capability.c and are used
* as the default capabilities functions
*/
extern int cap_capable(struct task_struct *tsk, const struct cred *cred,
struct user_namespace *ns, int cap, int audit);
extern int cap_capable(const struct cred *cred, struct user_namespace *ns,
int cap, int audit);
extern int cap_settime(const struct timespec *ts, const struct timezone *tz);
extern int cap_ptrace_access_check(struct task_struct *child, unsigned int mode);
extern int cap_ptrace_traceme(struct task_struct *parent);
Expand Down Expand Up @@ -96,7 +96,6 @@ struct xfrm_user_sec_ctx;
struct seq_file;

extern int cap_netlink_send(struct sock *sk, struct sk_buff *skb);
extern int cap_netlink_recv(struct sk_buff *skb, int cap);

void reset_security_ops(void);

Expand Down Expand Up @@ -799,12 +798,6 @@ static inline void security_free_mnt_opts(struct security_mnt_opts *opts)
* @skb contains the sk_buff structure for the netlink message.
* Return 0 if the information was successfully saved and message
* is allowed to be transmitted.
* @netlink_recv:
* Check permission before processing the received netlink message in
* @skb.
* @skb contains the sk_buff structure for the netlink message.
* @cap indicates the capability required
* Return 0 if permission is granted.
*
* Security hooks for Unix domain networking.
*
Expand Down Expand Up @@ -1268,7 +1261,6 @@ static inline void security_free_mnt_opts(struct security_mnt_opts *opts)
* @capable:
* Check whether the @tsk process has the @cap capability in the indicated
* credentials.
* @tsk contains the task_struct for the process.
* @cred contains the credentials to use.
* @ns contains the user namespace we want the capability in
* @cap contains the capability <include/linux/capability.h>.
Expand Down Expand Up @@ -1392,8 +1384,8 @@ struct security_operations {
const kernel_cap_t *effective,
const kernel_cap_t *inheritable,
const kernel_cap_t *permitted);
int (*capable) (struct task_struct *tsk, const struct cred *cred,
struct user_namespace *ns, int cap, int audit);
int (*capable) (const struct cred *cred, struct user_namespace *ns,
int cap, int audit);
int (*quotactl) (int cmds, int type, int id, struct super_block *sb);
int (*quota_on) (struct dentry *dentry);
int (*syslog) (int type);
Expand Down Expand Up @@ -1563,7 +1555,6 @@ struct security_operations {
struct sembuf *sops, unsigned nsops, int alter);

int (*netlink_send) (struct sock *sk, struct sk_buff *skb);
int (*netlink_recv) (struct sk_buff *skb, int cap);

void (*d_instantiate) (struct dentry *dentry, struct inode *inode);

Expand Down Expand Up @@ -1675,12 +1666,10 @@ int security_capset(struct cred *new, const struct cred *old,
const kernel_cap_t *effective,
const kernel_cap_t *inheritable,
const kernel_cap_t *permitted);
int security_capable(struct user_namespace *ns, const struct cred *cred,
int cap);
int security_real_capable(struct task_struct *tsk, struct user_namespace *ns,
int security_capable(const struct cred *cred, struct user_namespace *ns,
int cap);
int security_real_capable_noaudit(struct task_struct *tsk,
struct user_namespace *ns, int cap);
int security_capable_noaudit(const struct cred *cred, struct user_namespace *ns,
int cap);
int security_quotactl(int cmds, int type, int id, struct super_block *sb);
int security_quota_on(struct dentry *dentry);
int security_syslog(int type);
Expand Down Expand Up @@ -1817,7 +1806,6 @@ void security_d_instantiate(struct dentry *dentry, struct inode *inode);
int security_getprocattr(struct task_struct *p, char *name, char **value);
int security_setprocattr(struct task_struct *p, char *name, void *value, size_t size);
int security_netlink_send(struct sock *sk, struct sk_buff *skb);
int security_netlink_recv(struct sk_buff *skb, int cap);
int security_secid_to_secctx(u32 secid, char **secdata, u32 *seclen);
int security_secctx_to_secid(const char *secdata, u32 seclen, u32 *secid);
void security_release_secctx(char *secdata, u32 seclen);
Expand Down Expand Up @@ -1875,32 +1863,15 @@ static inline int security_capset(struct cred *new,
return cap_capset(new, old, effective, inheritable, permitted);
}

static inline int security_capable(struct user_namespace *ns,
const struct cred *cred, int cap)
{
return cap_capable(current, cred, ns, cap, SECURITY_CAP_AUDIT);
}

static inline int security_real_capable(struct task_struct *tsk, struct user_namespace *ns, int cap)
static inline int security_capable(const struct cred *cred,
struct user_namespace *ns, int cap)
{
int ret;

rcu_read_lock();
ret = cap_capable(tsk, __task_cred(tsk), ns, cap, SECURITY_CAP_AUDIT);
rcu_read_unlock();
return ret;
return cap_capable(cred, ns, cap, SECURITY_CAP_AUDIT);
}

static inline
int security_real_capable_noaudit(struct task_struct *tsk, struct user_namespace *ns, int cap)
{
int ret;

rcu_read_lock();
ret = cap_capable(tsk, __task_cred(tsk), ns, cap,
SECURITY_CAP_NOAUDIT);
rcu_read_unlock();
return ret;
static inline int security_capable_noaudit(const struct cred *cred,
struct user_namespace *ns, int cap) {
return cap_capable(cred, ns, cap, SECURITY_CAP_NOAUDIT);
}

static inline int security_quotactl(int cmds, int type, int id,
Expand Down Expand Up @@ -2517,11 +2488,6 @@ static inline int security_netlink_send(struct sock *sk, struct sk_buff *skb)
return cap_netlink_send(sk, skb);
}

static inline int security_netlink_recv(struct sk_buff *skb, int cap)
{
return cap_netlink_recv(skb, cap);
}

static inline int security_secid_to_secctx(u32 secid, char **secdata, u32 *seclen)
{
return -EOPNOTSUPP;
Expand Down
4 changes: 2 additions & 2 deletions kernel/audit.c
Original file line number Diff line number Diff line change
Expand Up @@ -601,13 +601,13 @@ static int audit_netlink_ok(struct sk_buff *skb, u16 msg_type)
case AUDIT_TTY_SET:
case AUDIT_TRIM:
case AUDIT_MAKE_EQUIV:
if (security_netlink_recv(skb, CAP_AUDIT_CONTROL))
if (!capable(CAP_AUDIT_CONTROL))
err = -EPERM;
break;
case AUDIT_USER:
case AUDIT_FIRST_USER_MSG ... AUDIT_LAST_USER_MSG:
case AUDIT_FIRST_USER_MSG2 ... AUDIT_LAST_USER_MSG2:
if (security_netlink_recv(skb, CAP_AUDIT_WRITE))
if (!capable(CAP_AUDIT_WRITE))
err = -EPERM;
break;
default: /* bad msg */
Expand Down
80 changes: 46 additions & 34 deletions kernel/capability.c
Original file line number Diff line number Diff line change
Expand Up @@ -287,74 +287,84 @@ SYSCALL_DEFINE2(capset, cap_user_header_t, header, const cap_user_data_t, data)
}

/**
* has_capability - Does a task have a capability in init_user_ns
* has_ns_capability - Does a task have a capability in a specific user ns
* @t: The task in question
* @ns: target user namespace
* @cap: The capability to be tested for
*
* Return true if the specified task has the given superior capability
* currently in effect to the initial user namespace, false if not.
* currently in effect to the specified user namespace, false if not.
*
* Note that this does not set PF_SUPERPRIV on the task.
*/
bool has_capability(struct task_struct *t, int cap)
bool has_ns_capability(struct task_struct *t,
struct user_namespace *ns, int cap)
{
int ret = security_real_capable(t, &init_user_ns, cap);
int ret;

rcu_read_lock();
ret = security_capable(__task_cred(t), ns, cap);
rcu_read_unlock();

return (ret == 0);
}

/**
* has_capability - Does a task have a capability in a specific user ns
* has_capability - Does a task have a capability in init_user_ns
* @t: The task in question
* @ns: target user namespace
* @cap: The capability to be tested for
*
* Return true if the specified task has the given superior capability
* currently in effect to the specified user namespace, false if not.
* currently in effect to the initial user namespace, false if not.
*
* Note that this does not set PF_SUPERPRIV on the task.
*/
bool has_ns_capability(struct task_struct *t,
struct user_namespace *ns, int cap)
bool has_capability(struct task_struct *t, int cap)
{
int ret = security_real_capable(t, ns, cap);

return (ret == 0);
return has_ns_capability(t, &init_user_ns, cap);
}

/**
* has_capability_noaudit - Does a task have a capability (unaudited)
* has_ns_capability_noaudit - Does a task have a capability (unaudited)
* in a specific user ns.
* @t: The task in question
* @ns: target user namespace
* @cap: The capability to be tested for
*
* Return true if the specified task has the given superior capability
* currently in effect to init_user_ns, false if not. Don't write an
* audit message for the check.
* currently in effect to the specified user namespace, false if not.
* Do not write an audit message for the check.
*
* Note that this does not set PF_SUPERPRIV on the task.
*/
bool has_capability_noaudit(struct task_struct *t, int cap)
bool has_ns_capability_noaudit(struct task_struct *t,
struct user_namespace *ns, int cap)
{
int ret = security_real_capable_noaudit(t, &init_user_ns, cap);
int ret;

rcu_read_lock();
ret = security_capable_noaudit(__task_cred(t), ns, cap);
rcu_read_unlock();

return (ret == 0);
}

/**
* capable - Determine if the current task has a superior capability in effect
* has_capability_noaudit - Does a task have a capability (unaudited) in the
* initial user ns
* @t: The task in question
* @cap: The capability to be tested for
*
* Return true if the current task has the given superior capability currently
* available for use, false if not.
* Return true if the specified task has the given superior capability
* currently in effect to init_user_ns, false if not. Don't write an
* audit message for the check.
*
* This sets PF_SUPERPRIV on the task if the capability is available on the
* assumption that it's about to be used.
* Note that this does not set PF_SUPERPRIV on the task.
*/
bool capable(int cap)
bool has_capability_noaudit(struct task_struct *t, int cap)
{
return ns_capable(&init_user_ns, cap);
return has_ns_capability_noaudit(t, &init_user_ns, cap);
}
EXPORT_SYMBOL(capable);

/**
* ns_capable - Determine if the current task has a superior capability in effect
Expand All @@ -374,7 +384,7 @@ bool ns_capable(struct user_namespace *ns, int cap)
BUG();
}

if (security_capable(ns, current_cred(), cap) == 0) {
if (has_ns_capability(current, ns, cap)) {
current->flags |= PF_SUPERPRIV;
return true;
}
Expand All @@ -383,18 +393,20 @@ bool ns_capable(struct user_namespace *ns, int cap)
EXPORT_SYMBOL(ns_capable);

/**
* task_ns_capable - Determine whether current task has a superior
* capability targeted at a specific task's user namespace.
* @t: The task whose user namespace is targeted.
* @cap: The capability in question.
* capable - Determine if the current task has a superior capability in effect
* @cap: The capability to be tested for
*
* Return true if the current task has the given superior capability currently
* available for use, false if not.
*
* Return true if it does, false otherwise.
* This sets PF_SUPERPRIV on the task if the capability is available on the
* assumption that it's about to be used.
*/
bool task_ns_capable(struct task_struct *t, int cap)
bool capable(int cap)
{
return ns_capable(task_cred_xxx(t, user)->user_ns, cap);
return ns_capable(&init_user_ns, cap);
}
EXPORT_SYMBOL(task_ns_capable);
EXPORT_SYMBOL(capable);

/**
* nsown_capable - Check superior capability to one's own user_ns
Expand Down
Loading

0 comments on commit c49c41a

Please sign in to comment.