Skip to content

Commit 98e3862

Browse files
congwangdavem330
authored andcommitted
kcm: fix 0-length case for kcm_sendmsg()
Dmitry reported a kernel warning: WARNING: CPU: 3 PID: 2936 at net/kcm/kcmsock.c:627 kcm_write_msgs+0x12e3/0x1b90 net/kcm/kcmsock.c:627 CPU: 3 PID: 2936 Comm: a.out Not tainted 4.10.0-rc6+ #209 Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS Bochs 01/01/2011 Call Trace: __dump_stack lib/dump_stack.c:15 [inline] dump_stack+0x2ee/0x3ef lib/dump_stack.c:51 panic+0x1fb/0x412 kernel/panic.c:179 __warn+0x1c4/0x1e0 kernel/panic.c:539 warn_slowpath_null+0x2c/0x40 kernel/panic.c:582 kcm_write_msgs+0x12e3/0x1b90 net/kcm/kcmsock.c:627 kcm_sendmsg+0x163a/0x2200 net/kcm/kcmsock.c:1029 sock_sendmsg_nosec net/socket.c:635 [inline] sock_sendmsg+0xca/0x110 net/socket.c:645 sock_write_iter+0x326/0x600 net/socket.c:848 new_sync_write fs/read_write.c:499 [inline] __vfs_write+0x483/0x740 fs/read_write.c:512 vfs_write+0x187/0x530 fs/read_write.c:560 SYSC_write fs/read_write.c:607 [inline] SyS_write+0xfb/0x230 fs/read_write.c:599 entry_SYSCALL_64_fastpath+0x1f/0xc2 when calling syscall(__NR_write, sock2, 0x208aaf27ul, 0x0ul) on a KCM seqpacket socket. It appears that kcm_sendmsg() does not handle len==0 case correctly, which causes an empty skb is allocated and queued. Fix this by skipping the skb allocation for len==0 case. Reported-by: Dmitry Vyukov <[email protected]> Cc: Tom Herbert <[email protected]> Signed-off-by: Cong Wang <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent 538d929 commit 98e3862

File tree

1 file changed

+22
-18
lines changed

1 file changed

+22
-18
lines changed

net/kcm/kcmsock.c

Lines changed: 22 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -929,23 +929,25 @@ static int kcm_sendmsg(struct socket *sock, struct msghdr *msg, size_t len)
929929
goto out_error;
930930
}
931931

932-
/* New message, alloc head skb */
933-
head = alloc_skb(0, sk->sk_allocation);
934-
while (!head) {
935-
kcm_push(kcm);
936-
err = sk_stream_wait_memory(sk, &timeo);
937-
if (err)
938-
goto out_error;
939-
932+
if (msg_data_left(msg)) {
933+
/* New message, alloc head skb */
940934
head = alloc_skb(0, sk->sk_allocation);
941-
}
935+
while (!head) {
936+
kcm_push(kcm);
937+
err = sk_stream_wait_memory(sk, &timeo);
938+
if (err)
939+
goto out_error;
942940

943-
skb = head;
941+
head = alloc_skb(0, sk->sk_allocation);
942+
}
944943

945-
/* Set ip_summed to CHECKSUM_UNNECESSARY to avoid calling
946-
* csum_and_copy_from_iter from skb_do_copy_data_nocache.
947-
*/
948-
skb->ip_summed = CHECKSUM_UNNECESSARY;
944+
skb = head;
945+
946+
/* Set ip_summed to CHECKSUM_UNNECESSARY to avoid calling
947+
* csum_and_copy_from_iter from skb_do_copy_data_nocache.
948+
*/
949+
skb->ip_summed = CHECKSUM_UNNECESSARY;
950+
}
949951

950952
start:
951953
while (msg_data_left(msg)) {
@@ -1018,10 +1020,12 @@ static int kcm_sendmsg(struct socket *sock, struct msghdr *msg, size_t len)
10181020
if (eor) {
10191021
bool not_busy = skb_queue_empty(&sk->sk_write_queue);
10201022

1021-
/* Message complete, queue it on send buffer */
1022-
__skb_queue_tail(&sk->sk_write_queue, head);
1023-
kcm->seq_skb = NULL;
1024-
KCM_STATS_INCR(kcm->stats.tx_msgs);
1023+
if (head) {
1024+
/* Message complete, queue it on send buffer */
1025+
__skb_queue_tail(&sk->sk_write_queue, head);
1026+
kcm->seq_skb = NULL;
1027+
KCM_STATS_INCR(kcm->stats.tx_msgs);
1028+
}
10251029

10261030
if (msg->msg_flags & MSG_BATCH) {
10271031
kcm->tx_wait_more = true;

0 commit comments

Comments
 (0)