Skip to content

Commit 5cbb96e

Browse files
author
Herton R. Krzesinski
committed
Merge: tipc: backports from upstream, 2nd phase
MR: https://gitlab.com/redhat/centos-stream/src/kernel/centos-stream-9/-/merge_requests/1879 Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=2160540 Tested: tipcutils v1-v2: - Append two more patches. Signed-off-by: Xin Long <lxin@redhat.com> Approved-by: Jon Maloy <jmaloy@redhat.com> Approved-by: Hangbin Liu <haliu@redhat.com> Signed-off-by: Herton R. Krzesinski <herton@redhat.com>
2 parents b1fdcdb + 8c652cb commit 5cbb96e

File tree

6 files changed

+75
-30
lines changed

6 files changed

+75
-30
lines changed

net/tipc/discover.c

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -211,7 +211,10 @@ void tipc_disc_rcv(struct net *net, struct sk_buff *skb,
211211
u32 self;
212212
int err;
213213

214-
skb_linearize(skb);
214+
if (skb_linearize(skb)) {
215+
kfree_skb(skb);
216+
return;
217+
}
215218
hdr = buf_msg(skb);
216219

217220
if (caps & TIPC_NODE_ID128)

net/tipc/link.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2224,7 +2224,9 @@ static int tipc_link_proto_rcv(struct tipc_link *l, struct sk_buff *skb,
22242224
if (tipc_own_addr(l->net) > msg_prevnode(hdr))
22252225
l->net_plane = msg_net_plane(hdr);
22262226

2227-
skb_linearize(skb);
2227+
if (skb_linearize(skb))
2228+
goto exit;
2229+
22282230
hdr = buf_msg(skb);
22292231
data = msg_data(hdr);
22302232

net/tipc/netlink_compat.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -880,7 +880,7 @@ static int tipc_nl_compat_name_table_dump_header(struct tipc_nl_compat_msg *msg)
880880
};
881881

882882
ntq = (struct tipc_name_table_query *)TLV_DATA(msg->req);
883-
if (TLV_GET_DATA_LEN(msg->req) < sizeof(struct tipc_name_table_query))
883+
if (TLV_GET_DATA_LEN(msg->req) < (int)sizeof(struct tipc_name_table_query))
884884
return -EINVAL;
885885

886886
depth = ntohl(ntq->depth);

net/tipc/node.c

Lines changed: 17 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1179,8 +1179,9 @@ void tipc_node_check_dest(struct net *net, u32 addr,
11791179
bool addr_match = false;
11801180
bool sign_match = false;
11811181
bool link_up = false;
1182+
bool link_is_reset = false;
11821183
bool accept_addr = false;
1183-
bool reset = true;
1184+
bool reset = false;
11841185
char *if_name;
11851186
unsigned long intv;
11861187
u16 session;
@@ -1200,14 +1201,14 @@ void tipc_node_check_dest(struct net *net, u32 addr,
12001201
/* Prepare to validate requesting node's signature and media address */
12011202
l = le->link;
12021203
link_up = l && tipc_link_is_up(l);
1204+
link_is_reset = l && tipc_link_is_reset(l);
12031205
addr_match = l && !memcmp(&le->maddr, maddr, sizeof(*maddr));
12041206
sign_match = (signature == n->signature);
12051207

12061208
/* These three flags give us eight permutations: */
12071209

12081210
if (sign_match && addr_match && link_up) {
1209-
/* All is fine. Do nothing. */
1210-
reset = false;
1211+
/* All is fine. Ignore requests. */
12111212
/* Peer node is not a container/local namespace */
12121213
if (!n->peer_hash_mix)
12131214
n->peer_hash_mix = hash_mixes;
@@ -1232,6 +1233,7 @@ void tipc_node_check_dest(struct net *net, u32 addr,
12321233
*/
12331234
accept_addr = true;
12341235
*respond = true;
1236+
reset = true;
12351237
} else if (!sign_match && addr_match && link_up) {
12361238
/* Peer node rebooted. Two possibilities:
12371239
* - Delayed re-discovery; this link endpoint has already
@@ -1263,6 +1265,7 @@ void tipc_node_check_dest(struct net *net, u32 addr,
12631265
n->signature = signature;
12641266
accept_addr = true;
12651267
*respond = true;
1268+
reset = true;
12661269
}
12671270

12681271
if (!accept_addr)
@@ -1291,6 +1294,7 @@ void tipc_node_check_dest(struct net *net, u32 addr,
12911294
tipc_link_fsm_evt(l, LINK_RESET_EVT);
12921295
if (n->state == NODE_FAILINGOVER)
12931296
tipc_link_fsm_evt(l, LINK_FAILOVER_BEGIN_EVT);
1297+
link_is_reset = tipc_link_is_reset(l);
12941298
le->link = l;
12951299
n->link_cnt++;
12961300
tipc_node_calculate_timer(n, l);
@@ -1303,7 +1307,7 @@ void tipc_node_check_dest(struct net *net, u32 addr,
13031307
memcpy(&le->maddr, maddr, sizeof(*maddr));
13041308
exit:
13051309
tipc_node_write_unlock(n);
1306-
if (reset && l && !tipc_link_is_reset(l))
1310+
if (reset && !link_is_reset)
13071311
tipc_node_link_down(n, b->identity, false);
13081312
tipc_node_put(n);
13091313
}
@@ -1689,6 +1693,7 @@ int tipc_node_xmit(struct net *net, struct sk_buff_head *list,
16891693
struct tipc_node *n;
16901694
struct sk_buff_head xmitq;
16911695
bool node_up = false;
1696+
struct net *peer_net;
16921697
int bearer_id;
16931698
int rc;
16941699

@@ -1705,18 +1710,23 @@ int tipc_node_xmit(struct net *net, struct sk_buff_head *list,
17051710
return -EHOSTUNREACH;
17061711
}
17071712

1713+
rcu_read_lock();
17081714
tipc_node_read_lock(n);
17091715
node_up = node_is_up(n);
1710-
if (node_up && n->peer_net && check_net(n->peer_net)) {
1716+
peer_net = n->peer_net;
1717+
tipc_node_read_unlock(n);
1718+
if (node_up && peer_net && check_net(peer_net)) {
17111719
/* xmit inner linux container */
1712-
tipc_lxc_xmit(n->peer_net, list);
1720+
tipc_lxc_xmit(peer_net, list);
17131721
if (likely(skb_queue_empty(list))) {
1714-
tipc_node_read_unlock(n);
1722+
rcu_read_unlock();
17151723
tipc_node_put(n);
17161724
return 0;
17171725
}
17181726
}
1727+
rcu_read_unlock();
17191728

1729+
tipc_node_read_lock(n);
17201730
bearer_id = n->active_links[selector & 1];
17211731
if (unlikely(bearer_id == INVALID_BEARER_ID)) {
17221732
tipc_node_read_unlock(n);

net/tipc/socket.c

Lines changed: 27 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1889,6 +1889,7 @@ static int tipc_recvmsg(struct socket *sock, struct msghdr *m,
18891889
bool connected = !tipc_sk_type_connectionless(sk);
18901890
struct tipc_sock *tsk = tipc_sk(sk);
18911891
int rc, err, hlen, dlen, copy;
1892+
struct tipc_skb_cb *skb_cb;
18921893
struct sk_buff_head xmitq;
18931894
struct tipc_msg *hdr;
18941895
struct sk_buff *skb;
@@ -1912,6 +1913,7 @@ static int tipc_recvmsg(struct socket *sock, struct msghdr *m,
19121913
if (unlikely(rc))
19131914
goto exit;
19141915
skb = skb_peek(&sk->sk_receive_queue);
1916+
skb_cb = TIPC_SKB_CB(skb);
19151917
hdr = buf_msg(skb);
19161918
dlen = msg_data_sz(hdr);
19171919
hlen = msg_hdr_sz(hdr);
@@ -1931,18 +1933,33 @@ static int tipc_recvmsg(struct socket *sock, struct msghdr *m,
19311933

19321934
/* Capture data if non-error msg, otherwise just set return value */
19331935
if (likely(!err)) {
1934-
copy = min_t(int, dlen, buflen);
1935-
if (unlikely(copy != dlen))
1936-
m->msg_flags |= MSG_TRUNC;
1937-
rc = skb_copy_datagram_msg(skb, hlen, m, copy);
1936+
int offset = skb_cb->bytes_read;
1937+
1938+
copy = min_t(int, dlen - offset, buflen);
1939+
rc = skb_copy_datagram_msg(skb, hlen + offset, m, copy);
1940+
if (unlikely(rc))
1941+
goto exit;
1942+
if (unlikely(offset + copy < dlen)) {
1943+
if (flags & MSG_EOR) {
1944+
if (!(flags & MSG_PEEK))
1945+
skb_cb->bytes_read = offset + copy;
1946+
} else {
1947+
m->msg_flags |= MSG_TRUNC;
1948+
skb_cb->bytes_read = 0;
1949+
}
1950+
} else {
1951+
if (flags & MSG_EOR)
1952+
m->msg_flags |= MSG_EOR;
1953+
skb_cb->bytes_read = 0;
1954+
}
19381955
} else {
19391956
copy = 0;
19401957
rc = 0;
1941-
if (err != TIPC_CONN_SHUTDOWN && connected && !m->msg_control)
1958+
if (err != TIPC_CONN_SHUTDOWN && connected && !m->msg_control) {
19421959
rc = -ECONNRESET;
1960+
goto exit;
1961+
}
19431962
}
1944-
if (unlikely(rc))
1945-
goto exit;
19461963

19471964
/* Mark message as group event if applicable */
19481965
if (unlikely(grp_evt)) {
@@ -1965,6 +1982,9 @@ static int tipc_recvmsg(struct socket *sock, struct msghdr *m,
19651982
tipc_node_distr_xmit(sock_net(sk), &xmitq);
19661983
}
19671984

1985+
if (skb_cb->bytes_read)
1986+
goto exit;
1987+
19681988
tsk_advance_rx_queue(sk);
19691989

19701990
if (likely(!connected))

net/tipc/topsrv.c

Lines changed: 23 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -176,7 +176,7 @@ static void tipc_conn_close(struct tipc_conn *con)
176176
conn_put(con);
177177
}
178178

179-
static struct tipc_conn *tipc_conn_alloc(struct tipc_topsrv *s)
179+
static struct tipc_conn *tipc_conn_alloc(struct tipc_topsrv *s, struct socket *sock)
180180
{
181181
struct tipc_conn *con;
182182
int ret;
@@ -202,10 +202,12 @@ static struct tipc_conn *tipc_conn_alloc(struct tipc_topsrv *s)
202202
}
203203
con->conid = ret;
204204
s->idr_in_use++;
205-
spin_unlock_bh(&s->idr_lock);
206205

207206
set_bit(CF_CONNECTED, &con->flags);
208207
con->server = s;
208+
con->sock = sock;
209+
conn_get(con);
210+
spin_unlock_bh(&s->idr_lock);
209211

210212
return con;
211213
}
@@ -450,17 +452,24 @@ static void tipc_conn_data_ready(struct sock *sk)
450452
static void tipc_topsrv_accept(struct work_struct *work)
451453
{
452454
struct tipc_topsrv *srv = container_of(work, struct tipc_topsrv, awork);
453-
struct socket *lsock = srv->listener;
454-
struct socket *newsock;
455+
struct socket *newsock, *lsock;
455456
struct tipc_conn *con;
456457
struct sock *newsk;
457458
int ret;
458459

460+
spin_lock_bh(&srv->idr_lock);
461+
if (!srv->listener) {
462+
spin_unlock_bh(&srv->idr_lock);
463+
return;
464+
}
465+
lsock = srv->listener;
466+
spin_unlock_bh(&srv->idr_lock);
467+
459468
while (1) {
460469
ret = kernel_accept(lsock, &newsock, O_NONBLOCK);
461470
if (ret < 0)
462471
return;
463-
con = tipc_conn_alloc(srv);
472+
con = tipc_conn_alloc(srv, newsock);
464473
if (IS_ERR(con)) {
465474
ret = PTR_ERR(con);
466475
sock_release(newsock);
@@ -472,11 +481,11 @@ static void tipc_topsrv_accept(struct work_struct *work)
472481
newsk->sk_data_ready = tipc_conn_data_ready;
473482
newsk->sk_write_space = tipc_conn_write_space;
474483
newsk->sk_user_data = con;
475-
con->sock = newsock;
476484
write_unlock_bh(&newsk->sk_callback_lock);
477485

478486
/* Wake up receive process in case of 'SYN+' message */
479487
newsk->sk_data_ready(newsk);
488+
conn_put(con);
480489
}
481490
}
482491

@@ -489,7 +498,7 @@ static void tipc_topsrv_listener_data_ready(struct sock *sk)
489498

490499
read_lock_bh(&sk->sk_callback_lock);
491500
srv = sk->sk_user_data;
492-
if (srv->listener)
501+
if (srv)
493502
queue_work(srv->rcv_wq, &srv->awork);
494503
read_unlock_bh(&sk->sk_callback_lock);
495504
}
@@ -570,17 +579,17 @@ bool tipc_topsrv_kern_subscr(struct net *net, u32 port, u32 type, u32 lower,
570579
sub.filter = filter;
571580
*(u64 *)&sub.usr_handle = (u64)port;
572581

573-
con = tipc_conn_alloc(tipc_topsrv(net));
582+
con = tipc_conn_alloc(tipc_topsrv(net), NULL);
574583
if (IS_ERR(con))
575584
return false;
576585

577586
*conid = con->conid;
578-
con->sock = NULL;
579587
rc = tipc_conn_rcv_sub(tipc_topsrv(net), con, &sub);
580-
if (rc >= 0)
581-
return true;
588+
if (rc)
589+
conn_put(con);
590+
582591
conn_put(con);
583-
return false;
592+
return !rc;
584593
}
585594

586595
void tipc_topsrv_kern_unsubscr(struct net *net, int conid)
@@ -699,8 +708,9 @@ static void tipc_topsrv_stop(struct net *net)
699708
__module_get(lsock->sk->sk_prot_creator->owner);
700709
srv->listener = NULL;
701710
spin_unlock_bh(&srv->idr_lock);
702-
sock_release(lsock);
711+
703712
tipc_topsrv_work_stop(srv);
713+
sock_release(lsock);
704714
idr_destroy(&srv->conn_idr);
705715
kfree(srv);
706716
}

0 commit comments

Comments
 (0)