|
|
@@ -1445,7 +1445,6 @@ static void maybe_add_creds(struct sk_buff *skb, const struct socket *sock,
|
|
|
static int unix_dgram_sendmsg(struct kiocb *kiocb, struct socket *sock,
|
|
|
struct msghdr *msg, size_t len)
|
|
|
{
|
|
|
- struct sock_iocb *siocb = kiocb_to_siocb(kiocb);
|
|
|
struct sock *sk = sock->sk;
|
|
|
struct net *net = sock_net(sk);
|
|
|
struct unix_sock *u = unix_sk(sk);
|
|
|
@@ -1456,14 +1455,12 @@ static int unix_dgram_sendmsg(struct kiocb *kiocb, struct socket *sock,
|
|
|
unsigned int hash;
|
|
|
struct sk_buff *skb;
|
|
|
long timeo;
|
|
|
- struct scm_cookie tmp_scm;
|
|
|
+ struct scm_cookie scm;
|
|
|
int max_level;
|
|
|
int data_len = 0;
|
|
|
|
|
|
- if (NULL == siocb->scm)
|
|
|
- siocb->scm = &tmp_scm;
|
|
|
wait_for_unix_gc();
|
|
|
- err = scm_send(sock, msg, siocb->scm, false);
|
|
|
+ err = scm_send(sock, msg, &scm, false);
|
|
|
if (err < 0)
|
|
|
return err;
|
|
|
|
|
|
@@ -1507,11 +1504,11 @@ static int unix_dgram_sendmsg(struct kiocb *kiocb, struct socket *sock,
|
|
|
if (skb == NULL)
|
|
|
goto out;
|
|
|
|
|
|
- err = unix_scm_to_skb(siocb->scm, skb, true);
|
|
|
+ err = unix_scm_to_skb(&scm, skb, true);
|
|
|
if (err < 0)
|
|
|
goto out_free;
|
|
|
max_level = err + 1;
|
|
|
- unix_get_secdata(siocb->scm, skb);
|
|
|
+ unix_get_secdata(&scm, skb);
|
|
|
|
|
|
skb_put(skb, len - data_len);
|
|
|
skb->data_len = data_len;
|
|
|
@@ -1606,7 +1603,7 @@ static int unix_dgram_sendmsg(struct kiocb *kiocb, struct socket *sock,
|
|
|
unix_state_unlock(other);
|
|
|
other->sk_data_ready(other);
|
|
|
sock_put(other);
|
|
|
- scm_destroy(siocb->scm);
|
|
|
+ scm_destroy(&scm);
|
|
|
return len;
|
|
|
|
|
|
out_unlock:
|
|
|
@@ -1616,7 +1613,7 @@ static int unix_dgram_sendmsg(struct kiocb *kiocb, struct socket *sock,
|
|
|
out:
|
|
|
if (other)
|
|
|
sock_put(other);
|
|
|
- scm_destroy(siocb->scm);
|
|
|
+ scm_destroy(&scm);
|
|
|
return err;
|
|
|
}
|
|
|
|
|
|
@@ -1628,21 +1625,18 @@ static int unix_dgram_sendmsg(struct kiocb *kiocb, struct socket *sock,
|
|
|
static int unix_stream_sendmsg(struct kiocb *kiocb, struct socket *sock,
|
|
|
struct msghdr *msg, size_t len)
|
|
|
{
|
|
|
- struct sock_iocb *siocb = kiocb_to_siocb(kiocb);
|
|
|
struct sock *sk = sock->sk;
|
|
|
struct sock *other = NULL;
|
|
|
int err, size;
|
|
|
struct sk_buff *skb;
|
|
|
int sent = 0;
|
|
|
- struct scm_cookie tmp_scm;
|
|
|
+ struct scm_cookie scm;
|
|
|
bool fds_sent = false;
|
|
|
int max_level;
|
|
|
int data_len;
|
|
|
|
|
|
- if (NULL == siocb->scm)
|
|
|
- siocb->scm = &tmp_scm;
|
|
|
wait_for_unix_gc();
|
|
|
- err = scm_send(sock, msg, siocb->scm, false);
|
|
|
+ err = scm_send(sock, msg, &scm, false);
|
|
|
if (err < 0)
|
|
|
return err;
|
|
|
|
|
|
@@ -1683,7 +1677,7 @@ static int unix_stream_sendmsg(struct kiocb *kiocb, struct socket *sock,
|
|
|
goto out_err;
|
|
|
|
|
|
/* Only send the fds in the first buffer */
|
|
|
- err = unix_scm_to_skb(siocb->scm, skb, !fds_sent);
|
|
|
+ err = unix_scm_to_skb(&scm, skb, !fds_sent);
|
|
|
if (err < 0) {
|
|
|
kfree_skb(skb);
|
|
|
goto out_err;
|
|
|
@@ -1715,8 +1709,7 @@ static int unix_stream_sendmsg(struct kiocb *kiocb, struct socket *sock,
|
|
|
sent += size;
|
|
|
}
|
|
|
|
|
|
- scm_destroy(siocb->scm);
|
|
|
- siocb->scm = NULL;
|
|
|
+ scm_destroy(&scm);
|
|
|
|
|
|
return sent;
|
|
|
|
|
|
@@ -1728,8 +1721,7 @@ static int unix_stream_sendmsg(struct kiocb *kiocb, struct socket *sock,
|
|
|
send_sig(SIGPIPE, current, 0);
|
|
|
err = -EPIPE;
|
|
|
out_err:
|
|
|
- scm_destroy(siocb->scm);
|
|
|
- siocb->scm = NULL;
|
|
|
+ scm_destroy(&scm);
|
|
|
return sent ? : err;
|
|
|
}
|
|
|
|
|
|
@@ -1778,8 +1770,7 @@ static int unix_dgram_recvmsg(struct kiocb *iocb, struct socket *sock,
|
|
|
struct msghdr *msg, size_t size,
|
|
|
int flags)
|
|
|
{
|
|
|
- struct sock_iocb *siocb = kiocb_to_siocb(iocb);
|
|
|
- struct scm_cookie tmp_scm;
|
|
|
+ struct scm_cookie scm;
|
|
|
struct sock *sk = sock->sk;
|
|
|
struct unix_sock *u = unix_sk(sk);
|
|
|
int noblock = flags & MSG_DONTWAIT;
|
|
|
@@ -1831,16 +1822,14 @@ static int unix_dgram_recvmsg(struct kiocb *iocb, struct socket *sock,
|
|
|
if (sock_flag(sk, SOCK_RCVTSTAMP))
|
|
|
__sock_recv_timestamp(msg, sk, skb);
|
|
|
|
|
|
- if (!siocb->scm) {
|
|
|
- siocb->scm = &tmp_scm;
|
|
|
- memset(&tmp_scm, 0, sizeof(tmp_scm));
|
|
|
- }
|
|
|
- scm_set_cred(siocb->scm, UNIXCB(skb).pid, UNIXCB(skb).uid, UNIXCB(skb).gid);
|
|
|
- unix_set_secdata(siocb->scm, skb);
|
|
|
+ memset(&scm, 0, sizeof(scm));
|
|
|
+
|
|
|
+ scm_set_cred(&scm, UNIXCB(skb).pid, UNIXCB(skb).uid, UNIXCB(skb).gid);
|
|
|
+ unix_set_secdata(&scm, skb);
|
|
|
|
|
|
if (!(flags & MSG_PEEK)) {
|
|
|
if (UNIXCB(skb).fp)
|
|
|
- unix_detach_fds(siocb->scm, skb);
|
|
|
+ unix_detach_fds(&scm, skb);
|
|
|
|
|
|
sk_peek_offset_bwd(sk, skb->len);
|
|
|
} else {
|
|
|
@@ -1860,11 +1849,11 @@ static int unix_dgram_recvmsg(struct kiocb *iocb, struct socket *sock,
|
|
|
sk_peek_offset_fwd(sk, size);
|
|
|
|
|
|
if (UNIXCB(skb).fp)
|
|
|
- siocb->scm->fp = scm_fp_dup(UNIXCB(skb).fp);
|
|
|
+ scm.fp = scm_fp_dup(UNIXCB(skb).fp);
|
|
|
}
|
|
|
err = (flags & MSG_TRUNC) ? skb->len - skip : size;
|
|
|
|
|
|
- scm_recv(sock, msg, siocb->scm, flags);
|
|
|
+ scm_recv(sock, msg, &scm, flags);
|
|
|
|
|
|
out_free:
|
|
|
skb_free_datagram(sk, skb);
|
|
|
@@ -1915,8 +1904,7 @@ static int unix_stream_recvmsg(struct kiocb *iocb, struct socket *sock,
|
|
|
struct msghdr *msg, size_t size,
|
|
|
int flags)
|
|
|
{
|
|
|
- struct sock_iocb *siocb = kiocb_to_siocb(iocb);
|
|
|
- struct scm_cookie tmp_scm;
|
|
|
+ struct scm_cookie scm;
|
|
|
struct sock *sk = sock->sk;
|
|
|
struct unix_sock *u = unix_sk(sk);
|
|
|
DECLARE_SOCKADDR(struct sockaddr_un *, sunaddr, msg->msg_name);
|
|
|
@@ -1943,10 +1931,7 @@ static int unix_stream_recvmsg(struct kiocb *iocb, struct socket *sock,
|
|
|
* while sleeps in memcpy_tomsg
|
|
|
*/
|
|
|
|
|
|
- if (!siocb->scm) {
|
|
|
- siocb->scm = &tmp_scm;
|
|
|
- memset(&tmp_scm, 0, sizeof(tmp_scm));
|
|
|
- }
|
|
|
+ memset(&scm, 0, sizeof(scm));
|
|
|
|
|
|
err = mutex_lock_interruptible(&u->readlock);
|
|
|
if (unlikely(err)) {
|
|
|
@@ -2012,13 +1997,13 @@ 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) ||
|
|
|
- !uid_eq(UNIXCB(skb).uid, siocb->scm->creds.uid) ||
|
|
|
- !gid_eq(UNIXCB(skb).gid, siocb->scm->creds.gid))
|
|
|
+ if ((UNIXCB(skb).pid != scm.pid) ||
|
|
|
+ !uid_eq(UNIXCB(skb).uid, scm.creds.uid) ||
|
|
|
+ !gid_eq(UNIXCB(skb).gid, scm.creds.gid))
|
|
|
break;
|
|
|
} else if (test_bit(SOCK_PASSCRED, &sock->flags)) {
|
|
|
/* Copy credentials */
|
|
|
- scm_set_cred(siocb->scm, UNIXCB(skb).pid, UNIXCB(skb).uid, UNIXCB(skb).gid);
|
|
|
+ scm_set_cred(&scm, UNIXCB(skb).pid, UNIXCB(skb).uid, UNIXCB(skb).gid);
|
|
|
check_creds = 1;
|
|
|
}
|
|
|
|
|
|
@@ -2045,7 +2030,7 @@ static int unix_stream_recvmsg(struct kiocb *iocb, struct socket *sock,
|
|
|
sk_peek_offset_bwd(sk, chunk);
|
|
|
|
|
|
if (UNIXCB(skb).fp)
|
|
|
- unix_detach_fds(siocb->scm, skb);
|
|
|
+ unix_detach_fds(&scm, skb);
|
|
|
|
|
|
if (unix_skb_len(skb))
|
|
|
break;
|
|
|
@@ -2053,13 +2038,13 @@ static int unix_stream_recvmsg(struct kiocb *iocb, struct socket *sock,
|
|
|
skb_unlink(skb, &sk->sk_receive_queue);
|
|
|
consume_skb(skb);
|
|
|
|
|
|
- if (siocb->scm->fp)
|
|
|
+ if (scm.fp)
|
|
|
break;
|
|
|
} else {
|
|
|
/* It is questionable, see note in unix_dgram_recvmsg.
|
|
|
*/
|
|
|
if (UNIXCB(skb).fp)
|
|
|
- siocb->scm->fp = scm_fp_dup(UNIXCB(skb).fp);
|
|
|
+ scm.fp = scm_fp_dup(UNIXCB(skb).fp);
|
|
|
|
|
|
sk_peek_offset_fwd(sk, chunk);
|
|
|
|
|
|
@@ -2068,7 +2053,7 @@ static int unix_stream_recvmsg(struct kiocb *iocb, struct socket *sock,
|
|
|
} while (size);
|
|
|
|
|
|
mutex_unlock(&u->readlock);
|
|
|
- scm_recv(sock, msg, siocb->scm, flags);
|
|
|
+ scm_recv(sock, msg, &scm, flags);
|
|
|
out:
|
|
|
return copied ? : err;
|
|
|
}
|