diff options
Diffstat (limited to 'net/tipc/port.c')
-rw-r--r-- | net/tipc/port.c | 59 |
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 | |||
79 | int 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 | } |
1178 | reject: | 1179 | |
1179 | return tipc_reject_msg(buf, err); | 1180 | return tipc_reject_msg(buf, err); |
1180 | } | 1181 | } |
1181 | 1182 | ||