projects/linux·commit 045958ac

Merge tag 'net-7.3-rc8' of git://git.kernel.org/pub/scm/linux/kernel/git/netdev/net

045958ac · Linus Torvalds <[email protected]> · 2026-10-15 08:20:20 -07:00

Pull networking fixes from Paolo Abeni:
 "This is considerably smaller than in recent history, mostly due to
  reduced capacity and increased backlog. Also we actively redirected
  more stuff towards next. I'm not aware of any pending regression.

  Current release - regressions:

   - eth: move netops initialization to fix crash

  Previous releases - regressions:

   - sched: fix use-after-free in __tcf_action_put()

   - rds: fix uninitialized trans dereference in CM event handler

  Previous releases - always broken:

   - vsock: treat TCP_CLOSING as once-established

   - netlink: avoid hashing the network namespace pointer

   - eth: mlx5: HWS, release L2 to L3 tunnel reformats to their own pool"

* tag 'net-7.3-rc8' of git://git.kernel.org/pub/scm/linux/kernel/git/netdev/net: (23 commits)
  net: stmmac: dwmac1000: clear the RGMII status interrupt
  net/sched: fix use-after-free in __tcf_action_put()
  calipso: keep BIG TCP payload_len in calipso_skbuff_setattr()
  MAINTAINERS: add Gustavo Luiz Duarte as netconsole reviewer
  net: bcmgenet: unshare the skb before writing the control block
  microchip: lan865x: move setting of netops to fix crash
  net: ti: icssm-prueth: Move setting of netops to fix crash
  net: ethernet: aeroflex: move setting of netops to fix crash
  net: ethoc: move setting of netops to fix crash
  net: au1000: move setting of netops to fix crash
  net: mv643xx: move setting of netops to fix crash
  net: ethernet: adi: Move setting of netops to fix crash
  net: ethernet: actions: Move setting of netops to fix crash
  net: hisilicon: hip04_eth: Move setting of netops to fix crash
  net: hisilicon: hisi_femac: Move setting of netops to fix crash
  netlink: avoid hashing the network namespace pointer
  net/mlx5: HWS, fix flow meter offset within its bulk
  net/mlx5: HWS, release L2 to L3 tunnel reformats to their own pool
  netlink: reset skb headers before unicast and multicast filtering
  sctp: revalidate output stream after association connect wait
  ...
Commit
045958acaa75205b31578cb22c4345e28dd2e4bf
Parents
9aa622db · aa072857

Merge commit. Changes below are compared with the first parent: 9aa622db.

Changes

20 files changed · +117 −51

MAINTAINERS

View file
diff --git a/MAINTAINERS b/MAINTAINERS
index c39194e..5d39ec6 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -18815,6 +18815,7 @@ F: drivers/hwmon/nct7363.c
NETCONSOLE
M: Breno Leitao <[email protected]>
+R: Gustavo Luiz Duarte <[email protected]>
S: Maintained
F: Documentation/networking/netconsole.rst
F: drivers/net/netconsole.c

drivers/net/ethernet/actions/owl-emac.c

View file
diff --git a/drivers/net/ethernet/actions/owl-emac.c b/drivers/net/ethernet/actions/owl-emac.c
index 0a08da7..2538275 100644
--- a/drivers/net/ethernet/actions/owl-emac.c
+++ b/drivers/net/ethernet/actions/owl-emac.c
@@ -1552,6 +1552,8 @@ static int owl_emac_probe(struct platform_device *pdev)
return ret;
}
+ netdev->netdev_ops = &owl_emac_netdev_ops;
+
ret = owl_emac_phy_init(netdev);
if (ret) {
dev_err(dev, "failed to initialize PHY\n");
@@ -1563,7 +1565,6 @@ static int owl_emac_probe(struct platform_device *pdev)
netdev->min_mtu = OWL_EMAC_MTU_MIN;
netdev->max_mtu = OWL_EMAC_MTU_MAX;
netdev->watchdog_timeo = OWL_EMAC_TX_TIMEOUT;
- netdev->netdev_ops = &owl_emac_netdev_ops;
netdev->ethtool_ops = &owl_emac_ethtool_ops;
netif_napi_add(netdev, &priv->napi, owl_emac_poll);

drivers/net/ethernet/adi/adin1140.c

View file
diff --git a/drivers/net/ethernet/adi/adin1140.c b/drivers/net/ethernet/adi/adin1140.c
index 93710ba..ca96a91 100644
--- a/drivers/net/ethernet/adi/adin1140.c
+++ b/drivers/net/ethernet/adi/adin1140.c
@@ -733,6 +733,8 @@ static int adin1140_probe(struct spi_device *spi)
if (ret)
return ret;
+ netdev->netdev_ops = &adin1140_netdev_ops;
+
ret = adin1140_phy_init(priv, spi);
if (ret)
return ret;
@@ -748,7 +750,6 @@ static int adin1140_probe(struct spi_device *spi)
netdev->if_port = IF_PORT_10BASET;
netdev->irq = spi->irq;
- netdev->netdev_ops = &adin1140_netdev_ops;
netdev->ethtool_ops = &adin1140_ethtool_ops;
netdev->netns_immutable = true;
netdev->priv_flags |= IFF_LIVE_ADDR_CHANGE |

drivers/net/ethernet/aeroflex/greth.c

View file
diff --git a/drivers/net/ethernet/aeroflex/greth.c b/drivers/net/ethernet/aeroflex/greth.c
index a593adc..fccb67b 100644
--- a/drivers/net/ethernet/aeroflex/greth.c
+++ b/drivers/net/ethernet/aeroflex/greth.c
@@ -1421,6 +1421,8 @@ static int greth_of_probe(struct platform_device *ofdev)
/* Check if MAC can handle MDIO interrupts */
greth->mdio_int_en = (tmp >> 26) & 1;
+ dev->netdev_ops = &greth_netdev_ops;
+
err = greth_mdio_init(greth);
if (err) {
if (netif_msg_probe(greth))
@@ -1498,7 +1500,6 @@ static int greth_of_probe(struct platform_device *ofdev)
dev->flags &= ~IFF_MULTICAST;
}
- dev->netdev_ops = &greth_netdev_ops;
dev->ethtool_ops = &greth_ethtool_ops;
err = register_netdev(dev);

drivers/net/ethernet/amd/au1000_eth.c

View file
diff --git a/drivers/net/ethernet/amd/au1000_eth.c b/drivers/net/ethernet/amd/au1000_eth.c
index 5a04056..8682323 100644
--- a/drivers/net/ethernet/amd/au1000_eth.c
+++ b/drivers/net/ethernet/amd/au1000_eth.c
@@ -1225,6 +1225,8 @@ static int au1000_probe(struct platform_device *pdev)
goto err_mdiobus_reg;
}
+ dev->netdev_ops = &au1000_netdev_ops;
+
err = au1000_mii_probe(dev);
if (err != 0)
goto err_out;
@@ -1263,7 +1265,6 @@ static int au1000_probe(struct platform_device *pdev)
dev->base_addr = base->start;
dev->irq = irq;
- dev->netdev_ops = &au1000_netdev_ops;
dev->ethtool_ops = &au1000_ethtool_ops;
dev->watchdog_timeo = ETH_TX_TIMEOUT;

drivers/net/ethernet/broadcom/genet/bcmgenet.c

View file
diff --git a/drivers/net/ethernet/broadcom/genet/bcmgenet.c b/drivers/net/ethernet/broadcom/genet/bcmgenet.c
index e890891..f4cfbff 100644
--- a/drivers/net/ethernet/broadcom/genet/bcmgenet.c
+++ b/drivers/net/ethernet/broadcom/genet/bcmgenet.c
@@ -2153,6 +2153,16 @@ static netdev_tx_t bcmgenet_xmit(struct sk_buff *skb, struct net_device *dev)
goto out;
}
+ /* We store Tx state in the control block, so the skb must not be
+ * shared, but ether_setup() leaves IFF_TX_SKB_SHARING set.
+ */
+ skb = skb_share_check(skb, GFP_ATOMIC);
+ if (!skb) {
+ BCMGENET_STATS64_INC((&ring->stats64), dropped);
+ ret = NETDEV_TX_OK;
+ goto out;
+ }
+
/* Retain how many bytes will be sent on the wire, without TSB inserted
* by transmit checksum offload
*/

drivers/net/ethernet/ethoc.c

View file
diff --git a/drivers/net/ethernet/ethoc.c b/drivers/net/ethernet/ethoc.c
index 0c41855..e5b7df4 100644
--- a/drivers/net/ethernet/ethoc.c
+++ b/drivers/net/ethernet/ethoc.c
@@ -1211,6 +1211,8 @@ static int ethoc_probe(struct platform_device *pdev)
goto free3;
}
+ netdev->netdev_ops = &ethoc_netdev_ops;
+
ret = ethoc_mdio_probe(netdev);
if (ret) {
dev_err(&netdev->dev, "failed to probe MDIO bus\n");
@@ -1218,7 +1220,6 @@ static int ethoc_probe(struct platform_device *pdev)
}
/* setup the net_device structure */
- netdev->netdev_ops = &ethoc_netdev_ops;
netdev->watchdog_timeo = ETHOC_TIMEOUT;
netdev->features |= 0;
netdev->ethtool_ops = &ethoc_ethtool_ops;

drivers/net/ethernet/hisilicon/hip04_eth.c

View file
diff --git a/drivers/net/ethernet/hisilicon/hip04_eth.c b/drivers/net/ethernet/hisilicon/hip04_eth.c
index fc2c47d..d0409de 100644
--- a/drivers/net/ethernet/hisilicon/hip04_eth.c
+++ b/drivers/net/ethernet/hisilicon/hip04_eth.c
@@ -976,6 +976,8 @@ static int hip04_mac_probe(struct platform_device *pdev)
goto init_fail;
}
+ ndev->netdev_ops = &hip04_netdev_ops;
+
priv->phy_node = of_parse_phandle(node, "phy-handle", 0);
if (priv->phy_node) {
priv->phy = of_phy_connect(ndev, priv->phy_node,
@@ -989,7 +991,6 @@ static int hip04_mac_probe(struct platform_device *pdev)
INIT_WORK(&priv->tx_timeout_task, hip04_tx_timeout_task);
- ndev->netdev_ops = &hip04_netdev_ops;
ndev->ethtool_ops = &hip04_ethtool_ops;
ndev->watchdog_timeo = TX_TIMEOUT;
ndev->priv_flags |= IFF_UNICAST_FLT;

drivers/net/ethernet/hisilicon/hisi_femac.c

View file
diff --git a/drivers/net/ethernet/hisilicon/hisi_femac.c b/drivers/net/ethernet/hisilicon/hisi_femac.c
index d244a40..016605e 100644
--- a/drivers/net/ethernet/hisilicon/hisi_femac.c
+++ b/drivers/net/ethernet/hisilicon/hisi_femac.c
@@ -830,6 +830,8 @@ static int hisi_femac_drv_probe(struct platform_device *pdev)
hisi_femac_phy_reset(priv);
}
+ ndev->netdev_ops = &hisi_femac_netdev_ops;
+
phy = of_phy_get_and_connect(ndev, node, hisi_femac_adjust_link);
if (!phy) {
dev_err(dev, "connect to PHY failed!\n");
@@ -850,7 +852,6 @@ static int hisi_femac_drv_probe(struct platform_device *pdev)
ndev->watchdog_timeo = 6 * HZ;
ndev->priv_flags |= IFF_UNICAST_FLT;
- ndev->netdev_ops = &hisi_femac_netdev_ops;
ndev->ethtool_ops = &hisi_femac_ethtools_ops;
netif_napi_add_weight(ndev, &priv->napi, hisi_femac_poll,
FEMAC_POLL_WEIGHT);

drivers/net/ethernet/marvell/mv643xx_eth.c

View file
diff --git a/drivers/net/ethernet/marvell/mv643xx_eth.c b/drivers/net/ethernet/marvell/mv643xx_eth.c
index 9caa1e4..38b4d65 100644
--- a/drivers/net/ethernet/marvell/mv643xx_eth.c
+++ b/drivers/net/ethernet/marvell/mv643xx_eth.c
@@ -3171,6 +3171,8 @@ static int mv643xx_eth_probe(struct platform_device *pdev)
netif_set_real_num_tx_queues(dev, mp->txq_count);
netif_set_real_num_rx_queues(dev, mp->rxq_count);
+ dev->netdev_ops = &mv643xx_eth_netdev_ops;
+
err = 0;
if (pd->phy_node) {
phydev = of_phy_connect(mp->dev, pd->phy_node,
@@ -3221,8 +3223,6 @@ static int mv643xx_eth_probe(struct platform_device *pdev)
}
dev->irq = irq;
- dev->netdev_ops = &mv643xx_eth_netdev_ops;
-
dev->watchdog_timeo = 2 * HZ;
dev->base_addr = 0;

drivers/net/ethernet/mellanox/mlx5/core/steering/hws/fs_hws.c

View file
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/steering/hws/fs_hws.c b/drivers/net/ethernet/mellanox/mlx5/core/steering/hws/fs_hws.c
index 5a172c5..5476175 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/steering/hws/fs_hws.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/steering/hws/fs_hws.c
@@ -928,6 +928,7 @@ static int mlx5_fs_fte_get_hws_actions(struct mlx5_flow_root_namespace *ns,
goto free_actions;
}
(*ractions)[num_actions].aso_meter.offset =
+ (fte_action->exe_aso.object_id - fte_action->exe_aso.base_id) * 2 +
fte_action->exe_aso.flow_meter.meter_idx;
(*ractions)[num_actions].aso_meter.init_color =
fte_action->exe_aso.flow_meter.init_color;
@@ -1398,8 +1399,8 @@ static void mlx5_cmd_hws_packet_reformat_dealloc(struct mlx5_flow_root_namespace
pr_data->data_size);
break;
case MLX5_REFORMAT_TYPE_L2_TO_L3_TUNNEL:
- pr_pool = mlx5_fs_get_pr_encap_pool(dev, &hws_pool->el2tol2tnl_pools,
- MLX5HWS_ACTION_TYP_REFORMAT_L2_TO_TNL_L2,
+ pr_pool = mlx5_fs_get_pr_encap_pool(dev, &hws_pool->el2tol3tnl_pools,
+ MLX5HWS_ACTION_TYP_REFORMAT_L2_TO_TNL_L3,
pr_data->data_size);
break;
case MLX5_REFORMAT_TYPE_L3_TUNNEL_TO_L2:

drivers/net/ethernet/microchip/lan865x/lan865x.c

View file
diff --git a/drivers/net/ethernet/microchip/lan865x/lan865x.c b/drivers/net/ethernet/microchip/lan865x/lan865x.c
index 26a2761..633d008 100644
--- a/drivers/net/ethernet/microchip/lan865x/lan865x.c
+++ b/drivers/net/ethernet/microchip/lan865x/lan865x.c
@@ -346,6 +346,8 @@ static int lan865x_probe(struct spi_device *spi)
spi_set_drvdata(spi, priv);
INIT_WORK(&priv->multicast_work, lan865x_multicast_work_handler);
+ netdev->netdev_ops = &lan865x_netdev_ops;
+
priv->tc6 = oa_tc6_init(spi, netdev, NULL);
if (!priv->tc6) {
ret = -ENODEV;
@@ -397,7 +399,6 @@ static int lan865x_probe(struct spi_device *spi)
netdev->if_port = IF_PORT_10BASET;
netdev->irq = spi->irq;
- netdev->netdev_ops = &lan865x_netdev_ops;
netdev->ethtool_ops = &lan865x_ethtool_ops;
ret = register_netdev(netdev);

drivers/net/ethernet/stmicro/stmmac/dwmac1000_core.c

View file
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac1000_core.c b/drivers/net/ethernet/stmicro/stmmac/dwmac1000_core.c
index d4ace39..66337cf 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac1000_core.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac1000_core.c
@@ -312,6 +312,12 @@ static int dwmac1000_irq_status(struct stmmac_priv *priv,
if (intr_status & (PCS_ANE_IRQ | PCS_LINK_IRQ))
stmmac_integrated_pcs_irq(priv, intr_status, x);
+ /* Reading RGSMIIIS clears the interrupt the MAC reset unmasks. */
+ if (intr_status & PCS_RGSMIIIS_IRQ) {
+ readl(ioaddr + GMAC_RGSMIIIS);
+ x->irq_rgmii_n++;
+ }
+
return ret;
}

drivers/net/ethernet/ti/icssm/icssm_prueth.c

View file
diff --git a/drivers/net/ethernet/ti/icssm/icssm_prueth.c b/drivers/net/ethernet/ti/icssm/icssm_prueth.c
index b7e9424..b42c98e 100644
--- a/drivers/net/ethernet/ti/icssm/icssm_prueth.c
+++ b/drivers/net/ethernet/ti/icssm/icssm_prueth.c
@@ -1563,6 +1563,8 @@ static int icssm_prueth_netdev_init(struct prueth *prueth,
}
ether_addr_copy(emac->mac_addr, ndev->dev_addr);
+ ndev->netdev_ops = &emac_netdev_ops;
+
/* connect PHY */
emac->phydev = of_phy_get_and_connect(ndev, eth_node,
icssm_emac_adjust_link);
@@ -1590,7 +1592,6 @@ static int icssm_prueth_netdev_init(struct prueth *prueth,
}
ndev->dev.of_node = eth_node;
- ndev->netdev_ops = &emac_netdev_ops;
netif_napi_add(ndev, &emac->napi, icssm_emac_napi_poll);

net/ipv6/calipso.c

View file
diff --git a/net/ipv6/calipso.c b/net/ipv6/calipso.c
index c6a3433..a0192b4 100644
--- a/net/ipv6/calipso.c
+++ b/net/ipv6/calipso.c
@@ -1318,7 +1318,7 @@ static int calipso_skbuff_setattr(struct sk_buff *skb,
struct ipv6hdr *ip6_hdr;
struct ipv6_opt_hdr *hop;
unsigned char buf[CALIPSO_MAX_BUFFER];
- int len_delta, new_end, pad, payload;
+ int len_delta, new_end, pad;
unsigned int start, end;
ip6_hdr = ipv6_hdr(skb);
@@ -1357,8 +1357,8 @@ static int calipso_skbuff_setattr(struct sk_buff *skb,
sizeof(*ip6_hdr) + start);
skb_reset_network_header(skb);
ip6_hdr = ipv6_hdr(skb);
- payload = ntohs(ip6_hdr->payload_len);
- ip6_hdr->payload_len = htons(payload + len_delta);
+ /* 0 above IPV6_MAXPLEN (BIG TCP), the real length otherwise */
+ ipv6_set_payload_len(ip6_hdr, skb->len - sizeof(*ip6_hdr));
}
hop = (struct ipv6_opt_hdr *)(ip6_hdr + 1);

net/netlink/af_netlink.c

View file
diff --git a/net/netlink/af_netlink.c b/net/netlink/af_netlink.c
index 9fdf964..3029894 100644
--- a/net/netlink/af_netlink.c
+++ b/net/netlink/af_netlink.c
@@ -464,7 +464,7 @@ netlink_unlock_table(void)
struct netlink_compare_arg
{
- possible_net_t pnet;
+ u64 net_cookie;
u32 portid;
};
@@ -479,14 +479,14 @@ static inline int netlink_compare(struct rhashtable_compare_arg *arg,
const struct netlink_sock *nlk = ptr;
return nlk->portid != x->portid ||
- !net_eq(sock_net(&nlk->sk), read_pnet(&x->pnet));
+ sock_net(&nlk->sk)->net_cookie != x->net_cookie;
}
static void netlink_compare_arg_init(struct netlink_compare_arg *arg,
struct net *net, u32 portid)
{
memset(arg, 0, sizeof(*arg));
- write_pnet(&arg->pnet, net);
+ arg->net_cookie = net->net_cookie;
arg->portid = portid;
}
@@ -1363,6 +1363,8 @@ retry:
if (netlink_is_kernel(sk))
return netlink_unicast_kernel(sk, skb, ssk);
+ skb_reset_network_header(skb);
+ skb_reset_mac_header(skb);
if (sk_filter(sk, skb)) {
err = skb->len;
kfree_skb(skb);
@@ -1497,6 +1499,8 @@ static void do_one_broadcast(struct sock *sk,
goto out;
}
+ skb_reset_network_header(p->skb2);
+ skb_reset_mac_header(p->skb2);
if (sk_filter(sk, p->skb2)) {
kfree_skb(p->skb2);
p->skb2 = NULL;

net/rds/rdma_transport.c

View file
diff --git a/net/rds/rdma_transport.c b/net/rds/rdma_transport.c
index b15cf31..7be38be 100644
--- a/net/rds/rdma_transport.c
+++ b/net/rds/rdma_transport.c
@@ -52,7 +52,7 @@ static int rds_rdma_cm_event_handler_cmn(struct rdma_cm_id *cm_id,
{
/* this can be null in the listening path */
struct rds_connection *conn = cm_id->context;
- struct rds_transport *trans;
+ struct rds_transport *trans = &rds_ib_transport;
int ret = 0;
int *err;
u8 len;
@@ -60,9 +60,6 @@ static int rds_rdma_cm_event_handler_cmn(struct rdma_cm_id *cm_id,
rdsdebug("conn %p id %p handling event %u (%s)\n", conn, cm_id,
event->event, rdma_event_msg(event->event));
- if (cm_id->device->node_type == RDMA_NODE_IB_CA)
- trans = &rds_ib_transport;
-
/* Prevent shutdown from tearing down the connection
* while we're executing. */
if (conn) {
@@ -82,16 +79,47 @@ static int rds_rdma_cm_event_handler_cmn(struct rdma_cm_id *cm_id,
switch (event->event) {
case RDMA_CM_EVENT_CONNECT_REQUEST:
+ /* Only the IB transport is supported, but RDS listens on
+ * every RDMA device: reject a request that arrived on any
+ * other kind. A non-zero return has rdma_cm destroy the
+ * request's id, which is what we want here and only here.
+ */
+ if (cm_id->device->node_type != RDMA_NODE_IB_CA) {
+ ret = 1;
+ break;
+ }
ret = trans->cm_handle_connect(cm_id, event, isv6);
break;
case RDMA_CM_EVENT_ADDR_RESOLVED:
if (conn) {
+ /* The address resolved to a device RDS has no
+ * transport for. Do not go on to resolve a route:
+ * an iWARP route leaves cm_id->route.path_rec
+ * unset, which the ROUTE_RESOLVED case below
+ * dereferences. Drop the connection instead; the
+ * id is still ic->i_cm_id, so return 0 and let the
+ * shutdown destroy it.
+ */
+ if (cm_id->device->node_type != RDMA_NODE_IB_CA) {
+ rds_conn_drop(conn);
+ break;
+ }
rdma_set_service_type(cm_id, conn->c_tos);
rdma_set_min_rnr_timer(cm_id, IB_RNR_TIMER_000_32);
- /* XXX do we need to clean up if this fails? */
ret = rdma_resolve_route(cm_id,
RDS_RDMA_RESOLVE_TIMEOUT_MS);
+ if (ret) {
+ /* A non-zero return has the rdma_cm destroy
+ * the id, but it is still ic->i_cm_id, which
+ * the connection's shutdown would then
+ * disconnect and destroy again. Drop the
+ * connection and keep the id for that
+ * shutdown.
+ */
+ rds_conn_drop(conn);
+ ret = 0;
+ }
}
break;

net/sched/act_api.c

View file
diff --git a/net/sched/act_api.c b/net/sched/act_api.c
index e45a63b..9eb1dec 100644
--- a/net/sched/act_api.c
+++ b/net/sched/act_api.c
@@ -372,9 +372,10 @@ static int __tcf_action_put(struct tc_action *p, bool bind)
{
struct tcf_idrinfo *idrinfo = p->idrinfo;
- if (refcount_dec_and_mutex_lock(&p->tcfa_refcnt, &idrinfo->lock)) {
- if (bind)
- atomic_dec(&p->tcfa_bindcnt);
+ mutex_lock(&idrinfo->lock);
+ if (bind)
+ atomic_dec(&p->tcfa_bindcnt);
+ if (refcount_dec_and_test(&p->tcfa_refcnt)) {
idr_remove(&idrinfo->action_idr, p->tcfa_index);
mutex_unlock(&idrinfo->lock);
@@ -382,9 +383,7 @@ static int __tcf_action_put(struct tc_action *p, bool bind)
return 1;
}
- if (bind)
- atomic_dec(&p->tcfa_bindcnt);
-
+ mutex_unlock(&idrinfo->lock);
return 0;
}

net/sctp/socket.c

View file
diff --git a/net/sctp/socket.c b/net/sctp/socket.c
index e35692d..321898f 100644
--- a/net/sctp/socket.c
+++ b/net/sctp/socket.c
@@ -1786,6 +1786,18 @@ static int sctp_sendmsg_check_sflags(struct sctp_association *asoc,
return 1;
}
+static int sctp_sendmsg_check_stream(struct sctp_association *asoc,
+ struct sctp_sndrcvinfo *sinfo)
+{
+ if (unlikely(sinfo->sinfo_stream >= asoc->stream.outcnt))
+ return -EINVAL;
+
+ if (unlikely(!SCTP_SO(&asoc->stream, sinfo->sinfo_stream)->ext))
+ return sctp_stream_init_ext(&asoc->stream, sinfo->sinfo_stream);
+
+ return 0;
+}
+
static int sctp_sendmsg_to_asoc(struct sctp_association *asoc,
struct msghdr *msg, size_t msg_len,
struct sctp_transport *transport,
@@ -1800,16 +1812,9 @@ static int sctp_sendmsg_to_asoc(struct sctp_association *asoc,
long timeo;
int err;
- if (sinfo->sinfo_stream >= asoc->stream.outcnt) {
- err = -EINVAL;
+ err = sctp_sendmsg_check_stream(asoc, sinfo);
+ if (err)
goto err;
- }
-
- if (unlikely(!SCTP_SO(&asoc->stream, sinfo->sinfo_stream)->ext)) {
- err = sctp_stream_init_ext(&asoc->stream, sinfo->sinfo_stream);
- if (err)
- goto err;
- }
if (sp->disable_fragments && msg_len > asoc->frag_point) {
err = -EMSGSIZE;
@@ -1830,10 +1835,9 @@ static int sctp_sendmsg_to_asoc(struct sctp_association *asoc,
err = sctp_wait_for_sndbuf(asoc, transport, &timeo, msg_len);
if (err)
goto err;
- if (unlikely(sinfo->sinfo_stream >= asoc->stream.outcnt)) {
- err = -EINVAL;
+ err = sctp_sendmsg_check_stream(asoc, sinfo);
+ if (err)
goto err;
- }
}
if (sctp_state(asoc, CLOSED)) {
@@ -1848,6 +1852,11 @@ static int sctp_sendmsg_to_asoc(struct sctp_association *asoc,
err = -ESRCH;
goto err;
}
+ err = sctp_sendmsg_check_stream(asoc, sinfo);
+ if (err) {
+ err = -ESRCH;
+ goto err;
+ }
} else {
wait_connect = true;
}

net/vmw_vsock/af_vsock.c

View file
diff --git a/net/vmw_vsock/af_vsock.c b/net/vmw_vsock/af_vsock.c
index 533c733..6ba8c85 100644
--- a/net/vmw_vsock/af_vsock.c
+++ b/net/vmw_vsock/af_vsock.c
@@ -1836,23 +1836,22 @@ static int vsock_connect(struct socket *sock, struct sockaddr_unsized *addr,
timeout = schedule_timeout(timeout);
lock_sock(sk);
- /* Connection established. Whatever happens to socket once we
- * release it, that's not connect()'s concern. No need to go
+ /* Connection was established. Whatever happens to socket once
+ * we release it, that's not connect()'s concern. No need to go
* into signal and timeout handling. Call it a day.
*
* Note that allowing to "reset" an already established socket
* here is racy and insecure.
*/
- if (sk->sk_state == TCP_ESTABLISHED)
- break;
+ if (sk->sk_state == TCP_ESTABLISHED ||
+ sk->sk_state == TCP_CLOSING) {
+ err = 0;
+ goto out_wait;
+ }
/* If connection was _not_ established and a signal/timeout came
* to be, we want the socket's state reset. User space may want
- * to retry.
- *
- * sk_state != TCP_ESTABLISHED implies that socket is not on
- * vsock_connected_table. We keep the binding and the transport
- * assigned.
+ * to retry, so we keep the binding and the transport assigned.
*/
if (signal_pending(current) || timeout == 0) {
err = timeout == 0 ? -ETIMEDOUT : sock_intr_errno(timeout);