Skip to content

Commit a33ef50

Browse files
committed
Merge: [s390] s390/iucv: MSG_PEEK causes memory leak in iucv_sock_destruct()
MR: https://gitlab.com/redhat/centos-stream/src/kernel/centos-stream-10/-/merge_requests/215 JIRA: https://issues.redhat.com/browse/RHEL-74386 Tested-by: IBM commits: ``` ebaf813 ``` Signed-off-by: Mete Durlu <mdurlu@redhat.com> Approved-by: Steve Best <sbest@redhat.com> Approved-by: Tony Camuso <tcamuso@redhat.com> Approved-by: CKI KWF Bot <cki-ci-bot+kwf-gitlab-com@redhat.com> Merged-by: Jan Stancek <jstancek@redhat.com>
2 parents bced22d + ea2965a commit a33ef50

File tree

1 file changed

+17
-9
lines changed

1 file changed

+17
-9
lines changed

net/iucv/af_iucv.c

Lines changed: 17 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1236,7 +1236,9 @@ static int iucv_sock_recvmsg(struct socket *sock, struct msghdr *msg,
12361236
return -EOPNOTSUPP;
12371237

12381238
/* receive/dequeue next skb:
1239-
* the function understands MSG_PEEK and, thus, does not dequeue skb */
1239+
* the function understands MSG_PEEK and, thus, does not dequeue skb
1240+
* only refcount is increased.
1241+
*/
12401242
skb = skb_recv_datagram(sk, flags, &err);
12411243
if (!skb) {
12421244
if (sk->sk_shutdown & RCV_SHUTDOWN)
@@ -1252,9 +1254,8 @@ static int iucv_sock_recvmsg(struct socket *sock, struct msghdr *msg,
12521254

12531255
cskb = skb;
12541256
if (skb_copy_datagram_msg(cskb, offset, msg, copied)) {
1255-
if (!(flags & MSG_PEEK))
1256-
skb_queue_head(&sk->sk_receive_queue, skb);
1257-
return -EFAULT;
1257+
err = -EFAULT;
1258+
goto err_out;
12581259
}
12591260

12601261
/* SOCK_SEQPACKET: set MSG_TRUNC if recv buf size is too small */
@@ -1271,11 +1272,8 @@ static int iucv_sock_recvmsg(struct socket *sock, struct msghdr *msg,
12711272
err = put_cmsg(msg, SOL_IUCV, SCM_IUCV_TRGCLS,
12721273
sizeof(IUCV_SKB_CB(skb)->class),
12731274
(void *)&IUCV_SKB_CB(skb)->class);
1274-
if (err) {
1275-
if (!(flags & MSG_PEEK))
1276-
skb_queue_head(&sk->sk_receive_queue, skb);
1277-
return err;
1278-
}
1275+
if (err)
1276+
goto err_out;
12791277

12801278
/* Mark read part of skb as used */
12811279
if (!(flags & MSG_PEEK)) {
@@ -1331,8 +1329,18 @@ static int iucv_sock_recvmsg(struct socket *sock, struct msghdr *msg,
13311329
/* SOCK_SEQPACKET: return real length if MSG_TRUNC is set */
13321330
if (sk->sk_type == SOCK_SEQPACKET && (flags & MSG_TRUNC))
13331331
copied = rlen;
1332+
if (flags & MSG_PEEK)
1333+
skb_unref(skb);
13341334

13351335
return copied;
1336+
1337+
err_out:
1338+
if (!(flags & MSG_PEEK))
1339+
skb_queue_head(&sk->sk_receive_queue, skb);
1340+
else
1341+
skb_unref(skb);
1342+
1343+
return err;
13361344
}
13371345

13381346
static inline __poll_t iucv_accept_poll(struct sock *parent)

0 commit comments

Comments
 (0)