Skip to content

Commit

Permalink
scm: Stop passing struct cred
Browse files Browse the repository at this point in the history
Now that uids and gids are completely encapsulated in kuid_t
and kgid_t we no longer need to pass struct cred which allowed
us to test both the uid and the user namespace for equality.

Passing struct cred potentially allows us to pass the entire group
list as BSD does but I don't believe the cost of cache line misses
justifies retaining code for a future potential application.

Signed-off-by: "Eric W. Biederman" <ebiederm@xmission.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
Eric W. Biederman authored and David S. Miller committed Apr 7, 2013
1 parent d978a63 commit 6b0ee8c
Show file tree
Hide file tree
Showing 4 changed files with 16 additions and 35 deletions.
3 changes: 2 additions & 1 deletion include/net/af_unix.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,8 @@ struct unix_address {

struct unix_skb_parms {
struct pid *pid; /* Skb credentials */
const struct cred *cred;
kuid_t uid;
kgid_t gid;
struct scm_fp_list *fp; /* Passed files */
#ifdef CONFIG_SECURITY_NETWORK
u32 secid; /* Security ID */
Expand Down
16 changes: 6 additions & 10 deletions include/net/scm.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@ struct scm_fp_list {

struct scm_cookie {
struct pid *pid; /* Skb credentials */
const struct cred *cred;
struct scm_fp_list *fp; /* Passed files */
struct scm_creds creds; /* Skb credentials */
#ifdef CONFIG_SECURITY_NETWORK
Expand All @@ -51,23 +50,18 @@ static __inline__ void unix_get_peersec_dgram(struct socket *sock, struct scm_co
#endif /* CONFIG_SECURITY_NETWORK */

static __inline__ void scm_set_cred(struct scm_cookie *scm,
struct pid *pid, const struct cred *cred)
struct pid *pid, kuid_t uid, kgid_t gid)
{
scm->pid = get_pid(pid);
scm->cred = cred ? get_cred(cred) : NULL;
scm->creds.pid = pid_vnr(pid);
scm->creds.uid = cred ? cred->euid : INVALID_UID;
scm->creds.gid = cred ? cred->egid : INVALID_GID;
scm->creds.uid = uid;
scm->creds.gid = gid;
}

static __inline__ void scm_destroy_cred(struct scm_cookie *scm)
{
put_pid(scm->pid);
scm->pid = NULL;

if (scm->cred)
put_cred(scm->cred);
scm->cred = NULL;
}

static __inline__ void scm_destroy(struct scm_cookie *scm)
Expand All @@ -81,8 +75,10 @@ static __inline__ int scm_send(struct socket *sock, struct msghdr *msg,
struct scm_cookie *scm, bool forcecreds)
{
memset(scm, 0, sizeof(*scm));
scm->creds.uid = INVALID_UID;
scm->creds.gid = INVALID_GID;
if (forcecreds)
scm_set_cred(scm, task_tgid(current), current_cred());
scm_set_cred(scm, task_tgid(current), current_euid(), current_egid());
unix_get_peersec_dgram(sock, scm);
if (msg->msg_controllen <= 0)
return 0;
Expand Down
16 changes: 0 additions & 16 deletions net/core/scm.c
Original file line number Diff line number Diff line change
Expand Up @@ -187,22 +187,6 @@ int __scm_send(struct socket *sock, struct msghdr *msg, struct scm_cookie *p)

p->creds.uid = uid;
p->creds.gid = gid;

if (!p->cred ||
!uid_eq(p->cred->euid, uid) ||
!gid_eq(p->cred->egid, gid)) {
struct cred *cred;
err = -ENOMEM;
cred = prepare_creds();
if (!cred)
goto error;

cred->uid = cred->euid = uid;
cred->gid = cred->egid = gid;
if (p->cred)
put_cred(p->cred);
p->cred = cred;
}
break;
}
default:
Expand Down
16 changes: 8 additions & 8 deletions net/unix/af_unix.c
Original file line number Diff line number Diff line change
Expand Up @@ -1340,7 +1340,6 @@ static void unix_destruct_scm(struct sk_buff *skb)
struct scm_cookie scm;
memset(&scm, 0, sizeof(scm));
scm.pid = UNIXCB(skb).pid;
scm.cred = UNIXCB(skb).cred;
if (UNIXCB(skb).fp)
unix_detach_fds(&scm, skb);

Expand Down Expand Up @@ -1391,8 +1390,8 @@ static int unix_scm_to_skb(struct scm_cookie *scm, struct sk_buff *skb, bool sen
int err = 0;

UNIXCB(skb).pid = get_pid(scm->pid);
if (scm->cred)
UNIXCB(skb).cred = get_cred(scm->cred);
UNIXCB(skb).uid = scm->creds.uid;
UNIXCB(skb).gid = scm->creds.gid;
UNIXCB(skb).fp = NULL;
if (scm->fp && send_fds)
err = unix_attach_fds(scm, skb);
Expand All @@ -1409,13 +1408,13 @@ static int unix_scm_to_skb(struct scm_cookie *scm, struct sk_buff *skb, bool sen
static void maybe_add_creds(struct sk_buff *skb, const struct socket *sock,
const struct sock *other)
{
if (UNIXCB(skb).cred)
if (UNIXCB(skb).pid)
return;
if (test_bit(SOCK_PASSCRED, &sock->flags) ||
!other->sk_socket ||
test_bit(SOCK_PASSCRED, &other->sk_socket->flags)) {
UNIXCB(skb).pid = get_pid(task_tgid(current));
UNIXCB(skb).cred = get_current_cred();
current_euid_egid(&UNIXCB(skb).uid, &UNIXCB(skb).gid);
}
}

Expand Down Expand Up @@ -1819,7 +1818,7 @@ static int unix_dgram_recvmsg(struct kiocb *iocb, struct socket *sock,
siocb->scm = &tmp_scm;
memset(&tmp_scm, 0, sizeof(tmp_scm));
}
scm_set_cred(siocb->scm, UNIXCB(skb).pid, UNIXCB(skb).cred);
scm_set_cred(siocb->scm, UNIXCB(skb).pid, UNIXCB(skb).uid, UNIXCB(skb).gid);
unix_set_secdata(siocb->scm, skb);

if (!(flags & MSG_PEEK)) {
Expand Down Expand Up @@ -1991,11 +1990,12 @@ static int unix_stream_recvmsg(struct kiocb *iocb, struct socket *sock,
if (check_creds) {
/* Never glue messages from different writers */
if ((UNIXCB(skb).pid != siocb->scm->pid) ||
(UNIXCB(skb).cred != siocb->scm->cred))
!uid_eq(UNIXCB(skb).uid, siocb->scm->creds.uid) ||
!gid_eq(UNIXCB(skb).gid, siocb->scm->creds.gid))
break;
} else if (test_bit(SOCK_PASSCRED, &sock->flags)) {
/* Copy credentials */
scm_set_cred(siocb->scm, UNIXCB(skb).pid, UNIXCB(skb).cred);
scm_set_cred(siocb->scm, UNIXCB(skb).pid, UNIXCB(skb).uid, UNIXCB(skb).gid);
check_creds = 1;
}

Expand Down

0 comments on commit 6b0ee8c

Please sign in to comment.