Skip to content

Commit 9fdfb15

Browse files
committed
Merge tag 'net-6.6-rc2' of git://git.kernel.org/pub/scm/linux/kernel/git/netdev/net
Pull networking fixes from Paolo Abeni: "Quite unusually, this does not contains any fix coming from subtrees (nf, ebpf, wifi, etc). Current release - regressions: - bcmasp: fix possible OOB write in bcmasp_netfilt_get_all_active() Previous releases - regressions: - ipv4: fix one memleak in __inet_del_ifa() - tcp: fix bind() regressions for v4-mapped-v6 addresses. - tls: do not free tls_rec on async operation in bpf_exec_tx_verdict() - dsa: fixes for SJA1105 FDB regressions - veth: update XDP feature set when bringing up device - igb: fix hangup when enabling SR-IOV Previous releases - always broken: - kcm: fix memory leak in error path of kcm_sendmsg() - smc: fix data corruption in smcr_port_add - microchip: fix possible memory leak for vcap_dup_rule()" * tag 'net-6.6-rc2' of git://git.kernel.org/pub/scm/linux/kernel/git/netdev/net: (37 commits) kcm: Fix error handling for SOCK_DGRAM in kcm_sendmsg(). net: renesas: rswitch: Add spin lock protection for irq {un}mask net: renesas: rswitch: Fix unmasking irq condition igb: clean up in all error paths when enabling SR-IOV ixgbe: fix timestamp configuration code selftest: tcp: Add v4-mapped-v6 cases in bind_wildcard.c. selftest: tcp: Move expected_errno into each test case in bind_wildcard.c. selftest: tcp: Fix address length in bind_wildcard.c. tcp: Fix bind() regression for v4-mapped-v6 non-wildcard address. tcp: Fix bind() regression for v4-mapped-v6 wildcard address. tcp: Factorise sk_family-independent comparison in inet_bind2_bucket_match(_addr_any). ipv6: fix ip6_sock_set_addr_preferences() typo veth: Update XDP feature set when bringing up device net: macb: fix sleep inside spinlock net/tls: do not free tls_rec on async operation in bpf_exec_tx_verdict() net: ethernet: mtk_eth_soc: fix pse_port configuration for MT7988 net: ethernet: mtk_eth_soc: fix uninitialized variable kcm: Fix memory leak in error path of kcm_sendmsg() r8152: check budget for r8152_poll() net: dsa: sja1105: block FDB accesses that are concurrent with a switch reset ...
2 parents aed8aee + a22730b commit 9fdfb15

File tree

36 files changed

+352
-207
lines changed

36 files changed

+352
-207
lines changed

drivers/net/dsa/sja1105/sja1105.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -266,6 +266,8 @@ struct sja1105_private {
266266
* the switch doesn't confuse them with one another.
267267
*/
268268
struct mutex mgmt_lock;
269+
/* Serializes accesses to the FDB */
270+
struct mutex fdb_lock;
269271
/* PTP two-step TX timestamp ID, and its serialization lock */
270272
spinlock_t ts_id_lock;
271273
u8 ts_id;

drivers/net/dsa/sja1105/sja1105_dynamic_config.c

Lines changed: 44 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -1175,18 +1175,15 @@ const struct sja1105_dynamic_table_ops sja1110_dyn_ops[BLK_IDX_MAX_DYN] = {
11751175

11761176
static int
11771177
sja1105_dynamic_config_poll_valid(struct sja1105_private *priv,
1178-
struct sja1105_dyn_cmd *cmd,
1179-
const struct sja1105_dynamic_table_ops *ops)
1178+
const struct sja1105_dynamic_table_ops *ops,
1179+
void *entry, bool check_valident,
1180+
bool check_errors)
11801181
{
11811182
u8 packed_buf[SJA1105_MAX_DYN_CMD_SIZE] = {};
1183+
struct sja1105_dyn_cmd cmd = {};
11821184
int rc;
11831185

1184-
/* We don't _need_ to read the full entry, just the command area which
1185-
* is a fixed SJA1105_SIZE_DYN_CMD. But our cmd_packing() API expects a
1186-
* buffer that contains the full entry too. Additionally, our API
1187-
* doesn't really know how many bytes into the buffer does the command
1188-
* area really begin. So just read back the whole entry.
1189-
*/
1186+
/* Read back the whole entry + command structure. */
11901187
rc = sja1105_xfer_buf(priv, SPI_READ, ops->addr, packed_buf,
11911188
ops->packed_size);
11921189
if (rc)
@@ -1195,11 +1192,25 @@ sja1105_dynamic_config_poll_valid(struct sja1105_private *priv,
11951192
/* Unpack the command structure, and return it to the caller in case it
11961193
* needs to perform further checks on it (VALIDENT).
11971194
*/
1198-
memset(cmd, 0, sizeof(*cmd));
1199-
ops->cmd_packing(packed_buf, cmd, UNPACK);
1195+
ops->cmd_packing(packed_buf, &cmd, UNPACK);
12001196

12011197
/* Hardware hasn't cleared VALID => still working on it */
1202-
return cmd->valid ? -EAGAIN : 0;
1198+
if (cmd.valid)
1199+
return -EAGAIN;
1200+
1201+
if (check_valident && !cmd.valident && !(ops->access & OP_VALID_ANYWAY))
1202+
return -ENOENT;
1203+
1204+
if (check_errors && cmd.errors)
1205+
return -EINVAL;
1206+
1207+
/* Don't dereference possibly NULL pointer - maybe caller
1208+
* only wanted to see whether the entry existed or not.
1209+
*/
1210+
if (entry)
1211+
ops->entry_packing(packed_buf, entry, UNPACK);
1212+
1213+
return 0;
12031214
}
12041215

12051216
/* Poll the dynamic config entry's control area until the hardware has
@@ -1208,16 +1219,19 @@ sja1105_dynamic_config_poll_valid(struct sja1105_private *priv,
12081219
*/
12091220
static int
12101221
sja1105_dynamic_config_wait_complete(struct sja1105_private *priv,
1211-
struct sja1105_dyn_cmd *cmd,
1212-
const struct sja1105_dynamic_table_ops *ops)
1222+
const struct sja1105_dynamic_table_ops *ops,
1223+
void *entry, bool check_valident,
1224+
bool check_errors)
12131225
{
1214-
int rc;
1215-
1216-
return read_poll_timeout(sja1105_dynamic_config_poll_valid,
1217-
rc, rc != -EAGAIN,
1218-
SJA1105_DYNAMIC_CONFIG_SLEEP_US,
1219-
SJA1105_DYNAMIC_CONFIG_TIMEOUT_US,
1220-
false, priv, cmd, ops);
1226+
int err, rc;
1227+
1228+
err = read_poll_timeout(sja1105_dynamic_config_poll_valid,
1229+
rc, rc != -EAGAIN,
1230+
SJA1105_DYNAMIC_CONFIG_SLEEP_US,
1231+
SJA1105_DYNAMIC_CONFIG_TIMEOUT_US,
1232+
false, priv, ops, entry, check_valident,
1233+
check_errors);
1234+
return err < 0 ? err : rc;
12211235
}
12221236

12231237
/* Provides read access to the settings through the dynamic interface
@@ -1286,25 +1300,14 @@ int sja1105_dynamic_config_read(struct sja1105_private *priv,
12861300
mutex_lock(&priv->dynamic_config_lock);
12871301
rc = sja1105_xfer_buf(priv, SPI_WRITE, ops->addr, packed_buf,
12881302
ops->packed_size);
1289-
if (rc < 0) {
1290-
mutex_unlock(&priv->dynamic_config_lock);
1291-
return rc;
1292-
}
1293-
1294-
rc = sja1105_dynamic_config_wait_complete(priv, &cmd, ops);
1295-
mutex_unlock(&priv->dynamic_config_lock);
12961303
if (rc < 0)
1297-
return rc;
1304+
goto out;
12981305

1299-
if (!cmd.valident && !(ops->access & OP_VALID_ANYWAY))
1300-
return -ENOENT;
1306+
rc = sja1105_dynamic_config_wait_complete(priv, ops, entry, true, false);
1307+
out:
1308+
mutex_unlock(&priv->dynamic_config_lock);
13011309

1302-
/* Don't dereference possibly NULL pointer - maybe caller
1303-
* only wanted to see whether the entry existed or not.
1304-
*/
1305-
if (entry)
1306-
ops->entry_packing(packed_buf, entry, UNPACK);
1307-
return 0;
1310+
return rc;
13081311
}
13091312

13101313
int sja1105_dynamic_config_write(struct sja1105_private *priv,
@@ -1356,22 +1359,14 @@ int sja1105_dynamic_config_write(struct sja1105_private *priv,
13561359
mutex_lock(&priv->dynamic_config_lock);
13571360
rc = sja1105_xfer_buf(priv, SPI_WRITE, ops->addr, packed_buf,
13581361
ops->packed_size);
1359-
if (rc < 0) {
1360-
mutex_unlock(&priv->dynamic_config_lock);
1361-
return rc;
1362-
}
1363-
1364-
rc = sja1105_dynamic_config_wait_complete(priv, &cmd, ops);
1365-
mutex_unlock(&priv->dynamic_config_lock);
13661362
if (rc < 0)
1367-
return rc;
1363+
goto out;
13681364

1369-
cmd = (struct sja1105_dyn_cmd) {0};
1370-
ops->cmd_packing(packed_buf, &cmd, UNPACK);
1371-
if (cmd.errors)
1372-
return -EINVAL;
1365+
rc = sja1105_dynamic_config_wait_complete(priv, ops, NULL, false, true);
1366+
out:
1367+
mutex_unlock(&priv->dynamic_config_lock);
13731368

1374-
return 0;
1369+
return rc;
13751370
}
13761371

13771372
static u8 sja1105_crc8_add(u8 crc, u8 byte, u8 poly)

drivers/net/dsa/sja1105/sja1105_main.c

Lines changed: 51 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1798,6 +1798,7 @@ static int sja1105_fdb_add(struct dsa_switch *ds, int port,
17981798
struct dsa_db db)
17991799
{
18001800
struct sja1105_private *priv = ds->priv;
1801+
int rc;
18011802

18021803
if (!vid) {
18031804
switch (db.type) {
@@ -1812,12 +1813,16 @@ static int sja1105_fdb_add(struct dsa_switch *ds, int port,
18121813
}
18131814
}
18141815

1815-
return priv->info->fdb_add_cmd(ds, port, addr, vid);
1816+
mutex_lock(&priv->fdb_lock);
1817+
rc = priv->info->fdb_add_cmd(ds, port, addr, vid);
1818+
mutex_unlock(&priv->fdb_lock);
1819+
1820+
return rc;
18161821
}
18171822

1818-
static int sja1105_fdb_del(struct dsa_switch *ds, int port,
1819-
const unsigned char *addr, u16 vid,
1820-
struct dsa_db db)
1823+
static int __sja1105_fdb_del(struct dsa_switch *ds, int port,
1824+
const unsigned char *addr, u16 vid,
1825+
struct dsa_db db)
18211826
{
18221827
struct sja1105_private *priv = ds->priv;
18231828

@@ -1837,6 +1842,20 @@ static int sja1105_fdb_del(struct dsa_switch *ds, int port,
18371842
return priv->info->fdb_del_cmd(ds, port, addr, vid);
18381843
}
18391844

1845+
static int sja1105_fdb_del(struct dsa_switch *ds, int port,
1846+
const unsigned char *addr, u16 vid,
1847+
struct dsa_db db)
1848+
{
1849+
struct sja1105_private *priv = ds->priv;
1850+
int rc;
1851+
1852+
mutex_lock(&priv->fdb_lock);
1853+
rc = __sja1105_fdb_del(ds, port, addr, vid, db);
1854+
mutex_unlock(&priv->fdb_lock);
1855+
1856+
return rc;
1857+
}
1858+
18401859
static int sja1105_fdb_dump(struct dsa_switch *ds, int port,
18411860
dsa_fdb_dump_cb_t *cb, void *data)
18421861
{
@@ -1868,13 +1887,14 @@ static int sja1105_fdb_dump(struct dsa_switch *ds, int port,
18681887
if (!(l2_lookup.destports & BIT(port)))
18691888
continue;
18701889

1871-
/* We need to hide the FDB entry for unknown multicast */
1872-
if (l2_lookup.macaddr == SJA1105_UNKNOWN_MULTICAST &&
1873-
l2_lookup.mask_macaddr == SJA1105_UNKNOWN_MULTICAST)
1874-
continue;
1875-
18761890
u64_to_ether_addr(l2_lookup.macaddr, macaddr);
18771891

1892+
/* Hardware FDB is shared for fdb and mdb, "bridge fdb show"
1893+
* only wants to see unicast
1894+
*/
1895+
if (is_multicast_ether_addr(macaddr))
1896+
continue;
1897+
18781898
/* We need to hide the dsa_8021q VLANs from the user. */
18791899
if (vid_is_dsa_8021q(l2_lookup.vlanid))
18801900
l2_lookup.vlanid = 0;
@@ -1898,6 +1918,8 @@ static void sja1105_fast_age(struct dsa_switch *ds, int port)
18981918
};
18991919
int i;
19001920

1921+
mutex_lock(&priv->fdb_lock);
1922+
19011923
for (i = 0; i < SJA1105_MAX_L2_LOOKUP_COUNT; i++) {
19021924
struct sja1105_l2_lookup_entry l2_lookup = {0};
19031925
u8 macaddr[ETH_ALEN];
@@ -1911,7 +1933,7 @@ static void sja1105_fast_age(struct dsa_switch *ds, int port)
19111933
if (rc) {
19121934
dev_err(ds->dev, "Failed to read FDB: %pe\n",
19131935
ERR_PTR(rc));
1914-
return;
1936+
break;
19151937
}
19161938

19171939
if (!(l2_lookup.destports & BIT(port)))
@@ -1923,14 +1945,16 @@ static void sja1105_fast_age(struct dsa_switch *ds, int port)
19231945

19241946
u64_to_ether_addr(l2_lookup.macaddr, macaddr);
19251947

1926-
rc = sja1105_fdb_del(ds, port, macaddr, l2_lookup.vlanid, db);
1948+
rc = __sja1105_fdb_del(ds, port, macaddr, l2_lookup.vlanid, db);
19271949
if (rc) {
19281950
dev_err(ds->dev,
19291951
"Failed to delete FDB entry %pM vid %lld: %pe\n",
19301952
macaddr, l2_lookup.vlanid, ERR_PTR(rc));
1931-
return;
1953+
break;
19321954
}
19331955
}
1956+
1957+
mutex_unlock(&priv->fdb_lock);
19341958
}
19351959

19361960
static int sja1105_mdb_add(struct dsa_switch *ds, int port,
@@ -2273,6 +2297,7 @@ int sja1105_static_config_reload(struct sja1105_private *priv,
22732297
int rc, i;
22742298
s64 now;
22752299

2300+
mutex_lock(&priv->fdb_lock);
22762301
mutex_lock(&priv->mgmt_lock);
22772302

22782303
mac = priv->static_config.tables[BLK_IDX_MAC_CONFIG].entries;
@@ -2385,6 +2410,7 @@ int sja1105_static_config_reload(struct sja1105_private *priv,
23852410
goto out;
23862411
out:
23872412
mutex_unlock(&priv->mgmt_lock);
2413+
mutex_unlock(&priv->fdb_lock);
23882414

23892415
return rc;
23902416
}
@@ -2954,7 +2980,9 @@ static int sja1105_port_mcast_flood(struct sja1105_private *priv, int to,
29542980
{
29552981
struct sja1105_l2_lookup_entry *l2_lookup;
29562982
struct sja1105_table *table;
2957-
int match;
2983+
int match, rc;
2984+
2985+
mutex_lock(&priv->fdb_lock);
29582986

29592987
table = &priv->static_config.tables[BLK_IDX_L2_LOOKUP];
29602988
l2_lookup = table->entries;
@@ -2967,18 +2995,22 @@ static int sja1105_port_mcast_flood(struct sja1105_private *priv, int to,
29672995
if (match == table->entry_count) {
29682996
NL_SET_ERR_MSG_MOD(extack,
29692997
"Could not find FDB entry for unknown multicast");
2970-
return -ENOSPC;
2998+
rc = -ENOSPC;
2999+
goto out;
29713000
}
29723001

29733002
if (flags.val & BR_MCAST_FLOOD)
29743003
l2_lookup[match].destports |= BIT(to);
29753004
else
29763005
l2_lookup[match].destports &= ~BIT(to);
29773006

2978-
return sja1105_dynamic_config_write(priv, BLK_IDX_L2_LOOKUP,
2979-
l2_lookup[match].index,
2980-
&l2_lookup[match],
2981-
true);
3007+
rc = sja1105_dynamic_config_write(priv, BLK_IDX_L2_LOOKUP,
3008+
l2_lookup[match].index,
3009+
&l2_lookup[match], true);
3010+
out:
3011+
mutex_unlock(&priv->fdb_lock);
3012+
3013+
return rc;
29823014
}
29833015

29843016
static int sja1105_port_pre_bridge_flags(struct dsa_switch *ds, int port,
@@ -3348,6 +3380,7 @@ static int sja1105_probe(struct spi_device *spi)
33483380
mutex_init(&priv->ptp_data.lock);
33493381
mutex_init(&priv->dynamic_config_lock);
33503382
mutex_init(&priv->mgmt_lock);
3383+
mutex_init(&priv->fdb_lock);
33513384
spin_lock_init(&priv->ts_id_lock);
33523385

33533386
rc = sja1105_parse_dt(priv);

drivers/net/ethernet/adi/adin1110.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1385,7 +1385,7 @@ static int adin1110_fdb_add(struct adin1110_port_priv *port_priv,
13851385
return -ENOMEM;
13861386

13871387
other_port = priv->ports[!port_priv->nr];
1388-
port_rules = adin1110_port_rules(port_priv, false, true);
1388+
port_rules = adin1110_port_rules(other_port, false, true);
13891389
eth_broadcast_addr(mask);
13901390

13911391
return adin1110_write_mac_address(other_port, mac_nr, (u8 *)fdb->addr,

drivers/net/ethernet/broadcom/asp2/bcmasp.c

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -528,13 +528,16 @@ void bcmasp_netfilt_suspend(struct bcmasp_intf *intf)
528528
ASP_RX_FILTER_BLK_CTRL);
529529
}
530530

531-
void bcmasp_netfilt_get_all_active(struct bcmasp_intf *intf, u32 *rule_locs,
532-
u32 *rule_cnt)
531+
int bcmasp_netfilt_get_all_active(struct bcmasp_intf *intf, u32 *rule_locs,
532+
u32 *rule_cnt)
533533
{
534534
struct bcmasp_priv *priv = intf->parent;
535535
int j = 0, i;
536536

537537
for (i = 0; i < NUM_NET_FILTERS; i++) {
538+
if (j == *rule_cnt)
539+
return -EMSGSIZE;
540+
538541
if (!priv->net_filters[i].claimed ||
539542
priv->net_filters[i].port != intf->port)
540543
continue;
@@ -548,6 +551,8 @@ void bcmasp_netfilt_get_all_active(struct bcmasp_intf *intf, u32 *rule_locs,
548551
}
549552

550553
*rule_cnt = j;
554+
555+
return 0;
551556
}
552557

553558
int bcmasp_netfilt_get_active(struct bcmasp_intf *intf)
@@ -1300,6 +1305,7 @@ static int bcmasp_probe(struct platform_device *pdev)
13001305
if (!intf) {
13011306
dev_err(dev, "Cannot create eth interface %d\n", i);
13021307
bcmasp_remove_intfs(priv);
1308+
of_node_put(intf_node);
13031309
goto of_put_exit;
13041310
}
13051311
list_add_tail(&intf->list, &priv->intfs);

drivers/net/ethernet/broadcom/asp2/bcmasp.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -577,8 +577,8 @@ void bcmasp_netfilt_release(struct bcmasp_intf *intf,
577577

578578
int bcmasp_netfilt_get_active(struct bcmasp_intf *intf);
579579

580-
void bcmasp_netfilt_get_all_active(struct bcmasp_intf *intf, u32 *rule_locs,
581-
u32 *rule_cnt);
580+
int bcmasp_netfilt_get_all_active(struct bcmasp_intf *intf, u32 *rule_locs,
581+
u32 *rule_cnt);
582582

583583
void bcmasp_netfilt_suspend(struct bcmasp_intf *intf);
584584

drivers/net/ethernet/broadcom/asp2/bcmasp_ethtool.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -335,7 +335,7 @@ static int bcmasp_get_rxnfc(struct net_device *dev, struct ethtool_rxnfc *cmd,
335335
err = bcmasp_flow_get(intf, cmd);
336336
break;
337337
case ETHTOOL_GRXCLSRLALL:
338-
bcmasp_netfilt_get_all_active(intf, rule_locs, &cmd->rule_cnt);
338+
err = bcmasp_netfilt_get_all_active(intf, rule_locs, &cmd->rule_cnt);
339339
cmd->data = NUM_NET_FILTERS;
340340
break;
341341
default:

0 commit comments

Comments
 (0)