Skip to content

Commit 6b4f3d0

Browse files
stephensmalleyJames Morris
authored andcommitted
usb, signal, security: only pass the cred, not the secid, to kill_pid_info_as_cred and security_task_kill
commit d178bc3 ("user namespace: usb: make usb urbs user namespace aware (v2)") changed kill_pid_info_as_uid to kill_pid_info_as_cred, saving and passing a cred structure instead of uids. Since the secid can be obtained from the cred, drop the secid fields from the usb_dev_state and async structures, and drop the secid argument to kill_pid_info_as_cred. Replace the secid argument to security_task_kill with the cred. Update SELinux, Smack, and AppArmor to use the cred, which avoids the need for Smack and AppArmor to use a secid at all in this hook. Further changes to Smack might still be required to take full advantage of this change, since it should now be possible to perform capability checking based on the supplied cred. The changes to Smack and AppArmor have only been compile-tested. Signed-off-by: Stephen Smalley <[email protected]> Acked-by: Paul Moore <[email protected]> Acked-by: Casey Schaufler <[email protected]> Acked-by: Greg Kroah-Hartman <[email protected]> Acked-by: John Johansen <[email protected]> Signed-off-by: James Morris <[email protected]>
1 parent a02633e commit 6b4f3d0

File tree

9 files changed

+35
-32
lines changed

9 files changed

+35
-32
lines changed

drivers/usb/core/devio.c

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,6 @@ struct usb_dev_state {
6565
const struct cred *cred;
6666
void __user *disccontext;
6767
unsigned long ifclaimed;
68-
u32 secid;
6968
u32 disabled_bulk_eps;
7069
bool privileges_dropped;
7170
unsigned long interface_allowed_mask;
@@ -95,7 +94,6 @@ struct async {
9594
struct usb_memory *usbm;
9695
unsigned int mem_usage;
9796
int status;
98-
u32 secid;
9997
u8 bulk_addr;
10098
u8 bulk_status;
10199
};
@@ -586,7 +584,6 @@ static void async_completed(struct urb *urb)
586584
struct usb_dev_state *ps = as->ps;
587585
struct siginfo sinfo;
588586
struct pid *pid = NULL;
589-
u32 secid = 0;
590587
const struct cred *cred = NULL;
591588
int signr;
592589

@@ -602,7 +599,6 @@ static void async_completed(struct urb *urb)
602599
sinfo.si_addr = as->userurb;
603600
pid = get_pid(as->pid);
604601
cred = get_cred(as->cred);
605-
secid = as->secid;
606602
}
607603
snoop(&urb->dev->dev, "urb complete\n");
608604
snoop_urb(urb->dev, as->userurb, urb->pipe, urb->actual_length,
@@ -618,7 +614,7 @@ static void async_completed(struct urb *urb)
618614
spin_unlock(&ps->lock);
619615

620616
if (signr) {
621-
kill_pid_info_as_cred(sinfo.si_signo, &sinfo, pid, cred, secid);
617+
kill_pid_info_as_cred(sinfo.si_signo, &sinfo, pid, cred);
622618
put_pid(pid);
623619
put_cred(cred);
624620
}
@@ -1013,7 +1009,6 @@ static int usbdev_open(struct inode *inode, struct file *file)
10131009
init_waitqueue_head(&ps->wait);
10141010
ps->disc_pid = get_pid(task_pid(current));
10151011
ps->cred = get_current_cred();
1016-
security_task_getsecid(current, &ps->secid);
10171012
smp_wmb();
10181013
list_add_tail(&ps->list, &dev->filelist);
10191014
file->private_data = ps;
@@ -1727,7 +1722,6 @@ static int proc_do_submiturb(struct usb_dev_state *ps, struct usbdevfs_urb *uurb
17271722
as->ifnum = ifnum;
17281723
as->pid = get_pid(task_pid(current));
17291724
as->cred = get_current_cred();
1730-
security_task_getsecid(current, &as->secid);
17311725
snoop_urb(ps->dev, as->userurb, as->urb->pipe,
17321726
as->urb->transfer_buffer_length, 0, SUBMIT,
17331727
NULL, 0);
@@ -2617,7 +2611,7 @@ static void usbdev_remove(struct usb_device *udev)
26172611
sinfo.si_code = SI_ASYNCIO;
26182612
sinfo.si_addr = ps->disccontext;
26192613
kill_pid_info_as_cred(ps->discsignr, &sinfo,
2620-
ps->disc_pid, ps->cred, ps->secid);
2614+
ps->disc_pid, ps->cred);
26212615
}
26222616
}
26232617
}

include/linux/lsm_hooks.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -672,7 +672,8 @@
672672
* @p contains the task_struct for process.
673673
* @info contains the signal information.
674674
* @sig contains the signal value.
675-
* @secid contains the sid of the process where the signal originated
675+
* @cred contains the cred of the process where the signal originated, or
676+
* NULL if the current task is the originator.
676677
* Return 0 if permission is granted.
677678
* @task_prctl:
678679
* Check permission before performing a process control operation on the
@@ -1564,7 +1565,7 @@ union security_list_options {
15641565
int (*task_getscheduler)(struct task_struct *p);
15651566
int (*task_movememory)(struct task_struct *p);
15661567
int (*task_kill)(struct task_struct *p, struct siginfo *info,
1567-
int sig, u32 secid);
1568+
int sig, const struct cred *cred);
15681569
int (*task_prctl)(int option, unsigned long arg2, unsigned long arg3,
15691570
unsigned long arg4, unsigned long arg5);
15701571
void (*task_to_inode)(struct task_struct *p, struct inode *inode);

include/linux/sched/signal.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -319,7 +319,7 @@ extern int force_sig_info(int, struct siginfo *, struct task_struct *);
319319
extern int __kill_pgrp_info(int sig, struct siginfo *info, struct pid *pgrp);
320320
extern int kill_pid_info(int sig, struct siginfo *info, struct pid *pid);
321321
extern int kill_pid_info_as_cred(int, struct siginfo *, struct pid *,
322-
const struct cred *, u32);
322+
const struct cred *);
323323
extern int kill_pgrp(struct pid *pid, int sig, int priv);
324324
extern int kill_pid(struct pid *pid, int sig, int priv);
325325
extern __must_check bool do_notify_parent(struct task_struct *, int);

include/linux/security.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -347,7 +347,7 @@ int security_task_setscheduler(struct task_struct *p);
347347
int security_task_getscheduler(struct task_struct *p);
348348
int security_task_movememory(struct task_struct *p);
349349
int security_task_kill(struct task_struct *p, struct siginfo *info,
350-
int sig, u32 secid);
350+
int sig, const struct cred *cred);
351351
int security_task_prctl(int option, unsigned long arg2, unsigned long arg3,
352352
unsigned long arg4, unsigned long arg5);
353353
void security_task_to_inode(struct task_struct *p, struct inode *inode);
@@ -1010,7 +1010,7 @@ static inline int security_task_movememory(struct task_struct *p)
10101010

10111011
static inline int security_task_kill(struct task_struct *p,
10121012
struct siginfo *info, int sig,
1013-
u32 secid)
1013+
const struct cred *cred)
10141014
{
10151015
return 0;
10161016
}

kernel/signal.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -770,7 +770,7 @@ static int check_kill_permission(int sig, struct siginfo *info,
770770
}
771771
}
772772

773-
return security_task_kill(t, info, sig, 0);
773+
return security_task_kill(t, info, sig, NULL);
774774
}
775775

776776
/**
@@ -1361,7 +1361,7 @@ static int kill_as_cred_perm(const struct cred *cred,
13611361

13621362
/* like kill_pid_info(), but doesn't use uid/euid of "current" */
13631363
int kill_pid_info_as_cred(int sig, struct siginfo *info, struct pid *pid,
1364-
const struct cred *cred, u32 secid)
1364+
const struct cred *cred)
13651365
{
13661366
int ret = -EINVAL;
13671367
struct task_struct *p;
@@ -1380,7 +1380,7 @@ int kill_pid_info_as_cred(int sig, struct siginfo *info, struct pid *pid,
13801380
ret = -EPERM;
13811381
goto out_unlock;
13821382
}
1383-
ret = security_task_kill(p, info, sig, secid);
1383+
ret = security_task_kill(p, info, sig, cred);
13841384
if (ret)
13851385
goto out_unlock;
13861386

security/apparmor/lsm.c

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -717,16 +717,23 @@ static int apparmor_task_setrlimit(struct task_struct *task,
717717
}
718718

719719
static int apparmor_task_kill(struct task_struct *target, struct siginfo *info,
720-
int sig, u32 secid)
720+
int sig, const struct cred *cred)
721721
{
722722
struct aa_label *cl, *tl;
723723
int error;
724724

725-
if (secid)
726-
/* TODO: after secid to label mapping is done.
727-
* Dealing with USB IO specific behavior
725+
if (cred) {
726+
/*
727+
* Dealing with USB IO specific behavior
728728
*/
729-
return 0;
729+
cl = aa_get_newest_cred_label(cred);
730+
tl = aa_get_task_label(target);
731+
error = aa_may_signal(cl, tl, sig);
732+
aa_put_label(cl);
733+
aa_put_label(tl);
734+
return error;
735+
}
736+
730737
cl = __begin_current_label_crit_section();
731738
tl = aa_get_task_label(target);
732739
error = aa_may_signal(cl, tl, sig);

security/security.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1114,9 +1114,9 @@ int security_task_movememory(struct task_struct *p)
11141114
}
11151115

11161116
int security_task_kill(struct task_struct *p, struct siginfo *info,
1117-
int sig, u32 secid)
1117+
int sig, const struct cred *cred)
11181118
{
1119-
return call_int_hook(task_kill, 0, p, info, sig, secid);
1119+
return call_int_hook(task_kill, 0, p, info, sig, cred);
11201120
}
11211121

11221122
int security_task_prctl(int option, unsigned long arg2, unsigned long arg3,

security/selinux/hooks.c

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4036,16 +4036,19 @@ static int selinux_task_movememory(struct task_struct *p)
40364036
}
40374037

40384038
static int selinux_task_kill(struct task_struct *p, struct siginfo *info,
4039-
int sig, u32 secid)
4039+
int sig, const struct cred *cred)
40404040
{
4041+
u32 secid;
40414042
u32 perm;
40424043

40434044
if (!sig)
40444045
perm = PROCESS__SIGNULL; /* null signal; existence test */
40454046
else
40464047
perm = signal_to_av(sig);
4047-
if (!secid)
4048+
if (!cred)
40484049
secid = current_sid();
4050+
else
4051+
secid = cred_sid(cred);
40494052
return avc_has_perm(secid, task_sid(p), SECCLASS_PROCESS, perm, NULL);
40504053
}
40514054

security/smack/smack_lsm.c

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2228,15 +2228,13 @@ static int smack_task_movememory(struct task_struct *p)
22282228
* @p: the task object
22292229
* @info: unused
22302230
* @sig: unused
2231-
* @secid: identifies the smack to use in lieu of current's
2231+
* @cred: identifies the cred to use in lieu of current's
22322232
*
22332233
* Return 0 if write access is permitted
22342234
*
2235-
* The secid behavior is an artifact of an SELinux hack
2236-
* in the USB code. Someday it may go away.
22372235
*/
22382236
static int smack_task_kill(struct task_struct *p, struct siginfo *info,
2239-
int sig, u32 secid)
2237+
int sig, const struct cred *cred)
22402238
{
22412239
struct smk_audit_info ad;
22422240
struct smack_known *skp;
@@ -2252,17 +2250,17 @@ static int smack_task_kill(struct task_struct *p, struct siginfo *info,
22522250
* Sending a signal requires that the sender
22532251
* can write the receiver.
22542252
*/
2255-
if (secid == 0) {
2253+
if (cred == NULL) {
22562254
rc = smk_curacc(tkp, MAY_DELIVER, &ad);
22572255
rc = smk_bu_task(p, MAY_DELIVER, rc);
22582256
return rc;
22592257
}
22602258
/*
2261-
* If the secid isn't 0 we're dealing with some USB IO
2259+
* If the cred isn't NULL we're dealing with some USB IO
22622260
* specific behavior. This is not clean. For one thing
22632261
* we can't take privilege into account.
22642262
*/
2265-
skp = smack_from_secid(secid);
2263+
skp = smk_of_task(cred->security);
22662264
rc = smk_access(skp, tkp, MAY_DELIVER, &ad);
22672265
rc = smk_bu_note("USB signal", skp, tkp, MAY_DELIVER, rc);
22682266
return rc;

0 commit comments

Comments
 (0)