summaryrefslogtreecommitdiff
path: root/usr/src
diff options
context:
space:
mode:
authorDan McDonald <danmcd@nexenta.com>2011-10-24 11:42:57 -0400
committerDan McDonald <danmcd@nexenta.com>2011-10-24 11:42:57 -0400
commitf2297e9296e52199b01691617a851111fa19a0b2 (patch)
tree08f9c751c7ab8a3b2efe38fbf9ff8441550a9c25 /usr/src
parent383e7c74ff3827d20f23fa87e37bd52d86fc1a26 (diff)
downloadillumos-joyent-f2297e9296e52199b01691617a851111fa19a0b2.tar.gz
1631 kernel panic in tcp_input_data
Reviewed by: Garrett D'Amore <gdamore@nexenta.com> Reviewed by: Richard Lowe <richlowe@richlowe.net> Approved by: Richard Lowe <richlowe@richlowe.net>
Diffstat (limited to 'usr/src')
-rw-r--r--usr/src/uts/common/inet/tcp/tcp_input.c134
-rw-r--r--usr/src/uts/intel/ip/ip.global-objs.debug642
-rw-r--r--usr/src/uts/intel/ip/ip.global-objs.obj642
-rw-r--r--usr/src/uts/sparc/ip/ip.global-objs.debug642
-rw-r--r--usr/src/uts/sparc/ip/ip.global-objs.obj642
5 files changed, 131 insertions, 11 deletions
diff --git a/usr/src/uts/common/inet/tcp/tcp_input.c b/usr/src/uts/common/inet/tcp/tcp_input.c
index 831ebc7ba5..918412d03a 100644
--- a/usr/src/uts/common/inet/tcp/tcp_input.c
+++ b/usr/src/uts/common/inet/tcp/tcp_input.c
@@ -21,6 +21,7 @@
/*
* Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright 2011 Nexenta Systems, Inc. All rights reserved.
*/
/* This file contains all TCP input processing functions. */
@@ -2230,6 +2231,114 @@ tcp_ack_mp(tcp_t *tcp)
}
/*
+ * Dummy socket upcalls for if/when the conn_t gets detached from a
+ * direct-callback sonode via a user-driven close(). Easy to catch with
+ * DTrace FBT, and should be mostly harmless.
+ */
+
+/* ARGSUSED */
+static sock_upper_handle_t
+tcp_dummy_newconn(sock_upper_handle_t x, sock_lower_handle_t y,
+ sock_downcalls_t *z, cred_t *cr, pid_t pid, sock_upcalls_t **ignored)
+{
+ ASSERT(0); /* Panic in debug, otherwise ignore. */
+ return (NULL);
+}
+
+/* ARGSUSED */
+static void
+tcp_dummy_connected(sock_upper_handle_t x, sock_connid_t y, cred_t *cr,
+ pid_t pid)
+{
+ ASSERT(x == NULL);
+ /* Normally we'd crhold(cr) and attach it to socket state. */
+ /* LINTED */
+}
+
+/* ARGSUSED */
+static int
+tcp_dummy_disconnected(sock_upper_handle_t x, sock_connid_t y, int blah)
+{
+ ASSERT(0); /* Panic in debug, otherwise ignore. */
+ return (-1);
+}
+
+/* ARGSUSED */
+static void
+tcp_dummy_opctl(sock_upper_handle_t x, sock_opctl_action_t y, uintptr_t blah)
+{
+ ASSERT(x == NULL);
+ /* We really want this one to be a harmless NOP for now. */
+ /* LINTED */
+}
+
+/* ARGSUSED */
+static ssize_t
+tcp_dummy_recv(sock_upper_handle_t x, mblk_t *mp, size_t len, int flags,
+ int *error, boolean_t *push)
+{
+ ASSERT(x == NULL);
+
+ /*
+ * Consume the message, set ESHUTDOWN, and return an error.
+ * Nobody's home!
+ */
+ freemsg(mp);
+ *error = ESHUTDOWN;
+ return (-1);
+}
+
+/* ARGSUSED */
+static void
+tcp_dummy_set_proto_props(sock_upper_handle_t x, struct sock_proto_props *y)
+{
+ ASSERT(0); /* Panic in debug, otherwise ignore. */
+}
+
+/* ARGSUSED */
+static void
+tcp_dummy_txq_full(sock_upper_handle_t x, boolean_t y)
+{
+ ASSERT(0); /* Panic in debug, otherwise ignore. */
+}
+
+/* ARGSUSED */
+static void
+tcp_dummy_signal_oob(sock_upper_handle_t x, ssize_t len)
+{
+ ASSERT(x == NULL);
+ /* Otherwise, this would signal socket state about OOB data. */
+}
+
+/* ARGSUSED */
+static void
+tcp_dummy_set_error(sock_upper_handle_t x, int err)
+{
+ ASSERT(0); /* Panic in debug, otherwise ignore. */
+}
+
+/* ARGSUSED */
+static void
+tcp_dummy_onearg(sock_upper_handle_t x)
+{
+ ASSERT(0); /* Panic in debug, otherwise ignore. */
+}
+
+static sock_upcalls_t tcp_dummy_upcalls = {
+ tcp_dummy_newconn,
+ tcp_dummy_connected,
+ tcp_dummy_disconnected,
+ tcp_dummy_opctl,
+ tcp_dummy_recv,
+ tcp_dummy_set_proto_props,
+ tcp_dummy_txq_full,
+ tcp_dummy_signal_oob,
+ tcp_dummy_onearg,
+ tcp_dummy_set_error,
+ tcp_dummy_onearg
+};
+
+/*
* Handle M_DATA messages from IP. Its called directly from IP via
* squeue for received IP packets.
*
@@ -2271,6 +2380,7 @@ tcp_input_data(void *arg, mblk_t *mp, void *arg2, ip_recv_attr_t *ira)
squeue_t *sqp = (squeue_t *)arg2;
tcp_t *tcp = connp->conn_tcp;
tcp_stack_t *tcps = tcp->tcp_tcps;
+ sock_upcalls_t *sockupcalls;
/*
* RST from fused tcp loopback peer should trigger an unfuse.
@@ -2396,6 +2506,11 @@ tcp_input_data(void *arg, mblk_t *mp, void *arg2, ip_recv_attr_t *ira)
}
}
+ sockupcalls = connp->conn_upcalls;
+ /* A conn_t may have belonged to a now-closed socket. Be careful. */
+ if (sockupcalls == NULL)
+ sockupcalls = &tcp_dummy_upcalls;
+
switch (tcp->tcp_state) {
case TCPS_SYN_SENT:
if (connp->conn_final_sqp == NULL &&
@@ -2607,8 +2722,7 @@ tcp_input_data(void *arg, mblk_t *mp, void *arg2, ip_recv_attr_t *ira)
}
putnext(connp->conn_rq, mp1);
} else {
- (*connp->conn_upcalls->
- su_connected)
+ (*sockupcalls->su_connected)
(connp->conn_upper_handle,
tcp->tcp_connid,
ira->ira_cred,
@@ -2635,7 +2749,7 @@ tcp_input_data(void *arg, mblk_t *mp, void *arg2, ip_recv_attr_t *ira)
}
putnext(connp->conn_rq, mp1);
} else {
- (*connp->conn_upcalls->su_connected)
+ (*sockupcalls->su_connected)
(connp->conn_upper_handle,
tcp->tcp_connid, ira->ira_cred,
ira->ira_cpid);
@@ -3009,8 +3123,7 @@ try_again:;
tcp->tcp_urp_last))) {
if (IPCL_IS_NONSTR(connp)) {
if (!TCP_IS_DETACHED(tcp)) {
- (*connp->conn_upcalls->
- su_signal_oob)
+ (*sockupcalls->su_signal_oob)
(connp->conn_upper_handle,
urp);
}
@@ -3288,7 +3401,7 @@ ok:;
*/
if (IPCL_IS_NONSTR(connp)) {
if (!TCP_IS_DETACHED(tcp)) {
- (*connp->conn_upcalls->su_signal_oob)
+ (*sockupcalls->su_signal_oob)
(connp->conn_upper_handle, urp);
}
} else {
@@ -3447,7 +3560,7 @@ ok:;
if (IPCL_IS_NONSTR(connp)) {
int error;
- (*connp->conn_upcalls->su_recv)
+ (*sockupcalls->su_recv)
(connp->conn_upper_handle, mp, seg_len,
MSG_OOB, &error, NULL);
/*
@@ -4626,8 +4739,7 @@ update_ack:
boolean_t push = flags & (TH_PUSH|TH_FIN);
int error;
- if ((*connp->conn_upcalls->su_recv)(
- connp->conn_upper_handle,
+ if ((*sockupcalls->su_recv)(connp->conn_upper_handle,
mp, seg_len, 0, &error, &push) <= 0) {
/*
* We should never be in middle of a
@@ -4869,8 +4981,8 @@ ack_check:
if (IPCL_IS_NONSTR(connp)) {
ASSERT(tcp->tcp_ordrel_mp == NULL);
tcp->tcp_ordrel_done = B_TRUE;
- (*connp->conn_upcalls->su_opctl)
- (connp->conn_upper_handle, SOCK_OPCTL_SHUT_RECV, 0);
+ (*sockupcalls->su_opctl)(connp->conn_upper_handle,
+ SOCK_OPCTL_SHUT_RECV, 0);
goto done;
}
diff --git a/usr/src/uts/intel/ip/ip.global-objs.debug64 b/usr/src/uts/intel/ip/ip.global-objs.debug64
index 7062aac6db..40d5bd498b 100644
--- a/usr/src/uts/intel/ip/ip.global-objs.debug64
+++ b/usr/src/uts/intel/ip/ip.global-objs.debug64
@@ -20,6 +20,7 @@
#
#
# Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
+# Copyright 2011 Nexenta Systems, Inc. All rights reserved
#
arp_m_tbl
@@ -253,6 +254,7 @@ tcp_conn_cache
tcp_conn_hash_size
tcp_do_reclaim
tcp_drop_ack_unsent_cnt
+tcp_dummy_upcalls
tcp_early_abort
tcp_fallback_sock_winit
tcp_free_list_max_cnt
diff --git a/usr/src/uts/intel/ip/ip.global-objs.obj64 b/usr/src/uts/intel/ip/ip.global-objs.obj64
index 6c095dd832..5c56fe7efd 100644
--- a/usr/src/uts/intel/ip/ip.global-objs.obj64
+++ b/usr/src/uts/intel/ip/ip.global-objs.obj64
@@ -20,6 +20,7 @@
#
#
# Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
+# Copyright 2011 Nexenta Systems, Inc. All rights reserved
#
arp_m_tbl
@@ -250,6 +251,7 @@ tcp_conn_cache
tcp_conn_hash_size
tcp_do_reclaim
tcp_drop_ack_unsent_cnt
+tcp_dummy_upcalls
tcp_early_abort
tcp_fallback_sock_winit
tcp_free_list_max_cnt
diff --git a/usr/src/uts/sparc/ip/ip.global-objs.debug64 b/usr/src/uts/sparc/ip/ip.global-objs.debug64
index 7062aac6db..40d5bd498b 100644
--- a/usr/src/uts/sparc/ip/ip.global-objs.debug64
+++ b/usr/src/uts/sparc/ip/ip.global-objs.debug64
@@ -20,6 +20,7 @@
#
#
# Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
+# Copyright 2011 Nexenta Systems, Inc. All rights reserved
#
arp_m_tbl
@@ -253,6 +254,7 @@ tcp_conn_cache
tcp_conn_hash_size
tcp_do_reclaim
tcp_drop_ack_unsent_cnt
+tcp_dummy_upcalls
tcp_early_abort
tcp_fallback_sock_winit
tcp_free_list_max_cnt
diff --git a/usr/src/uts/sparc/ip/ip.global-objs.obj64 b/usr/src/uts/sparc/ip/ip.global-objs.obj64
index 6c095dd832..5c56fe7efd 100644
--- a/usr/src/uts/sparc/ip/ip.global-objs.obj64
+++ b/usr/src/uts/sparc/ip/ip.global-objs.obj64
@@ -20,6 +20,7 @@
#
#
# Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
+# Copyright 2011 Nexenta Systems, Inc. All rights reserved
#
arp_m_tbl
@@ -250,6 +251,7 @@ tcp_conn_cache
tcp_conn_hash_size
tcp_do_reclaim
tcp_drop_ack_unsent_cnt
+tcp_dummy_upcalls
tcp_early_abort
tcp_fallback_sock_winit
tcp_free_list_max_cnt