Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 202975
b: refs/heads/master
c: 109f6e3
h: refs/heads/master
i:
  202973: 76bb918
  202971: e44b0b5
  202967: cc16e17
  202959: a86db5e
  202943: bd4a035
v: v3
  • Loading branch information
Eric W. Biederman authored and David S. Miller committed Jun 16, 2010
1 parent d5f199f commit 24c292a
Show file tree
Hide file tree
Showing 4 changed files with 43 additions and 17 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 3f551f9436c05a3b5eccdd6e94733df5bb98d2a5
refs/heads/master: 109f6e39fa07c48f580125f531f46cb7c245b528
3 changes: 2 additions & 1 deletion trunk/include/net/sock.h
Original file line number Diff line number Diff line change
Expand Up @@ -295,7 +295,8 @@ struct sock {
unsigned short sk_ack_backlog;
unsigned short sk_max_ack_backlog;
__u32 sk_priority;
struct ucred sk_peercred;
struct pid *sk_peer_pid;
const struct cred *sk_peer_cred;
long sk_rcvtimeo;
long sk_sndtimeo;
struct sk_filter *sk_filter;
Expand Down
18 changes: 12 additions & 6 deletions trunk/net/core/sock.c
Original file line number Diff line number Diff line change
Expand Up @@ -915,11 +915,15 @@ int sock_getsockopt(struct socket *sock, int level, int optname,
break;

case SO_PEERCRED:
if (len > sizeof(sk->sk_peercred))
len = sizeof(sk->sk_peercred);
if (copy_to_user(optval, &sk->sk_peercred, len))
{
struct ucred peercred;
if (len > sizeof(peercred))
len = sizeof(peercred);
cred_to_ucred(sk->sk_peer_pid, sk->sk_peer_cred, &peercred);
if (copy_to_user(optval, &peercred, len))
return -EFAULT;
goto lenout;
}

case SO_PEERNAME:
{
Expand Down Expand Up @@ -1133,6 +1137,9 @@ static void __sk_free(struct sock *sk)
printk(KERN_DEBUG "%s: optmem leakage (%d bytes) detected.\n",
__func__, atomic_read(&sk->sk_omem_alloc));

if (sk->sk_peer_cred)
put_cred(sk->sk_peer_cred);
put_pid(sk->sk_peer_pid);
put_net(sock_net(sk));
sk_prot_free(sk->sk_prot_creator, sk);
}
Expand Down Expand Up @@ -1968,9 +1975,8 @@ void sock_init_data(struct socket *sock, struct sock *sk)
sk->sk_sndmsg_page = NULL;
sk->sk_sndmsg_off = 0;

sk->sk_peercred.pid = 0;
sk->sk_peercred.uid = -1;
sk->sk_peercred.gid = -1;
sk->sk_peer_pid = NULL;
sk->sk_peer_cred = NULL;
sk->sk_write_pending = 0;
sk->sk_rcvlowat = 1;
sk->sk_rcvtimeo = MAX_SCHEDULE_TIMEOUT;
Expand Down
37 changes: 28 additions & 9 deletions trunk/net/unix/af_unix.c
Original file line number Diff line number Diff line change
Expand Up @@ -450,11 +450,31 @@ static int unix_release_sock(struct sock *sk, int embrion)
return 0;
}

static void init_peercred(struct sock *sk)
{
put_pid(sk->sk_peer_pid);
if (sk->sk_peer_cred)
put_cred(sk->sk_peer_cred);
sk->sk_peer_pid = get_pid(task_tgid(current));
sk->sk_peer_cred = get_current_cred();
}

static void copy_peercred(struct sock *sk, struct sock *peersk)
{
put_pid(sk->sk_peer_pid);
if (sk->sk_peer_cred)
put_cred(sk->sk_peer_cred);
sk->sk_peer_pid = get_pid(peersk->sk_peer_pid);
sk->sk_peer_cred = get_cred(peersk->sk_peer_cred);
}

static int unix_listen(struct socket *sock, int backlog)
{
int err;
struct sock *sk = sock->sk;
struct unix_sock *u = unix_sk(sk);
struct pid *old_pid = NULL;
const struct cred *old_cred = NULL;

err = -EOPNOTSUPP;
if (sock->type != SOCK_STREAM && sock->type != SOCK_SEQPACKET)
Expand All @@ -470,12 +490,14 @@ static int unix_listen(struct socket *sock, int backlog)
sk->sk_max_ack_backlog = backlog;
sk->sk_state = TCP_LISTEN;
/* set credentials so connect can copy them */
sk->sk_peercred.pid = task_tgid_vnr(current);
current_euid_egid(&sk->sk_peercred.uid, &sk->sk_peercred.gid);
init_peercred(sk);
err = 0;

out_unlock:
unix_state_unlock(sk);
put_pid(old_pid);
if (old_cred)
put_cred(old_cred);
out:
return err;
}
Expand Down Expand Up @@ -1140,8 +1162,7 @@ static int unix_stream_connect(struct socket *sock, struct sockaddr *uaddr,
unix_peer(newsk) = sk;
newsk->sk_state = TCP_ESTABLISHED;
newsk->sk_type = sk->sk_type;
newsk->sk_peercred.pid = task_tgid_vnr(current);
current_euid_egid(&newsk->sk_peercred.uid, &newsk->sk_peercred.gid);
init_peercred(newsk);
newu = unix_sk(newsk);
newsk->sk_wq = &newu->peer_wq;
otheru = unix_sk(other);
Expand All @@ -1157,7 +1178,7 @@ static int unix_stream_connect(struct socket *sock, struct sockaddr *uaddr,
}

/* Set credentials */
sk->sk_peercred = other->sk_peercred;
copy_peercred(sk, other);

sock->state = SS_CONNECTED;
sk->sk_state = TCP_ESTABLISHED;
Expand Down Expand Up @@ -1199,10 +1220,8 @@ static int unix_socketpair(struct socket *socka, struct socket *sockb)
sock_hold(skb);
unix_peer(ska) = skb;
unix_peer(skb) = ska;
ska->sk_peercred.pid = skb->sk_peercred.pid = task_tgid_vnr(current);
current_euid_egid(&skb->sk_peercred.uid, &skb->sk_peercred.gid);
ska->sk_peercred.uid = skb->sk_peercred.uid;
ska->sk_peercred.gid = skb->sk_peercred.gid;
init_peercred(ska);
init_peercred(skb);

if (ska->sk_type != SOCK_DGRAM) {
ska->sk_state = TCP_ESTABLISHED;
Expand Down

0 comments on commit 24c292a

Please sign in to comment.