aboutsummaryrefslogtreecommitdiffstats
path: root/net/tipc/port.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/tipc/port.c')
-rw-r--r--net/tipc/port.c59
1 files changed, 30 insertions, 29 deletions
diff --git a/net/tipc/port.c b/net/tipc/port.c
index f1f6b33f761c..616c72fb9234 100644
--- a/net/tipc/port.c
+++ b/net/tipc/port.c
@@ -69,6 +69,28 @@ static inline u32 port_peerport(struct tipc_port *p_ptr)
69 return msg_destport(&p_ptr->phdr); 69 return msg_destport(&p_ptr->phdr);
70} 70}
71 71
72/*
73 * tipc_port_peer_msg - verify message was sent by connected port's peer
74 *
75 * Handles cases where the node's network address has changed from
76 * the default of <0.0.0> to its configured setting.
77 */
78
79int tipc_port_peer_msg(struct tipc_port *p_ptr, struct tipc_msg *msg)
80{
81 u32 peernode;
82 u32 orignode;
83
84 if (msg_origport(msg) != port_peerport(p_ptr))
85 return 0;
86
87 orignode = msg_orignode(msg);
88 peernode = port_peernode(p_ptr);
89 return (orignode == peernode) ||
90 (!orignode && (peernode == tipc_own_addr)) ||
91 (!peernode && (orignode == tipc_own_addr));
92}
93
72/** 94/**
73 * tipc_multicast - send a multicast message to local and remote destinations 95 * tipc_multicast - send a multicast message to local and remote destinations
74 */ 96 */
@@ -526,25 +548,21 @@ void tipc_port_recv_proto_msg(struct sk_buff *buf)
526 struct tipc_msg *msg = buf_msg(buf); 548 struct tipc_msg *msg = buf_msg(buf);
527 struct tipc_port *p_ptr; 549 struct tipc_port *p_ptr;
528 struct sk_buff *r_buf = NULL; 550 struct sk_buff *r_buf = NULL;
529 u32 orignode = msg_orignode(msg);
530 u32 origport = msg_origport(msg);
531 u32 destport = msg_destport(msg); 551 u32 destport = msg_destport(msg);
532 int wakeable; 552 int wakeable;
533 553
534 /* Validate connection */ 554 /* Validate connection */
535 555
536 p_ptr = tipc_port_lock(destport); 556 p_ptr = tipc_port_lock(destport);
537 if (!p_ptr || !p_ptr->connected || 557 if (!p_ptr || !p_ptr->connected || !tipc_port_peer_msg(p_ptr, msg)) {
538 (port_peernode(p_ptr) != orignode) ||
539 (port_peerport(p_ptr) != origport)) {
540 r_buf = tipc_buf_acquire(BASIC_H_SIZE); 558 r_buf = tipc_buf_acquire(BASIC_H_SIZE);
541 if (r_buf) { 559 if (r_buf) {
542 msg = buf_msg(r_buf); 560 msg = buf_msg(r_buf);
543 tipc_msg_init(msg, TIPC_HIGH_IMPORTANCE, TIPC_CONN_MSG, 561 tipc_msg_init(msg, TIPC_HIGH_IMPORTANCE, TIPC_CONN_MSG,
544 BASIC_H_SIZE, orignode); 562 BASIC_H_SIZE, msg_orignode(msg));
545 msg_set_errcode(msg, TIPC_ERR_NO_PORT); 563 msg_set_errcode(msg, TIPC_ERR_NO_PORT);
546 msg_set_origport(msg, destport); 564 msg_set_origport(msg, destport);
547 msg_set_destport(msg, origport); 565 msg_set_destport(msg, msg_origport(msg));
548 } 566 }
549 if (p_ptr) 567 if (p_ptr)
550 tipc_port_unlock(p_ptr); 568 tipc_port_unlock(p_ptr);
@@ -681,6 +699,7 @@ static void port_dispatcher_sigh(void *dummy)
681 struct tipc_name_seq dseq; 699 struct tipc_name_seq dseq;
682 void *usr_handle; 700 void *usr_handle;
683 int connected; 701 int connected;
702 int peer_invalid;
684 int published; 703 int published;
685 u32 message_type; 704 u32 message_type;
686 705
@@ -701,6 +720,7 @@ static void port_dispatcher_sigh(void *dummy)
701 up_ptr = p_ptr->user_port; 720 up_ptr = p_ptr->user_port;
702 usr_handle = up_ptr->usr_handle; 721 usr_handle = up_ptr->usr_handle;
703 connected = p_ptr->connected; 722 connected = p_ptr->connected;
723 peer_invalid = connected && !tipc_port_peer_msg(p_ptr, msg);
704 published = p_ptr->published; 724 published = p_ptr->published;
705 725
706 if (unlikely(msg_errcode(msg))) 726 if (unlikely(msg_errcode(msg)))
@@ -710,8 +730,6 @@ static void port_dispatcher_sigh(void *dummy)
710 730
711 case TIPC_CONN_MSG:{ 731 case TIPC_CONN_MSG:{
712 tipc_conn_msg_event cb = up_ptr->conn_msg_cb; 732 tipc_conn_msg_event cb = up_ptr->conn_msg_cb;
713 u32 peer_port = port_peerport(p_ptr);
714 u32 peer_node = port_peernode(p_ptr);
715 u32 dsz; 733 u32 dsz;
716 734
717 tipc_port_unlock(p_ptr); 735 tipc_port_unlock(p_ptr);
@@ -720,8 +738,7 @@ static void port_dispatcher_sigh(void *dummy)
720 if (unlikely(!connected)) { 738 if (unlikely(!connected)) {
721 if (tipc_connect2port(dref, &orig)) 739 if (tipc_connect2port(dref, &orig))
722 goto reject; 740 goto reject;
723 } else if ((msg_origport(msg) != peer_port) || 741 } else if (peer_invalid)
724 (msg_orignode(msg) != peer_node))
725 goto reject; 742 goto reject;
726 dsz = msg_data_sz(msg); 743 dsz = msg_data_sz(msg);
727 if (unlikely(dsz && 744 if (unlikely(dsz &&
@@ -773,14 +790,9 @@ err:
773 case TIPC_CONN_MSG:{ 790 case TIPC_CONN_MSG:{
774 tipc_conn_shutdown_event cb = 791 tipc_conn_shutdown_event cb =
775 up_ptr->conn_err_cb; 792 up_ptr->conn_err_cb;
776 u32 peer_port = port_peerport(p_ptr);
777 u32 peer_node = port_peernode(p_ptr);
778 793
779 tipc_port_unlock(p_ptr); 794 tipc_port_unlock(p_ptr);
780 if (!cb || !connected) 795 if (!cb || !connected || peer_invalid)
781 break;
782 if ((msg_origport(msg) != peer_port) ||
783 (msg_orignode(msg) != peer_node))
784 break; 796 break;
785 tipc_disconnect(dref); 797 tipc_disconnect(dref);
786 skb_pull(buf, msg_hdr_sz(msg)); 798 skb_pull(buf, msg_hdr_sz(msg));
@@ -1157,17 +1169,6 @@ int tipc_port_recv_msg(struct sk_buff *buf)
1157 /* validate destination & pass to port, otherwise reject message */ 1169 /* validate destination & pass to port, otherwise reject message */
1158 p_ptr = tipc_port_lock(destport); 1170 p_ptr = tipc_port_lock(destport);
1159 if (likely(p_ptr)) { 1171 if (likely(p_ptr)) {
1160 if (likely(p_ptr->connected)) {
1161 if ((unlikely(msg_origport(msg) !=
1162 port_peerport(p_ptr))) ||
1163 (unlikely(msg_orignode(msg) !=
1164 port_peernode(p_ptr))) ||
1165 (unlikely(!msg_connected(msg)))) {
1166 err = TIPC_ERR_NO_PORT;
1167 tipc_port_unlock(p_ptr);
1168 goto reject;
1169 }
1170 }
1171 err = p_ptr->dispatcher(p_ptr, buf); 1172 err = p_ptr->dispatcher(p_ptr, buf);
1172 tipc_port_unlock(p_ptr); 1173 tipc_port_unlock(p_ptr);
1173 if (likely(!err)) 1174 if (likely(!err))
@@ -1175,7 +1176,7 @@ int tipc_port_recv_msg(struct sk_buff *buf)
1175 } else { 1176 } else {
1176 err = TIPC_ERR_NO_PORT; 1177 err = TIPC_ERR_NO_PORT;
1177 } 1178 }
1178reject: 1179
1179 return tipc_reject_msg(buf, err); 1180 return tipc_reject_msg(buf, err);
1180} 1181}
1181 1182