6.6.141-rc1 review
Subsystems (8)
Greg Kroah-Hartman
maintainerPATCH 420/508 ALSA: hda/conexant: Renaming the codec with device ID 0x1f86 and 0x1f87
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: wangdicheng <[email protected]>
[ Upstream commit 7f4c540e0859e2025675d2c5c5c6ab88eaf817e2 ]
Due to changes in the manufacturer's plan, all 0x14f11f86 will be named CX11880, and 0x14f11f87 will be named SN6140
Stable-dep-of: b0e2333a2311 ("ALSA: hda/conexant: Fix missing error check for jack detection")
--- sound/pci/hda/patch_conexant.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-)
sound/pci/hda/patch_conexant.c +6 -6
@@ -42,7 +42,7 @@ struct conexant_spec {unsigned int gpio_led;unsigned int gpio_mute_led_mask;unsigned int gpio_mic_led_mask; -bool is_cx8070_sn6140; +bool is_cx11880_sn6140; };
@@ -195,7 +195,7 @@ static int cx_auto_init(struct hda_codec *codec)cxt_init_gpio_led (codec);snd_hda_apply_fixup (codec,HDA_FIXUP_ACT_INIT ); -if (spec->is_cx8070_sn6140) +if (spec->is_cx11880_sn6140)cx_fixup_headset_recog (codec);return 0 ;
@@ -247,7 +247,7 @@ static void cx_update_headset_mic_vref(struct hda_codec *codec, struct hda_jack_ {unsigned int mic_present; -/* In cx8070 and sn6140, the node 16 can only be configured to headphone or disabled, +/* In cx11880 and sn6140, the node 16 can only be configured to headphone or disabled, * the node 19 can only be configured to microphone or disabled. * Check hp&mic tag to process headset plugin & plugout. */
@@ -1197,11 +1197,11 @@ static int patch_conexant_auto(struct hda_codec *codec) codec->spec = spec; codec->patch_ops = cx_auto_patch_ops; -/* init cx8070/sn6140 flag and reset headset_present_flag */ +/* init cx11880/sn6140 flag and reset headset_present_flag */ switch (codec->core.vendor_id) {case 0x14f11f86 :case 0x14f11f87 : - spec->is_cx8070_sn6140 = true; + spec->is_cx11880_sn6140 = true;snd_hda_jack_detect_enable_callback (codec,0x19 , cx_update_headset_mic_vref);break ; }
@@ -1289,7 +1289,7 @@ static int patch_conexant_auto(struct hda_codec *codec)*/ static const struct hda_device_id snd_hda_id_conexant[] = { -HDA_CODEC_ENTRY (0x14f11f86 ,"CX8070" , patch_conexant_auto), +HDA_CODEC_ENTRY (0x14f11f86 ,"CX11880" , patch_conexant_auto),HDA_CODEC_ENTRY (0x14f11f87 ,"SN6140" , patch_conexant_auto),HDA_CODEC_ENTRY (0x14f12008 ,"CX8200" , patch_conexant_auto),HDA_CODEC_ENTRY (0x14f120d0 ,"CX11970" , patch_conexant_auto),
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 421/508 ALSA: hda/conexant: Fix missing error check for jack detection
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: wangdicheng <[email protected]>
[ Upstream commit b0e2333a231107adedd38c6fcfe1adc6162716fc ]
In cx_probe(), the return value of snd_hda_jack_detect_enable_callback() is ignored. This function returns a pointer, and if it fails (e.g., due to memory allocation failure), it returns an error pointer which must be checked using IS_ERR().
If the registration fails, the driver continues to probe, but the jack detection callback will not be registered. This can lead to a kernel crash later when the driver attempts to handle jack events or accesses the uninitialized structure.
Check the return value using IS_ERR() and propagate the error via PTR_ERR() to the probe caller.
--- sound/pci/hda/patch_conexant.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-)
sound/pci/hda/patch_conexant.c +7 -1
@@ -1186,6 +1186,7 @@ static void add_cx5051_fake_mutes(struct hda_codec *codec)static int patch_conexant_auto (struct hda_codec *codec) {struct conexant_spec *spec; +struct hda_jack_callback *callback;int err;codec_info (codec,"%s: BIOS auto-probing.\n" , codec->core.chip_name);
@@ -1202,7 +1203,12 @@ static int patch_conexant_auto(struct hda_codec *codec)case 0x14f11f86 :case 0x14f11f87 : spec->is_cx11880_sn6140 = true; -snd_hda_jack_detect_enable_callback (codec,0x19 , cx_update_headset_mic_vref); + callback =snd_hda_jack_detect_enable_callback (codec,0x19 , + cx_update_headset_mic_vref); +if (IS_ERR (callback)) { + err =PTR_ERR (callback); + goto error; + }break ; }
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 422/508 futex: Prevent lockup in requeue-PI during signal/ timeout wakeup
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Sebastian Andrzej Siewior <[email protected]>
[ Upstream commit bc7304f3ae20972d11db6e0b1b541c63feda5f05 ]
During wait-requeue-pi (task A) and requeue-PI (task B) the following race can happen:
Task A Task B
futex_wait_requeue_pi()
futex_setup_timer()
futex_do_wait()
futex_requeue()
CLASS(hb, hb1)(&key1);
CLASS(hb, hb2)(&key2);
*timeout*
futex_requeue_pi_wakeup_sync()
requeue_state = Q_REQUEUE_PI_IGNORE
*blocks on hb->lock*
futex_proxy_trylock_atomic()
futex_requeue_pi_prepare()
Q_REQUEUE_PI_IGNORE => -EAGAIN
double_unlock_hb(hb1, hb2)
*retry*Task B acquires both hb locks and attempts to acquire the PI-lock of the top most waiter (task B). Task A is leaving early due to a signal/ timeout and started removing itself from the queue. It updates its requeue_state but can not remove it from the list because this requires the hb lock which is owned by task B.
Usually task A is able to swoop the lock after task B unlocked it. However if task B is of higher priority then task A may not be able to wake up in time and acquire the lock before task B gets it again. Especially on a UP system where A is never scheduled.
As a result task A blocks on the lock and task B busy loops, trying to make progress but live locks the system instead. Tragic.
This can be fixed by removing the top most waiter from the list in this case. This allows task B to grab the next top waiter (if any) in the next iteration and make progress.
Remove the top most waiter if futex_requeue_pi_prepare() fails. Let the waiter conditionally remove itself from the list in handle_early_requeue_pi_wakeup().
--- kernel/futex/requeue.c | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-)
kernel/futex/requeue.c +9 -4
@@ -307,8 +307,11 @@ futex_proxy_trylock_atomic(u32 __user *pifutex, struct futex_hash_bucket *hb1,return -EINVAL ;/* Ensure that this does not race against an early wakeup */ -if (!futex_requeue_pi_prepare (top_waiter,NULL )) +if (!futex_requeue_pi_prepare (top_waiter,NULL )) { +plist_del (&top_waiter->list, &hb1->chain); +futex_hb_waiters_dec (hb1);return -EAGAIN ; + }/* * Try to take the lock for top_waiter and set the FUTEX_WAITERS bit
@@ -707,10 +710,12 @@ int handle_early_requeue_pi_wakeup(struct futex_hash_bucket *hb,/* * We were woken prior to requeue by a timeout or a signal. -* Unqueue the futex_q and determine which it was. +* Conditionally unqueue the futex_q and determine which it was. */ -plist_del (&q->list, &hb->chain); -futex_hb_waiters_dec (hb); +if (!plist_node_empty (&q->list)) { +plist_del (&q->list, &hb->chain); +futex_hb_waiters_dec (hb); + }/* Handle spurious wakeups gracefully */ ret = -EWOULDBLOCK ;
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 423/508 drm/amd/display: Allow DCE link encoder without AUX registers
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Timur Kristóf <[email protected]>
[ Upstream commit ac27e3f99035f132f23bc0409d0e57f11f054c70 ]
Allow constructing the DCE link encoder without DDC, which means the AUX registers array will be NULL.
This is necessary to support embedded connectors without DDC.
--- drivers/gpu/drm/amd/display/dc/dce/dce_link_encoder.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
drivers/gpu/drm/amd/display/dc/dce/dce_link_encoder.c +3 -1
@@ -989,7 +989,9 @@ void dce110_link_encoder_hw_init(ASSERT (result ==BP_RESULT_OK ); } -aux_initialize (enc110); + +if (enc110->aux_regs) +aux_initialize (enc110);/* reinitialize HPD. * hpd_initialize() will pass DIG_FE id to HW context.
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 424/508 drm/amd/display: Read EDID from VBIOS embedded panel info
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Timur Kristóf <[email protected]>
[ Upstream commit 9ea16f64189bf7b6ba50fc7f0325b3c1f836d105 ]
Some board manufacturers hardcode the EDID for the embedded panel in the VBIOS. This EDID should be used when the panel doesn't have a DDC.
For reference, see the legacy non-DC display code:amdgpu_atombios_encoder_get_lcd_info()
This is necessary to support embedded connectors without DDC.
--- .../gpu/drm/amd/display/dc/bios/bios_parser.c | 62 +++++++++++++++++++ .../display/include/grph_object_ctrl_defs.h | 4 ++ 2 files changed, 66 insertions(+)
drivers/gpu/drm/amd/display/dc/bios/bios_parser.c +62 -0
@@ -1220,6 +1220,60 @@ static enum bp_result bios_parser_get_embedded_panel_info(return BP_RESULT_FAILURE ; } +static enum bp_result get_embedded_panel_extra_info ( +struct bios_parser *bp, +struct embedded_panel_info *info, +const uint32_t table_offset) +{ +uint8_t *record =bios_get_image (&bp->base, table_offset,1 ); +ATOM_PANEL_RESOLUTION_PATCH_RECORD *panel_res_record; +ATOM_FAKE_EDID_PATCH_RECORD *fake_edid_record; + +while (*record !=ATOM_RECORD_END_TYPE ) { +switch (*record) { +case LCD_MODE_PATCH_RECORD_MODE_TYPE : + record +=sizeof (ATOM_PATCH_RECORD_MODE ); +break ; +case LCD_RTS_RECORD_TYPE : + record +=sizeof (ATOM_LCD_RTS_RECORD ); +break ; +case LCD_CAP_RECORD_TYPE : + record +=sizeof (ATOM_LCD_MODE_CONTROL_CAP ); +break ; +case LCD_FAKE_EDID_PATCH_RECORD_TYPE : + fake_edid_record = (ATOM_FAKE_EDID_PATCH_RECORD *)record; +if (fake_edid_record->ucFakeEDIDLength) { +if (fake_edid_record->ucFakeEDIDLength ==128 ) + info->fake_edid_size = + fake_edid_record->ucFakeEDIDLength; +else + info->fake_edid_size = + fake_edid_record->ucFakeEDIDLength *128 ; + + info->fake_edid = fake_edid_record->ucFakeEDIDString; + + record +=struct_size (fake_edid_record, + ucFakeEDIDString, + info->fake_edid_size); + }else { +/* empty fake edid record must be 3 bytes long */ + record +=sizeof (ATOM_FAKE_EDID_PATCH_RECORD ) +1 ; + } +break ; +case LCD_PANEL_RESOLUTION_RECORD_TYPE : + panel_res_record = (ATOM_PANEL_RESOLUTION_PATCH_RECORD *)record; + info->panel_width_mm = panel_res_record->usHSize; + info->panel_height_mm = panel_res_record->usVSize; + record +=sizeof (ATOM_PANEL_RESOLUTION_PATCH_RECORD ); +break ; +default : +return BP_RESULT_BADBIOSTABLE ; + } + } + +return BP_RESULT_OK ; +} +static enum bp_result get_embedded_panel_info_v1_2 (struct bios_parser *bp,struct embedded_panel_info *info)
@@ -1336,6 +1390,10 @@ static enum bp_result get_embedded_panel_info_v1_2(if (ATOM_PANEL_MISC_API_ENABLED & lvds->ucLVDS_Misc) info->lcd_timing.misc_info.API_ENABLED = true; +if (lvds->usExtInfoTableOffset) +return get_embedded_panel_extra_info (bp, info, +le16_to_cpu (lvds->usExtInfoTableOffset) +DATA_TABLES (LCD_Info)); +return BP_RESULT_OK ; }
@@ -1461,6 +1519,10 @@ static enum bp_result get_embedded_panel_info_v1_3( (uint32_t ) (ATOM_PANEL_MISC_V13_GREY_LEVEL & lvds->ucLCD_Misc) >>ATOM_PANEL_MISC_V13_GREY_LEVEL_SHIFT ; +if (lvds->usExtInfoTableOffset) +return get_embedded_panel_extra_info (bp, info, +le16_to_cpu (lvds->usExtInfoTableOffset) +DATA_TABLES (LCD_Info)); +return BP_RESULT_OK ; }
drivers/gpu/drm/amd/display/include/grph_object_ctrl_defs.h +4 -0
@@ -153,6 +153,10 @@ struct embedded_panel_info {uint32_t drr_enabled;uint32_t min_drr_refresh_rate;bool realtek_eDPToLVDS; +uint16_t panel_width_mm; +uint16_t panel_height_mm; +uint16_t fake_edid_size; +const uint8_t *fake_edid; };struct dc_firmware_info {
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 425/508 bonding: 802.3ad replace MAC_ADDRESS_EQUAL with __agg_has_partner
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jones Syue 薛懷宗 <[email protected]>
[ Upstream commit 4440873f3655325f849366d75382aa05d09b5575 ]
Replace macro MAC_ADDRESS_EQUAL() for null_mac_addr checking with inline function__agg_has_partner(). When MAC_ADDRESS_EQUAL() is verifiying aggregator's partner mac addr with null_mac_addr, means that seeing if aggregator has a valid partner or not. Using __agg_has_partner() makes it more clear to understand.
In ad_port_selection_logic(), since aggregator->partner_system and port->partner_oper.system has been compared first as a prerequisite, it is safe to replace the upcoming MAC_ADDRESS_EQUAL() for null_mac_addr checking with __agg_has_partner().
Delete null_mac_addr, which is not required anymore in bond_3ad.c, since all references to it are gone.
Stable-dep-of: c4f050ce06c5 ("bonding: 3ad: implement proper RCU rules for port->aggregator")
--- drivers/net/bonding/bond_3ad.c | 14 +++----------- 1 file changed, 3 insertions(+), 11 deletions(-)
drivers/net/bonding/bond_3ad.c +3 -11
@@ -82,10 +82,6 @@ enum ad_link_speed_type {#define MAC_ADDRESS_EQUAL (A ,B ) \ ether_addr_equal_64bits((const u8 *)A, (const u8 *)B) -static const u8 null_mac_addr[ETH_ALEN + 2] __long_aligned = { -0 ,0 ,0 ,0 ,0 ,0 -}; -static const u16 ad_ticks_per_sec =1000 /AD_TIMER_INTERVAL ;static const int ad_delta_in_ticks = (AD_TIMER_INTERVAL *HZ ) /1000 ;
@@ -1592,7 +1588,7 @@ static void ad_port_selection_logic(struct port *port, bool *update_slave_arr) (aggregator->partner_system_priority == port->partner_oper.system_priority) && (aggregator->partner_oper_aggregator_key == port->partner_oper.key) ) && - ((!MAC_ADDRESS_EQUAL (&(port->partner_oper.system), &(null_mac_addr)) &&/* partner answers */ + ((__agg_has_partner (aggregator) &&/* partner answers */ !aggregator->is_individual)/* but is not individual OR */ ) ) {
@@ -2042,9 +2038,7 @@ static void ad_enable_collecting(struct port *port)*/ static void ad_disable_distributing (struct port *port,bool *update_slave_arr) { -if (port->aggregator && - !MAC_ADDRESS_EQUAL (&port->aggregator->partner_system, - &(null_mac_addr))) { +if (port->aggregator &&__agg_has_partner (port->aggregator)) { slave_dbg(port->slave->bond->dev, port->slave->dev, "Disabling distributing on port %d (LAG %d)\n", port->actor_port_number,
@@ -2084,9 +2078,7 @@ static void ad_enable_collecting_distributing(struct port *port,static void ad_disable_collecting_distributing (struct port *port,bool *update_slave_arr) { -if (port->aggregator && - !MAC_ADDRESS_EQUAL (&(port->aggregator->partner_system), - &(null_mac_addr))) { +if (port->aggregator &&__agg_has_partner (port->aggregator)) { slave_dbg(port->slave->bond->dev, port->slave->dev, "Disabling port %d (LAG %d)\n", port->actor_port_number,
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 426/508 net: bonding: add broadcast_neighbor option for 802.3ad
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Tonghao Zhang <[email protected]>
[ Upstream commit ce7a381697cb3958ffe0b45e5028ac69444e9288 ]
Stacking technology is a type of technology used to expand ports on Ethernet switches. It is widely used as a common access method in large-scale Internet data center architectures. Years of practice have proved that stacking technology has advantages and disadvantages in high-reliability network architecture scenarios. For instance, in stacking networking arch, conventional switch system upgrades require multiple stacked devices to restart at the same time. Therefore, it is inevitable that the business will be interrupted for a while. It is for this reason that "no-stacking" in data centers has become a trend. Additionally, when the stacking link connecting the switches fails or is abnormal, the stack will split. Although it is not common, it still happens in actual operation. The problem is that after the split, it is equivalent to two switches with the same configuration appearing in the network, causing network configuration conflicts and ultimately interrupting the services carried by the stacking system.
To improve network stability, "non-stacking" solutions have been increasingly adopted, particularly by public cloud providers and tech companies like Alibaba, Tencent, and Didi. "non-stacking" is a method of mimicing switch stacking that convinces a LACP peer, bonding in this case, connected to a set of "non-stacked" switches that all of its ports are connected to a single switch (i.e., LACP aggregator), as if those switches were stacked. This enables the LACP peer's ports to aggregate together, and requires
(a) special switch configuration, described in the linked article, and (b) modifications to the bonding 802.3ad (LACP) mode to send all ARP/ND packets across all ports of the active aggregator.
Note that, with multiple aggregators, the current broadcast mode logic will send only packets to the selected aggregator(s).
+-----------+ +-----------+
| switch1 | | switch2 |
+-----------+ +-----------+
^ ^
| |
+-----------------+
| bond4 lacp |
+-----------------+
| |
| NIC1 | NIC2
+-----------------+
| server |
+-----------------+- https://www.ruijie.com/fr-fr/support/tech-gallery/de-stack-data-center-network-architecture/
Stable-dep-of: c4f050ce06c5 ("bonding: 3ad: implement proper RCU rules for port->aggregator")
--- Documentation/networking/bonding.rst | 6 +++ drivers/net/bonding/bond_main.c | 66 +++++++++++++++++++++++++--- drivers/net/bonding/bond_options.c | 42 ++++++++++++++++++ include/net/bond_options.h | 1 + include/net/bonding.h | 3 ++ 5 files changed, 112 insertions(+), 6 deletions(-)
Documentation/networking/bonding.rst +6 -0
@@ -562,6 +562,12 @@ lacp_rate The default is slow. +broadcast_neighbor + + Option specifying whether to broadcast ARP/ND packets to all + active slaves. This option has no effect in modes other than + 802.3ad mode. The default is off (0). + max_bonds Specifies the number of bonding devices to create for this
drivers/net/bonding/bond_main.c +60 -6
117 lines not on this page · raw message
drivers/net/bonding/bond_options.c +42 -0
69 lines not on this page · raw message
include/net/bond_options.h +1 -0
@@ -77,6 +77,7 @@ enum {BOND_OPT_NS_TARGETS ,BOND_OPT_PRIO ,BOND_OPT_COUPLED_CONTROL , +BOND_OPT_BROADCAST_NEIGH , BOND_OPT_LAST };
include/net/bonding.h +3 -0
@@ -115,6 +115,8 @@ static inline int is_netpoll_tx_blocked(struct net_device *dev)#define is_netpoll_tx_blocked (dev) (0)#endif +DECLARE_STATIC_KEY_FALSE (bond_bcast_neigh_enabled); +struct bond_params {int mode;int xmit_policy;
@@ -149,6 +151,7 @@ struct bond_params {struct in6_addr ns_targets[BOND_MAX_NS_TARGETS ];#endif int coupled_control; +int broadcast_neighbor;/* 2 bytes of padding : see ether_addr_equal_64bits() */ u8 ad_actor_system[ETH_ALEN +2 ];
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 427/508 bonding: add support for per-port LACP actor priority
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Hangbin Liu <[email protected]>
[ Upstream commit 6b6dc81ee7e8ca87c71a533e1d69cf96a4f1e986 ]
Introduce a new netlink attribute 'actor_port_prio' to allow setting the LACP actor port priority on a per-slave basis. This extends the existing bonding infrastructure to support more granular control over LACP negotiations.
The priority value is embedded in LACPDU packets and will be used by subsequent patches to influence aggregator selection policies.
Stable-dep-of: c4f050ce06c5 ("bonding: 3ad: implement proper RCU rules for port->aggregator")
--- Documentation/networking/bonding.rst | 9 +++++++ drivers/net/bonding/bond_3ad.c | 4 ++++ drivers/net/bonding/bond_netlink.c | 16 +++++++++++++ drivers/net/bonding/bond_options.c | 36 ++++++++++++++++++++++++++++ include/net/bond_3ad.h | 1 + include/net/bond_options.h | 1 + include/uapi/linux/if_link.h | 1 + 7 files changed, 68 insertions(+)
Documentation/networking/bonding.rst +9 -0
@@ -193,6 +193,15 @@ ad_actor_sys_prio This parameter has effect only in 802.3ad mode and is available through SysFs interface. +actor_port_prio + + In an AD system, this specifies the port priority. The allowed range + is 1 - 65535. If the value is not specified, it takes 255 as the + default value. + + This parameter has effect only in 802.3ad mode and is available through + netlink interface. + ad_actor_system In an AD system, this specifies the mac-address for the actor in
drivers/net/bonding/bond_3ad.c +4 -0
@@ -436,6 +436,7 @@ static void __ad_actor_update_port(struct port *port) port->actor_system =BOND_AD_INFO (bond).system.sys_mac_addr; port->actor_system_priority =BOND_AD_INFO (bond).system.sys_priority; + port->actor_port_priority =SLAVE_AD_INFO (port->slave)->port_priority; }/* Conversions */
@@ -2195,6 +2196,9 @@ void bond_3ad_bind_slave(struct slave *slave)ad_initialize_port (port, &bond->params); +/* Port priority is initialized. Update it to slave's ad info */ +SLAVE_AD_INFO (slave)->port_priority = port->actor_port_priority; + port->slave = slave; port->actor_port_number =SLAVE_AD_INFO (slave)->id;/* key is determined according to the link speed, duplex and
drivers/net/bonding/bond_netlink.c +16 -0
@@ -28,6 +28,7 @@ static size_t bond_get_slave_size(const struct net_device *bond_dev,nla_total_size (sizeof (u8)) +/* IFLA_BOND_SLAVE_AD_ACTOR_OPER_PORT_STATE */ nla_total_size (sizeof (u16)) +/* IFLA_BOND_SLAVE_AD_PARTNER_OPER_PORT_STATE */ nla_total_size (sizeof (s32)) +/* IFLA_BOND_SLAVE_PRIO */ +nla_total_size (sizeof (u16)) +/* IFLA_BOND_SLAVE_ACTOR_PORT_PRIO */ 0 ; }
@@ -76,6 +77,10 @@ static int bond_fill_slave_info(struct sk_buff *skb, ad_port->partner_oper.port_state)) goto nla_put_failure; } + +if (nla_put_u16 (skb,IFLA_BOND_SLAVE_ACTOR_PORT_PRIO , +SLAVE_AD_INFO (slave)->port_priority)) + goto nla_put_failure; }return 0 ;
@@ -128,6 +133,7 @@ static const struct nla_policy bond_policy[IFLA_BOND_MAX + 1] = {static const struct nla_policy bond_slave_policy[IFLA_BOND_SLAVE_MAX +1 ] = { [IFLA_BOND_SLAVE_QUEUE_ID ] = { .type =NLA_U16 }, [IFLA_BOND_SLAVE_PRIO ] = { .type =NLA_S32 }, + [IFLA_BOND_SLAVE_ACTOR_PORT_PRIO ] = { .type =NLA_U16 }, }; static int bond_validate(struct nlattr *tb[], struct nlattr *data[],
@@ -178,6 +184,16 @@ static int bond_slave_changelink(struct net_device *bond_dev,return err; } +if (data[IFLA_BOND_SLAVE_ACTOR_PORT_PRIO ]) { +u16 ad_prio =nla_get_u16 (data[IFLA_BOND_SLAVE_ACTOR_PORT_PRIO ]); + +bond_opt_slave_initval (&newval, &slave_dev, ad_prio); + err =__bond_opt_set (bond,BOND_OPT_ACTOR_PORT_PRIO , &newval, + data[IFLA_BOND_SLAVE_ACTOR_PORT_PRIO ], extack); +if (err) +return err; + } +return 0 ; }
drivers/net/bonding/bond_options.c +36 -0
@@ -79,6 +79,8 @@ static int bond_option_tlb_dynamic_lb_set(struct bonding *bond, const struct bond_opt_value *newval);static int bond_option_ad_actor_sys_prio_set (struct bonding *bond,const struct bond_opt_value *newval); +static int bond_option_actor_port_prio_set (struct bonding *bond, +const struct bond_opt_value *newval);static int bond_option_ad_actor_system_set (struct bonding *bond,const struct bond_opt_value *newval); static int bond_option_ad_user_port_key_set(struct bonding *bond,
@@ -223,6 +225,13 @@ static const struct bond_opt_value bond_ad_actor_sys_prio_tbl[] = { { NULL, -1, 0}, }; +static const struct bond_opt_value bond_actor_port_prio_tbl[] = { + {"minval" ,0 ,BOND_VALFLAG_MIN }, + {"maxval" ,65535 ,BOND_VALFLAG_MAX }, + {"default" ,255 ,BOND_VALFLAG_DEFAULT }, + {NULL ,-1 ,0 }, +}; +static const struct bond_opt_value bond_ad_user_port_key_tbl[] = { {"minval" ,0 ,BOND_VALFLAG_MIN |BOND_VALFLAG_DEFAULT }, { "maxval", 1023, BOND_VALFLAG_MAX},
@@ -484,6 +493,13 @@ static const struct bond_option bond_opts[BOND_OPT_LAST] = { .values = bond_ad_actor_sys_prio_tbl, .set = bond_option_ad_actor_sys_prio_set, }, + [BOND_OPT_ACTOR_PORT_PRIO] = { + .id = BOND_OPT_ACTOR_PORT_PRIO, + .name = "actor_port_prio", + .unsuppmodes = BOND_MODE_ALL_EX(BIT(BOND_MODE_8023AD)), + .values = bond_actor_port_prio_tbl, + .set = bond_option_actor_port_prio_set, + }, [BOND_OPT_AD_ACTOR_SYSTEM] = { .id = BOND_OPT_AD_ACTOR_SYSTEM, .name = "ad_actor_system",
@@ -1819,6 +1835,26 @@ static int bond_option_ad_actor_sys_prio_set(struct bonding *bond,return 0 ; } +static int bond_option_actor_port_prio_set (struct bonding *bond, +const struct bond_opt_value *newval) +{ +struct slave *slave; + + slave =bond_slave_get_rtnl (newval->slave_dev); +if (!slave) { +netdev_dbg (bond->dev,"%s called on NULL slave\n" , __func__); +return -ENODEV ; + } + +netdev_dbg (newval->slave_dev,"Setting actor_port_prio to %llu\n" , + newval->value); + +SLAVE_AD_INFO (slave)->port_priority = newval->value; +bond_3ad_update_ad_actor_settings (bond); + +return 0 ; +} +static int bond_option_ad_actor_system_set (struct bonding *bond,const struct bond_opt_value *newval) {
include/net/bond_3ad.h +1 -0
@@ -271,6 +271,7 @@ struct ad_slave_info {struct port port;/* 802.3ad port structure */ struct bond_3ad_stats stats;u16 id; +u16 port_priority; };static inline const char *bond_3ad_churn_desc (churn_state_t state)
include/net/bond_options.h +1 -0
@@ -78,6 +78,7 @@ enum {BOND_OPT_PRIO ,BOND_OPT_COUPLED_CONTROL ,BOND_OPT_BROADCAST_NEIGH , +BOND_OPT_ACTOR_PORT_PRIO , BOND_OPT_LAST };
include/uapi/linux/if_link.h +1 -0
@@ -979,6 +979,7 @@ enum {IFLA_BOND_SLAVE_AD_ACTOR_OPER_PORT_STATE ,IFLA_BOND_SLAVE_AD_PARTNER_OPER_PORT_STATE ,IFLA_BOND_SLAVE_PRIO , +IFLA_BOND_SLAVE_ACTOR_PORT_PRIO , __IFLA_BOND_SLAVE_MAX, };
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 428/508 bonding: print churn state via netlink
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Hangbin Liu <[email protected]>
[ Upstream commit 4916f2e2f3fc9aef289fcd07949301e5c29094c2 ]
Currently, the churn state is printed only in sysfs. Add netlink support so users could get the state via netlink.
Stable-dep-of: c4f050ce06c5 ("bonding: 3ad: implement proper RCU rules for port->aggregator")
--- drivers/net/bonding/bond_netlink.c | 9 +++++++++ include/uapi/linux/if_link.h | 2 ++ 2 files changed, 11 insertions(+)
drivers/net/bonding/bond_netlink.c +9 -0
@@ -29,6 +29,8 @@ static size_t bond_get_slave_size(const struct net_device *bond_dev,nla_total_size (sizeof (u16)) +/* IFLA_BOND_SLAVE_AD_PARTNER_OPER_PORT_STATE */ nla_total_size (sizeof (s32)) +/* IFLA_BOND_SLAVE_PRIO */ nla_total_size (sizeof (u16)) +/* IFLA_BOND_SLAVE_ACTOR_PORT_PRIO */ +nla_total_size (sizeof (u8)) +/* IFLA_BOND_SLAVE_AD_CHURN_ACTOR_STATE */ +nla_total_size (sizeof (u8)) +/* IFLA_BOND_SLAVE_AD_CHURN_PARTNER_STATE */ 0 ; }
@@ -76,6 +78,13 @@ static int bond_fill_slave_info(struct sk_buff *skb, IFLA_BOND_SLAVE_AD_PARTNER_OPER_PORT_STATE, ad_port->partner_oper.port_state)) goto nla_put_failure; + +if (nla_put_u8 (skb,IFLA_BOND_SLAVE_AD_CHURN_ACTOR_STATE , + ad_port->sm_churn_actor_state)) + goto nla_put_failure; +if (nla_put_u8 (skb,IFLA_BOND_SLAVE_AD_CHURN_PARTNER_STATE , + ad_port->sm_churn_partner_state)) + goto nla_put_failure; } if (nla_put_u16(skb, IFLA_BOND_SLAVE_ACTOR_PORT_PRIO,
include/uapi/linux/if_link.h +2 -0
@@ -980,6 +980,8 @@ enum {IFLA_BOND_SLAVE_AD_PARTNER_OPER_PORT_STATE ,IFLA_BOND_SLAVE_PRIO ,IFLA_BOND_SLAVE_ACTOR_PORT_PRIO , +IFLA_BOND_SLAVE_AD_CHURN_ACTOR_STATE , +IFLA_BOND_SLAVE_AD_CHURN_PARTNER_STATE , __IFLA_BOND_SLAVE_MAX, };
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 429/508 bonding: 3ad: implement proper RCU rules for port->aggregator
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Eric Dumazet <[email protected]>
[ Upstream commit c4f050ce06c56cfb5993268af4a5cb66ed1cd04e ]
syzbot found a data-race in bond_3ad_get_active_agg_info / bond_3ad_state_machine_handler [1] which hints at lack of proper RCU implementation.
Add __rcu qualifier to port->aggregator, and add proper RCU API.
[1]
BUG: KCSAN: data-race in bond_3ad_get_active_agg_info / bond_3ad_state_machine_handler
write to 0xffff88813cf5c4b0 of 8 bytes by task 36 on cpu 0:
ad_port_selection_logic drivers/net/bonding/bond_3ad.c:1659 [inline] bond_3ad_state_machine_handler+0x9d5/0x2d60 drivers/net/bonding/bond_3ad.c:2569 process_one_work kernel/workqueue.c:3302 [inline] process_scheduled_works+0x4f0/0x9c0 kernel/workqueue.c:3385 worker_thread+0x58a/0x780 kernel/workqueue.c:3466 kthread+0x22a/0x280 kernel/kthread.c:436 ret_from_fork+0x146/0x330 arch/x86/kernel/process.c:158 ret_from_fork_asm+0x1a/0x30 arch/x86/entry/entry_64.S:245
read to 0xffff88813cf5c4b0 of 8 bytes by task 22063 on cpu 1:
__bond_3ad_get_active_agg_info drivers/net/bonding/bond_3ad.c:2858 [inline] bond_3ad_get_active_agg_info+0x8c/0x230 drivers/net/bonding/bond_3ad.c:2881 bond_fill_info+0xe0f/0x10f0 drivers/net/bonding/bond_netlink.c:853 rtnl_link_info_fill net/core/rtnetlink.c:906 [inline] rtnl_link_fill+0x1d7/0x4e0 net/core/rtnetlink.c:927 rtnl_fill_ifinfo+0xf8e/0x1380 net/core/rtnetlink.c:2168 rtmsg_ifinfo_build_skb+0x11c/0x1b0 net/core/rtnetlink.c:4453 rtmsg_ifinfo_event net/core/rtnetlink.c:4486 [inline] rtmsg_ifinfo+0x6d/0x110 net/core/rtnetlink.c:4495 __dev_notify_flags+0x76/0x390 net/core/dev.c:9790 netif_change_flags+0xac/0xd0 net/core/dev.c:9823 do_setlink+0x905/0x2950 net/core/rtnetlink.c:3180 rtnl_group_changelink net/core/rtnetlink.c:3813 [inline] __rtnl_newlink net/core/rtnetlink.c:3981 [inline] rtnl_newlink+0xf55/0x1400 net/core/rtnetlink.c:4109 rtnetlink_rcv_msg+0x64b/0x720 net/core/rtnetlink.c:6995 netlink_rcv_skb+0x123/0x220 net/netlink/af_netlink.c:2550 rtnetlink_rcv+0x1c/0x30 net/core/rtnetlink.c:7022 netlink_unicast_kernel net/netlink/af_netlink.c:1318 [inline] netlink_unicast+0x5a8/0x680 net/netlink/af_netlink.c:1344 netlink_sendmsg+0x5c8/0x6f0 net/netlink/af_netlink.c:1894 sock_sendmsg_nosec net/socket.c:787 [inline] __sock_sendmsg net/socket.c:802 [inline] ____sys_sendmsg+0x563/0x5b0 net/socket.c:2698 ___sys_sendmsg+0x195/0x1e0 net/socket.c:2752 __sys_sendmsg net/socket.c:2784 [inline] __do_sys_sendmsg net/socket.c:2789 [inline] __se_sys_sendmsg net/socket.c:2787 [inline] __x64_sys_sendmsg+0xd4/0x160 net/socket.c:2787 x64_sys_call+0x194c/0x3020 arch/x86/include/generated/asm/syscalls_64.h:47 do_syscall_x64 arch/x86/entry/syscall_64.c:63 [inline] do_syscall_64+0x12c/0x3b0 arch/x86/entry/syscall_64.c:94 entry_SYSCALL_64_after_hwframe+0x77/0x7f
value changed: 0x0000000000000000 -> 0xffff88813cf5c400
Reported by Kernel Concurrency Sanitizer on:
CPU: 1 UID: 0 PID: 22063 Comm: syz.0.31122 Tainted: G W syzkaller #0 PREEMPT(full) Tainted: [W]=WARN Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 04/18/2026
--- drivers/net/bonding/bond_3ad.c | 109 ++++++++++++++----------- drivers/net/bonding/bond_main.c | 8 +- drivers/net/bonding/bond_netlink.c | 16 ++-- drivers/net/bonding/bond_procfs.c | 3 +- drivers/net/bonding/bond_sysfs_slave.c | 17 ++-- include/net/bond_3ad.h | 2 +- 6 files changed, 89 insertions(+), 66 deletions(-)
drivers/net/bonding/bond_3ad.c +60 -49
@@ -991,6 +991,7 @@ static int ad_marker_send(struct port *port, struct bond_marker *marker)static void ad_mux_machine (struct port *port,bool *update_slave_arr) {struct bonding *bond =__get_bond_by_port (port); +struct aggregator *aggregator;mux_states_t last_state;/* keep current State Machine state to compare later if it was
@@ -998,6 +999,7 @@ static void ad_mux_machine(struct port *port, bool *update_slave_arr)*/ last_state = port->sm_mux_state; + aggregator =rcu_dereference (port->aggregator);if (port->sm_vars &AD_PORT_BEGIN ) { port->sm_mux_state =AD_MUX_DETACHED ; }else {
@@ -1017,7 +1019,7 @@ static void ad_mux_machine(struct port *port, bool *update_slave_arr)* cycle to update ready variable, we check * READY_N and update READY here */ -__set_agg_ports_ready (port->aggregator,__agg_ports_are_ready (port->aggregator)); +__set_agg_ports_ready (aggregator,__agg_ports_are_ready (aggregator)); port->sm_mux_state =AD_MUX_DETACHED ;break ; }
@@ -1032,7 +1034,7 @@ static void ad_mux_machine(struct port *port, bool *update_slave_arr)* update ready variable, we check READY_N and update * READY here */ -__set_agg_ports_ready (port->aggregator,__agg_ports_are_ready (port->aggregator)); +__set_agg_ports_ready (aggregator,__agg_ports_are_ready (aggregator));/* if the wait_while_timer expired, and the port is * in READY state, move to ATTACHED state
@@ -1048,7 +1050,7 @@ static void ad_mux_machine(struct port *port, bool *update_slave_arr)if ((port->sm_vars &AD_PORT_SELECTED ) && (port->partner_oper.port_state &LACP_STATE_SYNCHRONIZATION ) && !__check_agg_selection_timer (port)) { -if (port->aggregator->is_active) { +if (aggregator->is_active) {int state =AD_MUX_COLLECTING_DISTRIBUTING ;if (!bond->params.coupled_control)
@@ -1064,9 +1066,9 @@ static void ad_mux_machine(struct port *port, bool *update_slave_arr)* cycle to update ready variable, we check * READY_N and update READY here */ -__set_agg_ports_ready (port->aggregator,__agg_ports_are_ready (port->aggregator)); +__set_agg_ports_ready (aggregator,__agg_ports_are_ready (aggregator)); port->sm_mux_state =AD_MUX_DETACHED ; - }else if (port->aggregator->is_active) { + }else if (aggregator->is_active) { port->actor_oper_port_state |=LACP_STATE_SYNCHRONIZATION ; }
@@ -1077,7 +1079,7 @@ static void ad_mux_machine(struct port *port, bool *update_slave_arr)* sure that a collecting distributing * port in an active aggregator is enabled */ -if (port->aggregator->is_active && +if (aggregator->is_active && !__port_is_collecting_distributing (port)) {__enable_port (port); *update_slave_arr = true;
@@ -1096,7 +1098,7 @@ static void ad_mux_machine(struct port *port, bool *update_slave_arr)*/ struct slave *slave = port->slave; -if (port->aggregator->is_active && +if (aggregator->is_active &&bond_is_slave_rx_disabled (slave)) {ad_enable_collecting (port); *update_slave_arr = true;
@@ -1116,8 +1118,8 @@ static void ad_mux_machine(struct port *port, bool *update_slave_arr)* sure that a collecting distributing * port in an active aggregator is enabled */ -if (port->aggregator && - port->aggregator->is_active && +if (aggregator && + aggregator->is_active && !__port_is_collecting_distributing (port)) {__enable_port (port); *update_slave_arr = true;
@@ -1149,7 +1151,7 @@ static void ad_mux_machine(struct port *port, bool *update_slave_arr) port->sm_mux_timer_counter =__ad_timer_to_ticks (AD_WAIT_WHILE_TIMER ,0 );break ;case AD_MUX_ATTACHED : -if (port->aggregator->is_active) +if (aggregator->is_active) port->actor_oper_port_state |=LACP_STATE_SYNCHRONIZATION ;else
@@ -1522,9 +1524,9 @@ static void ad_port_selection_logic(struct port *port, bool *update_slave_arr) bond =__get_bond_by_port (port);/* if the port is connected to other aggregator, detach it */ -if (port->aggregator) { + temp_aggregator =rcu_dereference (port->aggregator); +if (temp_aggregator) {/* detach the port from its former aggregator */ - temp_aggregator = port->aggregator;for (curr_port = temp_aggregator->lag_ports; curr_port; last_port = curr_port, curr_port = curr_port->next_port_in_aggregator) {
@@ -1547,7 +1549,7 @@ static void ad_port_selection_logic(struct port *port, bool *update_slave_arr)/* clear the port's relations to this * aggregator */ - port->aggregator =NULL ; +RCU_INIT_POINTER (port->aggregator,NULL ); port->next_port_in_aggregator =NULL ; port->actor_port_aggregator_identifier =0 ;
@@ -1570,7 +1572,7 @@ static void ad_port_selection_logic(struct port *port, bool *update_slave_arr) port->slave->bond->dev->name, port->slave->dev->name, port->actor_port_number, - port->aggregator->aggregator_identifier); + temp_aggregator->aggregator_identifier); } }/* search on all aggregators for a suitable aggregator for this port */
@@ -1594,15 +1596,15 @@ static void ad_port_selection_logic(struct port *port, bool *update_slave_arr) ) ) {/* attach to the founded aggregator */ - port->aggregator = aggregator; +rcu_assign_pointer (port->aggregator, aggregator); port->actor_port_aggregator_identifier = - port->aggregator->aggregator_identifier; + aggregator->aggregator_identifier; port->next_port_in_aggregator = aggregator->lag_ports; - port->aggregator->num_of_ports++; + aggregator->num_of_ports++; aggregator->lag_ports = port;slave_dbg (bond->dev, slave->dev,"Port %d joined LAG %d (existing LAG)\n" , port->actor_port_number, - port->aggregator->aggregator_identifier); + aggregator->aggregator_identifier);/* mark this port as selected */ port->sm_vars |=AD_PORT_SELECTED ;
@@ -1617,39 +1619,40 @@ static void ad_port_selection_logic(struct port *port, bool *update_slave_arr)if (!found) {if (free_aggregator) {/* assign port a new aggregator */ - port->aggregator = free_aggregator; port->actor_port_aggregator_identifier = - port->aggregator->aggregator_identifier; + free_aggregator->aggregator_identifier;/* update the new aggregator's parameters * if port was responsed from the end-user */ if (port->actor_oper_port_key &AD_DUPLEX_KEY_MASKS )/* if port is full duplex */ - port->aggregator->is_individual = false; + free_aggregator->is_individual = false;else - port->aggregator->is_individual = true; + free_aggregator->is_individual = true; - port->aggregator->actor_admin_aggregator_key = + free_aggregator->actor_admin_aggregator_key = port->actor_admin_port_key; - port->aggregator->actor_oper_aggregator_key = + free_aggregator->actor_oper_aggregator_key = port->actor_oper_port_key; - port->aggregator->partner_system = + free_aggregator->partner_system = port->partner_oper.system; - port->aggregator->partner_system_priority = + free_aggregator->partner_system_priority = port->partner_oper.system_priority; - port->aggregator->partner_oper_aggregator_key = port->partner_oper.key; - port->aggregator->receive_state =1 ; - port->aggregator->transmit_state =1 ; - port->aggregator->lag_ports = port; - port->aggregator->num_of_ports++; + free_aggregator->partner_oper_aggregator_key = port->partner_oper.key; + free_aggregator->receive_state =1 ; + free_aggregator->transmit_state =1 ; + free_aggregator->lag_ports = port; + free_aggregator->num_of_ports++; + +rcu_assign_pointer (port->aggregator, free_aggregator);/* mark this port as selected */ port->sm_vars |=AD_PORT_SELECTED ;slave_dbg (bond->dev, port->slave->dev,"Port %d joined LAG %d (new LAG)\n" , port->actor_port_number, - port->aggregator->aggregator_identifier); + free_aggregator->aggregator_identifier); }else { slave_err(bond->dev, port->slave->dev, "Port %d did not find a suitable aggregator\n",
@@ -1661,13 +1664,12 @@ static void ad_port_selection_logic(struct port *port, bool *update_slave_arr)* in all aggregator's ports, else set ready=FALSE in all * aggregator's ports */ -__set_agg_ports_ready (port->aggregator, -__agg_ports_are_ready (port->aggregator)); + aggregator =rcu_dereference (port->aggregator); +__set_agg_ports_ready (aggregator,__agg_ports_are_ready (aggregator)); - aggregator =__get_first_agg (port); -ad_agg_selection_logic (aggregator, update_slave_arr); +ad_agg_selection_logic (__get_first_agg (port), update_slave_arr); -if (!port->aggregator->is_active) +if (!aggregator->is_active) port->actor_oper_port_state &= ~LACP_STATE_SYNCHRONIZATION ; }
@@ -2021,13 +2023,15 @@ static void ad_initialize_port(struct port *port, const struct bond_params *bond*/ static void ad_enable_collecting (struct port *port) { -if (port->aggregator->is_active) { +struct aggregator *aggregator =rcu_dereference (port->aggregator); + +if (aggregator->is_active) {struct slave *slave = port->slave;slave_dbg (slave->bond->dev, slave->dev,"Enabling collecting on port %d (LAG %d)\n" , port->actor_port_number, - port->aggregator->aggregator_identifier); + aggregator->aggregator_identifier);__enable_collecting_port (port); } }
@@ -2039,11 +2043,13 @@ static void ad_enable_collecting(struct port *port)*/ static void ad_disable_distributing (struct port *port,bool *update_slave_arr) { -if (port->aggregator &&__agg_has_partner (port->aggregator)) { +struct aggregator *aggregator =rcu_dereference (port->aggregator); + +if (aggregator &&__agg_has_partner (aggregator)) {slave_dbg (port->slave->bond->dev, port->slave->dev,"Disabling distributing on port %d (LAG %d)\n" , port->actor_port_number, - port->aggregator->aggregator_identifier); + aggregator->aggregator_identifier);__disable_distributing_port (port);/* Slave array needs an update */ *update_slave_arr = true;
@@ -2060,11 +2066,13 @@ static void ad_disable_distributing(struct port *port, bool *update_slave_arr)static void ad_enable_collecting_distributing (struct port *port,bool *update_slave_arr) { -if (port->aggregator->is_active) { +struct aggregator *aggregator =rcu_dereference (port->aggregator); + +if (aggregator->is_active) {slave_dbg (port->slave->bond->dev, port->slave->dev,"Enabling port %d (LAG %d)\n" , port->actor_port_number, - port->aggregator->aggregator_identifier); + aggregator->aggregator_identifier);__enable_port (port);/* Slave array needs update */ *update_slave_arr = true;
@@ -2079,11 +2087,13 @@ static void ad_enable_collecting_distributing(struct port *port,static void ad_disable_collecting_distributing (struct port *port,bool *update_slave_arr) { -if (port->aggregator &&__agg_has_partner (port->aggregator)) { +struct aggregator *aggregator =rcu_dereference (port->aggregator); + +if (aggregator &&__agg_has_partner (aggregator)) {slave_dbg (port->slave->bond->dev, port->slave->dev,"Disabling port %d (LAG %d)\n" , port->actor_port_number, - port->aggregator->aggregator_identifier); + aggregator->aggregator_identifier);__disable_port (port);/* Slave array needs an update */ *update_slave_arr = true;
@@ -2323,7 +2333,7 @@ void bond_3ad_unbind_slave(struct slave *slave)*/ for (temp_port = aggregator->lag_ports; temp_port; temp_port = temp_port->next_port_in_aggregator) { - temp_port->aggregator = new_aggregator; +rcu_assign_pointer (temp_port->aggregator, new_aggregator); temp_port->actor_port_aggregator_identifier = new_aggregator->aggregator_identifier; }
@@ -2792,15 +2802,16 @@ int bond_3ad_set_carrier(struct bonding *bond)int __bond_3ad_get_active_agg_info (struct bonding *bond,struct ad_info *ad_info) { -struct aggregator *aggregator =NULL ; +struct aggregator *aggregator =NULL , *tmp;struct list_head *iter;struct slave *slave;struct port *port;bond_for_each_slave_rcu (bond, slave, iter) { port = &(SLAVE_AD_INFO (slave)->port); -if (port->aggregator && port->aggregator->is_active) { - aggregator = port->aggregator; + tmp =rcu_dereference (port->aggregator); +if (tmp && tmp->is_active) { + aggregator = tmp;break ; } }
drivers/net/bonding/bond_main.c +5 -3
@@ -1394,7 +1394,7 @@ static void bond_poll_controller(struct net_device *bond_dev)if (BOND_MODE (bond) ==BOND_MODE_8023AD ) {struct aggregator *agg = -SLAVE_AD_INFO (slave)->port.aggregator; +rcu_dereference (SLAVE_AD_INFO (slave)->port.aggregator);if (agg && agg->aggregator_identifier != ad_info.aggregator_id)
@@ -5196,15 +5196,16 @@ int bond_update_slave_arr(struct bonding *bond, struct slave *skipslave)spin_unlock_bh (&bond->mode_lock); agg_id = ad_info.aggregator_id; } +rcu_read_lock ();bond_for_each_slave (bond, slave, iter) {if (skipslave == slave)continue ; all_slaves->arr[all_slaves->count++] = slave;if (BOND_MODE (bond) ==BOND_MODE_8023AD ) { -struct aggregator *agg; +const struct aggregator *agg; - agg =SLAVE_AD_INFO (slave)->port.aggregator; + agg =rcu_dereference (SLAVE_AD_INFO (slave)->port.aggregator);if (!agg || agg->aggregator_identifier != agg_id)continue ; }
@@ -5216,6 +5217,7 @@ int bond_update_slave_arr(struct bonding *bond, struct slave *skipslave) usable_slaves->arr[usable_slaves->count++] = slave; } +rcu_read_unlock ();bond_set_slave_arr (bond, usable_slaves, all_slaves);return ret;
drivers/net/bonding/bond_netlink.c +10 -6
@@ -65,27 +65,29 @@ static int bond_fill_slave_info(struct sk_buff *skb,const struct port *ad_port; ad_port = &SLAVE_AD_INFO (slave)->port; - agg =SLAVE_AD_INFO (slave)->port.aggregator; +rcu_read_lock (); + agg =rcu_dereference (SLAVE_AD_INFO (slave)->port.aggregator);if (agg) {if (nla_put_u16 (skb,IFLA_BOND_SLAVE_AD_AGGREGATOR_ID , agg->aggregator_identifier)) - goto nla_put_failure; + goto nla_put_failure_rcu;if (nla_put_u8 (skb,IFLA_BOND_SLAVE_AD_ACTOR_OPER_PORT_STATE , ad_port->actor_oper_port_state)) - goto nla_put_failure; + goto nla_put_failure_rcu;if (nla_put_u16 (skb,IFLA_BOND_SLAVE_AD_PARTNER_OPER_PORT_STATE , ad_port->partner_oper.port_state)) - goto nla_put_failure; + goto nla_put_failure_rcu;if (nla_put_u8 (skb,IFLA_BOND_SLAVE_AD_CHURN_ACTOR_STATE , ad_port->sm_churn_actor_state)) - goto nla_put_failure; + goto nla_put_failure_rcu;if (nla_put_u8 (skb,IFLA_BOND_SLAVE_AD_CHURN_PARTNER_STATE , ad_port->sm_churn_partner_state)) - goto nla_put_failure; + goto nla_put_failure_rcu; } +rcu_read_unlock ();if (nla_put_u16 (skb,IFLA_BOND_SLAVE_ACTOR_PORT_PRIO ,SLAVE_AD_INFO (slave)->port_priority))
@@ -94,6 +96,8 @@ static int bond_fill_slave_info(struct sk_buff *skb,return 0 ; +nla_put_failure_rcu: +rcu_read_unlock (); nla_put_failure:return -EMSGSIZE ; }
drivers/net/bonding/bond_procfs.c +2 -1
@@ -187,6 +187,7 @@ static void bond_info_show_master(struct seq_file *seq) } } +/* Note: runs under rcu_read_lock() */ static void bond_info_show_slave (struct seq_file *seq,const struct slave *slave) {
@@ -213,7 +214,7 @@ static void bond_info_show_slave(struct seq_file *seq,if (BOND_MODE (bond) ==BOND_MODE_8023AD ) {const struct port *port = &SLAVE_AD_INFO (slave)->port; -const struct aggregator *agg = port->aggregator; +const struct aggregator *agg =rcu_dereference (port->aggregator);if (agg) { seq_printf(seq, "Aggregator ID: %d\n",
drivers/net/bonding/bond_sysfs_slave.c +11 -6
@@ -62,10 +62,15 @@ static ssize_t ad_aggregator_id_show(struct slave *slave, char *buf)const struct aggregator *agg;if (BOND_MODE (slave->bond) ==BOND_MODE_8023AD ) { - agg =SLAVE_AD_INFO (slave)->port.aggregator; -if (agg) -return sysfs_emit (buf,"%d\n" , - agg->aggregator_identifier); +rcu_read_lock (); + agg =rcu_dereference (SLAVE_AD_INFO (slave)->port.aggregator); +if (agg) { +ssize_t res =sysfs_emit (buf,"%d\n" , + agg->aggregator_identifier); +rcu_read_unlock (); +return res; + } +rcu_read_unlock (); }return sysfs_emit (buf,"N/A\n" );
@@ -78,7 +83,7 @@ static ssize_t ad_actor_oper_port_state_show(struct slave *slave, char *buf)if (BOND_MODE (slave->bond) ==BOND_MODE_8023AD ) { ad_port = &SLAVE_AD_INFO (slave)->port; -if (ad_port->aggregator) +if (rcu_access_pointer (ad_port->aggregator))return sysfs_emit (buf,"%u\n" , ad_port->actor_oper_port_state); }
@@ -93,7 +98,7 @@ static ssize_t ad_partner_oper_port_state_show(struct slave *slave, char *buf)if (BOND_MODE (slave->bond) ==BOND_MODE_8023AD ) { ad_port = &SLAVE_AD_INFO (slave)->port; -if (ad_port->aggregator) +if (rcu_access_pointer (ad_port->aggregator))return sysfs_emit (buf,"%u\n" , ad_port->partner_oper.port_state); }
include/net/bond_3ad.h +1 -1
@@ -239,7 +239,7 @@ typedef struct port {churn_state_t sm_churn_actor_state;churn_state_t sm_churn_partner_state;struct slave *slave;/* pointer to the bond slave that this port belongs to */ -struct aggregator *aggregator;/* pointer to an aggregator that this port related to */ +struct aggregator __rcu *aggregator;/* pointer to an aggregator that this port related to */ struct port *next_port_in_aggregator;/* Next port on the linked list of the parent aggregator */ u32 transaction_id;/* continuous number for identification of Marker PDU's; */ struct lacpdu lacpdu;/* the lacpdu that will be sent for this port */
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 430/508 iavf: rename IAVF_VLAN_IS_NEW to IAVF_VLAN_ADDING
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Petr Oros <[email protected]>
[ Upstream commit 70d62b669f1f9080a25278fc90b64309f4ae8959 ]
Rename the IAVF_VLAN_IS_NEW state to IAVF_VLAN_ADDING to better describe what the state represents: an ADD request has been sent to the PF and is waiting for a response.
This is a pure rename with no behavioral change, preparing for a cleanup of the VLAN filter state machine.
Stable-dep-of: f2ce65b9b917 ("iavf: stop removing VLAN filters from PF on interface down")
--- drivers/net/ethernet/intel/iavf/iavf.h | 2 +- drivers/net/ethernet/intel/iavf/iavf_virtchnl.c | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-)
drivers/net/ethernet/intel/iavf/iavf.h +1 -1
@@ -158,7 +158,7 @@ struct iavf_vlan {enum iavf_vlan_state_t {IAVF_VLAN_INVALID ,IAVF_VLAN_ADD ,/* filter needs to be added */ -IAVF_VLAN_IS_NEW ,/* filter is new, wait for PF answer */ +IAVF_VLAN_ADDING ,/* ADD sent to PF, waiting for response */ IAVF_VLAN_ACTIVE ,/* filter is accepted by PF */ IAVF_VLAN_DISABLE ,/* filter needs to be deleted by PF, then marked INACTIVE */ IAVF_VLAN_INACTIVE ,/* filter is inactive, we are in IFF_DOWN */
drivers/net/ethernet/intel/iavf/iavf_virtchnl.c +4 -4
@@ -637,7 +637,7 @@ static void iavf_vlan_add_reject(struct iavf_adapter *adapter)spin_lock_bh (&adapter->mac_vlan_list_lock);list_for_each_entry_safe (f, ftmp, &adapter->vlan_filter_list, list) { -if (f->state ==IAVF_VLAN_IS_NEW ) { +if (f->state ==IAVF_VLAN_ADDING ) {list_del (&f->list);kfree (f); adapter->num_vlan_filters--;
@@ -702,7 +702,7 @@ void iavf_add_vlans(struct iavf_adapter *adapter)if (f->state ==IAVF_VLAN_ADD ) { vvfl->vlan_id[i] = f->vlan.vid; i++; - f->state =IAVF_VLAN_IS_NEW ; + f->state =IAVF_VLAN_ADDING ;if (i == count)break ; }
@@ -763,7 +763,7 @@ void iavf_add_vlans(struct iavf_adapter *adapter) vlan->tpid = f->vlan.tpid; i++; - f->state =IAVF_VLAN_IS_NEW ; + f->state =IAVF_VLAN_ADDING ; } }
@@ -2520,7 +2520,7 @@ void iavf_virtchnl_completion(struct iavf_adapter *adapter,spin_lock_bh (&adapter->mac_vlan_list_lock);list_for_each_entry (f, &adapter->vlan_filter_list, list) { -if (f->state ==IAVF_VLAN_IS_NEW ) +if (f->state ==IAVF_VLAN_ADDING ) f->state =IAVF_VLAN_ACTIVE ; }spin_unlock_bh (&adapter->mac_vlan_list_lock);
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 431/508 iavf: stop removing VLAN filters from PF on interface down
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Petr Oros <[email protected]>
[ Upstream commit f2ce65b9b917474a1a6ce68d357e15fac2aca0f2 ]
When a VF goes down, the driver currently sends DEL_VLAN to the PF for every VLAN filter (ACTIVE -> DISABLE -> send DEL -> INACTIVE), then re-adds them all on UP (INACTIVE -> ADD -> send ADD -> ADDING -> ACTIVE). This round-trip is unnecessary because:
1. The PF disables the VF's queues via VIRTCHNL_OP_DISABLE_QUEUES, which already prevents all RX/TX traffic regardless of VLAN filter state.
2. The VLAN filters remaining in PF HW while the VF is down is harmless - packets matching those filters have nowhere to go with queues disabled.
3. The DEL+ADD cycle during down/up creates race windows where the VLAN filter list is incomplete. With spoofcheck enabled, the PF enables TX VLAN filtering on the first non-zero VLAN add, blocking traffic for any VLANs not yet re-added.
Remove the entire DISABLE/INACTIVE state machinery:
- Remove IAVF_VLAN_DISABLE and IAVF_VLAN_INACTIVE enum values
- Remove iavf_restore_filters() and its call from iavf_open()
- Remove VLAN filter handling from iavf_clear_mac_vlan_filters(), rename it to iavf_clear_mac_filters()
- Remove DEL_VLAN_FILTER scheduling from iavf_down()
- Remove all DISABLE/INACTIVE handling from iavf_del_vlans()
VLAN filters now stay ACTIVE across down/up cycles. Only explicit user removal (ndo_vlan_rx_kill_vid) or PF/VF reset triggers VLAN filter deletion/re-addition.
--- drivers/net/ethernet/intel/iavf/iavf.h | 6 +-- drivers/net/ethernet/intel/iavf/iavf_main.c | 39 ++----------------- .../net/ethernet/intel/iavf/iavf_virtchnl.c | 33 +++------------- 3 files changed, 12 insertions(+), 66 deletions(-)
drivers/net/ethernet/intel/iavf/iavf.h +2 -4
@@ -159,10 +159,8 @@ enum iavf_vlan_state_t {IAVF_VLAN_INVALID ,IAVF_VLAN_ADD ,/* filter needs to be added */ IAVF_VLAN_ADDING ,/* ADD sent to PF, waiting for response */ -IAVF_VLAN_ACTIVE ,/* filter is accepted by PF */ -IAVF_VLAN_DISABLE ,/* filter needs to be deleted by PF, then marked INACTIVE */ -IAVF_VLAN_INACTIVE ,/* filter is inactive, we are in IFF_DOWN */ - IAVF_VLAN_REMOVE, /* filter needs to be removed from list */ +IAVF_VLAN_ACTIVE ,/* PF confirmed, filter is in HW */ + IAVF_VLAN_REMOVE, /* filter queued for DEL from PF */ }; struct iavf_vlan_filter {
drivers/net/ethernet/intel/iavf/iavf_main.c +4 -35
@@ -846,27 +846,6 @@ static void iavf_del_vlan(struct iavf_adapter *adapter, struct iavf_vlan vlan)spin_unlock_bh (&adapter->mac_vlan_list_lock); } -/** -* iavf_restore_filters -* @adapter: board private structure -* -* Restore existing non MAC filters when VF netdev comes back up -**/ -static void iavf_restore_filters (struct iavf_adapter *adapter) -{ -struct iavf_vlan_filter *f; - -/* re-add all VLAN filters */ -spin_lock_bh (&adapter->mac_vlan_list_lock); - -list_for_each_entry (f, &adapter->vlan_filter_list, list) { -if (f->state ==IAVF_VLAN_INACTIVE ) - f->state =IAVF_VLAN_ADD ; - } - -spin_unlock_bh (&adapter->mac_vlan_list_lock); - adapter->aq_required |=IAVF_FLAG_AQ_ADD_VLAN_FILTER ; -}/** * iavf_get_num_vlans_added - get number of VLANs added
@@ -1289,13 +1268,12 @@ static void iavf_up_complete(struct iavf_adapter *adapter) }/** -* iavf_clear_mac_vlan_filters - Remove mac and vlan filters not sent to PF -* yet and mark other to be removed. +* iavf_clear_mac_filters - Remove MAC filters not sent to PF yet and mark +* others to be removed. * @adapter: board private structure **/ -static void iavf_clear_mac_vlan_filters (struct iavf_adapter *adapter) +static void iavf_clear_mac_filters (struct iavf_adapter *adapter) { -struct iavf_vlan_filter *vlf, *vlftmp;struct iavf_mac_filter *f, *ftmp;spin_lock_bh (&adapter->mac_vlan_list_lock);
@@ -1314,11 +1292,6 @@ static void iavf_clear_mac_vlan_filters(struct iavf_adapter *adapter) } } -/* disable all VLAN filters */ -list_for_each_entry_safe (vlf, vlftmp, &adapter->vlan_filter_list, - list) - vlf->state =IAVF_VLAN_DISABLE ; -spin_unlock_bh (&adapter->mac_vlan_list_lock); }
@@ -1414,7 +1387,7 @@ void iavf_down(struct iavf_adapter *adapter)iavf_napi_disable_all (adapter);iavf_irq_disable (adapter); -iavf_clear_mac_vlan_filters (adapter); +iavf_clear_mac_filters (adapter);iavf_clear_cloud_filters (adapter);iavf_clear_fdir_filters (adapter);iavf_clear_adv_rss_conf (adapter);
@@ -1429,8 +1402,6 @@ void iavf_down(struct iavf_adapter *adapter)*/ if (!list_empty (&adapter->mac_filter_list)) adapter->aq_required |=IAVF_FLAG_AQ_DEL_MAC_FILTER ; -if (!list_empty (&adapter->vlan_filter_list)) - adapter->aq_required |=IAVF_FLAG_AQ_DEL_VLAN_FILTER ;if (!list_empty (&adapter->cloud_filter_list)) adapter->aq_required |=IAVF_FLAG_AQ_DEL_CLOUD_FILTER ;if (!list_empty (&adapter->fdir_list_head))
@@ -4295,8 +4266,6 @@ static int iavf_open(struct net_device *netdev)spin_unlock_bh (&adapter->mac_vlan_list_lock); -/* Restore filters that were removed with IFF_DOWN */ -iavf_restore_filters (adapter);iavf_restore_fdir_filters (adapter);iavf_configure (adapter);
drivers/net/ethernet/intel/iavf/iavf_virtchnl.c +6 -27
@@ -800,22 +800,12 @@ void iavf_del_vlans(struct iavf_adapter *adapter)spin_lock_bh (&adapter->mac_vlan_list_lock);list_for_each_entry_safe (f, ftmp, &adapter->vlan_filter_list, list) { -/* since VLAN capabilities are not allowed, we dont want to send -* a VLAN delete request because it will most likely fail and -* create unnecessary errors/noise, so just free the VLAN -* filters marked for removal to enable bailing out before -* sending a virtchnl message -*/ if (f->state ==IAVF_VLAN_REMOVE && !VLAN_FILTERING_ALLOWED (adapter)) {list_del (&f->list);kfree (f); adapter->num_vlan_filters--; - }else if (f->state ==IAVF_VLAN_DISABLE && - !VLAN_FILTERING_ALLOWED (adapter)) { - f->state =IAVF_VLAN_INACTIVE ; - }else if (f->state ==IAVF_VLAN_REMOVE || - f->state ==IAVF_VLAN_DISABLE ) { + }else if (f->state ==IAVF_VLAN_REMOVE ) { count++; } }
@@ -847,13 +837,7 @@ void iavf_del_vlans(struct iavf_adapter *adapter) vvfl->vsi_id = adapter->vsi_res->vsi_id; vvfl->num_elements = count;list_for_each_entry_safe (f, ftmp, &adapter->vlan_filter_list, list) { -if (f->state ==IAVF_VLAN_DISABLE ) { - vvfl->vlan_id[i] = f->vlan.vid; - f->state =IAVF_VLAN_INACTIVE ; - i++; -if (i == count) -break ; - }else if (f->state ==IAVF_VLAN_REMOVE ) { +if (f->state ==IAVF_VLAN_REMOVE ) { vvfl->vlan_id[i] = f->vlan.vid;list_del (&f->list);kfree (f);
@@ -894,8 +878,7 @@ void iavf_del_vlans(struct iavf_adapter *adapter) vvfl_v2->vport_id = adapter->vsi_res->vsi_id; vvfl_v2->num_elements = count;list_for_each_entry_safe (f, ftmp, &adapter->vlan_filter_list, list) { -if (f->state ==IAVF_VLAN_DISABLE || - f->state ==IAVF_VLAN_REMOVE ) { +if (f->state ==IAVF_VLAN_REMOVE ) {struct virtchnl_vlan_supported_caps *filtering_support = &adapter->vlan_v2_caps.filtering.filtering_support;struct virtchnl_vlan *vlan;
@@ -909,13 +892,9 @@ void iavf_del_vlans(struct iavf_adapter *adapter) vlan->tci = f->vlan.vid; vlan->tpid = f->vlan.tpid; -if (f->state ==IAVF_VLAN_DISABLE ) { - f->state =IAVF_VLAN_INACTIVE ; - }else { -list_del (&f->list); -kfree (f); - adapter->num_vlan_filters--; - } +list_del (&f->list); +kfree (f); + adapter->num_vlan_filters--; i++;if (i == count)break ;
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 432/508 iavf: wait for PF confirmation before removing VLAN filters
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Petr Oros <[email protected]>
[ Upstream commit bbcbe4ed70dea948849549af7edf44bd42bbd695 ]
The VLAN filter DELETE path was asymmetric with the ADD path: ADD waits for PF confirmation (ADD -> ADDING -> ACTIVE), but DELETE immediately frees the filter struct after sending the DEL message without waiting for the PF response.
This is problematic because:
- If the PF rejects the DEL, the filter remains in HW but the driver has already freed the tracking structure, losing sync.
- Race conditions between DEL pending and other operations (add, reset) cannot be properly resolved if the filter struct is already gone.
Add IAVF_VLAN_REMOVING state to make the DELETE path symmetric:
REMOVE -> REMOVING (send DEL) -> PF confirms -> kfree
-> PF rejects -> ACTIVE
In iavf_del_vlans(), transition filters from REMOVE to REMOVING instead of immediately freeing them. The new DEL completion handler in iavf_virtchnl_completion() frees filters on success or reverts them to ACTIVE on error.
Update iavf_add_vlan() to handle the REMOVING state: if a DEL is pending and the user re-adds the same VLAN, queue it for ADD so it gets re-programmed after the PF processes the DEL.
The !VLAN_FILTERING_ALLOWED early-exit path still frees filters directly since no PF message is sent in that case.
Also update iavf_del_vlan() to skip filters already in REMOVING
state: DEL has been sent to PF and the completion handler will free the filter when PF confirms. Without this guard, the sequence DEL(pending) -> user-del -> second DEL could cause the PF to return an error for the second DEL (filter already gone), causing the completion handler to incorrectly revert a deleted filter back to ACTIVE.
--- drivers/net/ethernet/intel/iavf/iavf.h | 1 + drivers/net/ethernet/intel/iavf/iavf_main.c | 13 ++++--- .../net/ethernet/intel/iavf/iavf_virtchnl.c | 37 +++++++++++++------ 3 files changed, 34 insertions(+), 17 deletions(-)
drivers/net/ethernet/intel/iavf/iavf.h +1 -0
@@ -161,6 +161,7 @@ enum iavf_vlan_state_t {IAVF_VLAN_ADDING ,/* ADD sent to PF, waiting for response */ IAVF_VLAN_ACTIVE ,/* PF confirmed, filter is in HW */ IAVF_VLAN_REMOVE ,/* filter queued for DEL from PF */ + IAVF_VLAN_REMOVING, /* DEL sent to PF, waiting for response */ }; struct iavf_vlan_filter {
drivers/net/ethernet/intel/iavf/iavf_main.c +8 -5
@@ -802,10 +802,10 @@ iavf_vlan_filter *iavf_add_vlan(struct iavf_adapter *adapter, adapter->num_vlan_filters++;iavf_schedule_aq_request (adapter,IAVF_FLAG_AQ_ADD_VLAN_FILTER ); }else if (f->state ==IAVF_VLAN_REMOVE ) { -/* Re-add the filter since we cannot tell whether the -* pending delete has already been processed by the PF. -* A duplicate add is harmless. -*/ +/* DEL not yet sent to PF, cancel it */ + f->state =IAVF_VLAN_ACTIVE ; + }else if (f->state ==IAVF_VLAN_REMOVING ) { +/* DEL already sent to PF, re-add after completion */ f->state =IAVF_VLAN_ADD ;iavf_schedule_aq_request (adapter,IAVF_FLAG_AQ_ADD_VLAN_FILTER );
@@ -836,11 +836,14 @@ static void iavf_del_vlan(struct iavf_adapter *adapter, struct iavf_vlan vlan)list_del (&f->list);kfree (f); adapter->num_vlan_filters--; - }else { + }else if (f->state !=IAVF_VLAN_REMOVING ) { f->state =IAVF_VLAN_REMOVE ;iavf_schedule_aq_request (adapter,IAVF_FLAG_AQ_DEL_VLAN_FILTER ); } +/* If REMOVING, DEL is already sent to PF; completion +* handler will free the filter when PF confirms. +*/ }spin_unlock_bh (&adapter->mac_vlan_list_lock);
drivers/net/ethernet/intel/iavf/iavf_virtchnl.c +25 -12
@@ -836,12 +836,10 @@ void iavf_del_vlans(struct iavf_adapter *adapter) vvfl->vsi_id = adapter->vsi_res->vsi_id; vvfl->num_elements = count; -list_for_each_entry_safe (f, ftmp, &adapter->vlan_filter_list, list) { +list_for_each_entry (f, &adapter->vlan_filter_list, list) {if (f->state ==IAVF_VLAN_REMOVE ) { vvfl->vlan_id[i] = f->vlan.vid; -list_del (&f->list); -kfree (f); - adapter->num_vlan_filters--; + f->state =IAVF_VLAN_REMOVING ; i++;if (i == count)break ;
@@ -877,7 +875,7 @@ void iavf_del_vlans(struct iavf_adapter *adapter) vvfl_v2->vport_id = adapter->vsi_res->vsi_id; vvfl_v2->num_elements = count; -list_for_each_entry_safe (f, ftmp, &adapter->vlan_filter_list, list) { +list_for_each_entry (f, &adapter->vlan_filter_list, list) {if (f->state ==IAVF_VLAN_REMOVE ) {struct virtchnl_vlan_supported_caps *filtering_support = &adapter->vlan_v2_caps.filtering.filtering_support;
@@ -892,9 +890,7 @@ void iavf_del_vlans(struct iavf_adapter *adapter) vlan->tci = f->vlan.vid; vlan->tpid = f->vlan.tpid; -list_del (&f->list); -kfree (f); - adapter->num_vlan_filters--; + f->state =IAVF_VLAN_REMOVING ; i++;if (i == count)break ;
@@ -2019,10 +2015,6 @@ void iavf_virtchnl_completion(struct iavf_adapter *adapter,ether_addr_copy (adapter->hw.mac.addr, netdev->dev_addr);wake_up (&adapter->vc_waitqueue);break ; -case VIRTCHNL_OP_DEL_VLAN : -dev_err (&adapter->pdev->dev,"Failed to delete VLAN filter, error %s\n" , -iavf_stat_str (&adapter->hw, v_retval)); -break ;case VIRTCHNL_OP_DEL_ETH_ADDR :dev_err (&adapter->pdev->dev,"Failed to delete MAC filter, error %s\n" ,iavf_stat_str (&adapter->hw, v_retval));
@@ -2505,6 +2497,27 @@ void iavf_virtchnl_completion(struct iavf_adapter *adapter,spin_unlock_bh (&adapter->mac_vlan_list_lock); }break ; +case VIRTCHNL_OP_DEL_VLAN : +case VIRTCHNL_OP_DEL_VLAN_V2 : { +struct iavf_vlan_filter *f, *ftmp; + +spin_lock_bh (&adapter->mac_vlan_list_lock); +list_for_each_entry_safe (f, ftmp, &adapter->vlan_filter_list, + list) { +if (f->state ==IAVF_VLAN_REMOVING ) { +if (v_retval) { +/* PF rejected DEL, keep filter */ + f->state =IAVF_VLAN_ACTIVE ; + }else { +list_del (&f->list); +kfree (f); + adapter->num_vlan_filters--; + } + } + } +spin_unlock_bh (&adapter->mac_vlan_list_lock); + } +break ;case VIRTCHNL_OP_ENABLE_VLAN_STRIPPING :/* PF enabled vlan strip on this VF. * Update netdev->features if needed to be in sync with ethtool.
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 433/508 iavf: add VIRTCHNL_OP_ADD_VLAN to success completion handler
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Petr Oros <[email protected]>
[ Upstream commit 34d33313b52eeac3a97ad2e3176d523ec70d9283 ]
The V1 ADD_VLAN opcode had no success handler; filters sent via V1 stayed in ADDING state permanently. Add a fallthrough case so V1 filters also transition ADDING -> ACTIVE on PF confirmation.
Critically, add an if (v_retval) break guard: the error switch in iavf_virtchnl_completion() does NOT return after handling errors, it falls through to the success switch. Without this guard, a PF-rejected ADD would incorrectly mark ADDING filters as ACTIVE, creating a driver/HW mismatch where the driver believes the filter is installed but the PF never accepted it.
For V2, this is harmless: iavf_vlan_add_reject() in the error block already kfree'd all ADDING filters, so the success handler finds nothing to transition.
--- drivers/net/ethernet/intel/iavf/iavf_virtchnl.c | 4 ++++ 1 file changed, 4 insertions(+)
drivers/net/ethernet/intel/iavf/iavf_virtchnl.c +4 -0
@@ -2486,9 +2486,13 @@ void iavf_virtchnl_completion(struct iavf_adapter *adapter,spin_unlock_bh (&adapter->adv_rss_lock); }break ; +case VIRTCHNL_OP_ADD_VLAN :case VIRTCHNL_OP_ADD_VLAN_V2 : {struct iavf_vlan_filter *f; +if (v_retval) +break ; +spin_lock_bh (&adapter->mac_vlan_list_lock);list_for_each_entry (f, &adapter->vlan_filter_list, list) {if (f->state ==IAVF_VLAN_ADDING )
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 434/508 ice: fix NULL pointer dereference in ice_reset_all_vfs()
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Petr Oros <[email protected]>
[ Upstream commit 54ef02487914c24170c7e1c061e45212dc55365e ]
ice_reset_all_vfs() ignores the return value of ice_vf_rebuild_vsi(). When the VSI rebuild fails (e.g. during NVM firmware update via nvmupdate64e), ice_vsi_rebuild() tears down the VSI on its error path, leaving txq_map and rxq_map as NULL. The subsequent unconditional call to ice_vf_post_vsi_rebuild() leads to a NULL pointer dereference in ice_ena_vf_q_mappings() when it accesses vsi->txq_map[0].
The single-VF reset path in ice_reset_vf() already handles this correctly by checking the return value of ice_vf_reconfig_vsi() and skipping ice_vf_post_vsi_rebuild() on failure.
Apply the same pattern to ice_reset_all_vfs(): check the return value of ice_vf_rebuild_vsi() and skip ice_vf_post_vsi_rebuild() and ice_eswitch_attach_vf() on failure. The VF is left safely disabled (ICE_VF_STATE_INIT not set, VFGEN_RSTAT not set to VFACTIVE) and can be recovered via a VFLR triggered by a PCI reset of the VF (sysfs reset or driver rebind).
Note that this patch does not prevent the VF VSI rebuild from failing during NVM update — the underlying cause is firmware being in a transitional state while the EMP reset is processed, which can cause Admin Queue commands (ice_add_vsi, ice_cfg_vsi_lan) to fail. This patch only prevents the subsequent NULL pointer dereference that crashes the kernel when the rebuild does fail.
crash> bt
PID: 50795 TASK: ff34c9ee708dc680 CPU: 1 COMMAND: "kworker/u512:5"
#0 [ff72159bcfe5bb50] machine_kexec at ffffffffaa8850ee
#1 [ff72159bcfe5bba8] __crash_kexec at ffffffffaaa15fba
#2 [ff72159bcfe5bc68] crash_kexec at ffffffffaaa16540
#3 [ff72159bcfe5bc70] oops_end at ffffffffaa837eda
#4 [ff72159bcfe5bc90] page_fault_oops at ffffffffaa893997
#5 [ff72159bcfe5bce8] exc_page_fault at ffffffffab528595
#6 [ff72159bcfe5bd10] asm_exc_page_fault at ffffffffab600bb2
[exception RIP: ice_ena_vf_q_mappings+0x79]
RIP: ffffffffc0a85b29 RSP: ff72159bcfe5bdc8 RFLAGS: 00010206
RAX: 00000000000f0000 RBX: ff34c9efc9c00000 RCX: 0000000000000000
RDX: 0000000000000000 RSI: 0000000000000010 RDI: ff34c9efc9c00000
RBP: ff34c9efc27d4828 R8: 0000000000000093 R9: 0000000000000040
R10: ff34c9efc27d4828 R11: 0000000000000040 R12: 0000000000100000
R13: 0000000000000010 R14: R15:
ORIG_RAX: ffffffffffffffff CS: 0010 SS: 0018
#7 [ff72159bcfe5bdf8] ice_sriov_post_vsi_rebuild at ffffffffc0a85e2e [ice]
#8 [ff72159bcfe5be08] ice_reset_all_vfs at ffffffffc0a920b4 [ice]
#9 [ff72159bcfe5be48] ice_service_task at ffffffffc0a31519 [ice]
#10 [ff72159bcfe5be88] process_one_work at ffffffffaa93dca4
#11 [ff72159bcfe5bec8] worker_thread at ffffffffaa93e9de
#12 [ff72159bcfe5bf18] kthread at ffffffffaa946663
#13 [ff72159bcfe5bf50] ret_from_fork at ffffffffaa8086b9 The panic occurs attempting to dereference the NULL pointer in RDX at ice_sriov.c:294, which loads vsi->txq_map (offset 0x4b8 in ice_vsi).
The faulting VSI is an allocated slab object but not fully initialized after a failed ice_vsi_rebuild():
crash> struct ice_vsi 0xff34c9efc27d4828
netdev = 0x0,
rx_rings = 0x0,
tx_rings = 0x0,
q_vectors = 0x0,
txq_map = 0x0,
rxq_map = 0x0,
alloc_txq = 0x10,
num_txq = 0x10,
alloc_rxq = 0x10,
num_rxq = 0x10,The nvmupdate64e process was performing NVM firmware update:
crash> bt 0xff34c9edd1a30000
PID: 49858 TASK: ff34c9edd1a30000 CPU: 1 COMMAND: "nvmupdate64e"
#0 [ff72159bcd617618] __schedule at ffffffffab5333f8
#4 [ff72159bcd617750] ice_sq_send_cmd at ffffffffc0a35347 [ice] #5 [ff72159bcd6177a8] ice_sq_send_cmd_retry at ffffffffc0a35b47 [ice] #6 [ff72159bcd617810] ice_aq_send_cmd at ffffffffc0a38018 [ice] #7 [ff72159bcd617848] ice_aq_read_nvm at ffffffffc0a40254 [ice] #8 [ff72159bcd6178b8] ice_read_flat_nvm at ffffffffc0a4034c [ice] #9 [ff72159bcd617918] ice_devlink_nvm_snapshot at ffffffffc0a6ffa5 [ice]
dmesg:
ice 0000:13:00.0: firmware recommends not updating fw.mgmt, as it
may result in a downgrade. continuing anyways
ice 0000:13:00.1: ice_init_nvm failed -5
ice 0000:13:00.1: Rebuild failed, unload and reload driver
--- drivers/net/ethernet/intel/ice/ice_vf_lib.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-)
drivers/net/ethernet/intel/ice/ice_vf_lib.c +6 -1
@@ -787,7 +787,12 @@ void ice_reset_all_vfs(struct ice_pf *pf)ice_vf_ctrl_invalidate_vsi (vf);ice_vf_pre_vsi_rebuild (vf); -ice_vf_rebuild_vsi (vf); +if (ice_vf_rebuild_vsi (vf)) { +dev_err (dev,"VF %u VSI rebuild failed, leaving VF disabled\n" , + vf->vf_id); +mutex_unlock (&vf->cfg_lock); +continue ; + }ice_vf_post_vsi_rebuild (vf);mutex_unlock (&vf->cfg_lock);
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 435/508 net: tls: fix strparser anchor skb leak on offload RX setup failure
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jakub Kicinski <[email protected]>
[ Upstream commit 58689498ca3384851145a754dbb1d8ed1cf9fb54 ]
When tls_set_device_offload_rx() fails at tls_dev_add(), the error path calls tls_sw_free_resources_rx() to clean up the SW context that was initialized by tls_set_sw_offload(). This function calls tls_sw_release_resources_rx() (which stops the strparser via tls_strp_stop()) and tls_sw_free_ctx_rx() (which kfrees the context), but never frees the anchor skb that was allocated by alloc_skb(0) in tls_strp_init().
Note that tls_sw_free_resources_rx() is exclusively used for this "failed to start offload" code path, there's no other caller.
The leak did not exist before commit 84c61fe1a75b ("tls: rx: do not use the standard strparser"), because the standard strparser doesn't try to pre-allocate an skb.
The normal close path in tls_sk_proto_close() handles cleanup by calling tls_sw_strparser_done() (which calls tls_strp_done()) after dropping the socket lock, because tls_strp_done() does cancel_work_sync() and the strparser work handler takes the socket lock.
--- net/tls/tls.h | 1 + net/tls/tls_strp.c | 6 ++++++ net/tls/tls_sw.c | 4 ++++ 3 files changed, 11 insertions(+)
net/tls/tls.h +1 -0
@@ -183,6 +183,7 @@ int tls_strp_dev_init(void);void tls_strp_dev_exit (void );void tls_strp_done (struct tls_strparser *strp); +void __tls_strp_done (struct tls_strparser *strp);void tls_strp_stop (struct tls_strparser *strp);int tls_strp_init (struct tls_strparser *strp,struct sock *sk);void tls_strp_data_ready (struct tls_strparser *strp);
net/tls/tls_strp.c +6 -0
@@ -623,6 +623,12 @@ void tls_strp_done(struct tls_strparser *strp)WARN_ON (!strp->stopped);cancel_work_sync (&strp->work); +__tls_strp_done (strp); +} + +/* For setup error paths where the strparser was initialized but never armed. */ +void __tls_strp_done (struct tls_strparser *strp) +{tls_strp_anchor_free (strp); }
net/tls/tls_sw.c +4 -0
@@ -2595,8 +2595,12 @@ void tls_sw_free_ctx_rx(struct tls_context *tls_ctx)void tls_sw_free_resources_rx (struct sock *sk) {struct tls_context *tls_ctx =tls_get_ctx (sk); +struct tls_sw_context_rx *ctx; + + ctx =tls_sw_ctx_rx (tls_ctx);tls_sw_release_resources_rx (sk); +__tls_strp_done (&ctx->strp);tls_sw_free_ctx_rx (tls_ctx); }
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 436/508 sfc: fix error code in efx_devlink_info_running_versions()
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Dan Carpenter <[email protected]>
[ Upstream commit 051ffb001b8a232cfa6e72f38bb5f51c4270a60b ]
Return -EIO if efx_mcdi_rpc() doesn't return enough space.
--- drivers/net/ethernet/sfc/efx_devlink.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/net/ethernet/sfc/efx_devlink.c +1 -1
@@ -530,7 +530,7 @@ static int efx_devlink_info_running_versions(struct efx_nic *efx,if (rc || outlength <MC_CMD_GET_VERSION_OUT_LEN ) {netif_err (efx, drv, efx->net_dev,"mcdi MC_CMD_GET_VERSION failed\n" ); -return rc; +return rc ?: -EIO ; }/* Handle previous output */
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 437/508 net/sched: cls_flower: revert unintended changes
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Paolo Abeni <[email protected]>
[ Upstream commit 1e01abec856593e02cd69fd95b784c10dd46880c ]
While applying the blamed commit 4ca07b9239bd ("net: mctp i2c: check length before marking flow active"), I unintentionally included unrelated and unacceptable changes.
Revert them.
--- net/sched/cls_flower.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-)
net/sched/cls_flower.c +1 -3
@@ -549,7 +549,6 @@ static int __fl_delete(struct tcf_proto *tp, struct cls_fl_filter *f, struct netlink_ext_ack *extack) {struct cls_fl_head *head =fl_head_dereference (tp); -struct fl_flow_mask *mask; *last = false;
@@ -566,12 +565,11 @@ static int __fl_delete(struct tcf_proto *tp, struct cls_fl_filter *f,list_del_rcu (&f->list);spin_unlock (&tp->lock); - mask = f->mask; + *last =fl_mask_put (head, f->mask);if (!tc_skip_hw (f->flags))fl_hw_destroy_filter (tp, f, rtnl_held, extack);tcf_unbind_filter (tp, &f->res);__fl_put (f); - *last =fl_mask_put (head, mask);return 0 ; }
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 438/508 ntfs: ->d_compare() must not block
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Al Viro <[email protected]>
[ Upstream commit ca2a04e84af79596e5cd9cfe697d5122ec39c8ce ]
... so don't use __getname() there. Switch it (and ntfs_d_hash(), while we are at it) to kmalloc(PATH_MAX, GFP_NOWAIT). Yes, ntfs_d_hash() almost certainly can do with smaller allocations, but let ntfs folks deal with that - keep the allocation size as-is for now.
Stop abusing names_cachep in ntfs, period - various uses of that thing in there have nothing to do with pathnames; just use k[mz]alloc() and be done with that. For now let's keep sizes as-in, but AFAICS none of the users actually want PATH_MAX.
--- fs/ntfs3/dir.c | 5 ++--- fs/ntfs3/fsntfs.c | 4 ++-- fs/ntfs3/inode.c | 13 ++++++------- fs/ntfs3/namei.c | 17 ++++++++--------- fs/ntfs3/xattr.c | 5 ++--- 5 files changed, 20 insertions(+), 24 deletions(-)
fs/ntfs3/dir.c +2 -3
@@ -425,8 +425,7 @@ static int ntfs_readdir(struct file *file, struct dir_context *ctx)if (!dir_emit_dots (file, ctx))return 0 ; -/* Allocate PATH_MAX bytes. */ - name =__getname (); + name =kmalloc (PATH_MAX ,GFP_KERNEL );if (!name)return -ENOMEM ;
@@ -504,7 +503,7 @@ static int ntfs_readdir(struct file *file, struct dir_context *ctx) out: -__putname (name); +kfree (name);put_indx_node (node);if (err ==1 ) {
fs/ntfs3/fsntfs.c +2 -2
@@ -2666,7 +2666,7 @@ int ntfs_set_label(struct ntfs_sb_info *sbi, u8 *label, int len)struct ntfs_inode *ni = sbi->volume.ni;const u8 max_ulen =0x80 ;/* TODO: use attrdef to get maximum length */ /* Allocate PATH_MAX bytes. */ -struct cpu_str *uni =__getname (); +struct cpu_str *uni =kmalloc (PATH_MAX ,GFP_KERNEL );if (!uni)return -ENOMEM ;
@@ -2709,6 +2709,6 @@ int ntfs_set_label(struct ntfs_sb_info *sbi, u8 *label, int len) err =_ni_write_inode (&ni->vfs_inode,0 ); out: -__putname (uni); +kfree (uni);return err; }
fs/ntfs3/inode.c +6 -7
@@ -1327,7 +1327,7 @@ struct inode *ntfs_create_inode(struct mnt_idmap *idmap, struct inode *dir, fa |=FILE_ATTRIBUTE_READONLY ;/* Allocate PATH_MAX bytes. */ - new_de =kmem_cache_zalloc (names_cachep,GFP_KERNEL ); + new_de =kzalloc (PATH_MAX ,GFP_KERNEL );if (!new_de) { err = -ENOMEM ; goto out1;
@@ -1733,7 +1733,7 @@ struct inode *ntfs_create_inode(struct mnt_idmap *idmap, struct inode *dir,ntfs_mark_rec_free (sbi, ino, false); out2: -__putname (new_de); +kfree (new_de);kfree (rp); out1:
@@ -1756,7 +1756,7 @@ int ntfs_link_inode(struct inode *inode, struct dentry *dentry)struct NTFS_DE *de;/* Allocate PATH_MAX bytes. */ - de =kmem_cache_zalloc (names_cachep,GFP_KERNEL ); + de =kzalloc (PATH_MAX ,GFP_KERNEL );if (!de)return -ENOMEM ;
@@ -1770,7 +1770,7 @@ int ntfs_link_inode(struct inode *inode, struct dentry *dentry) err =ni_add_name (ntfs_i (d_inode (dentry->d_parent)), ni, de); out: -__putname (de); +kfree (de);return err; }
@@ -1793,8 +1793,7 @@ int ntfs_unlink_inode(struct inode *dir, const struct dentry *dentry)if (ntfs_is_meta_file (sbi, ni->mi.rno))return -EINVAL ; -/* Allocate PATH_MAX bytes. */ - de =kmem_cache_zalloc (names_cachep,GFP_KERNEL ); + de =kzalloc (PATH_MAX ,GFP_KERNEL );if (!de)return -ENOMEM ;
@@ -1830,7 +1829,7 @@ int ntfs_unlink_inode(struct inode *dir, const struct dentry *dentry) out:ni_unlock (ni); -__putname (de); +kfree (de);return err; }
fs/ntfs3/namei.c +8 -9
@@ -68,7 +68,7 @@ static struct dentry *ntfs_lookup(struct inode *dir, struct dentry *dentry, u32 flags) {struct ntfs_inode *ni =ntfs_i (dir); -struct cpu_str *uni =__getname (); +struct cpu_str *uni =kmalloc (PATH_MAX ,GFP_KERNEL );struct inode *inode;int err;
@@ -85,7 +85,7 @@ static struct dentry *ntfs_lookup(struct inode *dir, struct dentry *dentry, inode =dir_search_u (dir, uni,NULL );ni_unlock (ni); } -__putname (uni); +kfree (uni); }/*
@@ -304,8 +304,7 @@ static int ntfs_rename(struct mnt_idmap *idmap, struct inode *dir,return err; } -/* Allocate PATH_MAX bytes. */ - de =__getname (); + de =kmalloc (PATH_MAX ,GFP_KERNEL );if (!de)return -ENOMEM ;
@@ -350,7 +349,7 @@ static int ntfs_rename(struct mnt_idmap *idmap, struct inode *dir,ni_unlock (ni);ni_unlock (dir_ni); out: -__putname (de); +kfree (de);return err; }
@@ -497,7 +496,7 @@ static int ntfs_d_hash(const struct dentry *dentry, struct qstr *name)/* * Try slow way with current upcase table */ - uni =kmem_cache_alloc (names_cachep,GFP_NOWAIT ); + uni =kmalloc (PATH_MAX ,GFP_NOWAIT );if (!uni)return -ENOMEM ;
@@ -519,7 +518,7 @@ static int ntfs_d_hash(const struct dentry *dentry, struct qstr *name) err =0 ; out: -kmem_cache_free (names_cachep, uni); +kfree (uni);return err; }
@@ -558,7 +557,7 @@ static int ntfs_d_compare(const struct dentry *dentry, unsigned int len1,* Try slow way with current upcase table */ sbi = dentry->d_sb->s_fs_info; - uni1 =__getname (); + uni1 =kmalloc (PATH_MAX ,GFP_NOWAIT );if (!uni1)return -ENOMEM ;
@@ -588,7 +587,7 @@ static int ntfs_d_compare(const struct dentry *dentry, unsigned int len1, ret = !ntfs_cmp_names_cpu (uni1, uni2, sbi->upcase, false) ?0 :1 ; out: -__putname (uni1); +kfree (uni1);return ret; }
fs/ntfs3/xattr.c +2 -3
@@ -551,8 +551,7 @@ struct posix_acl *ntfs_get_acl(struct mnt_idmap *idmap, struct dentry *dentry,int err;void *buf; -/* Allocate PATH_MAX bytes. */ - buf =__getname (); + buf =kmalloc (PATH_MAX ,GFP_KERNEL );if (!buf)return ERR_PTR (-ENOMEM );
@@ -583,7 +582,7 @@ struct posix_acl *ntfs_get_acl(struct mnt_idmap *idmap, struct dentry *dentry,if (!IS_ERR (acl))set_cached_acl (inode, type, acl); -__putname (buf); +kfree (buf);return acl; }
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 439/508 Revert "crypto: nx - fix context leak in nx842_crypto_free_ctx"
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
This reverts commit b94588f5a69718be2c942f4a851125f655e4e819.
--- drivers/crypto/nx/nx-842.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-)
drivers/crypto/nx/nx-842.c +4 -2
@@ -115,7 +115,10 @@ void *nx842_crypto_alloc_ctx(struct nx842_driver *driver) ctx->sbounce = (u8 *)__get_free_pages (GFP_KERNEL ,BOUNCE_BUFFER_ORDER ); ctx->dbounce = (u8 *)__get_free_pages (GFP_KERNEL ,BOUNCE_BUFFER_ORDER );if (!ctx->wmem || !ctx->sbounce || !ctx->dbounce) { -nx842_crypto_free_ctx (ctx); +kfree (ctx->wmem); +free_pages ((unsigned long )ctx->sbounce,BOUNCE_BUFFER_ORDER ); +free_pages ((unsigned long )ctx->dbounce,BOUNCE_BUFFER_ORDER ); +kfree (ctx);return ERR_PTR (-ENOMEM ); }
@@ -130,7 +133,6 @@ void nx842_crypto_free_ctx(void *p)kfree (ctx->wmem);free_pages ((unsigned long )ctx->sbounce,BOUNCE_BUFFER_ORDER );free_pages ((unsigned long )ctx->dbounce,BOUNCE_BUFFER_ORDER ); -kfree (ctx); }EXPORT_SYMBOL_GPL (nx842_crypto_free_ctx);
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 440/508 Revert "crypto: nx - fix bounce buffer leaks in nx842_crypto_{alloc,free}_ctx"
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
This reverts commit 6923cde8dc1d501e79b312139819c88b54463803.
--- drivers/crypto/nx/nx-842.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-)
drivers/crypto/nx/nx-842.c +4 -4
@@ -116,8 +116,8 @@ void *nx842_crypto_alloc_ctx(struct nx842_driver *driver) ctx->dbounce = (u8 *)__get_free_pages (GFP_KERNEL ,BOUNCE_BUFFER_ORDER );if (!ctx->wmem || !ctx->sbounce || !ctx->dbounce) {kfree (ctx->wmem); -free_pages ((unsigned long )ctx->sbounce,BOUNCE_BUFFER_ORDER ); -free_pages ((unsigned long )ctx->dbounce,BOUNCE_BUFFER_ORDER ); +free_page ((unsigned long )ctx->sbounce); +free_page ((unsigned long )ctx->dbounce);kfree (ctx);return ERR_PTR (-ENOMEM ); }
@@ -131,8 +131,8 @@ void nx842_crypto_free_ctx(void *p)struct nx842_crypto_ctx *ctx = p;kfree (ctx->wmem); -free_pages ((unsigned long )ctx->sbounce,BOUNCE_BUFFER_ORDER ); -free_pages ((unsigned long )ctx->dbounce,BOUNCE_BUFFER_ORDER ); +free_page ((unsigned long )ctx->sbounce); +free_page ((unsigned long )ctx->dbounce); }EXPORT_SYMBOL_GPL (nx842_crypto_free_ctx);
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 441/508 Revert "crypto: nx - Migrate to scomp API"
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
This reverts commit 268ae55a4c4fbff3ff54f92a4642f497da814f49.
--- drivers/crypto/nx/nx-842.c | 33 ++++++++++++--------------- drivers/crypto/nx/nx-842.h | 15 ++++++------ drivers/crypto/nx/nx-common-powernv.c | 31 +++++++++++++------------ drivers/crypto/nx/nx-common-pseries.c | 33 ++++++++++++++------------- 4 files changed, 54 insertions(+), 58 deletions(-)
drivers/crypto/nx/nx-842.c +14 -19
@@ -101,13 +101,9 @@ static int update_param(struct nx842_crypto_param *p,return 0 ; } -void *nx842_crypto_alloc_ctx (struct nx842_driver *driver) +int nx842_crypto_init (struct crypto_tfm *tfm,struct nx842_driver *driver) { -struct nx842_crypto_ctx *ctx; - - ctx =kzalloc (sizeof (*ctx),GFP_KERNEL ); -if (!ctx) -return ERR_PTR (-ENOMEM ); +struct nx842_crypto_ctx *ctx =crypto_tfm_ctx (tfm);spin_lock_init (&ctx->lock); ctx->driver = driver;
@@ -118,23 +114,22 @@ void *nx842_crypto_alloc_ctx(struct nx842_driver *driver)kfree (ctx->wmem);free_page ((unsigned long )ctx->sbounce);free_page ((unsigned long )ctx->dbounce); -kfree (ctx); -return ERR_PTR (-ENOMEM ); +return -ENOMEM ; } -return ctx; +return 0 ; } -EXPORT_SYMBOL_GPL (nx842_crypto_alloc_ctx); +EXPORT_SYMBOL_GPL (nx842_crypto_init); -void nx842_crypto_free_ctx (void *p) +void nx842_crypto_exit (struct crypto_tfm *tfm) { -struct nx842_crypto_ctx *ctx = p; +struct nx842_crypto_ctx *ctx =crypto_tfm_ctx (tfm);kfree (ctx->wmem);free_page ((unsigned long )ctx->sbounce);free_page ((unsigned long )ctx->dbounce); } -EXPORT_SYMBOL_GPL (nx842_crypto_free_ctx); +EXPORT_SYMBOL_GPL (nx842_crypto_exit);static void check_constraints (struct nx842_constraints *c) {
@@ -251,11 +246,11 @@ static int compress(struct nx842_crypto_ctx *ctx,return update_param (p, slen, dskip + dlen); } -int nx842_crypto_compress (struct crypto_scomp *tfm, +int nx842_crypto_compress (struct crypto_tfm *tfm,const u8 *src,unsigned int slen, -u8 *dst,unsigned int *dlen,void *pctx) +u8 *dst,unsigned int *dlen) { -struct nx842_crypto_ctx *ctx = pctx; +struct nx842_crypto_ctx *ctx =crypto_tfm_ctx (tfm);struct nx842_crypto_header *hdr =container_of (&ctx->header, struct nx842_crypto_header, hdr);
@@ -436,11 +431,11 @@ static int decompress(struct nx842_crypto_ctx *ctx,return update_param (p, slen + padding, dlen); } -int nx842_crypto_decompress (struct crypto_scomp *tfm, +int nx842_crypto_decompress (struct crypto_tfm *tfm,const u8 *src,unsigned int slen, -u8 *dst,unsigned int *dlen,void *pctx) +u8 *dst,unsigned int *dlen) { -struct nx842_crypto_ctx *ctx = pctx; +struct nx842_crypto_ctx *ctx =crypto_tfm_ctx (tfm);struct nx842_crypto_header *hdr;struct nx842_crypto_param p;struct nx842_constraints c = *ctx->driver->constraints;
drivers/crypto/nx/nx-842.h +7 -8
@@ -3,6 +3,7 @@#ifndef __NX_842_H__#define __NX_842_H__ +#include <crypto/algapi.h> #include <linux/kernel.h> #include <linux/init.h> #include <linux/module.h>
@@ -100,8 +101,6 @@#define LEN_ON_SIZE (pa, size) ((size) - ((pa) & ((size) - 1)))#define LEN_ON_PAGE (pa) LEN_ON_SIZE(pa, PAGE_SIZE) -struct crypto_scomp ; -static inline unsigned long nx842_get_pa (void *addr) {if (!is_vmalloc_addr (addr))
@@ -180,13 +179,13 @@ struct nx842_crypto_ctx { struct nx842_driver *driver; }; -void *nx842_crypto_alloc_ctx (struct nx842_driver *driver); -void nx842_crypto_free_ctx (void *ctx); -int nx842_crypto_compress (struct crypto_scomp *tfm, +int nx842_crypto_init (struct crypto_tfm *tfm,struct nx842_driver *driver); +void nx842_crypto_exit (struct crypto_tfm *tfm); +int nx842_crypto_compress (struct crypto_tfm *tfm,const u8 *src,unsigned int slen, -u8 *dst,unsigned int *dlen,void *ctx); -int nx842_crypto_decompress (struct crypto_scomp *tfm, +u8 *dst,unsigned int *dlen); +int nx842_crypto_decompress (struct crypto_tfm *tfm,const u8 *src,unsigned int slen, -u8 *dst,unsigned int *dlen,void *ctx); +u8 *dst,unsigned int *dlen);#endif /* __NX_842_H__ */
drivers/crypto/nx/nx-common-powernv.c +16 -15
@@ -9,7 +9,6 @@#include "nx-842.h" -#include <crypto/internal/scompress.h> #include <linux/timer.h> #include <asm/prom.h>
@@ -1032,21 +1031,23 @@ static struct nx842_driver nx842_powernv_driver = { .decompress = nx842_powernv_decompress, }; -static void *nx842_powernv_crypto_alloc_ctx (void ) +static int nx842_powernv_crypto_init (struct crypto_tfm *tfm) { -return nx842_crypto_alloc_ctx (&nx842_powernv_driver); +return nx842_crypto_init (tfm, &nx842_powernv_driver); } -static struct scomp_alg nx842_powernv_alg = { - .base.cra_name ="842" , - .base.cra_driver_name ="842-nx" , - .base.cra_priority =300 , - .base.cra_module =THIS_MODULE , - - .alloc_ctx = nx842_powernv_crypto_alloc_ctx, - .free_ctx = nx842_crypto_free_ctx, - .compress = nx842_crypto_compress, - .decompress = nx842_crypto_decompress, +static struct crypto_alg nx842_powernv_alg = { + .cra_name ="842" , + .cra_driver_name ="842-nx" , + .cra_priority =300 , + .cra_flags =CRYPTO_ALG_TYPE_COMPRESS , + .cra_ctxsize =sizeof (struct nx842_crypto_ctx ), + .cra_module =THIS_MODULE , + .cra_init = nx842_powernv_crypto_init, + .cra_exit = nx842_crypto_exit, + .cra_u = { .compress = { + .coa_compress = nx842_crypto_compress, + .coa_decompress = nx842_crypto_decompress } } };static __init int nx_compress_powernv_init (void )
@@ -1106,7 +1107,7 @@ static __init int nx_compress_powernv_init(void) nx842_powernv_exec = nx842_exec_vas; } - ret =crypto_register_scomp (&nx842_powernv_alg); + ret =crypto_register_alg (&nx842_powernv_alg);if (ret) {nx_delete_coprocs ();return ret;
@@ -1127,7 +1128,7 @@ static void __exit nx_compress_powernv_exit(void)if (!nx842_ct)vas_unregister_api_powernv (); -crypto_unregister_scomp (&nx842_powernv_alg); +crypto_unregister_alg (&nx842_powernv_alg);nx_delete_coprocs (); }
drivers/crypto/nx/nx-common-pseries.c +17 -16
@@ -11,7 +11,6 @@#include <asm/vio.h> #include <asm/hvcall.h> #include <asm/vas.h> -#include <crypto/internal/scompress.h> #include "nx-842.h" #include "nx_csbcpb.h" /* struct nx_csbcpb */
@@ -1009,21 +1008,23 @@ static struct nx842_driver nx842_pseries_driver = { .decompress = nx842_pseries_decompress, }; -static void *nx842_pseries_crypto_alloc_ctx (void ) +static int nx842_pseries_crypto_init (struct crypto_tfm *tfm) { -return nx842_crypto_alloc_ctx (&nx842_pseries_driver); +return nx842_crypto_init (tfm, &nx842_pseries_driver); } -static struct scomp_alg nx842_pseries_alg = { - .base.cra_name ="842" , - .base.cra_driver_name ="842-nx" , - .base.cra_priority =300 , - .base.cra_module =THIS_MODULE , - - .alloc_ctx = nx842_pseries_crypto_alloc_ctx, - .free_ctx = nx842_crypto_free_ctx, - .compress = nx842_crypto_compress, - .decompress = nx842_crypto_decompress, +static struct crypto_alg nx842_pseries_alg = { + .cra_name ="842" , + .cra_driver_name ="842-nx" , + .cra_priority =300 , + .cra_flags =CRYPTO_ALG_TYPE_COMPRESS , + .cra_ctxsize =sizeof (struct nx842_crypto_ctx ), + .cra_module =THIS_MODULE , + .cra_init = nx842_pseries_crypto_init, + .cra_exit = nx842_crypto_exit, + .cra_u = { .compress = { + .coa_compress = nx842_crypto_compress, + .coa_decompress = nx842_crypto_decompress } } }; static int nx842_probe(struct vio_dev *viodev,
@@ -1071,7 +1072,7 @@ static int nx842_probe(struct vio_dev *viodev,if (ret) goto error; - ret =crypto_register_scomp (&nx842_pseries_alg); + ret =crypto_register_alg (&nx842_pseries_alg);if (ret) {dev_err (&viodev->dev,"could not register comp alg: %d\n" , ret); goto error;
@@ -1119,7 +1120,7 @@ static void nx842_remove(struct vio_dev *viodev)if (caps_feat)sysfs_remove_group (&viodev->dev.kobj, &nxcop_caps_attr_group); -crypto_unregister_scomp (&nx842_pseries_alg); +crypto_unregister_alg (&nx842_pseries_alg);spin_lock_irqsave (&devdata_mutex, flags); old_devdata = rcu_dereference_check(devdata,
@@ -1251,7 +1252,7 @@ static void __exit nx842_pseries_exit(void)vas_unregister_api_pseries (); -crypto_unregister_scomp (&nx842_pseries_alg); +crypto_unregister_alg (&nx842_pseries_alg);spin_lock_irqsave (&devdata_mutex, flags); old_devdata = rcu_dereference_check(devdata,
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 442/508 smb: client: correctly handle ErrorContextData as a flexible array
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Liang Jie <[email protected]>
[ Upstream commit 215b7f9ecb8d7c14d56febdcdd246f3579c32aba ]
The smb2_symlink_err_rsp structure was previously defined with ErrorContextData as a single __u8 byte. However, the ErrorContextData field is intended to be a variable-length array based on ErrorDataLength. This mismatch leads to incorrect pointer arithmetic and potential memory access issues when processing error contexts.
Updates the ErrorContextData field to be a flexible array (__u8 ErrorContextData[]). Additionally, it modifies the corresponding casts in the symlink_data() function to properly handle the flexible array, ensuring correct memory calculations and data handling.
These changes improve the robustness of SMB2 symlink error processing.
--- fs/smb/client/smb2file.c | 4 ++-- fs/smb/client/smb2pdu.h | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-)
fs/smb/client/smb2file.c +2 -2
@@ -42,14 +42,14 @@ static struct smb2_symlink_err_rsp *symlink_data(const struct kvec *iov) end = (struct smb2_error_context_rsp *)((u8 *)err + iov->iov_len);do {if (le32_to_cpu (p->ErrorId) ==SMB2_ERROR_ID_DEFAULT ) { - sym = (struct smb2_symlink_err_rsp *)&p->ErrorContextData; + sym = (struct smb2_symlink_err_rsp *)p->ErrorContextData;break ; }cifs_dbg (FYI ,"%s: skipping unhandled error context: 0x%x\n" , __func__,le32_to_cpu (p->ErrorId)); len =ALIGN (le32_to_cpu (p->ErrorDataLength),8 ); - p = (struct smb2_error_context_rsp *)((u8 *)&p->ErrorContextData + len); + p = (struct smb2_error_context_rsp *)(p->ErrorContextData + len); }while (p < end); }else if (le32_to_cpu (err->ByteCount) >=sizeof (*sym) && iov->iov_len >=SMB2_SYMLINK_STRUCT_SIZE ) {
fs/smb/client/smb2pdu.h +1 -1
@@ -79,7 +79,7 @@ struct smb2_symlink_err_rsp {struct smb2_error_context_rsp {__le32 ErrorDataLength;__le32 ErrorId; -__u8 ErrorContextData;/* ErrorDataLength long array */ +__u8 ErrorContextData[]; } __packed;/* ErrorId values */
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 443/508 smb: client: fix OOB reads parsing symlink error response
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Greg Kroah-Hartman <[email protected]>
[ Upstream commit 3df690bba28edec865cf7190be10708ad0ddd67e ]
When a CREATE returns STATUS_STOPPED_ON_SYMLINK, smb2_check_message() returns success without any length validation, leaving the symlink parsers as the only defense against an untrusted server.
symlink_data() walks SMB 3.1.1 error contexts with the loop test "p < end", but reads p->ErrorId at offset 4 and p->ErrorDataLength at offset
0. When the server-controlled ErrorDataLength advances p to within 1-7 bytes of end, the next iteration will read past it. When the matching context is found, sym->SymLinkErrorTag is read at offset 4 from p->ErrorContextData with no check that the symlink header itself fits.
smb2_parse_symlink_response() then bounds-checks the substitute name using SMB2_SYMLINK_STRUCT_SIZE as the offset of PathBuffer from iov_base. That value is computed as sizeof(smb2_err_rsp) + sizeof(smb2_symlink_err_rsp), which is correct only when ErrorContextCount == 0.
With at least one error context the symlink data sits 8 bytes deeper, and each skipped non-matching context shifts it further by 8 + ALIGN(ErrorDataLength, 8). The check is too short, allowing the substitute name read to run past iov_len. The out-of-bound heap bytes are UTF-16-decoded into the symlink target and returned to userspace via readlink(2).
Fix this all up by making the loops test require the full context header to fit, rejecting sym if its header runs past end, and bound the substitute name against the actual position of sym->PathBuffer rather than a fixed offset.
Because sub_offs and sub_len are 16bits, the pointer math will not overflow here with the new greater-than.
--- fs/smb/client/smb2file.c | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-)
fs/smb/client/smb2file.c +12 -8
@@ -27,10 +27,11 @@ static struct smb2_symlink_err_rsp *symlink_data(const struct kvec *iov) {struct smb2_err_rsp *err = iov->iov_base;struct smb2_symlink_err_rsp *sym =ERR_PTR (-EINVAL ); +u8 *end = (u8 *)err + iov->iov_len;u32 len;if (err->ErrorContextCount) { -struct smb2_error_context_rsp *p, *end; +struct smb2_error_context_rsp *p; len = (u32)err->ErrorContextCount * (offsetof(struct smb2_error_context_rsp, ErrorContextData) +
@@ -39,8 +40,7 @@ static struct smb2_symlink_err_rsp *symlink_data(const struct kvec *iov)return ERR_PTR (-EINVAL ); p = (struct smb2_error_context_rsp *)err->ErrorData; - end = (struct smb2_error_context_rsp *)((u8 *)err + iov->iov_len); - do { +while ((u8 *)p +sizeof (*p) <= end) {if (le32_to_cpu (p->ErrorId) ==SMB2_ERROR_ID_DEFAULT ) { sym = (struct smb2_symlink_err_rsp *)p->ErrorContextData;break ;
@@ -50,14 +50,16 @@ static struct smb2_symlink_err_rsp *symlink_data(const struct kvec *iov) len =ALIGN (le32_to_cpu (p->ErrorDataLength),8 ); p = (struct smb2_error_context_rsp *)(p->ErrorContextData + len); - }while (p < end); + } }else if (le32_to_cpu (err->ByteCount) >=sizeof (*sym) && iov->iov_len >=SMB2_SYMLINK_STRUCT_SIZE ) { sym = (struct smb2_symlink_err_rsp *)err->ErrorData; } -if (!IS_ERR (sym) && (le32_to_cpu (sym->SymLinkErrorTag) !=SYMLINK_ERROR_TAG || -le32_to_cpu (sym->ReparseTag) !=IO_REPARSE_TAG_SYMLINK )) +if (!IS_ERR (sym) && + ((u8 *)sym +sizeof (*sym) > end || +le32_to_cpu (sym->SymLinkErrorTag) !=SYMLINK_ERROR_TAG || +le32_to_cpu (sym->ReparseTag) !=IO_REPARSE_TAG_SYMLINK )) sym =ERR_PTR (-EINVAL );return sym;
@@ -82,8 +84,10 @@ int smb2_parse_symlink_response(struct cifs_sb_info *cifs_sb, const struct kvec print_len =le16_to_cpu (sym->PrintNameLength); print_offs =le16_to_cpu (sym->PrintNameOffset); -if (iov->iov_len <SMB2_SYMLINK_STRUCT_SIZE + sub_offs + sub_len || - iov->iov_len <SMB2_SYMLINK_STRUCT_SIZE + print_offs + print_len) +if ((char *)sym->PathBuffer + sub_offs + sub_len > + (char *)iov->iov_base + iov->iov_len || + (char *)sym->PathBuffer + print_offs + print_len > + (char *)iov->iov_base + iov->iov_len)return -EINVAL ; return smb2_parse_native_symlink(path,
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 444/508 crypto: nx - fix bounce buffer leaks in nx842_crypto_{alloc,free}_ctx
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Thorsten Blum <[email protected]>
[ Upstream commit adb3faf2db1a66d0f015b44ac909a32dfc7f2f9c ]
The bounce buffers are allocated with __get_free_pages() using BOUNCE_BUFFER_ORDER (order 2 = 4 pages), but both the allocation error path and nx842_crypto_free_ctx() release the buffers with free_page(). Use free_pages() with the matching order instead.
--- drivers/crypto/nx/nx-842.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-)
drivers/crypto/nx/nx-842.c +4 -4
@@ -112,8 +112,8 @@ int nx842_crypto_init(struct crypto_tfm *tfm, struct nx842_driver *driver) ctx->dbounce = (u8 *)__get_free_pages (GFP_KERNEL ,BOUNCE_BUFFER_ORDER );if (!ctx->wmem || !ctx->sbounce || !ctx->dbounce) {kfree (ctx->wmem); -free_page ((unsigned long )ctx->sbounce); -free_page ((unsigned long )ctx->dbounce); +free_pages ((unsigned long )ctx->sbounce,BOUNCE_BUFFER_ORDER ); +free_pages ((unsigned long )ctx->dbounce,BOUNCE_BUFFER_ORDER );return -ENOMEM ; }
@@ -126,8 +126,8 @@ void nx842_crypto_exit(struct crypto_tfm *tfm)struct nx842_crypto_ctx *ctx =crypto_tfm_ctx (tfm);kfree (ctx->wmem); -free_page ((unsigned long )ctx->sbounce); -free_page ((unsigned long )ctx->dbounce); +free_pages ((unsigned long )ctx->sbounce,BOUNCE_BUFFER_ORDER ); +free_pages ((unsigned long )ctx->dbounce,BOUNCE_BUFFER_ORDER ); }EXPORT_SYMBOL_GPL (nx842_crypto_exit);
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 445/508 net: bcmgenet: Initialize u64 stats seq counter
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ryo Takakura <[email protected]>
[ Upstream commit ffc2c8c4a714df53a715827d6334ab9474424f6a ]
Initialize u64 stats as it uses seq counter on 32bit machines as suggested by lockdep below.
[ 1.830953][ T1] INFO: trying to register non-static key. [ 1.830993][ T1] The code is fine but needs lockdep annotation, or maybe [ 1.831027][ T1] you didn't initialize this object before use? [ 1.831057][ T1] turning off the locking correctness validator. [ 1.831090][ T1] CPU: 1 UID: 0 PID: 1 Comm: swapper/0 Tainted: G W 6.16.0-rc2-v7l+ #1 PREEMPT [ 1.831097][ T1] Tainted: [W]=WARN [ 1.831099][ T1] Hardware name: BCM2711 [ 1.831101][ T1] Call trace: [ 1.831104][ T1] unwind_backtrace from show_stack+0x18/0x1c [ 1.831120][ T1] show_stack from dump_stack_lvl+0x8c/0xcc [ 1.831129][ T1] dump_stack_lvl from register_lock_class+0x9e8/0x9fc [ 1.831141][ T1] register_lock_class from __lock_acquire+0x420/0x22c0 [ 1.831154][ T1] __lock_acquire from lock_acquire+0x130/0x3f8 [ 1.831166][ T1] lock_acquire from bcmgenet_get_stats64+0x4a4/0x4c8 [ 1.831176][ T1] bcmgenet_get_stats64 from dev_get_stats+0x4c/0x408 [ 1.831184][ T1] dev_get_stats from rtnl_fill_stats+0x38/0x120 [ 1.831193][ T1] rtnl_fill_stats from rtnl_fill_ifinfo+0x7f8/0x1890 [ 1.831203][ T1] rtnl_fill_ifinfo from rtmsg_ifinfo_build_skb+0xd0/0x138 [ 1.831214][ T1] rtmsg_ifinfo_build_skb from rtmsg_ifinfo+0x48/0x8c [ 1.831225][ T1] rtmsg_ifinfo from register_netdevice+0x8c0/0x95c [ 1.831237][ T1] register_netdevice from register_netdev+0x28/0x40 [ 1.831247][ T1] register_netdev from bcmgenet_probe+0x690/0x6bc [ 1.831255][ T1] bcmgenet_probe from platform_probe+0x64/0xbc [ 1.831263][ T1] platform_probe from really_probe+0xd0/0x2d4 [ 1.831269][ T1] really_probe from __driver_probe_device+0x90/0x1a4 [ 1.831273][ T1] __driver_probe_device from driver_probe_device+0x38/0x11c [ 1.831278][ T1] driver_probe_device from __driver_attach+0x9c/0x18c [ 1.831282][ T1] __driver_attach from bus_for_each_dev+0x84/0xd4 [ 1.831291][ T1] bus_for_each_dev from bus_add_driver+0xd4/0x1f4 [ 1.831303][ T1] bus_add_driver from driver_register+0x88/0x120 [ 1.831312][ T1] driver_register from do_one_initcall+0x78/0x360 [ 1.831320][ T1] do_one_initcall from kernel_init_freeable+0x2bc/0x314 [ 1.831331][ T1] kernel_init_freeable from kernel_init+0x1c/0x144 [ 1.831339][ T1] kernel_init from ret_from_fork+0x14/0x20 [ 1.831344][ T1] Exception stack(0xf082dfb0 to 0xf082dff8) [ 1.831349][ T1] dfa0: 00000000 00000000 00000000 00000000 [ 1.831353][ T1] dfc0: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 [ 1.831356][ T1] dfe0: 00000000 00000000 00000000 00000000 00000013 00000000
--- drivers/net/ethernet/broadcom/genet/bcmgenet.c | 6 ++++++ 1 file changed, 6 insertions(+)
drivers/net/ethernet/broadcom/genet/bcmgenet.c +6 -0
@@ -4084,6 +4084,12 @@ static int bcmgenet_probe(struct platform_device *pdev)for (i =0 ; i <= priv->hw_params->rx_queues; i++) priv->rx_rings[i].rx_max_coalesced_frames =1 ; +/* Initialize u64 stats seq counter for 32bit machines */ +for (i =0 ; i <= priv->hw_params->rx_queues; i++) +u64_stats_init (&priv->rx_rings[i].stats64.syncp); +for (i =0 ; i <= priv->hw_params->tx_queues; i++) +u64_stats_init (&priv->tx_rings[i].stats64.syncp); +/* libphy will determine the link state */ netif_carrier_off (dev);
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 446/508 net: bcmgenet: fix leaking free_bds
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Justin Chen <[email protected]>
[ Upstream commit 3f3168300efb839028328d720ab3962f91d6a0d0 ]
While reclaiming the tx queue we fast forward the write pointer to drop any data in flight. These dropped frames are not added back to the pool of free bds. We also need to tell the netdev that we are dropping said data.
--- drivers/net/ethernet/broadcom/genet/bcmgenet.c | 2 ++ 1 file changed, 2 insertions(+)
drivers/net/ethernet/broadcom/genet/bcmgenet.c +2 -0
@@ -1942,6 +1942,7 @@ static unsigned int bcmgenet_tx_reclaim(struct net_device *dev, drop = (ring->prod_index - ring->c_index) &DMA_C_INDEX_MASK ; released += drop; ring->prod_index = ring->c_index &DMA_C_INDEX_MASK ; + ring->free_bds += drop;while (drop--) { cb_ptr =bcmgenet_put_txcb (priv, ring); skb = cb_ptr->skb;
@@ -1953,6 +1954,7 @@ static unsigned int bcmgenet_tx_reclaim(struct net_device *dev, }if (skb)dev_consume_skb_any (skb); +netdev_tx_reset_queue (netdev_get_tx_queue (dev, ring->index));bcmgenet_tdma_ring_writel (priv, ring->index, ring->prod_index,TDMA_PROD_INDEX ); wr_ptr = ring->write_ptr *WORDS_PER_BD (priv);
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 447/508 ksmbd: validate response sizes in ipc_validate_msg()
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Michael Bommarito <[email protected]>
[ Upstream commit d6a6aa81eac2c9bff66dc6e191179cb69a14426b ]
ipc_validate_msg() computes the expected message size for each response type by adding (or multiplying) attacker-controlled fields from the daemon response to a fixed struct size in unsigned int arithmetic. Three cases can overflow:
KSMBD_EVENT_RPC_REQUEST:
msg_sz = sizeof(struct ksmbd_rpc_command) + resp->payload_sz;
KSMBD_EVENT_SHARE_CONFIG_REQUEST:
msg_sz = sizeof(struct ksmbd_share_config_response) +
resp->payload_sz;
KSMBD_EVENT_LOGIN_REQUEST_EXT:
msg_sz = sizeof(struct ksmbd_login_response_ext) +
resp->ngroups * sizeof(gid_t);resp->payload_sz is __u32 and resp->ngroups is __s32. Each addition can wrap in unsigned int; the multiplication by sizeof(gid_t) mixes signed and size_t, so a negative ngroups is converted to SIZE_MAX before the multiply. A wrapped value of msg_sz that happens to equal entry->msg_sz bypasses the size check on the next line, and downstream consumers (smb2pdu.c:6742 memcpy using rpc_resp->payload_sz, kmemdup in ksmbd_alloc_user using resp_ext->ngroups) then trust the unverified length.
Use check_add_overflow() on the RPC_REQUEST and SHARE_CONFIG_REQUEST paths to detect integer overflow without constraining functional payload size; userspace ksmbd-tools grows NDR responses in 4096-byte chunks for calls like NetShareEnumAll, so a hard transport cap is unworkable on the response side. For LOGIN_REQUEST_EXT, reject resp->ngroups outside the signed [0, NGROUPS_MAX] range up front and report the error from ipc_validate_msg() so it fires at the IPC boundary; with that bound the subsequent multiplication and addition stay well below UINT_MAX. The now-redundant ngroups check and pr_err in ksmbd_alloc_user() are removed.
This is the response-side analogue of aab98e2dbd64 ("ksmbd: fix integer overflows on 32 bit systems"), which hardened the request side.
--- fs/smb/server/mgmt/user_config.c | 6 ------ fs/smb/server/transport_ipc.c | 16 +++++++++++++--- 2 files changed, 13 insertions(+), 9 deletions(-)
fs/smb/server/mgmt/user_config.c +0 -6
@@ -56,12 +56,6 @@ struct ksmbd_user *ksmbd_alloc_user(struct ksmbd_login_response *resp, goto err_free;if (resp_ext) { -if (resp_ext->ngroups >NGROUPS_MAX ) { -pr_err ("ngroups(%u) from login response exceeds max groups(%d)\n" , - resp_ext->ngroups,NGROUPS_MAX ); - goto err_free; - } - user->sgid =kmemdup (resp_ext->____payload, resp_ext->ngroups *sizeof (gid_t),GFP_KERNEL );
fs/smb/server/transport_ipc.c +13 -3
@@ -13,6 +13,7 @@#include <net/genetlink.h> #include <linux/socket.h> #include <linux/workqueue.h> +#include <linux/overflow.h> #include "vfs_cache.h" #include "transport_ipc.h"
@@ -497,7 +498,9 @@ static int ipc_validate_msg(struct ipc_msg_table_entry *entry) {struct ksmbd_rpc_command *resp = entry->response; - msg_sz =sizeof (struct ksmbd_rpc_command ) + resp->payload_sz; +if (check_add_overflow (sizeof (struct ksmbd_rpc_command ), + resp->payload_sz, &msg_sz)) +return -EINVAL ;break ; }case KSMBD_EVENT_SPNEGO_AUTHEN_REQUEST :
@@ -516,8 +519,9 @@ static int ipc_validate_msg(struct ipc_msg_table_entry *entry)if (resp->payload_sz < resp->veto_list_sz)return -EINVAL ; - msg_sz =sizeof (struct ksmbd_share_config_response ) + - resp->payload_sz; +if (check_add_overflow (sizeof (struct ksmbd_share_config_response ), + resp->payload_sz, &msg_sz)) +return -EINVAL ; }break ; }
@@ -526,6 +530,12 @@ static int ipc_validate_msg(struct ipc_msg_table_entry *entry)struct ksmbd_login_response_ext *resp = entry->response;if (resp->ngroups) { +if (resp->ngroups <0 || + resp->ngroups >NGROUPS_MAX ) { +pr_err ("ngroups(%d) from login response exceeds max groups(%d)\n" , + resp->ngroups,NGROUPS_MAX ); +return -EINVAL ; + } msg_sz =sizeof (struct ksmbd_login_response_ext ) + resp->ngroups *sizeof (gid_t); }
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 448/508 net/sched: sch_pie: annotate more data-races in pie_dump_stats()
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Eric Dumazet <[email protected]>
[ Upstream commit 6d4106e8df94c0c52cf3ca6a6a0d01567fb3844e ]
My prior patch missed few READ_ONCE()/WRITE_ONCE() annotations.
--- net/sched/sch_pie.c | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-)
net/sched/sch_pie.c +6 -8
@@ -212,16 +212,14 @@ void pie_process_dequeue(struct sk_buff *skb, struct pie_params *params,* packet timestamp. */ if (!params->dq_rate_estimator) { - vars->qdelay = now -pie_get_enqueue_time (skb); +WRITE_ONCE (vars->qdelay, + backlog ? now -pie_get_enqueue_time (skb) :0 );if (vars->dq_tstamp !=DTIME_INVALID ) dtime = now - vars->dq_tstamp; vars->dq_tstamp = now; -if (backlog ==0 ) - vars->qdelay =0 ; -if (dtime ==0 )return ;
@@ -369,7 +367,7 @@ void pie_calculate_probability(struct pie_params *params, struct pie_vars *vars,if (qdelay > (PSCHED_NS2TICKS (250 *NSEC_PER_MSEC ))) delta +=MAX_PROB / (100 /2 ); - vars->prob += delta; +WRITE_ONCE (vars->prob, vars->prob + delta);if (delta >0 ) {/* prevent overflow */
@@ -394,7 +392,7 @@ void pie_calculate_probability(struct pie_params *params, struct pie_vars *vars,if (qdelay ==0 && qdelay_old ==0 && update_prob)/* Reduce drop probability to 98.4% */ - vars->prob -= vars->prob /64 ; +WRITE_ONCE (vars->prob, vars->prob - vars->prob /64 );WRITE_ONCE (vars->qdelay, qdelay); vars->backlog_old = backlog;
@@ -493,7 +491,7 @@ static int pie_dump_stats(struct Qdisc *sch, struct gnet_dump *d) {struct pie_sched_data *q =qdisc_priv (sch);struct tc_pie_xstats st = { - .prob = q->vars.prob <<BITS_PER_BYTE , + .prob =READ_ONCE (q->vars.prob) <<BITS_PER_BYTE , .delay = ((u32 )PSCHED_TICKS2NS (READ_ONCE (q->vars.qdelay))) /NSEC_PER_USEC , .packets_in =READ_ONCE (q->stats.packets_in),
@@ -504,7 +502,7 @@ static int pie_dump_stats(struct Qdisc *sch, struct gnet_dump *d) };/* avg_dq_rate is only valid if dq_rate_estimator is enabled */ - st.dq_rate_estimating = q->params.dq_rate_estimator; + st.dq_rate_estimating =READ_ONCE (q->params.dq_rate_estimator);/* unscale and return dq_rate in bytes per sec */ if (st.dq_rate_estimating)
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 449/508 netconsole: avoid out-of-bounds access on empty string in trim_newline()
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Breno Leitao <[email protected]>
[ Upstream commit 7079c8c13f2d33992bc846240517d88f4ab07781 ]
trim_newline() unconditionally dereferences s[len - 1] after computing len = strnlen(s, maxlen). When the string is empty, len is 0 and the expression underflows to s[(size_t)-1], reading (and potentially writing) one byte before the buffer.
The two callers feed trim_newline() with the result of strscpy() from configfs store callbacks (dev_name_store, userdatum_value_store). configfs guarantees count >= 1 reaches the callback, but the byte itself can be NUL: a userspace write(fd, "\0", 1) leaves the destination empty after strscpy() and triggers the underflow. The OOB write only fires if the adjacent byte happens to be '\n', so this is not a security issue, but the access is undefined behaviour either way.
This pattern is commonly flagged by LLM-based code reviewers. While it is not a security fix, the underlying access is undefined behaviour and the change is small and self-contained, so it is a reasonable candidate for the stable trees.
Guard the dereference on a non-zero length.
--- drivers/net/netconsole.c | 2 ++ 1 file changed, 2 insertions(+)
drivers/net/netconsole.c +2 -0
@@ -278,6 +278,8 @@ static void trim_newline(char *s, size_t maxlen)size_t len; len =strnlen (s, maxlen); +if (!len) +return ;if (s[len -1 ] =='\n' ) s[len -1 ] ='\0' ; }
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 450/508 bonding: fix NULL pointer dereference in actor_port_prio setting
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Hangbin Liu <[email protected]>
[ Upstream commit 067bf016e99ad72aa4ff869d6dec1fd62a9c6202 ]
Liang reported an issue where setting a slave’s actor_port_prio to predefined values such as 0, 255, or 65535 would cause a system crash.
The problem occurs because in bond_opt_parse(), when the provided value matches a predefined table entry, the function returns that table entry, which does not contain slave information. Later, in bond_option_actor_port_prio_set(), calling bond_slave_get_rtnl() leads to a NULL pointer dereference.
Since actor_port_prio is defined as a u16 and initialized to the default value of 255 in ad_initialize_port(), there is no need for the bond_actor_port_prio_tbl. Using the BOND_OPTFLAG_RAWVAL flag is sufficient.
--- drivers/net/bonding/bond_options.c | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-)
drivers/net/bonding/bond_options.c +1 -8
@@ -225,13 +225,6 @@ static const struct bond_opt_value bond_ad_actor_sys_prio_tbl[] = { { NULL, -1, 0}, }; -static const struct bond_opt_value bond_actor_port_prio_tbl[] = { - {"minval" ,0 ,BOND_VALFLAG_MIN }, - {"maxval" ,65535 ,BOND_VALFLAG_MAX }, - {"default" ,255 ,BOND_VALFLAG_DEFAULT }, - {NULL ,-1 ,0 }, -}; -static const struct bond_opt_value bond_ad_user_port_key_tbl[] = { {"minval" ,0 ,BOND_VALFLAG_MIN |BOND_VALFLAG_DEFAULT }, { "maxval", 1023, BOND_VALFLAG_MAX},
@@ -497,7 +490,7 @@ static const struct bond_option bond_opts[BOND_OPT_LAST] = { .id = BOND_OPT_ACTOR_PORT_PRIO, .name = "actor_port_prio", .unsuppmodes = BOND_MODE_ALL_EX(BIT(BOND_MODE_8023AD)), - .values = bond_actor_port_prio_tbl, + .flags = BOND_OPTFLAG_RAWVAL, .set = bond_option_actor_port_prio_set, }, [BOND_OPT_AD_ACTOR_SYSTEM] = {
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 451/508 crypto: af_alg - Cap AEAD AD length to 0x80000000
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Herbert Xu <[email protected]>
commit e4c06479d7059888adf2f22bc1ebcf053bf691a2 upstream.
In order to prevent arithmetic overflows when checking the TX buffer size, cap the associated data length to 0x80000000.
--- crypto/af_alg.c | 2 ++ 1 file changed, 2 insertions(+)
crypto/af_alg.c +2 -0
@@ -585,6 +585,8 @@ static int af_alg_cmsg_send(struct msghdif (cmsg->cmsg_len <CMSG_LEN (sizeof (u32)))return -EINVAL ; con->aead_assoclen = *(u32 *)CMSG_DATA (cmsg); +if (con->aead_assoclen >=0x80000000u ) +return -EINVAL ;break ;default :
Greg Kroah-Hartman
maintainerPATCH 452/508 i40e: Cleanup PTP pins on probe failure
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Matt Vollrath <[email protected]>
commit 678b713ece1e853f11e670a84cb887c35e1381b7 upstream.
PTP pin structs are allocated early in probe, but never cleaned up.
Fix this by calling i40e_ptp_free_pins in the error path.
To support this, i40e_ptp_free_pins is added to the header and pin_config is correctly nullified after being freed.
This has been an issue since i40e_ptp_alloc_pins was introduced.
--- drivers/net/ethernet/intel/i40e/i40e.h | 1 + drivers/net/ethernet/intel/i40e/i40e_main.c | 1 + drivers/net/ethernet/intel/i40e/i40e_ptp.c | 3 ++- 3 files changed, 4 insertions(+), 1 deletion(-)
drivers/net/ethernet/intel/i40e/i40e.h +1 -0
@@ -1262,6 +1262,7 @@ void i40e_ptp_restore_hw_time(struct i40void i40e_ptp_init (struct i40e_pf *pf);void i40e_ptp_stop (struct i40e_pf *pf);int i40e_ptp_alloc_pins (struct i40e_pf *pf); +void i40e_ptp_free_pins (struct i40e_pf *pf);int i40e_update_adq_vsi_queues (struct i40e_vsi *vsi,int vsi_offset);int i40e_is_vsi_uplink_mode_veb (struct i40e_vsi *vsi);int i40e_get_partition_bw_setting (struct i40e_pf *pf);
drivers/net/ethernet/intel/i40e/i40e_main.c +1 -0
@@ -16300,6 +16300,7 @@ err_vsis:i40e_clear_interrupt_scheme (pf);kfree (pf->vsi); err_switch_setup: +i40e_ptp_free_pins (pf);i40e_reset_interrupt_capability (pf);timer_shutdown_sync (&pf->service_timer); err_mac_addr:
drivers/net/ethernet/intel/i40e/i40e_ptp.c +2 -1
@@ -937,12 +937,13 @@ int i40e_ptp_get_ts_config(struct i40e_p* * Release memory allocated for PTP pins. **/ -static void i40e_ptp_free_pins (struct i40e_pf *pf) +void i40e_ptp_free_pins (struct i40e_pf *pf) {if (i40e_is_ptp_pin_dev (&pf->hw)) {kfree (pf->ptp_pins);kfree (pf->ptp_caps.pin_config); pf->ptp_pins =NULL ; + pf->ptp_caps.pin_config =NULL ; } }
Greg Kroah-Hartman
maintainerPATCH 453/508 workqueue: Fix wq->cpu_pwq leak in alloc_and_link_pwqs() WQ_UNBOUND path
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Breno Leitao <[email protected]>
commit 0143033dc22cdff912cfc13419f5db92fea3b4cb upstream.
For WQ_UNBOUND workqueues, alloc_and_link_pwqs() allocates wq->cpu_pwq via alloc_percpu() and then calls apply_workqueue_attrs_locked(). On failure it returns the error directly, bypassing the enomem: label which holds the only free_percpu(wq->cpu_pwq) in this function.
The caller's error path kfree()s wq without touching wq->cpu_pwq, leaking one percpu pointer table (nr_cpu_ids * sizeof(void *) bytes) per failed call.
If kmemleak is enabled, we can see:
unreferenced object (percpu) 0xc0fffa5b121048 (size 8):
comm "insmod", pid 776, jiffies 4294682844
backtrace (crc 0):
pcpu_alloc_noprof+0x665/0xac0
__alloc_workqueue+0x33f/0xa20
alloc_workqueue_noprof+0x60/0x100Route the error through the existing enomem: cleanup and any error before this one.
--- kernel/workqueue.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
kernel/workqueue.c +3 -1
@@ -4683,7 +4683,9 @@ static int alloc_and_link_pwqs(struct woif (ret)kthread_flush_worker (pwq_release_worker); -return ret; +if (ret) + goto enomem; +return 0 ; enomem:if (wq->cpu_pwq) {
Greg Kroah-Hartman
maintainerPATCH 454/508 netfilter: nf_conntrack_sip: get helper before allocating expectation
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Li Xiasong <[email protected]>
commit eb6317739b1ea3ab28791e1f91b24781905fa815 upstream.
process_register_request() allocates an expectation and then checks whether a conntrack helper is available. If helper lookup fails, the function returns early and the allocated expectation is left behind.
Reorder the code to fetch and validate helper before calling nf_ct_expect_alloc(). This keeps the logic simpler and removes the leak path while preserving existing behavior.
--- net/netfilter/nf_conntrack_sip.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-)
net/netfilter/nf_conntrack_sip.c +4 -4
@@ -1367,6 +1367,10 @@ static int process_register_request(stru goto store_cseq; } + helper =rcu_dereference (nfct_help (ct)->helper); +if (!helper) +return NF_DROP ; + exp =nf_ct_expect_alloc (ct);if (!exp) {nf_ct_helper_log (skb, ct,"cannot alloc expectation" );
@@ -1377,10 +1381,6 @@ static int process_register_request(struif (sip_direct_signalling) saddr = &ct->tuplehash[!dir].tuple.src.u3; - helper =rcu_dereference (nfct_help (ct)->helper); -if (!helper) -return NF_DROP ; -nf_ct_expect_init (exp,SIP_EXPECT_SIGNALLING ,nf_ct_l3num (ct), saddr, &daddr, proto,NULL , &port); exp->timeout.expires = sip_timeout *HZ ;
Greg Kroah-Hartman
maintainerPATCH 455/508 audit: fix incorrect inheritable capability in CAPSET records
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Sergio Correia <[email protected]>
commit e4a640475e43f406fdfd56d370b1f34b0cbbc18d upstream.
__audit_log_capset() records the effective capability set into the inheritable field due to a copy-paste error. Every CAPSET audit record therefore reports cap_pi (process inheritable) with the value of cap_effective instead of cap_inheritable.
This silently corrupts audit data used for compliance and forensic
analysis: an attacker who modifies inheritable capabilities to prepare for a privilege-escalating exec would have the change masked in the audit trail.
The bug has been present since the original introduction of CAPSET audit records in 2008.
--- kernel/auditsc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
kernel/auditsc.c +1 -1
@@ -2845,7 +2845,7 @@ void __audit_log_capset(const struct cre context->capset.pid =task_tgid_nr (current); context->capset.cap.effective = new->cap_effective; - context->capset.cap.inheritable = new->cap_effective; + context->capset.cap.inheritable = new->cap_inheritable; context->capset.cap.permitted = new->cap_permitted; context->capset.cap.ambient = new->cap_ambient; context->type =AUDIT_CAPSET ;
Greg Kroah-Hartman
maintainerPATCH 456/508 netfilter: nft_ct: fix missing expect put in obj eval
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Li Xiasong <[email protected]>
commit 19f94b6fee75b3ef7fbc06f3745b9a771a8a19a4 upstream.
nft_ct_expect_obj_eval() allocates an expectation and may call nf_ct_expect_related(), but never drops its local reference.
Add nf_ct_expect_put(exp) before return to balance allocation.
--- net/netfilter/nft_ct.c | 2 ++ 1 file changed, 2 insertions(+)
net/netfilter/nft_ct.c +2 -0
@@ -1363,6 +1363,8 @@ static void nft_ct_expect_obj_eval(strucif (nf_ct_expect_related (exp,0 ) !=0 ) regs->verdict.code =NF_DROP ; + +nf_ct_expect_put (exp); }static const struct nla_policy nft_ct_expect_policy[NFTA_CT_EXPECT_MAX +1 ] = {
Greg Kroah-Hartman
maintainerPATCH 457/508 net: atlantic: preserve PCI wake-from-D3 on shutdown when WOL enabled
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Zoran Ilievski <[email protected]>
commit 2c308cf34284420963607d677d576a2b4124d8bd upstream.
The shutdown handler aq_pci_shutdown() unconditionally calls pci_wake_from_d3(pdev, false), clearing the PCI PME_En bit even when wake-on-LAN has been configured. While aq_nic_shutdown() correctly programs the NIC firmware via aq_nic_set_power() to listen for magic packets, the PCI subsystem will not propagate the resulting PME wake event from D3, so the system never wakes after poweroff.
WOL from suspend (S3) is unaffected because aq_suspend_common() does not touch pci_wake_from_d3() and relies on the PM core's wake configuration via device_may_wakeup().
This affects all atlantic-supported NICs (AQC107/108/111/112/113); users have reported that WOL works if the atlantic driver is never loaded, but breaks once it has run its shutdown path.
Pass the configured WOL state to pci_wake_from_d3() instead of a literal false, so the PCI PME_En bit is preserved when the user has armed WOL via ethtool.
--- drivers/net/ethernet/aquantia/atlantic/aq_pci_func.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/net/ethernet/aquantia/atlantic/aq_pci_func.c +1 -1
@@ -374,7 +374,7 @@ static void aq_pci_shutdown(struct pci_dpci_disable_device (pdev);if (system_state ==SYSTEM_POWER_OFF ) { -pci_wake_from_d3 (pdev, false); +pci_wake_from_d3 (pdev, self->aq_hw->aq_nic_cfg->wol);pci_set_power_state (pdev, PCI_D3hot); } }
Greg Kroah-Hartman
maintainerPATCH 458/508 audit: enforce AUDIT_LOCKED for AUDIT_TRIM and AUDIT_MAKE_EQUIV
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Sergio Correia <[email protected]>
commit f9e1c1324b4d98d591a6f7568fdebf5cf456dfc2 upstream.
AUDIT_ADD_RULE and AUDIT_DEL_RULE correctly check for AUDIT_LOCKED and return -EPERM, but AUDIT_TRIM and AUDIT_MAKE_EQUIV do not. This allows a process with CAP_AUDIT_CONTROL to modify directory tree watches and equivalence mappings even when the audit configuration has been locked, undermining the purpose of the lock.
Add AUDIT_LOCKED checks to both commands.
--- kernel/audit.c | 4 ++++ 1 file changed, 4 insertions(+)
kernel/audit.c +4 -0
@@ -1427,6 +1427,8 @@ static int audit_receive_msg(struct sk_b err =audit_list_rules_send (skb, seq);break ;case AUDIT_TRIM : +if (audit_enabled ==AUDIT_LOCKED ) +return -EPERM ;audit_trim_trees ();audit_log_common_recv_msg (audit_context (), &ab,AUDIT_CONFIG_CHANGE );
@@ -1439,6 +1441,8 @@ static int audit_receive_msg(struct sk_bsize_t msglen = data_len;char *old, *new; +if (audit_enabled ==AUDIT_LOCKED ) +return -EPERM ; err = -EINVAL ;if (msglen <2 *sizeof (u32))break ;
Greg Kroah-Hartman
maintainerPATCH 459/508 KVM: Reject wrapped offset in kvm_reset_dirty_gfn()
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Aaron Sacks <[email protected]>
commit 577a8d3bae0531f0e5ccfac919cd8192f920a804 upstream.
kvm_reset_dirty_gfn() guards the gfn range with
if (!memslot || (offset + __fls(mask)) >= memslot->npages) return;
but offset is u64 and the addition is unchecked. The check can be silently bypassed by a u64 wrap.
The dirty ring backing those entries is MAP_SHARED at KVM_DIRTY_LOG_PAGE_OFFSET of the vcpu fd, so the VMM can rewrite the slot and offset fields of any entry between when the kernel pushes them and when KVM_RESET_DIRTY_RINGS consumes them. On reset, kvm_dirty_ring_reset() re-reads the values via READ_ONCE() and feeds them straight back into this check; only the flags handshake is treated as the handover, the slot/offset payload is taken on trust.
Crafting two entries
entry[i].offset = 0xffffffffffffffc1 entry[i+1].offset = 0
makes the coalescing loop in kvm_dirty_ring_reset() compute
delta = (s64)(0 - 0xffffffffffffffc1) = 63
which falls in [0, BITS_PER_LONG), so it folds entry[i+1] into the existing mask by setting bit 63. The trailing kvm_reset_dirty_gfn() call then sees offset = 0xffffffffffffffc1 and __fls(mask) = 63; the sum is 0 in u64 and the bounds check passes.
That offset propagates into kvm_arch_mmu_enable_log_dirty_pt_masked() unchanged. On the legacy MMU path -- kvm_memslots_have_rmaps() == true, i.e. shadow paging, any VM that has allocated shadow roots, or a write-tracked slot -- it reaches gfn_to_rmap(), which indexes slot->arch.rmap[0][] with a near-U64_MAX gfn. That is an out-of-bounds load of a kvm_rmap_head, followed by a conditional clear of PT_WRITABLE_MASK in whatever the loaded pointer points at. The path is reachable from any process holding /dev/kvm.
Range-check offset on its own first, so the addition cannot wrap. memslot->npages is bounded well below U64_MAX, so once offset < npages holds, offset + __fls(mask) (with __fls(mask) < BITS_PER_LONG) stays in range.
--- virt/kvm/dirty_ring.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
virt/kvm/dirty_ring.c +2 -1
@@ -63,7 +63,8 @@ static void kvm_reset_dirty_gfn(struct k memslot =id_to_memslot (__kvm_memslots (kvm, as_id), id); -if (!memslot || (offset +__fls (mask)) >= memslot->npages) +if (!memslot || offset >= memslot->npages || + offset +__fls (mask) >= memslot->npages)return ;KVM_MMU_LOCK (kvm);
Greg Kroah-Hartman
maintainerPATCH 460/508 KVM: s390: pci: fix GAIT table indexing due to double-scaling pointer arithmetic
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Junrui Luo <[email protected]>
commit 16d990a15491cf76cd6eef0846e1b4100e63261a upstream.
kvm_s390_pci_aif_enable(), kvm_s390_pci_aif_disable(), and aen_host_forward() index the GAIT by manually multiplying the index with sizeof(struct zpci_gaite).
Since aift->gait is already a struct zpci_gaite pointer, this double-scales the offset, accessing element aisb*16 instead of aisb.
This causes out-of-bounds accesses when aisb >= 32 (with ZPCI_NR_DEVICES=512)
Fix by removing the erroneous sizeof multiplication.
--- arch/s390/kvm/interrupt.c | 3 +-- arch/s390/kvm/pci.c | 6 ++---- 2 files changed, 3 insertions(+), 6 deletions(-)
arch/s390/kvm/interrupt.c +1 -2
@@ -3329,8 +3329,7 @@ static void aen_host_forward(unsigned lostruct zpci_gaite *gaite;struct kvm *kvm; - gaite = (struct zpci_gaite *)aift->gait + - (si *sizeof (struct zpci_gaite )); + gaite = aift->gait + si;if (gaite->count ==0 )return ;if (gaite->aisb !=0 )
arch/s390/kvm/pci.c +2 -4
@@ -292,8 +292,7 @@ static int kvm_s390_pci_aif_enable(struc phys_to_virt(fib->fmt0.aibv));spin_lock_irq (&aift->gait_lock); - gaite = (struct zpci_gaite *)aift->gait + (zdev->aisb * -sizeof (struct zpci_gaite )); + gaite = aift->gait + zdev->aisb;/* If assist not requested, host will get all alerts */ if (assist)
@@ -359,8 +358,7 @@ static int kvm_s390_pci_aif_disable(struif (zdev->kzdev->fib.fmt0.aibv ==0 ) goto out;spin_lock_irq (&aift->gait_lock); - gaite = (struct zpci_gaite *)aift->gait + (zdev->aisb * -sizeof (struct zpci_gaite )); + gaite = aift->gait + zdev->aisb; isc = gaite->gisc; gaite->count--;if (gaite->count ==0 ) {
Greg Kroah-Hartman
maintainerPATCH 461/508 KVM: x86: Fix Xen hypercall tracepoint argument assignment
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Qiang Ma <[email protected]>
commit 2b72f1674e427c56e3772c5ccf785fdda2138820 upstream.
TRACE_EVENT(kvm_xen_hypercall) stores a5 in __entry->a4 instead of __entry->a5.
That overwrites the recorded a4 argument and leaves a5 unset in the trace entry. Fix the typo so both arguments are captured correctly.
--- arch/x86/kvm/trace.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
arch/x86/kvm/trace.h +1 -1
@@ -140,7 +140,7 @@ TRACE_EVENT(kvm_xen_hypercall, __entry->a2 = a2; __entry->a3 = a3; __entry->a4 = a4; - __entry->a4 = a5; + __entry->a5 = a5; ), TP_printk("cpl %d nr 0x%lx a0 0x%lx a1 0x%lx a2 0x%lx a3 0x%lx a4 0x%lx a5 %lx",
Greg Kroah-Hartman
maintainerPATCH 462/508 netfilter: nf_tables: unconditionally bump set->nelems before insertion
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Pablo Neira Ayuso <[email protected]>
[ Upstream commit def602e498a4f951da95c95b1b8ce8ae68aa733a ]
In case that the set is full, a new element gets published then removed without waiting for the RCU grace period, while RCU reader can be walking over it already.
To address this issue, add the element transaction even if set is full, but toggle the set_full flag to report -ENFILE so the abort path safely unwinds the set to its previous state.
As for element updates, decrement set->nelems to restore it.
A simpler fix is to call synchronize_rcu() in the error path. However, with a large batch adding elements to already maxed-out set, this could cause noticeable slowdown of such batches.
--- net/netfilter/nf_tables_api.c | 28 +++++++++++++++------------- 1 file changed, 15 insertions(+), 13 deletions(-)
net/netfilter/nf_tables_api.c +15 -13
@@ -6803,6 +6803,7 @@ static int nft_add_set_elem(struct nft_ctx *ctx, struct nft_set *set,struct nft_data_desc desc;enum nft_registers dreg;struct nft_trans *trans; +bool set_full = false;u64 timeout;u64 expiration;int err, i;
@@ -7095,10 +7096,18 @@ static int nft_add_set_elem(struct nft_ctx *ctx, struct nft_set *set,if (err <0 ) goto err_elem_free; +if (!(flags &NFT_SET_ELEM_CATCHALL )) { +unsigned int max =nft_set_maxsize (set), nelems; + + nelems =atomic_inc_return (&set->nelems); +if (nelems > max) + set_full = true; + } + trans =nft_trans_elem_alloc (ctx,NFT_MSG_NEWSETELEM , set);if (trans ==NULL ) { err = -ENOMEM ; - goto err_elem_free; + goto err_set_size; } ext->genmask =nft_genmask_cur (ctx->net);
@@ -7130,23 +7139,16 @@ static int nft_add_set_elem(struct nft_ctx *ctx, struct nft_set *set, goto err_element_clash; } -if (!(flags &NFT_SET_ELEM_CATCHALL )) { -unsigned int max =nft_set_maxsize (set); - -if (!atomic_add_unless (&set->nelems,1 , max)) { - err = -ENFILE ; - goto err_set_full; - } - } -nft_trans_elem (trans) = elem;nft_trans_commit_list_add_tail (ctx->net, trans); -return 0 ; -err_set_full: -nft_setelem_remove (ctx->net, set, &elem); +return set_full ? -ENFILE :0 ; + err_element_clash:kfree (trans); +err_set_size: +if (!(flags &NFT_SET_ELEM_CATCHALL )) +atomic_dec (&set->nelems); err_elem_free:nf_tables_set_elem_destroy (ctx, set, elem.priv); err_parse_data:
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 463/508 ASoC: SOF: Intel: hda-dai: remove dspless special case
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Pierre-Louis Bossart <[email protected]>
[ Upstream commit daa09d0615ce9c781777802874cffa4380f883c3 ]
The existing code forces a parameter to be NULL but that parameter is not used yet. Remove the special case in preparation for additional changes.
--- sound/soc/sof/intel/hda-dai.c | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-)
sound/soc/sof/intel/hda-dai.c +1 -5
@@ -83,12 +83,8 @@ hda_dai_get_ops(struct snd_pcm_substream *substream, struct snd_soc_dai *cpu_dai sdev =widget_to_sdev (w); -/* -* The swidget parameter of hda_select_dai_widget_ops() is ignored in -* case of DSPless mode -*/ if (sdev->dspless_mode_selected) -return hda_select_dai_widget_ops (sdev,NULL ); +return hda_select_dai_widget_ops (sdev, swidget); sdai = swidget->private;
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 464/508 ASoC: SOF: Intel: hda-dai: add support for dspless mode beyond HDAudio
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Pierre-Louis Bossart <[email protected]>
[ Upstream commit 2065610b5ddd5b58eed1dc3b3c3db27a26ebd4b6 ]
For SoundWire/ALH, we need to have a dai configured, but we don't want to send a DMA_TLV to firmware. Add additional code branches.
--- sound/soc/sof/intel/hda-dai.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-)
sound/soc/sof/intel/hda-dai.c +10 -1
@@ -83,6 +83,11 @@ hda_dai_get_ops(struct snd_pcm_substream *substream, struct snd_soc_dai *cpu_dai sdev =widget_to_sdev (w); +if (!swidget) { +dev_err (sdev->dev,"%s: swidget is NULL\n" , __func__); +return NULL ; + } +if (sdev->dspless_mode_selected)return hda_select_dai_widget_ops (sdev, swidget);
@@ -364,8 +369,11 @@ static int non_hda_dai_hw_params(struct snd_pcm_substream *substream,return ret; } -/* get stream_id */ sdev =widget_to_sdev (w); +if (sdev->dspless_mode_selected) + goto skip_tlv; + +/* get stream_id */ hext_stream = ops->get_hext_stream (sdev, cpu_dai, substream);if (!hext_stream) {
@@ -398,6 +406,7 @@ static int non_hda_dai_hw_params(struct snd_pcm_substream *substream, dma_config->dma_stream_channel_map.device_count =0 ;/* mapping not used */ dma_config->dma_priv_config_size =0 ; +skip_tlv:return 0 ; }
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 465/508 ASoC: SOF: Intel: hda: Fix NULL pointer dereference
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ranjani Sridharan <[email protected]>
[ Upstream commit 16c589567a956d46a7c1363af3f64de3d420af20 ]
If there's a mismatch between the DAI links in the machine driver and the topology, it is possible that the playback/capture widget is not set, especially in the case of loopback capture for echo reference where we use the dummy DAI link. Return the error when the widget is not set to avoid a null pointer dereference like below when the topology is broken.
RIP: 0010:hda_dai_get_ops.isra.0+0x14/0xa0 [snd_sof_intel_hda_common]
--- sound/soc/sof/intel/hda-dai.c | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-)
sound/soc/sof/intel/hda-dai.c +12 -2
@@ -77,12 +77,22 @@ static const struct hda_dai_widget_dma_ops * hda_dai_get_ops(struct snd_pcm_substream *substream, struct snd_soc_dai *cpu_dai) { struct snd_soc_dapm_widget *w = snd_soc_dai_get_widget(cpu_dai, substream->stream); -struct snd_sof_widget *swidget = w->dobj.private; +struct snd_sof_widget *swidget;struct snd_sof_dev *sdev;struct snd_sof_dai *sdai; - sdev =widget_to_sdev (w); +/* +* this is unlikely if the topology and the machine driver DAI links match. +* But if there's a missing DAI link in topology, this will prevent a NULL pointer +* dereference later on. +*/ +if (!w) { +dev_err (cpu_dai->dev,"%s: widget is NULL\n" , __func__); +return NULL ; + } + sdev =widget_to_sdev (w); + swidget = w->dobj.private;if (!swidget) {dev_err (sdev->dev,"%s: swidget is NULL\n" , __func__);return NULL ;
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 466/508 smb/client: fix possible infinite loop and oob read in symlink_data()
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ye Bin <[email protected]>
commit 7d9a7f1f96cd617ee9e75bb22217c709038e26b8 upstream.
On 32-bit architectures, the infinite loop is as follows:
len = p->ErrorDataLength == 0xfffffff8
u8 *next = p->ErrorContextData + len
next == p
On 32-bit architectures, the out-of-bounds read is as follows:
len = p->ErrorDataLength == 0xfffffff0
u8 *next = p->ErrorContextData + len
next == (u8 *)p - 8
--- fs/smb/client/smb2file.c | 3 +++ 1 file changed, 3 insertions(+)
fs/smb/client/smb2file.c +3 -0
@@ -49,6 +49,9 @@ static struct smb2_symlink_err_rsp *syml __func__, le32_to_cpu(p->ErrorId)); len =ALIGN (le32_to_cpu (p->ErrorDataLength),8 ); +if (len > end - ((u8 *)p +sizeof (*p))) +return ERR_PTR (-EINVAL ); + p = (struct smb2_error_context_rsp *)(p->ErrorContextData + len); } } else if (le32_to_cpu(err->ByteCount) >= sizeof(*sym) &&
Greg Kroah-Hartman
maintainerPATCH 467/508 drm/i915/dp: Fix VSC dynamic range signaling for RGB formats
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Chaitanya Kumar Borah <[email protected]>
commit 1ae15b6c7965d137eef21f2cc7d367b29cb88369 upstream.
For RGB, set dynamic_range to CTA or VESA based on crtc_state->limited_color_range so sinks apply correct quantization. YCbCr remains limited (CTA) range. (DP v1.4, Table 5-1)
v2:
- Added Reported-by and Tested-by tags
v3:
- Add back YCbCr comment(Suraj)
--- drivers/gpu/drm/i915/display/intel_dp.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-)
drivers/gpu/drm/i915/display/intel_dp.c +7 -2
@@ -2029,8 +2029,13 @@ static void intel_dp_compute_vsc_colorimdrm_WARN_ON (&dev_priv->drm, vsc->bpc ==6 && vsc->pixelformat !=DP_PIXELFORMAT_RGB ); -/* all YCbCr are always limited range */ - vsc->dynamic_range =DP_DYNAMIC_RANGE_CTA ; +/* All YCbCr formats are always limited range. */ +if (vsc->pixelformat ==DP_PIXELFORMAT_RGB ) + vsc->dynamic_range = crtc_state->limited_color_range ? +DP_DYNAMIC_RANGE_CTA :DP_DYNAMIC_RANGE_VESA ; +else + vsc->dynamic_range =DP_DYNAMIC_RANGE_CTA ; + vsc->content_type =DP_CONTENT_TYPE_NOT_DEFINED ; }
Greg Kroah-Hartman
maintainerPATCH 468/508 ALSA: usb-audio: Bound MIDI 2.0 endpoint descriptor scans
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Cássio Gabriel <[email protected]>
commit 918be519c7876329e1b6e2ea1c59f0b75e792dca upstream.
The USB MIDI 2.0 endpoint parser has the same descriptor walking pattern as the legacy MIDI parser. It validates bLength against bNumGrpTrmBlock before reading baAssoGrpTrmBlkID[], but not against the remaining bytes in the endpoint-extra scan.
A malformed device can therefore make later baAssoGrpTrmBlkID[] reads consume bytes past the walked descriptor.
Reject zero-length and overlong descriptors while walking endpoint extras.
--- sound/usb/midi2.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-)
sound/usb/midi2.c +7 -5
@@ -504,15 +504,17 @@ static void *find_usb_ms_endpoint_descriwhile (extralen >3 ) {struct usb_ms_endpoint_descriptor *ms_ep = (struct usb_ms_endpoint_descriptor *)extra; +int length = ms_ep->bLength; -if (ms_ep->bLength >3 && +if (!length || length > extralen) +break ; + +if (length >3 && ms_ep->bDescriptorType ==USB_DT_CS_ENDPOINT && ms_ep->bDescriptorSubtype == subtype)return ms_ep; -if (!extra[0 ]) -break ; - extralen -= extra[0 ]; - extra += extra[0 ]; + extralen -= length; + extra += length; }return NULL ; }
Greg Kroah-Hartman
maintainerPATCH 469/508 ALSA: usb-audio: Bound MIDI endpoint descriptor scans
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Cássio Gabriel <[email protected]>
commit d6854daa67be623860f4e1873fd3d3c275aba4ed upstream.
snd_usbmidi_get_ms_info() validates the internal MIDIStreaming endpoint descriptor size before using baAssocJackID[], but the descriptor walker can still return a class-specific endpoint descriptor whose bLength exceeds the remaining bytes in the endpoint-extra scan.
That leaves later flexible-array reads bounded by bLength, but not by the remaining bytes in the endpoint-extra scan.
Stop walking when bLength is zero or
extends past the remaining endpoint-extra scan.
--- sound/usb/midi.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-)
sound/usb/midi.c +7 -5
@@ -1974,15 +1974,17 @@ static struct usb_ms_endpoint_descriptorwhile (extralen >3 ) {struct usb_ms_endpoint_descriptor *ms_ep = (struct usb_ms_endpoint_descriptor *)extra; +int length = ms_ep->bLength; -if (ms_ep->bLength >3 && +if (!length || length > extralen) +break ; + +if (length >3 && ms_ep->bDescriptorType ==USB_DT_CS_ENDPOINT && ms_ep->bDescriptorSubtype ==UAC_MS_GENERAL )return ms_ep; -if (!extra[0 ]) -break ; - extralen -= extra[0 ]; - extra += extra[0 ]; + extralen -= length; + extra += length; }return NULL ; }
Greg Kroah-Hartman
maintainerPATCH 470/508 ceph: fix a buffer leak in __ceph_setxattr()
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Viacheslav Dubeyko <[email protected]>
commit 5d3cc36b4e77a27ce7b686b7c59c7072bcb3fa8e upstream.
The old_blob in __ceph_setxattr() can store ci->i_xattrs.prealloc_blob value during the retry. However, it is never called the ceph_buffer_put() for the old_blob object. This patch fixes the issue of the buffer leak.
--- fs/ceph/xattr.c | 1 + 1 file changed, 1 insertion(+)
fs/ceph/xattr.c +1 -0
@@ -1279,6 +1279,7 @@ retry: do_sync:spin_unlock (&ci->i_ceph_lock); +ceph_buffer_put (old_blob); do_sync_unlocked:if (lock_snap_rwsem)up_read (&mdsc->snap_rwsem);
Greg Kroah-Hartman
maintainerPATCH 471/508 io-wq: check that the predecessor is hashed in io_wq_remove_pending()
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Nicholas Carlini <[email protected]>
commit d6a2d7b04b5a093021a7a0e2e69e9d5237dfa8cc upstream.
io_wq_remove_pending() needs to fix up wq->hash_tail[] if the cancelled work was the tail of its hash bucket. When doing this, it checks whether the preceding entry in acct->work_list has the same hash value, but never checks that the predecessor is hashed at all. io_get_work_hash() is simply atomic_read(&work->flags) >> IO_WQ_HASH_SHIFT, and the hash bits are never set for non-hashed work, so it returns 0. Thus, when a hashed bucket-0 work is cancelled while a non-hashed work is its list predecessor, the check spuriously passes and a pointer to the non-hashed io_kiocb is stored in wq->hash_tail[0].
Because non-hashed work is dequeued via the fast path in io_get_next_work(), which never touches hash_tail[], the stale pointer is never cleared. Therefore, after the non-hashed io_kiocb completes and is freed back to req_cachep, wq->hash_tail[0] is a dangling pointer. The io_wq is per-task (tctx->io_wq) and survives ring open/close, so the dangling pointer persists for the lifetime of the task; the next hashed bucket-0 enqueue dereferences it in io_wq_insert_work() and wq_list_add_after() writes through freed memory.
Add the missing io_wq_is_hashed() check so a non-hashed predecessor never inherits a hash_tail[] slot.
--- io_uring/io-wq.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
io_uring/io-wq.c +2 -1
@@ -1046,7 +1046,8 @@ static inline void io_wq_remove_pending(if (io_wq_is_hashed (work) && work == wq->hash_tail[hash]) {if (prev) prev_work = container_of(prev, struct io_wq_work, list); -if (prev_work &&io_get_work_hash (prev_work) == hash) +if (prev_work &&io_wq_is_hashed (prev_work) && +io_get_work_hash (prev_work) == hash) wq->hash_tail[hash] = prev_work;else wq->hash_tail[hash] =NULL ;
Greg Kroah-Hartman
maintainerPATCH 472/508 powerpc/warp: Fix error handling in pika_dtm_thread
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ma Ke <[email protected]>
commit 108d7f951271cbd36ca36efc5e5d106966f5180c upstream.
pika_dtm_thread() acquires client through of_find_i2c_device_by_node() but fails to release it in error handling path. This could result in a reference count leak, preventing proper cleanup and potentially leading to resource exhaustion. Add put_device() to release the reference in the error handling path.
Found by code review.
--- arch/powerpc/platforms/44x/warp.c | 2 ++ 1 file changed, 2 insertions(+)
arch/powerpc/platforms/44x/warp.c +2 -0
@@ -292,6 +292,8 @@ static int pika_dtm_thread(void __iomemschedule_timeout (HZ ); } +put_device (&client->dev); +return 0 ; }
Greg Kroah-Hartman
maintainerPATCH 473/508 netfs: fix error handling in netfs_extract_user_iter()
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Paulo Alcantara <[email protected]>
commit 0aad5704c6b4d14007d4eab15883e8524e4310f4 upstream.
In netfs_extract_user_iter(), if iov_iter_extract_pages() failed to extract user pages, bail out on -ENOMEM, otherwise return the error code only if @npages == 0, allowing short DIO reads and writes to be issued.
This fixes mmapstress02 from LTP tests against CIFS.
--- fs/netfs/iterator.c | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-)
fs/netfs/iterator.c +10 -3
@@ -22,7 +22,7 @@* * Extract the page fragments from the given amount of the source iterator and * build up a second iterator that refers to all of those bits. This allows -* the original iterator to disposed of. +* the original iterator to be disposed of. * * @extraction_flags can have ITER_ALLOW_P2PDMA set to request peer-to-peer DMA be * allowed on the pages extracted.
@@ -67,8 +67,8 @@ ssize_t netfs_extract_user_iter(struct i ret =iov_iter_extract_pages (orig, &pages, count, max_pages - npages, extraction_flags, &offset); -if (ret <0 ) { -pr_err ("Couldn't get user pages (rc=%zd)\n" , ret); +if (unlikely (ret <=0 )) { + ret = ret ?: -EIO ;break ; }
@@ -97,6 +97,13 @@ ssize_t netfs_extract_user_iter(struct i npages += cur_npages; } +if (ret <0 && (ret == -ENOMEM || npages ==0 )) { +for (i =0 ; i < npages; i++) +unpin_user_page (bv[i].bv_page); +kvfree (bv); +return ret; + } +iov_iter_bvec (new, orig->data_source, bv, npages, orig_len - count);return npages; }
Greg Kroah-Hartman
maintainerPATCH 474/508 libceph: Fix potential out-of-bounds access in osdmap_decode()
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Raphael Zimmer <[email protected]>
commit 35d0ed82d03e5ee77ea4f31f20e29562a7721649 upstream.
When decoding osd_state and osd_weight from an incoming osdmap in osdmap_decode(), both are decoded for each osd, i.e., map->max_osd times. The ceph_decode_need() check only accounts for sizeof(*map->osd_weight) once. This can potentially result in an out-of-bounds memory access if the incoming message is corrupted such that the max_osd value exceeds the actual content of the osdmap message.
This patch fixes the issue by changing the corresponding part in the ceph_decode_need() check to account for map->max_osd*sizeof(*map->osd_weight).
--- net/ceph/osdmap.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
net/ceph/osdmap.c +1 -1
@@ -1703,7 +1703,7 @@ static int osdmap_decode(void **p, voidceph_decode_need (p, end,3 *sizeof (u32) + map->max_osd*(struct_v >=5 ?sizeof (u32) :sizeof (u8)) + -sizeof (*map->osd_weight), e_inval); + map->max_osd*sizeof (*map->osd_weight), e_inval);if (ceph_decode_32 (p) != map->max_osd) goto e_inval;
Greg Kroah-Hartman
maintainerPATCH 475/508 libceph: Fix potential null-ptr-deref in decode_choose_args()
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Raphael Zimmer <[email protected]>
commit 28b0a2ab8c82d0bbdeb8013029c67c978ce6e4bf upstream.
A message of type CEPH_MSG_OSD_MAP contains an OSD map that itself contains a CRUSH map. When decoding this CRUSH map in crush_decode(), an array of max_buckets CRUSH buckets is decoded, where some indices may not refer to actual buckets and are therefore set to NULL. The received CRUSH map may optionally contain choose_args that get decoded in decode_choose_args(). When decoding a crush_choose_arg_map, a series of choose_args for different buckets is decoded, with the bucket_index being read from the incoming message. It is only checked that the bucket index does not exceed max_buckets, but not that it doesn't point to an index with a NULL bucket. If a (potentially corrupted) message contains a crush_choose_arg_map including such a bucket_index, a null pointer dereference may occur in the subsequent processing when attempting to access the bucket with the given index.
This patch fixes the issue by extending the affected check. Now, it is only attempted to access the bucket if it is not NULL.
--- net/ceph/osdmap.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
net/ceph/osdmap.c +2 -1
@@ -390,7 +390,8 @@ static int decode_choose_args(void **p, goto fail;if (arg->ids_size && - arg->ids_size != c->buckets[bucket_index]->size) + (!c->buckets[bucket_index] || + arg->ids_size != c->buckets[bucket_index]->size)) goto e_inval; }
Greg Kroah-Hartman
maintainerPATCH 476/508 libceph: Fix potential out-of-bounds access in crush_decode()
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Raphael Zimmer <[email protected]>
commit 4c79fc2d598694bda845b46229c9d48b65042970 upstream.
A message of type CEPH_MSG_OSD_MAP containing a crush map with at least one bucket has two fields holding the bucket algorithm. If the values in these two fields differ, an out-of-bounds access can occur. This is the case because the first algorithm field (alg) is used to allocate the correct amount of memory for a bucket of this type, while the second algorithm field inside the bucket (b->alg) is used in the subsequent processing.
This patch fixes the issue by adding a check that compares alg and b->alg and aborts the processing in case they differ. Furthermore, b->alg is set to 0 in this case, because the destruction of the crush map also uses this field to determine the bucket type, which can again result in an out-of-bounds access when trying to free the memory pointed to by the fields of the bucket. To correctly free the memory allocated for the bucket in such a case, the corresponding call to kfree is moved from the algorithm-specific crush_destroy_bucket functions to the generic crush_destroy_bucket().
--- net/ceph/crush/crush.c | 6 +----- net/ceph/osdmap.c | 4 ++++ 2 files changed, 5 insertions(+), 5 deletions(-)
net/ceph/crush/crush.c +1 -5
@@ -47,7 +47,6 @@ int crush_get_bucket_item_weight(const svoid crush_destroy_bucket_uniform (struct crush_bucket_uniform *b) {kfree (b->h.items); -kfree (b); }void crush_destroy_bucket_list (struct crush_bucket_list *b)
@@ -55,14 +54,12 @@ void crush_destroy_bucket_list(struct crkfree (b->item_weights);kfree (b->sum_weights);kfree (b->h.items); -kfree (b); }void crush_destroy_bucket_tree (struct crush_bucket_tree *b) {kfree (b->h.items);kfree (b->node_weights); -kfree (b); }void crush_destroy_bucket_straw (struct crush_bucket_straw *b)
@@ -70,14 +67,12 @@ void crush_destroy_bucket_straw(struct ckfree (b->straws);kfree (b->item_weights);kfree (b->h.items); -kfree (b); }void crush_destroy_bucket_straw2 (struct crush_bucket_straw2 *b) {kfree (b->item_weights);kfree (b->h.items); -kfree (b); }void crush_destroy_bucket (struct crush_bucket *b)
@@ -99,6 +94,7 @@ void crush_destroy_bucket(struct crush_bcrush_destroy_bucket_straw2 ((struct crush_bucket_straw2 *)b);break ; } +kfree (b); }/**
net/ceph/osdmap.c +4 -0
@@ -518,6 +518,10 @@ static struct crush_map *crush_decode(vo b->id =ceph_decode_32 (p); b->type =ceph_decode_16 (p); b->alg =ceph_decode_8 (p); +if (b->alg != alg) { + b->alg =0 ; + goto bad; + } b->hash =ceph_decode_8 (p); b->weight =ceph_decode_32 (p); b->size =ceph_decode_32 (p);
Greg Kroah-Hartman
maintainerPATCH 477/508 libceph: handle rbtree insertion error in decode_choose_args()
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Raphael Zimmer <[email protected]>
commit d289478cfc0bcf81c7914200d6abdcb78bd04ded upstream.
A message of type CEPH_MSG_OSD_MAP contains an OSD map that itself contains a CRUSH map. The received CRUSH map may optionally contain choose_args that get decoded in decode_choose_args(). In this function, num_choose_arg_maps is read from the message, and a corresponding number of crush_choose_arg_maps gets decoded afterwards. Each crush_choose_arg_map has a choose_args_index, which serves as the key when inserting it into the choose_args rbtree of the decoded crush_map. If a (potentially corrupted) message contains two crush_choose_arg_maps with the same index, the assertion in insert_choose_arg_map() triggers a kernel BUG when trying to insert the second crush_choose_arg_map.
This patch fixes the issue by switching to the non-asserting rbtree insertion function and rejecting the message if the insertion fails.
[ idryomov: changelog ]
--- net/ceph/osdmap.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-)
net/ceph/osdmap.c +4 -1
@@ -395,7 +395,10 @@ static int decode_choose_args(void **p, goto e_inval; } -insert_choose_arg_map (&c->choose_args, arg_map); +if (!__insert_choose_arg_map (&c->choose_args, arg_map)) { + ret = -EEXIST ; + goto fail; + } }return 0 ;
Greg Kroah-Hartman
maintainerPATCH 478/508 iommu/vt-d: Disable DMAR for Intel Q35 IGFX
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Naval Alcalá <[email protected]>
commit 2cda2e10dc8343ae01eae9e999a876b7e7d37861 upstream.
Intel Q35 integrated graphics (8086:29b2) exhibits broken DMAR behaviour similar to other G4x/GM45 devices for which DMAR is already disabled via quirks.
When DMAR is enabled, the system may hard lock up during boot or early device initialization, requiring a reset.
Add the missing PCI ID to the existing quirk list to disable DMAR for this device.
--- drivers/iommu/intel/iommu.c | 3 +++ 1 file changed, 3 insertions(+)
drivers/iommu/intel/iommu.c +3 -0
@@ -4851,6 +4851,9 @@ static void quirk_iommu_igfx(struct pci_ dmar_map_gfx =0 ; } +/* Q35 integrated gfx dmar support is totally busted. */ +DECLARE_PCI_FIXUP_HEADER (PCI_VENDOR_ID_INTEL ,0x29b2 , quirk_iommu_igfx); +/* G4x/GM45 integrated gfx dmar support is totally busted. */ DECLARE_PCI_FIXUP_HEADER (PCI_VENDOR_ID_INTEL ,0x2a40 , quirk_iommu_igfx);DECLARE_PCI_FIXUP_HEADER (PCI_VENDOR_ID_INTEL ,0x2e00 , quirk_iommu_igfx);
Greg Kroah-Hartman
maintainerPATCH 479/508 drm/i915: skip __i915_request_skip() for already signaled requests
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Sebastian Brzezinka <[email protected]>
commit 4cfe4c0efbdcde742a47813180cc69b132d7598e upstream.
After a GPU reset the HWSP is zeroed, so previously completed requests appear incomplete. If such a request is picked up during reset_rewind() and marked guilty, i915_request_set_error_once() returns early (fence already signaled), leaving fence.error without a fatal error code. The subsequent __i915_request_skip() then hits:
``` GEM_BUG_ON(!fatal_error(rq->fence.error)) ```
Fixes a kernel BUG observed on Sandy Bridge (Gen6) during heartbeat-triggered engine resets.
``` kernel BUG at drivers/gpu/drm/i915/i915_request.c:556! RIP: __i915_request_skip+0x15e/0x1d0 [i915] ... __i915_request_reset+0x212/0xa70 [i915] reset_rewind+0xe4/0x280 [i915] intel_gt_reset+0x30d/0x5b0 [i915] heartbeat+0x516/0x530 [i915] ```
Guard __i915_request_skip() with i915_request_signaled(), if the fence is already signaled, the ring content is committed and there is nothing left to skip.
--- drivers/gpu/drm/i915/gt/intel_reset.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
drivers/gpu/drm/i915/gt/intel_reset.c +2 -1
@@ -134,7 +134,8 @@ void __i915_request_reset(struct i915_rercu_read_lock ();/* protect the GEM context */ if (guilty) {i915_request_set_error_once (rq, -EIO ); -__i915_request_skip (rq); +if (!i915_request_signaled (rq)) +__i915_request_skip (rq); banned =mark_guilty (rq); }else {i915_request_set_error_once (rq, -EAGAIN );
Greg Kroah-Hartman
maintainerPATCH 480/508 drm/panfrost: Fix wait_bo ioctl leaking positive return from dma_resv_wait_timeout()
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Gyeyoung Baek <[email protected]>
commit 459d75523b71c0ec254d153d8850d0b7008af396 upstream.
dma_resv_wait_timeout() returns a positive 'remaining jiffies' value on success, 0 on timeout, and -errno on failure.
panfrost_ioctl_wait_bo() returns this 'long' result from an int-typed ioctl handler, so positive values reach userspace as bogus errors. Explicitly set ret to 0 on the success path.
--- drivers/gpu/drm/panfrost/panfrost_drv.c | 2 ++ 1 file changed, 2 insertions(+)
drivers/gpu/drm/panfrost/panfrost_drv.c +2 -0
@@ -324,6 +324,8 @@ panfrost_ioctl_wait_bo(struct drm_device true, timeout);if (!ret) ret = timeout ? -ETIMEDOUT : -EBUSY ; +else if (ret >0 ) + ret =0 ;drm_gem_object_put (gem_obj);
Greg Kroah-Hartman
maintainerPATCH 481/508 drm/gma500/oaktrail_hdmi: fix i2c adapter leak on setup
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Johan Hovold <[email protected]>
commit 950953f774b3f69da6f413e045ef075e1f3da2df upstream.
Make sure to drop the reference taken to the I2C adapter (and its module) when setting up HDMI to allow the adapter to be deregistered.
--- drivers/gpu/drm/gma500/oaktrail_hdmi.c | 1 + 1 file changed, 1 insertion(+)
drivers/gpu/drm/gma500/oaktrail_hdmi.c +1 -0
@@ -579,6 +579,7 @@ static int oaktrail_hdmi_get_modes(struc }else { edid = (struct edid *)raw_edid;/* FIXME ? edid = drm_get_edid(connector, i2c_adap); */ +i2c_put_adapter (i2c_adap); }if (edid) {
Greg Kroah-Hartman
maintainerPATCH 482/508 drm/gma500/oaktrail_lvds: fix hang on init failure
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Johan Hovold <[email protected]>
commit 657a091ab6d01d0091b77660c75cfed573c9a53e upstream.
The LVDS init code looks up an I2C adapter using i2c_get_adapter() and tries to read the EDID before falling back to allocating and registering its own adapter.
The error handling does not separate these cases so on a late init failure it will try to deregister and free also an adapter that had previously been registered. Since i2c_get_adapter() takes another reference to the adapter, deregistration hangs indefinitely while waiting for the reference to be released.
Fix this by only destroying adapters allocated during LVDS init on errors.
--- drivers/gpu/drm/gma500/oaktrail_lvds.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-)
drivers/gpu/drm/gma500/oaktrail_lvds.c +3 -2
@@ -294,7 +294,7 @@ void oaktrail_lvds_init(struct drm_devic {struct gma_encoder *gma_encoder;struct gma_connector *gma_connector; -struct gma_i2c_chan *ddc_bus; +struct gma_i2c_chan *ddc_bus =NULL ;struct drm_connector *connector;struct drm_encoder *encoder;struct drm_psb_private *dev_priv =to_drm_psb_private (dev);
@@ -422,7 +422,8 @@ out: err_unlock:mutex_unlock (&dev->mode_config.mutex); -gma_i2c_destroy (to_gma_i2c_chan (connector->ddc)); +if (!IS_ERR_OR_NULL (ddc_bus)) +gma_i2c_destroy (ddc_bus);drm_encoder_cleanup (encoder); err_connector_cleanup:drm_connector_cleanup (connector);
Greg Kroah-Hartman
maintainerPATCH 483/508 drm/gma500/oaktrail_lvds: fix i2c adapter leaks on init
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Johan Hovold <[email protected]>
commit 84d1c9b416d54afe760ca4c378bd95c89261254c upstream.
The LVDS init code looks up an I2C adapter using i2c_get_adapter() and tries to read the EDID before falling back to allocating and registering its own adapter.
Make sure to drop the references taken by i2c_get_adapter() when falling back to allocating an adapter as well as on late errors to allow the looked up adapter to be deregistered.
--- drivers/gpu/drm/gma500/oaktrail_lvds.c | 4 ++++ 1 file changed, 4 insertions(+)
drivers/gpu/drm/gma500/oaktrail_lvds.c +4 -0
@@ -368,6 +368,8 @@ void oaktrail_lvds_init(struct drm_devicif (edid ==NULL && dev_priv->lpc_gpio_base) { ddc_bus =oaktrail_lvds_i2c_init (dev);if (!IS_ERR (ddc_bus)) { +if (i2c_adap) +i2c_put_adapter (i2c_adap); i2c_adap = &ddc_bus->base; edid =drm_get_edid (connector, i2c_adap); }
@@ -424,6 +426,8 @@ err_unlock:mutex_unlock (&dev->mode_config.mutex);if (!IS_ERR_OR_NULL (ddc_bus))gma_i2c_destroy (ddc_bus); +else if (i2c_adap) +i2c_put_adapter (i2c_adap);drm_encoder_cleanup (encoder); err_connector_cleanup:drm_connector_cleanup (connector);
Greg Kroah-Hartman
maintainerPATCH 484/508 pmdomain: core: Fix detach procedure for virtual devices in genpd
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ulf Hansson <[email protected]>
[ Upstream commit 26735dfdd8930d9ef1fa92e590a9bf77726efdf6 ]
If a device is attached to a PM domain through genpd_dev_pm_attach_by_id(), genpd calls pm_runtime_enable() for the corresponding virtual device that it registers. While this avoids boilerplate code in drivers, there is no corresponding call to pm_runtime_disable() in genpd_dev_pm_detach().
This means these virtual devices are typically detached from its genpd, while runtime PM remains enabled for them, which is not how things are designed to work. In worst cases it may lead to critical errors, like a NULL pointer dereference bug in genpd_runtime_suspend(), which was recently reported. For another case, we may end up keeping an unnecessary vote for a performance state for the device.
To fix these problems, let's add this missing call to pm_runtime_disable() in genpd_dev_pm_detach().
--- drivers/base/power/domain.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-)
drivers/base/power/domain.c +9 -1
@@ -2676,6 +2676,7 @@ static struct bus_type genpd_bus_type =static void genpd_dev_pm_detach (struct device *dev,bool power_off) {struct generic_pm_domain *pd; +bool is_virt_dev;unsigned int i;int ret =0 ;
@@ -2685,6 +2686,13 @@ static void genpd_dev_pm_detach(struct ddev_dbg (dev,"removing from PM domain %s\n" , pd->name); +/* Check if the device was created by genpd at attach. */ + is_virt_dev = dev->bus == &genpd_bus_type; + +/* Disable runtime PM if we enabled it at attach. */ +if (is_virt_dev) +pm_runtime_disable (dev); +/* Drop the default performance state */ if (dev_gpd_data (dev)->default_pstate) {dev_pm_genpd_set_performance_state (dev,0 );
@@ -2710,7 +2718,7 @@ static void genpd_dev_pm_detach(struct dgenpd_queue_power_off_work (pd);/* Unregister the device if it was created by genpd. */ -if (dev->bus == &genpd_bus_type) +if (is_virt_dev)device_unregister (dev); }
Greg Kroah-Hartman
maintainerPATCH 485/508 btrfs: remove fs_info argument from btrfs_sysfs_add_space_info_type()
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Filipe Manana <[email protected]>
[ Upstream commit 771af6ff72e0ed0eb8bf97e5ae4fa5094e0c5d1d ]
We don't need it since we can grab fs_info from the given space_info. So remove the fs_info argument.
Stable-dep-of: a7449edf9614 ("btrfs: fix double free in create_space_info_sub_group() error path")
--- fs/btrfs/space-info.c | 4 ++-- fs/btrfs/sysfs.c | 5 ++--- fs/btrfs/sysfs.h | 3 +-- 3 files changed, 5 insertions(+), 7 deletions(-)
fs/btrfs/space-info.c +2 -2
@@ -262,7 +262,7 @@ static int create_space_info_sub_group(s sub_group->parent = parent; sub_group->subgroup_id = id; - ret =btrfs_sysfs_add_space_info_type (fs_info, sub_group); + ret =btrfs_sysfs_add_space_info_type (sub_group);if (ret) {kfree (sub_group); parent->sub_group[index] =NULL ;
@@ -291,7 +291,7 @@ static int create_space_info(struct btrf goto out_free; } - ret =btrfs_sysfs_add_space_info_type (info, space_info); + ret =btrfs_sysfs_add_space_info_type (space_info);if (ret)return ret;
fs/btrfs/sysfs.c +2 -3
@@ -1674,13 +1674,12 @@ static const char *alloc_name(struct btr* Create a sysfs entry for a space info type at path * /sys/fs/btrfs/UUID/allocation/TYPE */ -int btrfs_sysfs_add_space_info_type (struct btrfs_fs_info *fs_info, -struct btrfs_space_info *space_info) +int btrfs_sysfs_add_space_info_type (struct btrfs_space_info *space_info) {int ret; ret =kobject_init_and_add (&space_info->kobj, &space_info_ktype, - fs_info->space_info_kobj,"%s" , + space_info->fs_info->space_info_kobj,"%s" ,alloc_name (space_info));if (ret) {kobject_put (&space_info->kobj);
fs/btrfs/sysfs.h +1 -2
@@ -27,8 +27,7 @@ void __cold btrfs_exit_sysfs(void);int btrfs_sysfs_add_mounted (struct btrfs_fs_info *fs_info);void btrfs_sysfs_remove_mounted (struct btrfs_fs_info *fs_info);void btrfs_sysfs_add_block_group_type (struct btrfs_block_group *cache); -int btrfs_sysfs_add_space_info_type (struct btrfs_fs_info *fs_info, -struct btrfs_space_info *space_info); +int btrfs_sysfs_add_space_info_type (struct btrfs_space_info *space_info);void btrfs_sysfs_remove_space_info (struct btrfs_space_info *space_info);void btrfs_sysfs_update_devid (struct btrfs_device *device);
Greg Kroah-Hartman
maintainerPATCH 486/508 btrfs: fix double free in create_space_info_sub_group() error path
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Guangshuo Li <[email protected]>
[ Upstream commit a7449edf96143f192606ec8647e3167e1ecbd728 ]
When kobject_init_and_add() fails, the call chain is:
create_space_info_sub_group()
-> btrfs_sysfs_add_space_info_type()
-> kobject_init_and_add()
-> failure
-> kobject_put(&sub_group->kobj)
-> space_info_release()
-> kfree(sub_group)
Then control returns to create_space_info_sub_group(), where:
btrfs_sysfs_add_space_info_type() returns error
-> kfree(sub_group)
Thus, sub_group is freed twice.
Keep parent->sub_group[index] = NULL for the failure path, but after btrfs_sysfs_add_space_info_type() has called kobject_put(), let the kobject release callback handle the cleanup.
--- fs/btrfs/space-info.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-)
fs/btrfs/space-info.c +1 -3
@@ -263,10 +263,8 @@ static int create_space_info_sub_group(s sub_group->subgroup_id = id; ret =btrfs_sysfs_add_space_info_type (sub_group); -if (ret) { -kfree (sub_group); +if (ret) parent->sub_group[index] =NULL ; - }return ret; }
Greg Kroah-Hartman
maintainerPATCH 487/508 eventfs: Use list_add_tail_rcu() for SRCU-protected children list
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: David Carlier <[email protected]>
[ Upstream commit f67950b2887fa10df50c4317a1fe98a65bc6875b ]
Commit d2603279c7d6 ("eventfs: Use list_del_rcu() for SRCU protected list variable") converted the removal side to pair with the list_for_each_entry_srcu() walker in eventfs_iterate(). The insertion in eventfs_create_dir() was left as a plain list_add_tail(), which on weakly-ordered architectures can expose a new entry to the SRCU reader before its list pointers and fields are observable.
Use list_add_tail_rcu() so the publication pairs with the existing list_del_rcu() and list_for_each_entry_srcu().
--- fs/tracefs/event_inode.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
fs/tracefs/event_inode.c +1 -1
@@ -802,7 +802,7 @@ struct eventfs_inode *eventfs_create_dirmutex_lock (&eventfs_mutex);if (!parent->is_freed) -list_add_tail (&ei->list, &parent->children); +list_add_tail_rcu (&ei->list, &parent->children);mutex_unlock (&eventfs_mutex);/* Was the parent freed? */
Greg Kroah-Hartman
maintainerPATCH 488/508 drm/v3d: Reject empty multisync extension to prevent infinite loop
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ashutosh Desai <[email protected]>
v3d_get_extensions() walks a userspace-provided singly-linked list of ioctl extensions without any bound on the chain length. A local user can craft a self-referential extension (ext->next == &ext) with zero in_sync_count and out_sync_count, which bypasses the existing duplicate- extension guard:
if (se->in_sync_count || se->out_sync_count)
return -EINVAL;The guard never fires because v3d_get_multisync_post_deps() returns immediately when count is zero, leaving both fields at zero on every iteration. The result is an infinite loop in kernel context, blocking the calling thread and pegging a CPU core indefinitely.
Fix this by rejecting a multisync extension where both in_sync_count and out_sync_count are zero in v3d_get_multisync_submit_deps(). An empty multisync carries no synchronization information and serves no useful purpose, so returning -EINVAL for such an extension is the correct defense against this attack vector.
--- drivers/gpu/drm/v3d/v3d_gem.c | 5 +++++ 1 file changed, 5 insertions(+)
drivers/gpu/drm/v3d/v3d_gem.c +5 -0
@@ -597,6 +597,11 @@ v3d_get_multisync_submit_deps(struct drmif (multisync.pad)return -EINVAL ; +if (!multisync.in_sync_count && !multisync.out_sync_count) { +DRM_DEBUG ("Empty multisync extension\n" ); +return -EINVAL ; + } + ret =v3d_get_multisync_post_deps (file_priv, data, multisync.out_sync_count, multisync.out_syncs);if (ret)
Greg Kroah-Hartman
maintainerPATCH 489/508 smb: client: Use FullSessionKey for AES-256 encryption key derivation
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Piyush Sachdeva <[email protected]>
[ Upstream commit 5be7a0cef3229fb3b63a07c0d289daf752545424 ]
When Kerberos authentication is used with AES-256 encryption (AES-256-CCM or AES-256-GCM), the SMB3 encryption and decryption keys must be derived using the full session key (Session.FullSessionKey) rather than just the first 16 bytes (Session.SessionKey).
Per MS-SMB2 section 3.2.5.3.1, when Connection.Dialect is "3.1.1" and Connection.CipherId is AES-256-CCM or AES-256-GCM, Session.FullSessionKey must be set to the full cryptographic key from the GSS authentication context. The encryption and decryption key derivation (SMBC2SCipherKey, SMBS2CCipherKey) must use this FullSessionKey as the KDF input. The signing key derivation continues to use Session.SessionKey (first 16 bytes) in all cases.
Previously, generate_key() hardcoded SMB2_NTLMV2_SESSKEY_SIZE (16) as the HMAC-SHA256 key input length for all derivations. When Kerberos with AES-256 provides a 32-byte session key, the KDF for encryption/decryption was using only the first 16 bytes, producing keys that did not match the server's, causing mount failures with sec=krb5 and require_gcm_256=1.
Add a full_key_size parameter to generate_key() and pass the appropriate size from generate_smb3signingkey():
- Signing: always SMB2_NTLMV2_SESSKEY_SIZE (16 bytes)
- Encryption/Decryption: ses->auth_key.len when AES-256, otherwise 16
Also fix cifs_dump_full_key() to report the actual session key length for AES-256 instead of hardcoded CIFS_SESS_KEY_SIZE, so that userspace tools like Wireshark receive the correct key for decryption.
--- fs/smb/client/ioctl.c | 2 +- fs/smb/client/smb2transport.c | 32 +++++++++++++++++++++++++------- 2 files changed, 26 insertions(+), 8 deletions(-)
fs/smb/client/ioctl.c +1 -1
@@ -280,7 +280,7 @@ search_end:break ;case SMB2_ENCRYPTION_AES256_CCM :case SMB2_ENCRYPTION_AES256_GCM : - out.session_key_length =CIFS_SESS_KEY_SIZE ; + out.session_key_length = ses->auth_key.len; out.server_in_key_length = out.server_out_key_length =SMB3_GCM256_CRYPTKEY_SIZE ;break ;default :
fs/smb/client/smb2transport.c +25 -7
@@ -334,7 +334,8 @@ out: }static int generate_key (struct cifs_ses *ses,struct kvec label, -struct kvec context,__u8 *key,unsigned int key_size) +struct kvec context,__u8 *key,unsigned int key_size, +unsigned int full_key_size) {unsigned char zero =0x0 ;__u8 i[4 ] = {0 ,0 ,0 ,1 };
@@ -355,7 +356,7 @@ static int generate_key(struct cifs_ses } rc =crypto_shash_setkey (server->secmech.hmacsha256->tfm, - ses->auth_key.response,SMB2_NTLMV2_SESSKEY_SIZE ); + ses->auth_key.response, full_key_size);if (rc) {cifs_server_dbg (VFS ,"%s: Could not set with session key\n" , __func__); goto smb3signkey_ret;
@@ -430,6 +431,7 @@ generate_smb3signingkey(struct cifs_sesstruct TCP_Server_Info *server, const struct derivation_triplet *ptriplet) { + unsigned int full_key_size = SMB2_NTLMV2_SESSKEY_SIZE;int rc;bool is_binding = false;int chan_index =0 ;
@@ -464,17 +466,31 @@ generate_smb3signingkey(struct cifs_ses rc =generate_key (ses, ptriplet->signing.label, ptriplet->signing.context, ses->chans[chan_index].signkey, -SMB3_SIGN_KEY_SIZE ); +SMB3_SIGN_KEY_SIZE , +SMB2_NTLMV2_SESSKEY_SIZE );if (rc)return rc; }else { rc =generate_key (ses, ptriplet->signing.label, ptriplet->signing.context, ses->smb3signingkey, -SMB3_SIGN_KEY_SIZE ); +SMB3_SIGN_KEY_SIZE , +SMB2_NTLMV2_SESSKEY_SIZE );if (rc)return rc; +/* +* Per MS-SMB2 3.2.5.3.1, signing key always uses Session.SessionKey +* (first 16 bytes). Encryption/decryption keys use +* Session.FullSessionKey when dialect is 3.1.1 and cipher is +* AES-256-CCM or AES-256-GCM, otherwise Session.SessionKey. +*/ + +if (server->dialect ==SMB311_PROT_ID && + (server->cipher_type ==SMB2_ENCRYPTION_AES256_CCM || + server->cipher_type ==SMB2_ENCRYPTION_AES256_GCM )) + full_key_size = ses->auth_key.len; +/* safe to access primary channel, since it will never go away */ spin_lock (&ses->chan_lock); memcpy(ses->chans[chan_index].signkey, ses->smb3signingkey,
@@ -484,13 +500,15 @@ generate_smb3signingkey(struct cifs_ses rc =generate_key (ses, ptriplet->encryption.label, ptriplet->encryption.context, ses->smb3encryptionkey, -SMB3_ENC_DEC_KEY_SIZE ); +SMB3_ENC_DEC_KEY_SIZE , + full_key_size);if (rc)return rc; rc =generate_key (ses, ptriplet->decryption.label, ptriplet->decryption.context, ses->smb3decryptionkey, -SMB3_ENC_DEC_KEY_SIZE ); +SMB3_ENC_DEC_KEY_SIZE , + full_key_size);if (rc)return rc; }
@@ -505,7 +523,7 @@ generate_smb3signingkey(struct cifs_ses &ses->Suid);cifs_dbg (VFS ,"Cipher type %d\n" , server->cipher_type);cifs_dbg (VFS ,"Session Key %*ph\n" , -SMB2_NTLMV2_SESSKEY_SIZE , ses->auth_key.response); + (int )ses->auth_key.len, ses->auth_key.response);cifs_dbg (VFS ,"Signing Key %*ph\n" ,SMB3_SIGN_KEY_SIZE , ses->smb3signingkey); if ((server->cipher_type == SMB2_ENCRYPTION_AES256_CCM) ||
Greg Kroah-Hartman
maintainerPATCH 490/508 btrfs: use inode already stored in local variable at btrfs_rmdir()
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Filipe Manana <[email protected]>
[ Upstream commit 9f82a4ed34d870b5719f9b95f7da4f74d3325a6f ]
There's no need to call d_inode(dentry) when calling btrfs_unlink_inode() since we have already stored that in a local inode variable. So just use the local variable to make the code less verbose.
Stable-dep-of: 999757231c49 ("btrfs: fix missing last_unlink_trans update when removing a directory")
--- fs/btrfs/inode.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-)
fs/btrfs/inode.c +1 -2
@@ -4681,8 +4681,7 @@ static int btrfs_rmdir(struct inode *dir goto out;/* now the directory is empty */ - ret =btrfs_unlink_inode (trans,BTRFS_I (dir),BTRFS_I (d_inode (dentry)), - &fname.disk_name); + ret =btrfs_unlink_inode (trans,BTRFS_I (dir),BTRFS_I (inode), &fname.disk_name);if (!ret)btrfs_i_size_write (BTRFS_I (inode),0 ); out:
Greg Kroah-Hartman
maintainerPATCH 491/508 btrfs: use btrfs inodes in btrfs_rmdir() to avoid so much usage of BTRFS_I()
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Filipe Manana <[email protected]>
[ Upstream commit 98060e1611177ddc842601a58258876ab435fdbf ]
Almost everywhere we want to use a btrfs inode and therefore we have a lot of calls to BTRFS_I(), making the code more verbose. Instead use btrfs inode local variables to avoid so much use of BTRFS_I().
Stable-dep-of: 999757231c49 ("btrfs: fix missing last_unlink_trans update when removing a directory")
--- fs/btrfs/inode.c | 31 ++++++++++++++++--------------- 1 file changed, 16 insertions(+), 15 deletions(-)
fs/btrfs/inode.c +16 -15
@@ -4623,32 +4623,33 @@ out_up_write:return ret; } -static int btrfs_rmdir (struct inode *dir,struct dentry *dentry) +static int btrfs_rmdir (struct inode *vfs_dir,struct dentry *dentry) { -struct inode *inode =d_inode (dentry); -struct btrfs_fs_info *fs_info =BTRFS_I (inode)->root->fs_info; +struct btrfs_inode *dir =BTRFS_I (vfs_dir); +struct btrfs_inode *inode =BTRFS_I (d_inode (dentry)); +struct btrfs_fs_info *fs_info = inode->root->fs_info;int ret =0 ;struct btrfs_trans_handle *trans;struct fscrypt_name fname; -if (inode->i_size >BTRFS_EMPTY_DIR_SIZE ) +if (inode->vfs_inode.i_size >BTRFS_EMPTY_DIR_SIZE )return -ENOTEMPTY ; -if (btrfs_ino (BTRFS_I (inode)) ==BTRFS_FIRST_FREE_OBJECTID ) { +if (btrfs_ino (inode) ==BTRFS_FIRST_FREE_OBJECTID ) {if (unlikely (btrfs_fs_incompat (fs_info,EXTENT_TREE_V2 ))) {btrfs_err (fs_info,"extent tree v2 doesn't support snapshot deletion yet" );return -EOPNOTSUPP ; } -return btrfs_delete_subvolume (BTRFS_I (dir), dentry); +return btrfs_delete_subvolume (dir, dentry); } - ret =fscrypt_setup_filename (dir, &dentry->d_name,1 , &fname); + ret =fscrypt_setup_filename (vfs_dir, &dentry->d_name,1 , &fname);if (ret)return ret;/* This needs to handle no-key deletions later on */ - trans =__unlink_start_trans (BTRFS_I (dir)); + trans =__unlink_start_trans (dir);if (IS_ERR (trans)) { ret =PTR_ERR (trans); goto out_notrans;
@@ -4668,22 +4669,22 @@ static int btrfs_rmdir(struct inode *dir* This is because we can't unlink other roots when replaying the dir * deletes for directory foo. */ -if (BTRFS_I (inode)->last_unlink_trans >= trans->transid) -btrfs_record_snapshot_destroy (trans,BTRFS_I (dir)); +if (inode->last_unlink_trans >= trans->transid) +btrfs_record_snapshot_destroy (trans, dir); -if (unlikely (btrfs_ino (BTRFS_I (inode)) ==BTRFS_EMPTY_SUBVOL_DIR_OBJECTID )) { - ret =btrfs_unlink_subvol (trans,BTRFS_I (dir), dentry); +if (unlikely (btrfs_ino (inode) ==BTRFS_EMPTY_SUBVOL_DIR_OBJECTID )) { + ret =btrfs_unlink_subvol (trans, dir, dentry); goto out; } - ret =btrfs_orphan_add (trans,BTRFS_I (inode)); + ret =btrfs_orphan_add (trans, inode);if (ret) goto out;/* now the directory is empty */ - ret =btrfs_unlink_inode (trans,BTRFS_I (dir),BTRFS_I (inode), &fname.disk_name); + ret =btrfs_unlink_inode (trans, dir, inode, &fname.disk_name);if (!ret) -btrfs_i_size_write (BTRFS_I (inode),0 ); +btrfs_i_size_write (inode,0 ); out:btrfs_end_transaction (trans); out_notrans:
Greg Kroah-Hartman
maintainerPATCH 492/508 btrfs: fix missing last_unlink_trans update when removing a directory
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Filipe Manana <[email protected]>
[ Upstream commit 999757231c49376cd1a37308d2c8c4c9932571e1 ]
When removing a directory we are not updating its last_unlink_trans field, which can result in incorrect fsync behaviour in case some one fsyncs the directory after it was removed because it's holding a file descriptor on it.
Example scenario:
mkdir /mnt/dir1
mkdir /mnt/dir1/dir2
mkdir /mnt/dir3
sync -f /mnt
# Do some change to the directory and fsync it. chmod 700 /mnt/dir1
xfs_io -c fsync /mnt/dir1
# Move dir2 out of dir1 so that dir1 becomes empty. mv /mnt/dir1/dir2 /mnt/dir3/
open fd on /mnt/dir1
call rmdir(2) on path "/mnt/dir1"
fsync fd
<trigger power failure>
When attempting to mount the filesystem, the log replay will fail with an -EIO error and dmesg/syslog has the following:
[445771.626482] BTRFS info (device dm-0): first mount of filesystem 0368bbea-6c5e-44b5-b409-09abe496e650 [445771.626486] BTRFS info (device dm-0): using crc32c checksum algorithm [445771.627912] BTRFS info (device dm-0): start tree-log replay [445771.628335] page: refcount:2 mapcount:0 mapping:0000000061443ddc index:0x1d00 pfn:0x7072a5 [445771.629453] memcg:ffff89f400351b00 [445771.629892] aops:btree_aops [btrfs] ino:1 [445771.630737] flags: 0x17fffc00000402a(uptodate|lru|private|writeback|node=0|zone=2|lastcpupid=0x1ffff) [445771.632359] raw: 017fffc00000402a fffff47284d950c8 fffff472907b7c08 ffff89f458e412b8 [445771.633713] raw: 0000000000001d00 ffff89f6c51d1a90 00000002ffffffff ffff89f400351b00 [445771.635029] page dumped because: eb page dump [445771.635825] BTRFS critical (device dm-0): corrupt leaf: root=5 block=30408704 slot=10 ino=258, invalid nlink: has 2 expect no more than 1 for dir [445771.638088] BTRFS info (device dm-0): leaf 30408704 gen 10 total ptrs 17 free space 14878 owner 5 [445771.638091] BTRFS info (device dm-0): refs 4 lock_owner 0 current 3581087 [445771.638094] item 0 key (256 INODE_ITEM 0) itemoff 16123 itemsize 160 [445771.638097] inode generation 3 transid 9 size 16 nbytes 16384 [445771.638098] block group 0 mode 40755 links 1 uid 0 gid 0 [445771.638100] rdev 0 sequence 2 flags 0x0 [445771.638102] atime 1775744884.0 [445771.660056] ctime 1775744885.645502983 [445771.660058] mtime 1775744885.645502983 [445771.660060] otime 1775744884.0 [445771.660062] item 1 key (256 INODE_REF 256) itemoff 16111 itemsize 12 [445771.660064] index 0 name_len 2 [445771.660066] item 2 key (256 DIR_ITEM 1843588421) itemoff 16077 itemsize 34 [445771.660068] location key (259 1 0) type 2 [445771.660070] transid 9 data_len 0 name_len 4 [445771.660075] item 3 key (256 DIR_ITEM 2363071922) itemoff 16043 itemsize 34 [445771.660076] location key (257 1 0) type 2 [445771.660077] transid 9 data_len 0 name_len 4 [445771.660078] item 4 key (256 DIR_INDEX 2) itemoff 16009 itemsize 34 [445771.660079] location key (257 1 0) type 2 [445771.660080] transid 9 data_len 0 name_len 4 [445771.660081] item 5 key (256 DIR_INDEX 3) itemoff 15975 itemsize 34 [445771.660082] location key (259 1 0) type 2 [445771.660083] transid 9 data_len 0 name_len 4 [445771.660084] item 6 key (257 INODE_ITEM 0) itemoff 15815 itemsize 160 [445771.660086] inode generation 9 transid 9 size 8 nbytes 0 [445771.660087] block group 0 mode 40777 links 1 uid 0 gid 0 [445771.660088] rdev 0 sequence 2 flags 0x0 [445771.660089] atime 1775744885.641174097 [445771.660090] ctime 1775744885.645502983 [445771.660091] mtime 1775744885.645502983 [445771.660105] otime 1775744885.641174097 [445771.660106] item 7 key (257 INODE_REF 256) itemoff 15801 itemsize 14 [445771.660107] index 2 name_len 4 [445771.660108] item 8 key (257 DIR_ITEM 2676584006) itemoff 15767 itemsize 34 [445771.660109] location key (258 1 0) type 2 [445771.660110] transid 9 data_len 0 name_len 4 [445771.660111] item 9 key (257 DIR_INDEX 2) itemoff 15733 itemsize 34 [445771.660112] location key (258 1 0) type 2 [445771.660113] transid 9 data_len 0 name_len 4 [445771.660114] item 10 key (258 INODE_ITEM 0) itemoff 15573 itemsize 160 [445771.660115] inode generation 9 transid 10 size 0 nbytes 0 [445771.660116] block group 0 mode 40755 links 2 uid 0 gid 0 [445771.660117] rdev 0 sequence 0 flags 0x0 [445771.660118] atime 1775744885.645502983 [445771.660119] ctime 1775744885.645502983 [445771.660120] mtime 1775744885.645502983 [445771.660121] otime 1775744885.645502983 [445771.660122] item 11 key (258 INODE_REF 257) itemoff 15559 itemsize 14 [445771.660123] index 2 name_len 4 [445771.660124] item 12 key (258 INODE_REF 259) itemoff 15545 itemsize 14 [445771.660125] index 2 name_len 4 [445771.660126] item 13 key (259 INODE_ITEM 0) itemoff 15385 itemsize 160 [445771.660127] inode generation 9 transid 10 size 8 nbytes 0 [445771.660128] block group 0 mode 40755 links 1 uid 0 gid 0 [445771.660129] rdev 0 sequence 1 flags 0x0 [445771.660130] atime 1775744885.645502983 [445771.660130] ctime 1775744885.645502983 [445771.660131] mtime 1775744885.645502983 [445771.660132] otime 1775744885.645502983 [445771.660133] item 14 key (259 INODE_REF 256) itemoff 15371 itemsize 14 [445771.660134] index 3 name_len 4 [445771.660135] item 15 key (259 DIR_ITEM 2676584006) itemoff 15337 itemsize 34 [445771.660136] location key (258 1 0) type 2 [445771.660137] transid 10 data_len 0 name_len 4 [445771.660138] item 16 key (259 DIR_INDEX 2) itemoff 15303 itemsize 34 [445771.660139] location key (258 1 0) type 2 [445771.660140] transid 10 data_len 0 name_len 4 [445771.660144] BTRFS error (device dm-0): block=30408704 write time tree block corruption detected [445771.661650] ------------[ cut here ]------------ [445771.662358] WARNING: fs/btrfs/disk-io.c:326 at btree_csum_one_bio+0x217/0x230 [btrfs], CPU#8: mount/3581087 [445771.663588] Modules linked in: btrfs f2fs xfs (...) [445771.671229] CPU: 8 UID: 0 PID: 3581087 Comm: mount Tainted: G W 7.0.0-rc6-btrfs-next-230+ #2 PREEMPT(full) [445771.672575] Tainted: [W]=WARN [445771.672987] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS rel-1.16.2-0-gea1b7a073390-prebuilt.qemu.org 04/01/2014 [445771.674460] RIP: 0010:btree_csum_one_bio+0x217/0x230 [btrfs] [445771.675222] Code: 89 44 24 (...) [445771.677364] RSP: 0018:ffffd23882247660 EFLAGS: 00010246 [445771.678029] RAX: 0000000000000000 RBX: ffff89f6c51d1a90 RCX: 0000000000000000 [445771.678975] RDX: 0000000000000000 RSI: 0000000000000001 RDI: ffff89f406020000 [445771.679983] RBP: ffff89f821204000 R08: 0000000000000000 R09: 00000000ffefffff [445771.680905] R10: ffffd23882247448 R11: 0000000000000003 R12: ffffd23882247668 [445771.681978] R13: ffff89f458e40fc0 R14: ffff89f737f4f500 R15: ffff89f737f4f500 [445771.682912] FS: 00007f0447a98840(0000) GS:ffff89fb9771d000(0000) knlGS:0000000000000000 [445771.684393] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 [445771.685230] CR2: 00007f0447bf1330 CR3: 000000017cb02002 CR4: 0000000000370ef0 [445771.686273] Call Trace: [445771.686646] <TASK> [445771.686969] btrfs_submit_bbio+0x83f/0x860 [btrfs] [445771.687750] ? write_one_eb+0x28f/0x340 [btrfs] [445771.688428] btree_writepages+0x2e3/0x550 [btrfs] [445771.689180] ? kmem_cache_alloc_noprof+0x12a/0x490 [445771.689963] ? alloc_extent_state+0x19/0x120 [btrfs] [445771.690801] ? kmem_cache_free+0x135/0x380 [445771.691328] ? preempt_count_add+0x69/0xa0 [445771.691831] ? set_extent_bit+0x252/0x8e0 [btrfs] [445771.692468] ? xas_load+0x9/0xc0 [445771.692873] ? xas_find+0x14d/0x1a0 [445771.693304] do_writepages+0xc6/0x160 [445771.693756] filemap_writeback+0xb8/0xe0 [445771.694274] btrfs_write_marked_extents+0x61/0x170 [btrfs] [445771.694999] btrfs_write_and_wait_transaction+0x4e/0xc0 [btrfs] [445771.695818] btrfs_commit_transaction+0x5c8/0xd10 [btrfs] [445771.696530] ? kmem_cache_free+0x135/0x380 [445771.697120] ? release_extent_buffer+0x34/0x160 [btrfs] [445771.697786] btrfs_recover_log_trees+0x7be/0x7e0 [btrfs] [445771.698525] ? __pfx_replay_one_buffer+0x10/0x10 [btrfs] [445771.699206] open_ctree+0x11e5/0x1810 [btrfs] [445771.699776] btrfs_get_tree.cold+0xb/0x162 [btrfs] [445771.700463] ? fscontext_read+0x165/0x180 [445771.701146] ? rw_verify_area+0x50/0x180 [445771.701866] vfs_get_tree+0x25/0xd0 [445771.702491] vfs_cmd_create+0x59/0xe0 [445771.703125] __do_sys_fsconfig+0x303/0x610 [445771.703603] do_syscall_64+0xe9/0xf20 [445771.703974] entry_SYSCALL_64_after_hwframe+0x76/0x7e [445771.704700] RIP: 0033:0x7f0447cbd4aa [445771.705108] Code: 73 01 c3 (...) [445771.707263] RSP: 002b:00007ffc4e528318 EFLAGS: 00000246 ORIG_RAX: 00000000000001af [445771.708107] RAX: ffffffffffffffda RBX: 00005561585d8c20 RCX: 00007f0447cbd4aa [445771.708931] RDX: 0000000000000000 RSI: 0000000000000006 RDI: 0000000000000003 [445771.709744] RBP: 00005561585d9120 R08: 0000000000000000 R09: 0000000000000000 [445771.710674] R10: 0000000000000000 R11: 0000000000000246 R12: 0000000000000000 [445771.711477] R13: 00007f0447e4f580 R14: 00007f0447e5126c R15: 00007f0447e36a23 [445771.712277] </TASK> [445771.712541] ---[ end trace 0000000000000000 ]--- [445771.713382] BTRFS error (device dm-0): error while writing out transaction: -5 [445771.714679] BTRFS warning (device dm-0): Skipping commit of aborted transaction. [445771.715562] BTRFS error (device dm-0 state A): Transaction aborted (error -5) [445771.716459] BTRFS: error (device dm-0 state A) in cleanup_transaction:2068: errno=-5 IO failure [445771.717936] BTRFS error (device dm-0 state EA): failed to recover log trees with error: -5 [445771.719681] BTRFS error (device dm-0 state EA): open_ctree failed: -5
The problem is that such a fsync should have result in a fallback to a transaction commit, but that did not happen because through the btrfs_rmdir() we never update the directory's last_unlink_trans field. Any inode that had a link removed must have its last_unlink_trans updated to the ID of transaction used for the operation, otherwise fsync and log replay will not work correctly.
btrfs_rmdir() calls btrfs_unlink_inode() and through that call chain we never call btrfs_record_unlink_dir() in order to update last_unlink_trans. However btrfs_unlink(), which is used for unlinking regular files, calls btrfs_record_unlink_dir() and then calls btrfs_unlink_inode(). So fix this by moving the call to btrfs_record_unlink_dir() from btrfs_unlink() to btrfs_unlink_inode().
A test case for fstests will follow soon.
--- fs/btrfs/inode.c | 2 ++ 1 file changed, 2 insertions(+)
fs/btrfs/inode.c +2 -0
@@ -4681,6 +4681,8 @@ static int btrfs_rmdir(struct inode *vfsif (ret) goto out; +btrfs_record_unlink_dir (trans, dir, inode, false); +/* now the directory is empty */ ret =btrfs_unlink_inode (trans, dir, inode, &fname.disk_name);if (!ret)
Greg Kroah-Hartman
maintainerPATCH 493/508 RDMA/mana: Validate rx_hash_key_len
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jason Gunthorpe <[email protected]>
[ Upstream commit 6dd2d4ad9c8429523b1c220c5132bd551c006425 ]
Sashiko points out that rx_hash_key_len comes from a uAPI structure and is blindly passed to memcpy, allowing the userspace to trash kernel memory. Bounds check it so the memcpy cannot overflow.
--- drivers/infiniband/hw/mana/qp.c | 3 +++ 1 file changed, 3 insertions(+)
drivers/infiniband/hw/mana/qp.c +3 -0
@@ -24,6 +24,9 @@ static int mana_ib_cfg_vport_steering(st mdev = dev->gdma_dev; gc = mdev->gdma_context; +if (rx_hash_key_len >sizeof (req->hashkey)) +return -EINVAL ; + req_buf_size =sizeof (*req) +sizeof (mana_handle_t) *MANA_INDIRECT_TABLE_SIZE ; req =kzalloc (req_buf_size,GFP_KERNEL );
Greg Kroah-Hartman
maintainerPATCH 494/508 mptcp: drop __mptcp_fastopen_gen_msk_ackseq()
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Paolo Abeni <[email protected]>
[ Upstream commit f03afb3aeb9d81f6c5ab728a61a040012923e3b3 ]
When we will move the whole RX path under the msk socket lock, updating the already queued skb for passive fastopen socket at 3rd ack time will be extremely painful and race prone
The map_seq for already enqueued skbs is used only to allow correct coalescing with later data; preventing collapsing to the first skb of a fastopen connect we can completely remove the __mptcp_fastopen_gen_msk_ackseq() helper.
Before dropping this helper, a new item had to be added to the mptcp_skb_cb structure. Because this item will be frequently tested in the fast path -- almost on every packet -- and because there is free space there, a single byte is used instead of a bitfield. This micro optimisation slightly reduces the number of CPU operations to do the associated check.
Stable-dep-of: 6254a16d6f0c ("mptcp: fix rx timestamp corruption on fastopen")
--- net/mptcp/fastopen.c | 24 ++---------------------- net/mptcp/protocol.c | 4 +++- net/mptcp/protocol.h | 5 ++--- net/mptcp/subflow.c | 3 --- 4 files changed, 7 insertions(+), 29 deletions(-)
net/mptcp/fastopen.c +2 -22
@@ -40,13 +40,12 @@ void mptcp_fastopen_subflow_synack_set_p tp->copied_seq += skb->len; subflow->ssn_offset += skb->len; -/* initialize a dummy sequence number, we will update it at MPC -* completion, if needed -*/ +/* Only the sequence delta is relevant */ MPTCP_SKB_CB (skb)->map_seq = -skb->len;MPTCP_SKB_CB (skb)->end_seq =0 ;MPTCP_SKB_CB (skb)->offset =0 ;MPTCP_SKB_CB (skb)->has_rxtstamp =TCP_SKB_CB (skb)->has_rxtstamp; +MPTCP_SKB_CB (skb)->cant_coalesce =1 ;mptcp_data_lock (sk);
@@ -58,22 +57,3 @@ void mptcp_fastopen_subflow_synack_set_pmptcp_data_unlock (sk); } - -void __mptcp_fastopen_gen_msk_ackseq (struct mptcp_sock *msk,struct mptcp_subflow_context *subflow, -const struct mptcp_options_received *mp_opt) -{ -struct sock *sk = (struct sock *)msk; -struct sk_buff *skb; - - skb =skb_peek_tail (&sk->sk_receive_queue); -if (skb) { -WARN_ON_ONCE (MPTCP_SKB_CB (skb)->end_seq); -pr_debug ("msk %p moving seq %llx -> %llx end_seq %llx -> %llx\n" , sk, -MPTCP_SKB_CB (skb)->map_seq,MPTCP_SKB_CB (skb)->map_seq + msk->ack_seq, -MPTCP_SKB_CB (skb)->end_seq,MPTCP_SKB_CB (skb)->end_seq + msk->ack_seq); -MPTCP_SKB_CB (skb)->map_seq += msk->ack_seq; -MPTCP_SKB_CB (skb)->end_seq += msk->ack_seq; - } - -pr_debug ("msk=%p ack_seq=%llx\n" , msk, msk->ack_seq); -}
net/mptcp/protocol.c +3 -1
@@ -139,7 +139,8 @@ static bool mptcp_try_coalesce(struct sobool fragstolen;int delta; -if (MPTCP_SKB_CB (from)->offset || +if (unlikely (MPTCP_SKB_CB (to)->cant_coalesce) || +MPTCP_SKB_CB (from)->offset || ((to->len + from->len) > (sk->sk_rcvbuf >>3 )) || !skb_try_coalesce (to, from, &fragstolen, &delta))return false;
@@ -370,6 +371,7 @@ static bool __mptcp_move_skb(struct mptcMPTCP_SKB_CB (skb)->end_seq =MPTCP_SKB_CB (skb)->map_seq + copy_len;MPTCP_SKB_CB (skb)->offset = offset;MPTCP_SKB_CB (skb)->has_rxtstamp = has_rxtstamp; +MPTCP_SKB_CB (skb)->cant_coalesce =0 ;if (MPTCP_SKB_CB (skb)->map_seq == msk->ack_seq) {/* in sequence */
net/mptcp/protocol.h +2 -3
@@ -129,7 +129,8 @@ struct mptcp_skb_cb {u64 map_seq;u64 end_seq;u32 offset; - u8 has_rxtstamp:1; +u8 has_rxtstamp; +u8 cant_coalesce; };#define MPTCP_SKB_CB (__skb) ((struct mptcp_skb_cb *)&((__skb)->cb[0]))
@@ -988,8 +989,6 @@ void mptcp_event_pm_listener(const struc enum mptcp_event_type event);bool mptcp_userspace_pm_active (const struct mptcp_sock *msk); -void __mptcp_fastopen_gen_msk_ackseq (struct mptcp_sock *msk,struct mptcp_subflow_context *subflow, -const struct mptcp_options_received *mp_opt);void mptcp_fastopen_subflow_synack_set_params (struct mptcp_subflow_context *subflow,struct request_sock *req);
net/mptcp/subflow.c +0 -3
@@ -778,9 +778,6 @@ void __mptcp_subflow_fully_established(ssubflow_set_remote_key (msk, subflow, mp_opt); subflow->fully_established =1 ;WRITE_ONCE (msk->fully_established, true); - -if (subflow->is_mptfo) -__mptcp_fastopen_gen_msk_ackseq (msk, subflow, mp_opt); } static struct sock *subflow_syn_recv_sock(const struct sock *sk,
Greg Kroah-Hartman
maintainerPATCH 495/508 mptcp: fix rx timestamp corruption on fastopen
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Paolo Abeni <[email protected]>
[ Upstream commit 6254a16d6f0c672e3809ca5d7c9a28a55d71f764 ]
The skb cb offset containing the timestamp presence flag is cleared before loading such information. Cache such value before MPTCP CB initialization.
--- net/mptcp/fastopen.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
net/mptcp/fastopen.c +3 -1
@@ -12,6 +12,7 @@ void mptcp_fastopen_subflow_synack_set_pstruct sock *sk, *ssk;struct sk_buff *skb;struct tcp_sock *tp; +bool has_rxtstamp;/* on early fallback the subflow context is deleted by * subflow_syn_recv_sock()
@@ -39,12 +40,13 @@ void mptcp_fastopen_subflow_synack_set_p*/ tp->copied_seq += skb->len; subflow->ssn_offset += skb->len; + has_rxtstamp =TCP_SKB_CB (skb)->has_rxtstamp;/* Only the sequence delta is relevant */ MPTCP_SKB_CB (skb)->map_seq = -skb->len;MPTCP_SKB_CB (skb)->end_seq =0 ;MPTCP_SKB_CB (skb)->offset =0 ; -MPTCP_SKB_CB (skb)->has_rxtstamp =TCP_SKB_CB (skb)->has_rxtstamp; +MPTCP_SKB_CB (skb)->has_rxtstamp = has_rxtstamp;MPTCP_SKB_CB (skb)->cant_coalesce =1 ;mptcp_data_lock (sk);
Greg Kroah-Hartman
maintainerPATCH 496/508 mptcp: pm: prio: skip closed subflows
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: "Matthieu Baerts (NGI0)" <[email protected]>
[ Upstream commit 166b78344031bf7ac9f55cb5282776cfd85f220e ]
When sending an MP_PRIO, closed subflows need to be skipped.
This fixes the case where the initial subflow got closed, re-opened later, then an MP_PRIO is needed for the same local address.
Note that explicit MP_PRIO cannot be sent during the 3WHS, so it is fine to use __mptcp_subflow_active().
--- net/mptcp/pm_netlink.c | 3 +++ 1 file changed, 3 insertions(+)
net/mptcp/pm_netlink.c +3 -0
@@ -923,6 +923,9 @@ int mptcp_pm_nl_mp_prio_send_ack(structstruct sock *ssk =mptcp_subflow_tcp_sock (subflow);struct mptcp_addr_info local, remote; +if (!__mptcp_subflow_active (subflow)) +continue ; +mptcp_local_address ((struct sock_common *)ssk, &local);if (!mptcp_addresses_equal (&local, addr, addr->port))continue ;
Greg Kroah-Hartman
maintainerPATCH 497/508 mptcp: pm: kernel: correctly retransmit ADD_ADDR ID 0
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: "Matthieu Baerts (NGI0)" <[email protected]>
[ Upstream commit b12014d2d36eaed4e4bec5f1ac7e91110eeb100d ]
When adding the ADD_ADDR to the list, the address including the IP, port and ID are copied. On the other hand, when the endpoint corresponds to the one from the initial subflow, the ID is set to 0, as specified by the MPTCP protocol.
The issue is that the ID was reset after having copied the ID in the ADD_ADDR entry. So the retransmission was done, but using a different ID than the initial one.
--- net/mptcp/pm_netlink.c | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-)
net/mptcp/pm_netlink.c +8 -5
@@ -591,6 +591,8 @@ static void mptcp_pm_create_subflow_or_s/* check first for announce */ if (msk->pm.add_addr_signaled < add_addr_signal_max) { +u8 endp_id; +/* due to racing events on both ends we can reach here while * previous add address is still running: if we invoke now * mptcp_pm_announce_addr(), that will fail and the
@@ -604,19 +606,20 @@ static void mptcp_pm_create_subflow_or_sif (!select_signal_address (pernet, msk, &local)) goto subflow; +/* Special case for ID0: set the correct ID */ + endp_id = local.addr.id; +if (endp_id == msk->mpc_endpoint_id) + local.addr.id =0 ; +/* If the alloc fails, we are on memory pressure, not worth * continuing, and trying to create subflows. */ if (!mptcp_pm_alloc_anno_list (msk, &local.addr))return ; -__clear_bit (local.addr.id, msk->pm.id_avail_bitmap); +__clear_bit (endp_id, msk->pm.id_avail_bitmap); msk->pm.add_addr_signaled++; -/* Special case for ID0: set the correct ID */ -if (local.addr.id == msk->mpc_endpoint_id) - local.addr.id =0 ; -mptcp_pm_announce_addr (msk, &local.addr, false);mptcp_pm_nl_addr_send_ack (msk);
Greg Kroah-Hartman
maintainerPATCH 498/508 f2fs: fix incorrect file address mapping when inline inode is unwritten
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Yongpeng Yang <[email protected]>
[ Upstream commit 68a0178981a0f493295afa29f8880246e561494c ]
When fileinfo->fi_flags does not have the FIEMAP_FLAG_SYNC bit set and inline data has not been persisted yet, the physical address of the extent is calculated incorrectly for unwritten inline inodes.
root@vm:/mnt/f2fs# dd if=/dev/zero of=data.3k bs=3k count=1 root@vm:/mnt/f2fs# f2fs_io fiemap 0 100 data.3k Fiemap: offset = 0 len = 100 logical addr. physical addr. length flags 0 0000000000000000 00000ffffffff16c 0000000000000c00 00000301
This patch fixes the issue by checking if the inode's address is valid. If the inline inode is unwritten, set the physical address to 0 and mark the extent with FIEMAP_EXTENT_UNKNOWN | FIEMAP_EXTENT_DELALLOC flags.
--- fs/f2fs/inline.c | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-)
fs/f2fs/inline.c +9 -4
@@ -791,7 +791,7 @@ int f2fs_read_inline_dir(struct file *fiint f2fs_inline_data_fiemap (struct inode *inode,struct fiemap_extent_info *fieinfo,__u64 start,__u64 len) { -__u64 byteaddr, ilen; +__u64 byteaddr =0 , ilen;__u32 flags =FIEMAP_EXTENT_DATA_INLINE |FIEMAP_EXTENT_NOT_ALIGNED |FIEMAP_EXTENT_LAST ;struct node_info ni;
@@ -824,9 +824,14 @@ int f2fs_inline_data_fiemap(struct inodeif (err) goto out; - byteaddr = (__u64 )ni.blk_addr << inode->i_sb->s_blocksize_bits; - byteaddr += (char *)inline_data_addr (inode, ipage) - - (char *)F2FS_INODE (ipage); +if (__is_valid_data_blkaddr (ni.blk_addr)) { + byteaddr = (__u64 )ni.blk_addr << inode->i_sb->s_blocksize_bits; + byteaddr += (char *)inline_data_addr (inode, ipage) - + (char *)F2FS_INODE (ipage); + }else { +f2fs_bug_on (F2FS_I_SB (inode), ni.blk_addr !=NEW_ADDR ); + flags |=FIEMAP_EXTENT_DELALLOC |FIEMAP_EXTENT_UNKNOWN ; + } err =fiemap_fill_next_extent (fieinfo, start, byteaddr, ilen, flags);trace_f2fs_fiemap (inode, start, byteaddr, ilen, flags, err); out:
Greg Kroah-Hartman
maintainerPATCH 499/508 f2fs: fix false alarm of lockdep on cp_global_sem lock
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Chao Yu <[email protected]>
[ Upstream commit 6a5e3de9c2bb0b691d16789a5d19e9276a09b308 ]
lockdep reported a potential deadlock:
a) TCMU device removal context:
- call del_gendisk() to get q->q_usage_counter
- call start_flush_work() to get work_completion of wb->dwork
b) f2fs writeback context:
- in wb_workfn(), which holds work_completion of wb->dwork
- call f2fs_balance_fs() to get sbi->gc_lock
c) f2fs vfs_write context:
- call f2fs_gc() to get sbi->gc_lock
- call f2fs_write_checkpoint() to get sbi->cp_global_sem
d) f2fs mount context:
- call recover_fsync_data() to get sbi->cp_global_sem
- call f2fs_check_and_fix_write_pointer() to call blkdev_report_zones() that goes down to blk_mq_alloc_request and get q->q_usage_counter
Original callstack is in Closes tag.
However, I think this is a false alarm due to before mount returns successfully (context d), we can not access file therein via vfs_write (context c).
Let's introduce per-sb cp_global_sem_key, and assign the key for cp_global_sem, so that lockdep can recognize cp_global_sem from different super block correctly.
A lot of work are done by Shin'ichiro Kawasaki, thanks a lot for the work.
--- fs/f2fs/f2fs.h | 3 +++ fs/f2fs/super.c | 11 +++++++++++ 2 files changed, 14 insertions(+)
fs/f2fs/f2fs.h +3 -0
@@ -1824,6 +1824,9 @@ struct f2fs_sb_info {spinlock_t iostat_lat_lock;struct iostat_lat_info *iostat_io_lat;#endif +#ifdef CONFIG_DEBUG_LOCK_ALLOC +struct lock_class_key cp_global_sem_key; +#endif };/* Definitions to access f2fs_sb_info */
fs/f2fs/super.c +11 -0
@@ -1695,6 +1695,9 @@ static void f2fs_put_super(struct super_#if IS_ENABLED (CONFIG_UNICODE )utf8_unload (sb->s_encoding);#endif +#ifdef CONFIG_DEBUG_LOCK_ALLOC +lockdep_unregister_key (&sbi->cp_global_sem_key); +#endif kfree (sbi); }
@@ -4380,6 +4383,11 @@ try_onemore:init_f2fs_rwsem (&sbi->gc_lock);mutex_init (&sbi->writepages);init_f2fs_rwsem (&sbi->cp_global_sem); +#ifdef CONFIG_DEBUG_LOCK_ALLOC +lockdep_register_key (&sbi->cp_global_sem_key); +lockdep_set_class (&sbi->cp_global_sem.internal_rwsem, + &sbi->cp_global_sem_key); +#endif init_f2fs_rwsem (&sbi->node_write);init_f2fs_rwsem (&sbi->node_change);spin_lock_init (&sbi->stat_lock);
@@ -4838,6 +4846,9 @@ free_sb_buf: free_sbi:if (sbi->s_chksum_driver)crypto_free_shash (sbi->s_chksum_driver); +#ifdef CONFIG_DEBUG_LOCK_ALLOC +lockdep_unregister_key (&sbi->cp_global_sem_key); +#endif kfree (sbi);/* give only one another chance */
Greg Kroah-Hartman
maintainerPATCH 500/508 RDMA/mana: Fix error unwind in mana_ib_create_qp_rss()
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jason Gunthorpe <[email protected]>
[ Upstream commit 6aaa978c6b6218cfac15fe1dab17c76fe229ce3f ]
Sashiko points out that mana_ib_cfg_vport_steering() is leaked, the normal destroy path cleans it up.
--- drivers/infiniband/hw/mana/qp.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
drivers/infiniband/hw/mana/qp.c +3 -1
@@ -237,13 +237,15 @@ static int mana_ib_create_qp_rss(structibdev_dbg (&mdev->ib_dev,"Failed to copy to udata create rss-qp, %d\n" , ret); - goto fail; + goto err_disable_vport_rx; }kfree (mana_ind_table);return 0 ; +err_disable_vport_rx: +mana_disable_vport_rx (mpc); fail:while (i-- >0 ) { ibwq = ind_tbl->ind_tbl[i];
Greg Kroah-Hartman
maintainerPATCH 501/508 ksmbd: validate inherited ACE SID length
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Shota Zaizen <[email protected]>
[ Upstream commit 996454bc0da84d5a1dedb1a7861823087e01a7ae ]
smb_inherit_dacl() walks the parent directory DACL loaded from the security descriptor xattr. It verifies that each ACE contains the fixed SID header before using it, but does not verify that the variable-length SID described by sid.num_subauth is fully contained in the ACE.
A malformed inheritable ACE can advertise more subauthorities than are present in the ACE. compare_sids() may then read past the ACE. smb_set_ace() also clamps the copied destination SID, but used the unchecked source SID count to compute the inherited ACE size. That could advance the temporary inherited ACE buffer pointer and nt_size accounting past the allocated buffer.
Fix this by validating the parent ACE SID count and SID length before using the SID during inheritance. Compute the inherited ACE size from the copied SID so the size matches the bounded destination SID. Reject the inherited DACL if size accumulation would overflow smb_acl.size or the security descriptor allocation size.
--- fs/smb/server/smbacl.c | 66 ++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 52 insertions(+), 14 deletions(-)
fs/smb/server/smbacl.c +52 -14
@@ -1025,7 +1025,26 @@ static void smb_set_ace(struct smb_ace * ace->flags = flags; ace->access_req = access_req;smb_copy_sid (&ace->sid, sid); - ace->size =cpu_to_le16 (1 +1 +2 +4 +1 +1 +6 + (sid->num_subauth *4 )); + ace->size =cpu_to_le16 (1 +1 +2 +4 +1 +1 +6 + + (ace->sid.num_subauth *4 )); +} + +static int smb_append_inherited_ace (struct smb_ace **ace,int *nt_size, +u16 *ace_cnt,const struct smb_sid *sid, +u8 type,u8 flags,__le32 access_req) +{ +int ace_size; + +smb_set_ace (*ace, sid, type, flags, access_req); + ace_size =le16_to_cpu ((*ace)->size); +/* pdacl->size is __le16 and includes struct smb_acl. */ +if (check_add_overflow (*nt_size, ace_size, nt_size) || + *nt_size >U16_MAX - (int )sizeof (struct smb_acl )) +return -EINVAL ; + + (*ace_cnt)++; + *ace = (struct smb_ace *)((char *)*ace + ace_size); +return 0 ; } int smb_inherit_dacl(struct ksmbd_conn *conn,
@@ -1090,6 +1109,12 @@ int smb_inherit_dacl(struct ksmbd_conn *if (pace_size > aces_size)break ; +if (parent_aces->sid.num_subauth >SID_MAX_SUB_AUTHORITIES || + pace_size < offsetof(struct smb_ace , sid) + +CIFS_SID_BASE_SIZE + +sizeof (__le32) * parent_aces->sid.num_subauth) +break ; + aces_size -= pace_size; flags = parent_aces->flags;
@@ -1119,22 +1144,24 @@ int smb_inherit_dacl(struct ksmbd_conn * }if (is_dir && creator && flags &CONTAINER_INHERIT_ACE ) { -smb_set_ace (aces, psid, parent_aces->type, inherited_flags, - parent_aces->access_req); - nt_size +=le16_to_cpu (aces->size); - ace_cnt++; - aces = (struct smb_ace *)((char *)aces +le16_to_cpu (aces->size)); + rc =smb_append_inherited_ace (&aces, &nt_size, &ace_cnt, + psid, parent_aces->type, + inherited_flags, + parent_aces->access_req); +if (rc) + goto free_aces_base; flags |=INHERIT_ONLY_ACE ; psid = creator; }else if (is_dir && !(parent_aces->flags &NO_PROPAGATE_INHERIT_ACE )) { psid = &parent_aces->sid; } -smb_set_ace (aces, psid, parent_aces->type, flags | inherited_flags, - parent_aces->access_req); - nt_size +=le16_to_cpu (aces->size); - aces = (struct smb_ace *)((char *)aces +le16_to_cpu (aces->size)); - ace_cnt++; + rc =smb_append_inherited_ace (&aces, &nt_size, &ace_cnt, psid, + parent_aces->type, + flags | inherited_flags, + parent_aces->access_req); +if (rc) + goto free_aces_base; pass: parent_aces = (struct smb_ace *)((char *)parent_aces + pace_size); }
@@ -1144,7 +1171,7 @@ pass:struct smb_acl *pdacl;struct smb_sid *powner_sid =NULL , *pgroup_sid =NULL ;int powner_sid_size =0 , pgroup_sid_size =0 , pntsd_size; -int pntsd_alloc_size; +size_t pntsd_alloc_size;if (parent_pntsd->osidoffset) { powner_sid = (struct smb_sid *)((char *)parent_pntsd +
@@ -1157,8 +1184,19 @@ pass: pgroup_sid_size =1 +1 +6 + (pgroup_sid->num_subauth *4 ); } - pntsd_alloc_size =sizeof (struct smb_ntsd ) + powner_sid_size + - pgroup_sid_size +sizeof (struct smb_acl ) + nt_size; +if (check_add_overflow (sizeof (struct smb_ntsd ), + (size_t )powner_sid_size, + &pntsd_alloc_size) || +check_add_overflow (pntsd_alloc_size, + (size_t )pgroup_sid_size, + &pntsd_alloc_size) || +check_add_overflow (pntsd_alloc_size,sizeof (struct smb_acl ), + &pntsd_alloc_size) || +check_add_overflow (pntsd_alloc_size, (size_t )nt_size, + &pntsd_alloc_size)) { + rc = -EINVAL ; + goto free_aces_base; + } pntsd =kzalloc (pntsd_alloc_size,GFP_KERNEL );if (!pntsd) {
Greg Kroah-Hartman
maintainerPATCH 502/508 spi: st-ssc4: switch to use modern name
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Yang Yingliang <[email protected]>
[ Upstream commit e6b7e64cb11966b26646a362677ca5a08481157e ]
Change legacy name master/slave to modern name host/target or controller.
No functional changed.
Stable-dep-of: 19857374010d ("spi: st-ssc4: fix controller deregistration")
--- drivers/spi/spi-st-ssc4.c | 70 +++++++++++++++++++++++----------------------- 1 file changed, 35 insertions(+), 35 deletions(-)
drivers/spi/spi-st-ssc4.c +35 -35
@@ -6,7 +6,7 @@* Patrice Chotard <[email protected]> * Lee Jones <[email protected]> * -* SPI master mode controller driver, used in STMicroelectronics devices. +* SPI host mode controller driver, used in STMicroelectronics devices. */ #include <linux/clk.h>
@@ -115,10 +115,10 @@ static void ssc_read_rx_fifo(struct spi_ spi_st->words_remaining -= count; } -static int spi_st_transfer_one (struct spi_master *master, +static int spi_st_transfer_one (struct spi_controller *host,struct spi_device *spi,struct spi_transfer *t) { -struct spi_st *spi_st =spi_master_get_devdata (master); +struct spi_st *spi_st =spi_controller_get_devdata (host);uint32_t ctl =0 ;/* Setup transfer */
@@ -165,7 +165,7 @@ static int spi_st_transfer_one(struct spif (ctl)writel_relaxed (ctl, spi_st->base +SSC_CTL ); -spi_finalize_current_transfer (spi->master); +spi_finalize_current_transfer (spi->controller);return t->len; }
@@ -174,7 +174,7 @@ static int spi_st_transfer_one(struct sp#define MODEBITS (SPI_CPOL | SPI_CPHA | SPI_LSB_FIRST | SPI_LOOP | SPI_CS_HIGH)static int spi_st_setup (struct spi_device *spi) { -struct spi_st *spi_st =spi_master_get_devdata (spi->master); +struct spi_st *spi_st =spi_controller_get_devdata (spi->controller);u32 spi_st_clk, sscbrg, var;u32 hz = spi->max_speed_hz;
@@ -274,35 +274,35 @@ static irqreturn_t spi_st_irq(int irq, vstatic int spi_st_probe (struct platform_device *pdev) {struct device_node *np = pdev->dev.of_node; -struct spi_master *master; +struct spi_controller *host;struct spi_st *spi_st;int irq, ret =0 ;u32 var; - master =spi_alloc_master (&pdev->dev,sizeof (*spi_st)); -if (!master) + host =spi_alloc_host (&pdev->dev,sizeof (*spi_st)); +if (!host)return -ENOMEM ; - master->dev.of_node = np; - master->mode_bits =MODEBITS ; - master->setup = spi_st_setup; - master->transfer_one = spi_st_transfer_one; - master->bits_per_word_mask =SPI_BPW_MASK (8 ) |SPI_BPW_MASK (16 ); - master->auto_runtime_pm = true; - master->bus_num = pdev->id; - master->use_gpio_descriptors = true; - spi_st =spi_master_get_devdata (master); + host->dev.of_node = np; + host->mode_bits =MODEBITS ; + host->setup = spi_st_setup; + host->transfer_one = spi_st_transfer_one; + host->bits_per_word_mask =SPI_BPW_MASK (8 ) |SPI_BPW_MASK (16 ); + host->auto_runtime_pm = true; + host->bus_num = pdev->id; + host->use_gpio_descriptors = true; + spi_st =spi_controller_get_devdata (host); spi_st->clk =devm_clk_get (&pdev->dev,"ssc" );if (IS_ERR (spi_st->clk)) {dev_err (&pdev->dev,"Unable to request clock\n" ); ret =PTR_ERR (spi_st->clk); - goto put_master; + goto put_host; } ret =clk_prepare_enable (spi_st->clk);if (ret) - goto put_master; + goto put_host;init_completion (&spi_st->done);
@@ -324,7 +324,7 @@ static int spi_st_probe(struct platform_ var &= ~SSC_CTL_SR ;writel_relaxed (var, spi_st->base +SSC_CTL ); -/* Set SSC into slave mode before reconfiguring PIO pins */ +/* Set SSC into target mode before reconfiguring PIO pins */ var =readl_relaxed (spi_st->base +SSC_CTL ); var &= ~SSC_CTL_MS ;writel_relaxed (var, spi_st->base +SSC_CTL );
@@ -347,11 +347,11 @@ static int spi_st_probe(struct platform_pm_runtime_set_active (&pdev->dev);pm_runtime_enable (&pdev->dev); -platform_set_drvdata (pdev, master); +platform_set_drvdata (pdev, host); - ret =devm_spi_register_master (&pdev->dev, master); + ret =devm_spi_register_controller (&pdev->dev, host);if (ret) { -dev_err (&pdev->dev,"Failed to register master\n" ); +dev_err (&pdev->dev,"Failed to register host\n" ); goto rpm_disable; }
@@ -361,15 +361,15 @@ rpm_disable:pm_runtime_disable (&pdev->dev); clk_disable:clk_disable_unprepare (spi_st->clk); -put_master: -spi_master_put (master); +put_host: +spi_controller_put (host);return ret; }static void spi_st_remove (struct platform_device *pdev) { -struct spi_master *master =platform_get_drvdata (pdev); -struct spi_st *spi_st =spi_master_get_devdata (master); +struct spi_controller *host =platform_get_drvdata (pdev); +struct spi_st *spi_st =spi_controller_get_devdata (host);pm_runtime_disable (&pdev->dev);
@@ -381,8 +381,8 @@ static void spi_st_remove(struct platfor#ifdef CONFIG_PM static int spi_st_runtime_suspend (struct device *dev) { -struct spi_master *master =dev_get_drvdata (dev); -struct spi_st *spi_st =spi_master_get_devdata (master); +struct spi_controller *host =dev_get_drvdata (dev); +struct spi_st *spi_st =spi_controller_get_devdata (host);writel_relaxed (0 , spi_st->base +SSC_IEN );pinctrl_pm_select_sleep_state (dev);
@@ -394,8 +394,8 @@ static int spi_st_runtime_suspend(structstatic int spi_st_runtime_resume (struct device *dev) { -struct spi_master *master =dev_get_drvdata (dev); -struct spi_st *spi_st =spi_master_get_devdata (master); +struct spi_controller *host =dev_get_drvdata (dev); +struct spi_st *spi_st =spi_controller_get_devdata (host);int ret; ret =clk_prepare_enable (spi_st->clk);
@@ -408,10 +408,10 @@ static int spi_st_runtime_resume(struct#ifdef CONFIG_PM_SLEEP static int spi_st_suspend (struct device *dev) { -struct spi_master *master =dev_get_drvdata (dev); +struct spi_controller *host =dev_get_drvdata (dev);int ret; - ret =spi_master_suspend (master); + ret =spi_controller_suspend (host);if (ret)return ret;
@@ -420,10 +420,10 @@ static int spi_st_suspend(struct devicestatic int spi_st_resume (struct device *dev) { -struct spi_master *master =dev_get_drvdata (dev); +struct spi_controller *host =dev_get_drvdata (dev);int ret; - ret =spi_master_resume (master); + ret =spi_controller_resume (host);if (ret)return ret;
Greg Kroah-Hartman
maintainerPATCH 503/508 spi: st-ssc4: fix controller deregistration
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Johan Hovold <[email protected]>
[ Upstream commit 19857374010d06ca6a2f7c2c53464122eb804df0 ]
Make sure to deregister the controller before disabling underlying resources like clocks during driver unbind.
--- drivers/spi/spi-st-ssc4.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-)
drivers/spi/spi-st-ssc4.c +7 -1
@@ -349,7 +349,7 @@ static int spi_st_probe(struct platform_platform_set_drvdata (pdev, host); - ret =devm_spi_register_controller (&pdev->dev, host); + ret =spi_register_controller (host);if (ret) {dev_err (&pdev->dev,"Failed to register host\n" ); goto rpm_disable;
@@ -371,10 +371,16 @@ static void spi_st_remove(struct platforstruct spi_controller *host =platform_get_drvdata (pdev);struct spi_st *spi_st =spi_controller_get_devdata (host); +spi_controller_get (host); + +spi_unregister_controller (host); +pm_runtime_disable (&pdev->dev);clk_disable_unprepare (spi_st->clk); +spi_controller_put (host); +pinctrl_pm_select_sleep_state (&pdev->dev); }
Greg Kroah-Hartman
maintainerPATCH 504/508 media: nxp: imx8-isi: Reduce minimum queued buffers from 2 to 0
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Guoniu Zhou <[email protected]>
[ Upstream commit 2f38622d0f85f317be9e6b131da6cd511db94fd2 ]
Fix a hang issue when capturing a single frame with applications like cam in libcamera. It would hang waiting for the driver to complete the buffer, but streaming never starts because min_queued_buffers was set to 2.
The ISI module uses a ping-pong buffer mechanism that requires two buffers to be programmed at all times. However, when fewer than 2 user buffers are available, the driver use internal discard buffers to fill the remaining slot(s). Reduce minimum queued buffers from 2 to 0 allows streaming to start without any queued buffers.
--- drivers/media/platform/nxp/imx8-isi/imx8-isi-video.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/media/platform/nxp/imx8-isi/imx8-isi-video.c +1 -1
@@ -1456,7 +1456,7 @@ int mxc_isi_video_register(struct mxc_is q->mem_ops = &vb2_dma_contig_memops; q->buf_struct_size =sizeof (struct mxc_isi_buffer ); q->timestamp_flags =V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC ; - q->min_buffers_needed =2 ; + q->min_buffers_needed =0 ; q->lock = &video->lock; q->dev = pipe->isi->dev;
Greg Kroah-Hartman
maintainerPATCH 505/508 spi: sifive: Simplify clock handling with devm_clk_get_enabled()
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Pei Xiao <[email protected]>
[ Upstream commit 140039c23aca067b9ff0242e3c0ce96276bb95f3 ]
Replace devm_clk_get() followed by clk_prepare_enable() with devm_clk_get_enabled() for the bus clock. This reduces boilerplate code and error handling, as the managed API automatically disables the clock when the device is removed or if probe fails.
Remove the now-unnecessary clk_disable_unprepare() calls from the probe error path and the remove callback. Adjust the error handling to use the existing put_host label.
Stable-dep-of: 0f25236694a2 ("spi: sifive: fix controller deregistration")
--- drivers/spi/spi-sifive.c | 21 ++++++--------------- 1 file changed, 6 insertions(+), 15 deletions(-)
drivers/spi/spi-sifive.c +6 -15
@@ -312,7 +312,8 @@ static int sifive_spi_probe(struct platf goto put_host; } - spi->clk =devm_clk_get (&pdev->dev,NULL ); +/* Spin up the bus clock before hitting registers */ + spi->clk =devm_clk_get_enabled (&pdev->dev,NULL );if (IS_ERR (spi->clk)) {dev_err (&pdev->dev,"Unable to find bus clock\n" ); ret =PTR_ERR (spi->clk);
@@ -342,13 +343,6 @@ static int sifive_spi_probe(struct platf goto put_host; } -/* Spin up the bus clock before hitting registers */ - ret =clk_prepare_enable (spi->clk); -if (ret) { -dev_err (&pdev->dev,"Unable to enable bus clock\n" ); - goto put_host; - } -/* probe the number of CS lines */ spi->cs_inactive =sifive_spi_read (spi,SIFIVE_SPI_REG_CSDEF );sifive_spi_write (spi,SIFIVE_SPI_REG_CSDEF ,0xffffffffU );
@@ -357,14 +351,14 @@ static int sifive_spi_probe(struct platfif (!cs_bits) {dev_err (&pdev->dev,"Could not auto probe CS lines\n" ); ret = -EINVAL ; - goto disable_clk; + goto put_host; } num_cs =ilog2 (cs_bits) +1 ;if (num_cs >SIFIVE_SPI_MAX_CS ) {dev_err (&pdev->dev,"Invalid number of spi targets\n" ); ret = -EINVAL ; - goto disable_clk; + goto put_host; }/* Define our host */
@@ -393,7 +387,7 @@ static int sifive_spi_probe(struct platf dev_name(&pdev->dev), spi);if (ret) {dev_err (&pdev->dev,"Unable to bind to interrupt\n" ); - goto disable_clk; + goto put_host; } dev_info(&pdev->dev, "mapped; irq=%d, cs=%d\n",
@@ -402,13 +396,11 @@ static int sifive_spi_probe(struct platf ret =devm_spi_register_controller (&pdev->dev, host);if (ret <0 ) {dev_err (&pdev->dev,"spi_register_host failed\n" ); - goto disable_clk; + goto put_host; }return 0 ; -disable_clk: -clk_disable_unprepare (spi->clk); put_host:spi_controller_put (host);
@@ -422,7 +414,6 @@ static void sifive_spi_remove(struct pla/* Disable all the interrupts just in case */ sifive_spi_write (spi,SIFIVE_SPI_REG_IE ,0 ); -clk_disable_unprepare (spi->clk); }static int sifive_spi_suspend (struct device *dev)
Greg Kroah-Hartman
maintainerPATCH 506/508 spi: sifive: fix controller deregistration
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Johan Hovold <[email protected]>
[ Upstream commit 0f25236694a2854627c1597465a071e6bb6fe572 ]
Make sure to deregister the controller before disabling underlying resources like interrupts during driver unbind.
Note that clocks were also disabled before the recent commit 140039c23aca ("spi: sifive: Simplify clock handling with devm_clk_get_enabled()").
--- drivers/spi/spi-sifive.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-)
drivers/spi/spi-sifive.c +7 -1
@@ -393,7 +393,7 @@ static int sifive_spi_probe(struct platfdev_info (&pdev->dev,"mapped; irq=%d, cs=%d\n" , irq, host->num_chipselect); - ret =devm_spi_register_controller (&pdev->dev, host); + ret =spi_register_controller (host);if (ret <0 ) {dev_err (&pdev->dev,"spi_register_host failed\n" ); goto put_host;
@@ -412,8 +412,14 @@ static void sifive_spi_remove(struct plastruct spi_controller *host =platform_get_drvdata (pdev);struct sifive_spi *spi =spi_controller_get_devdata (host); +spi_controller_get (host); + +spi_unregister_controller (host); +/* Disable all the interrupts just in case */ sifive_spi_write (spi,SIFIVE_SPI_REG_IE ,0 ); + +spi_controller_put (host); }static int sifive_spi_suspend (struct device *dev)
Greg Kroah-Hartman
maintainerPATCH 507/508 mptcp: pm: ADD_ADDR rtx: fix potential data-race
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: "Matthieu Baerts (NGI0)" <[email protected]>
[ Upstream commit 5cd6e0ad79d2615264f63929f8b457ad97ae550d ]
This mptcp_pm_add_timer() helper is executed as a timer callback in softirq context. To avoid any data races, the socket lock needs to be held with bh_lock_sock().
If the socket is in use, retry again soon after, similar to what is done with the keepalive timer.
--- net/mptcp/pm_netlink.c | 8 ++++++++ 1 file changed, 8 insertions(+)
net/mptcp/pm_netlink.c +8 -0
@@ -308,6 +308,13 @@ static void mptcp_pm_add_timer(struct tiif (!entry->addr.id)return ; +bh_lock_sock (sk); +if (sock_owned_by_user (sk)) { +/* Try again later. */ +sk_reset_timer (sk, timer, jiffies +HZ /20 ); + goto out; + } +if (mptcp_pm_should_add_signal_addr (msk)) {sk_reset_timer (sk, timer, jiffies +TCP_RTO_MAX /8 ); goto out;
@@ -336,6 +343,7 @@ static void mptcp_pm_add_timer(struct timptcp_pm_subflow_established (msk); out: +bh_unlock_sock (sk);__sock_put (sk); }
Greg Kroah-Hartman
maintainerPATCH 508/508 mptcp: pm: ADD_ADDR rtx: resched blocked ADD_ADDR quicker
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: "Matthieu Baerts (NGI0)" <[email protected]>
[ Upstream commit 3cf12492891c4b5ff54dda404a2de4ec54c9e1b5 ]
When an ADD_ADDR needs to be retransmitted and another one has already been prepared -- e.g. multiple ADD_ADDRs have been sent in a row and need to be retransmitted later -- this additional retransmission will need to wait.
In this case, the timer was reset to TCP_RTO_MAX / 8, which is ~15 seconds. This delay is unnecessary long: it should just be rescheduled at the next opportunity, e.g. after the retransmission timeout.
Without this modification, some issues can be seen from time to time in the selftests when multiple ADD_ADDRs are sent, and the host takes time to process them, e.g. the "signal addresses, ADD_ADDR timeout" MPTCP Join selftest, especially with a debug kernel config.
Note that on older kernels, 'timeout' is not available. It should be enough to replace it by one second (HZ).
--- net/mptcp/pm_netlink.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
net/mptcp/pm_netlink.c +1 -1
@@ -316,7 +316,7 @@ static void mptcp_pm_add_timer(struct ti }if (mptcp_pm_should_add_signal_addr (msk)) { -sk_reset_timer (sk, timer, jiffies +TCP_RTO_MAX /8 ); +sk_reset_timer (sk, timer, jiffies +HZ ); goto out; }
# Librecast Test Results
020/020 [ OK ] liblcrq
010/010 [ OK ] libmld
120/120 [ OK ] liblibrecast
CPU/kernel: Linux auntie 6.6.141-rc1-g6c78ba1a564c #1 SMP PREEMPT_DYNAMIC Wed May 20 18:52:34 -00 2026 x86_64 AMD Ryzen 9 9950X 16-Core Processor AuthenticAMD GNU/Linux
Quoted 9 lines · Greg Kroah-Hartman
This is the start of the stable review cycle for the 6.6.141 release. There are 508 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.
Responses should be made by Fri, 22 May 2026 16:20:16 +0000. Anything received after that time might be too late.
The whole patch series can be found in one patch at:
Quoted 8 lines
https://www.kernel.org/pub/linux/kernel/v6.x/stable-review/patch-6.6.141-rc1.gzor in the git tree and branch at:
git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.gitlinux-6.6.y
and the diffstat can be found below.thanks,
greg k-h
perf fails to build with:
util/symbol-elf.c: In function 'dso__process_kernel_symbol':util/symbol-elf.c:1379:7: warning: implicit declaration of function 'dso__rel'; did you mean 'dso__get'? [-Wimplicit-function-declaration]
if (dso__rel(dso))
^~~~~~~~
dso__getthis is coming from this commit:
commit 8b4beba45e858aa793dd5d4d2e86d60c8c1915e6
Author: Chuck Lever <[email protected]> Date: Mon Mar 23 11:58:04 2026 -0400
perf tools: Fix module symbol resolution for non-zero .text sh_addr
[ Upstream commit 9a82bfde4775b7a87cd1a7e791f46f83ae442848 ]
Signature · 1 line
Florian
Sasha Levin
maintainerQuoted 9 lines · Florian Fainelli
perf fails to build with:
util/symbol-elf.c: In function 'dso__process_kernel_symbol':util/symbol-elf.c:1379:7: warning: implicit declaration of function 'dso__rel'; did you mean 'dso__get'? [-Wimplicit-function-declaration]if (dso__rel(dso))[...]
perf tools: Fix module symbol resolution for non-zero .textsh_addr[ Upstream commit9a82bfde4775b7a87cd1a7e791f46f83ae442848]
Dropped from the 6.6, 6.1, 5.15, and 5.10 queues -- the dso__rel() inline came in as part of the dso refcount refactor that was never backported to those versions. Kept on 7.0/6.18/6.12 where the inline is present and the patch builds.
Thanks for the report.
--
Thanks,
Sasha
Quoted 4 lines · Greg Kroah-Hartman
This is the start of the stable review cycle for the 6.6.141 release. There are 508 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.
Hello Greg,
Quoted 7 lines · Francesco Dolcini
Quoted 4 lines · Greg Kroah-Hartman
This is the start of the stable review cycle for the 6.6.141 release. There are 508 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.
Tested-by Francesco Dolcini <[email protected]>
I had another look, and despite my test passing there are warnings
kern :info : [ 0.593597] pci 0000:01:00.0: BAR 4 [io 0x1000-0x101f]: assigned kern :info : [ 0.593629] pci 0000:01:00.0: BAR 0 [io 0x1020-0x1027]: assigned kern :info : [ 0.593660] pci 0000:01:00.0: BAR 2 [io 0x1028-0x102f]: assigned kern :info : [ 0.593692] pci 0000:01:00.0: BAR 1 [io 0x1030-0x1033]: assigned kern :info : [ 0.593722] pci 0000:01:00.0: BAR 3 [io 0x1034-0x1037]: assigned kern :info : [ 0.593753] pci 0000:00:00.0: PCI bridge to [bus 01-ff] kern :info : [ 0.593767] pci 0000:00:00.0: bridge window [io 0x1000-0x1fff] kern :info : [ 0.593781] pci 0000:00:00.0: bridge window [mem 0x01100000-0x011fffff] kern :info : [ 0.593795] pci 0000:00:00.0: bridge window [mem 0x01200000-0x012fffff pref] kern :warn : [ 0.593856] sysfs: cannot create duplicate filename '/devices/platform/soc/1ffc000.pcie/pci0000:00/0000:00:00.0/resource0' kern :warn : [ 0.593875] CPU: 1 PID: 28 Comm: kworker/u5:1 Not tainted 6.6.141-rc1-7.7.0-devel #1 kern :warn : [ 0.593891] Hardware name: Freescale i.MX6 Quad/DualLite (Device Tree) kern :warn : [ 0.593904] Workqueue: events_unbound async_run_entry_fn kern :warn : [ 0.593959] unwind_backtrace from show_stack+0x10/0x14 kern :warn : [ 0.594004] show_stack from dump_stack_lvl+0x40/0x4c kern :warn : [ 0.594040] dump_stack_lvl from sysfs_warn_dup+0x58/0x64 kern :warn : [ 0.594080] sysfs_warn_dup from sysfs_add_bin_file_mode_ns+0xbc/0xcc kern :warn : [ 0.594112] sysfs_add_bin_file_mode_ns from sysfs_create_bin_file+0xac/0xb4 kern :warn : [ 0.594144] sysfs_create_bin_file from pci_create_resource_files+0x84/0x13c kern :warn : [ 0.594181] pci_create_resource_files from pci_bus_add_device+0x24/0x94 kern :warn : [ 0.594220] pci_bus_add_device from pci_bus_add_devices+0x2c/0x70 kern :warn : [ 0.594250] pci_bus_add_devices from pci_host_probe+0x40/0x90 kern :warn : [ 0.594276] pci_host_probe from dw_pcie_host_init+0x3e4/0x614 kern :warn : [ 0.594309] dw_pcie_host_init from imx6_pcie_probe+0x414/0x6ec kern :warn : [ 0.594340] imx6_pcie_probe from platform_probe+0x5c/0xb0 kern :warn : [ 0.594375] platform_probe from really_probe+0xd0/0x3c8 kern :warn : [ 0.594415] really_probe from __driver_probe_device+0x98/0x20c kern :warn : [ 0.594448] __driver_probe_device from driver_probe_device+0x30/0xc0 kern :warn : [ 0.594482] driver_probe_device from __driver_attach_async_helper+0x50/0xd8 kern :warn : [ 0.594515] __driver_attach_async_helper from async_run_entry_fn+0x30/0x144 kern :warn : [ 0.594548] async_run_entry_fn from process_one_work+0x144/0x2cc kern :warn : [ 0.594584] process_one_work from worker_thread+0x18c/0x3b8 kern :warn : [ 0.594611] worker_thread from kthread+0x110/0x12c kern :warn : [ 0.594647] kthread from ret_from_fork+0x14/0x28 kern :warn : [ 0.594670] Exception stack(0xf08edfb0 to 0xf08edff8) kern :warn : [ 0.594683] dfa0: 00000000 00000000 00000000 00000000 kern :warn : [ 0.594697] dfc0: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 kern :warn : [ 0.594709] dfe0: 00000000 00000000 00000000 00000000 00000013 00000000 kern :info : [ 0.594873] mmc0: SDHCI controller on 2198000.mmc [2198000.mmc] using ADMA kern :info : [ 0.594997] mmc1: SDHCI controller on 2190000.mmc [2190000.mmc] using ADMA kern :info : [ 0.595838] pcieport 0000:00:00.0: PME: Signaling with IRQ 291 kern :info : [ 0.596396] pcieport 0000:00:00.0: AER: enabled with IRQ 291 kern :warn : [ 0.596583] sysfs: cannot create duplicate filename '/devices/platform/soc/1ffc000.pcie/pci0000:00/0000:00:00.0/0000:01:00.0/resource0' kern :warn : [ 0.596598] CPU: 1 PID: 28 Comm: kworker/u5:1 Not tainted 6.6.141-rc1-7.7.0-devel #1 kern :warn : [ 0.596614] Hardware name: Freescale i.MX6 Quad/DualLite (Device Tree) kern :warn : [ 0.596626] Workqueue: events_unbound async_run_entry_fn kern :warn : [ 0.596659] unwind_backtrace from show_stack+0x10/0x14 kern :warn : [ 0.596702] show_stack from dump_stack_lvl+0x40/0x4c kern :warn : [ 0.596738] dump_stack_lvl from sysfs_warn_dup+0x58/0x64 kern :warn : [ 0.596772] sysfs_warn_dup from sysfs_add_bin_file_mode_ns+0xbc/0xcc kern :warn : [ 0.596804] sysfs_add_bin_file_mode_ns from sysfs_create_bin_file+0xac/0xb4 kern :warn : [ 0.596836] sysfs_create_bin_file from pci_create_resource_files+0x84/0x13c kern :warn : [ 0.596872] pci_create_resource_files from pci_bus_add_device+0x24/0x94 kern :warn : [ 0.596907] pci_bus_add_device from pci_bus_add_devices+0x2c/0x70 kern :warn : [ 0.596938] pci_bus_add_devices from pci_bus_add_devices+0x60/0x70 kern :warn : [ 0.596968] pci_bus_add_devices from pci_host_probe+0x40/0x90 kern :warn : [ 0.596994] pci_host_probe from dw_pcie_host_init+0x3e4/0x614 kern :warn : [ 0.597022] dw_pcie_host_init from imx6_pcie_probe+0x414/0x6ec kern :warn : [ 0.597048] imx6_pcie_probe from platform_probe+0x5c/0xb0 kern :warn : [ 0.597074] platform_probe from really_probe+0xd0/0x3c8 kern :warn : [ 0.597105] really_probe from __driver_probe_device+0x98/0x20c kern :warn : [ 0.597138] __driver_probe_device from driver_probe_device+0x30/0xc0 kern :warn : [ 0.597170] driver_probe_device from __driver_attach_async_helper+0x50/0xd8 kern :warn : [ 0.597202] __driver_attach_async_helper from async_run_entry_fn+0x30/0x144 kern :warn : [ 0.597232] async_run_entry_fn from process_one_work+0x144/0x2cc kern :warn : [ 0.597261] process_one_work from worker_thread+0x18c/0x3b8 kern :warn : [ 0.597288] worker_thread from kthread+0x110/0x12c kern :warn : [ 0.597315] kthread from ret_from_fork+0x14/0x28 kern :warn : [ 0.597335] Exception stack(0xf08edfb0 to 0xf08edff8) kern :warn : [ 0.597350] dfa0: 00000000 00000000 00000000 00000000 kern :warn : [ 0.597364] dfc0: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 kern :warn : [ 0.597376] dfe0: 00000000 00000000 00000000 00000000 00000013 00000000 kern :info : [ 0.631336] mmc1: new high speed SDXC card at address 0001 kern :info : [ 0.632908] mmcblk1: mmc1:0001 SD64G 58.2 GiB kern :info : [ 0.642235] fec 2188000.ethernet eth0: registered PHC device 0 kern :info : [ 0.643162] imx_thermal 20c8000.anatop:tempmon: Industrial CPU temperature grade - max:105C critical:105C passive:95C
Hello all,
Quoted 68 lines
kern :info : [ 0.593597] pci 0000:01:00.0: BAR 4 [io 0x1000-0x101f]: assigned kern :info : [ 0.593629] pci 0000:01:00.0: BAR 0 [io 0x1020-0x1027]: assigned kern :info : [ 0.593660] pci 0000:01:00.0: BAR 2 [io 0x1028-0x102f]: assigned kern :info : [ 0.593692] pci 0000:01:00.0: BAR 1 [io 0x1030-0x1033]: assigned kern :info : [ 0.593722] pci 0000:01:00.0: BAR 3 [io 0x1034-0x1037]: assigned kern :info : [ 0.593753] pci 0000:00:00.0: PCI bridge to [bus 01-ff] kern :info : [ 0.593767] pci 0000:00:00.0: bridge window [io 0x1000-0x1fff] kern :info : [ 0.593781] pci 0000:00:00.0: bridge window [mem 0x01100000-0x011fffff] kern :info : [ 0.593795] pci 0000:00:00.0: bridge window [mem 0x01200000-0x012fffff pref] kern :warn : [ 0.593856] sysfs: cannot create duplicate filename '/devices/platform/soc/1ffc000.pcie/pci0000:00/0000:00:00.0/resource0' kern :warn : [ 0.593875] CPU: 1 PID: 28 Comm: kworker/u5:1 Not tainted 6.6.141-rc1-7.7.0-devel #1 kern :warn : [ 0.593891] Hardware name: Freescale i.MX6 Quad/DualLite (Device Tree) kern :warn : [ 0.593904] Workqueue: events_unbound async_run_entry_fn kern :warn : [ 0.593959] unwind_backtrace from show_stack+0x10/0x14 kern :warn : [ 0.594004] show_stack from dump_stack_lvl+0x40/0x4c kern :warn : [ 0.594040] dump_stack_lvl from sysfs_warn_dup+0x58/0x64 kern :warn : [ 0.594080] sysfs_warn_dup from sysfs_add_bin_file_mode_ns+0xbc/0xcc kern :warn : [ 0.594112] sysfs_add_bin_file_mode_ns from sysfs_create_bin_file+0xac/0xb4 kern :warn : [ 0.594144] sysfs_create_bin_file from pci_create_resource_files+0x84/0x13c kern :warn : [ 0.594181] pci_create_resource_files from pci_bus_add_device+0x24/0x94 kern :warn : [ 0.594220] pci_bus_add_device from pci_bus_add_devices+0x2c/0x70 kern :warn : [ 0.594250] pci_bus_add_devices from pci_host_probe+0x40/0x90 kern :warn : [ 0.594276] pci_host_probe from dw_pcie_host_init+0x3e4/0x614 kern :warn : [ 0.594309] dw_pcie_host_init from imx6_pcie_probe+0x414/0x6ec kern :warn : [ 0.594340] imx6_pcie_probe from platform_probe+0x5c/0xb0 kern :warn : [ 0.594375] platform_probe from really_probe+0xd0/0x3c8 kern :warn : [ 0.594415] really_probe from __driver_probe_device+0x98/0x20c kern :warn : [ 0.594448] __driver_probe_device from driver_probe_device+0x30/0xc0 kern :warn : [ 0.594482] driver_probe_device from __driver_attach_async_helper+0x50/0xd8 kern :warn : [ 0.594515] __driver_attach_async_helper from async_run_entry_fn+0x30/0x144 kern :warn : [ 0.594548] async_run_entry_fn from process_one_work+0x144/0x2cc kern :warn : [ 0.594584] process_one_work from worker_thread+0x18c/0x3b8 kern :warn : [ 0.594611] worker_thread from kthread+0x110/0x12c kern :warn : [ 0.594647] kthread from ret_from_fork+0x14/0x28 kern :warn : [ 0.594670] Exception stack(0xf08edfb0 to 0xf08edff8) kern :warn : [ 0.594683] dfa0: 00000000 00000000 00000000 00000000 kern :warn : [ 0.594697] dfc0: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 kern :warn : [ 0.594709] dfe0: 00000000 00000000 00000000 00000000 00000013 00000000 kern :info : [ 0.594873] mmc0: SDHCI controller on 2198000.mmc [2198000.mmc] using ADMA kern :info : [ 0.594997] mmc1: SDHCI controller on 2190000.mmc [2190000.mmc] using ADMA kern :info : [ 0.595838] pcieport 0000:00:00.0: PME: Signaling with IRQ 291 kern :info : [ 0.596396] pcieport 0000:00:00.0: AER: enabled with IRQ 291 kern :warn : [ 0.596583] sysfs: cannot create duplicate filename '/devices/platform/soc/1ffc000.pcie/pci0000:00/0000:00:00.0/0000:01:00.0/resource0' kern :warn : [ 0.596598] CPU: 1 PID: 28 Comm: kworker/u5:1 Not tainted 6.6.141-rc1-7.7.0-devel #1 kern :warn : [ 0.596614] Hardware name: Freescale i.MX6 Quad/DualLite (Device Tree) kern :warn : [ 0.596626] Workqueue: events_unbound async_run_entry_fn kern :warn : [ 0.596659] unwind_backtrace from show_stack+0x10/0x14 kern :warn : [ 0.596702] show_stack from dump_stack_lvl+0x40/0x4c kern :warn : [ 0.596738] dump_stack_lvl from sysfs_warn_dup+0x58/0x64 kern :warn : [ 0.596772] sysfs_warn_dup from sysfs_add_bin_file_mode_ns+0xbc/0xcc kern :warn : [ 0.596804] sysfs_add_bin_file_mode_ns from sysfs_create_bin_file+0xac/0xb4 kern :warn : [ 0.596836] sysfs_create_bin_file from pci_create_resource_files+0x84/0x13c kern :warn : [ 0.596872] pci_create_resource_files from pci_bus_add_device+0x24/0x94 kern :warn : [ 0.596907] pci_bus_add_device from pci_bus_add_devices+0x2c/0x70 kern :warn : [ 0.596938] pci_bus_add_devices from pci_bus_add_devices+0x60/0x70 kern :warn : [ 0.596968] pci_bus_add_devices from pci_host_probe+0x40/0x90 kern :warn : [ 0.596994] pci_host_probe from dw_pcie_host_init+0x3e4/0x614 kern :warn : [ 0.597022] dw_pcie_host_init from imx6_pcie_probe+0x414/0x6ec kern :warn : [ 0.597048] imx6_pcie_probe from platform_probe+0x5c/0xb0 kern :warn : [ 0.597074] platform_probe from really_probe+0xd0/0x3c8 kern :warn : [ 0.597105] really_probe from __driver_probe_device+0x98/0x20c kern :warn : [ 0.597138] __driver_probe_device from driver_probe_device+0x30/0xc0 kern :warn : [ 0.597170] driver_probe_device from __driver_attach_async_helper+0x50/0xd8 kern :warn : [ 0.597202] __driver_attach_async_helper from async_run_entry_fn+0x30/0x144 kern :warn : [ 0.597232] async_run_entry_fn from process_one_work+0x144/0x2cc kern :warn : [ 0.597261] process_one_work from worker_thread+0x18c/0x3b8 kern :warn : [ 0.597288] worker_thread from kthread+0x110/0x12c kern :warn : [ 0.597315] kthread from ret_from_fork+0x14/0x28
Quoted 8 lines
kern :warn : [ 0.597335] Exception stack(0xf08edfb0 to 0xf08edff8) kern :warn : [ 0.597350] dfa0: 00000000 00000000 00000000 00000000 kern :warn : [ 0.597364] dfc0: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 kern :warn : [ 0.597376] dfe0: 00000000 00000000 00000000 00000000 00000013 00000000 kern :info : [ 0.631336] mmc1: new high speed SDXC card at address 0001 kern :info : [ 0.632908] mmcblk1: mmc1:0001 SD64G 58.2 GiB kern :info : [ 0.642235] fec 2188000.ethernet eth0: registered PHC device 0 kern :info : [ 0.643162] imx_thermal 20c8000.anatop:tempmon: Industrial CPU temperature grade - max:105C critical:105C passive:95C
This warning happens on our tests for Apalis iMX6, and seems to come from the imx6_pcie_probe function in the pci-imx6.c driver. We found some instances of this happening on as early as 6.6.129. This went unnoticed until now, we're not sure when this started to happen.
Do you know what could be causing the duplicate file here?
Hello,
Quoted 10 lines
Quoted 10 lines
kern :info : [ 0.593597] pci 0000:01:00.0: BAR 4 [io 0x1000-0x101f]: assigned kern :info : [ 0.593629] pci 0000:01:00.0: BAR 0 [io 0x1020-0x1027]: assigned kern :info : [ 0.593660] pci 0000:01:00.0: BAR 2 [io 0x1028-0x102f]: assigned kern :info : [ 0.593692] pci 0000:01:00.0: BAR 1 [io 0x1030-0x1033]: assigned kern :info : [ 0.593722] pci 0000:01:00.0: BAR 3 [io 0x1034-0x1037]: assigned kern :info : [ 0.593753] pci 0000:00:00.0: PCI bridge to [bus 01-ff] kern :info : [ 0.593767] pci 0000:00:00.0: bridge window [io 0x1000-0x1fff] kern :info : [ 0.593781] pci 0000:00:00.0: bridge window [mem 0x01100000-0x011fffff] kern :info : [ 0.593795] pci 0000:00:00.0: bridge window [mem 0x01200000-0x012fffff pref] kern :warn : [ 0.593856] sysfs: cannot create duplicate filename '/devices/platform/soc/1ffc000.pcie/pci0000:00/0000:00:00.0/resource0'
[...]
This is a known issue you are seeing here manifesting itself. Given this specific error message.
Quoted 4 lines
This warning happens on our tests for Apalis iMX6, and seems to come from the
imx6_pcie_probefunction in thepci-imx6.cdriver. We found some instances of this happening on as early as 6.6.129. This went unnoticed until now, we're not sure when this started to happen.
Sorry you are having issues with this!
When you have a moment, consider changes from the following series:
https://git.kernel.org/pub/scm/linux/kernel/git/pci/pci.git/log/?h=sysfs
Test, and let us know if this fixes the problem for you.
I would appreciate if you could test this for us.
Quoted 1 line
Do you know what could be causing the duplicate file here?
The series cover letter has a bit of information about what is going on here, and why, see:
https://lore.kernel.org/linux-pci/[email protected]/#t
Hope this helps.
Thank you!
Krzysztof
Hello,
Quoted 7 lines
When you have a moment, consider changes from the following series:
https://git.kernel.org/pub/scm/linux/kernel/git/pci/pci.git/log/?h=sysfs
Test, and let us know if this fixes the problem for you.
I would appreciate if you could test this for us.
I realise that 6.6 is a bit of a far cry from changes against the upcoming 7.2 release, so you might have to massage the series/patches into sensible state, so to speak.
Let me know if testing is too involved, given the need to potentially backport a lot. I will think of something.
Thank you!
Krzysztof
Hello Krzysztof,
Quoted 6 lines
Quoted 6 lines
When you have a moment, consider changes from the following series:
https://git.kernel.org/pub/scm/linux/kernel/git/pci/pci.git/log/?h=sysfs
Test, and let us know if this fixes the problem for you.
Quoted 8 lines
Quoted 1 line
I would appreciate if you could test this for us.
I realise that 6.6 is a bit of a far cry from changes against the upcoming 7.2 release, so you might have to massage the series/patches into sensible state, so to speak.
Let me know if testing is too involved, given the need to potentially backport a lot. I will think of something.
I tried backporting the patches to do a test, but it turned out giving too many errors due to the different context. Since it's not really breaking anything, we'll leave it as it currently is.
Either way thanks a lot for clarifying this! It's good knowing the patches where this issue was addressed.
Leonardo
Hi!
Quoted 4 lines
This is the start of the stable review cycle for the 6.6.141 release. There are 508 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.
CIP testing did not find any problems here:
https://gitlab.com/cip-project/cip-testing/linux-stable-rc-ci/-/tree/linux-6.6.y
Best regards,
Pavel
Quoted 4 lines · Greg Kroah-Hartman
This is the start of the stable review cycle for the 6.6.141 release. There are 508 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.
Am 20.05.2026 um 18:17 schrieb Greg Kroah-Hartman:
Quoted 4 lines
This is the start of the stable review cycle for the 6.6.141 release. There are 508 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.
Builds, boots and works on my 2-socket Ivy Bridge Xeon E5-2697 v2 server. No dmesg oddities or regressions found.
Beste Grüße,
Peter Schneider
Signature · 8 lines
Climb the mountain not to plant your flag, but to embrace the challenge, enjoy the air and behold the view. Climb it so you can see the world, not so the world can see you. -- David McCullough Jr. OpenPGP: 0xA3828BD796CCE11A8CADE8866E3A92C92C3FF244 Download: https://www.peters-netzplatz.de/download/pschneider1968_pub.asc https://keys.mailvelope.com/pks/lookup?op=get&[email protected] https://keys.mailvelope.com/pks/lookup?op=get&[email protected]
Quoted 9 lines · Greg Kroah-Hartman
This is the start of the stable review cycle for the 6.6.141 release. There are 508 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.
Responses should be made by Fri, 22 May 2026 16:20:16 +0000. Anything received after that time might be too late.
The whole patch series can be found in one patch at:
Quoted 8 lines
https://www.kernel.org/pub/linux/kernel/v6.x/stable-review/patch-6.6.141-rc1.gzor in the git tree and branch at:
git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.gitlinux-6.6.y
and the diffstat can be found below.thanks,
greg k-h
The build fails on RISC-V RV64 with:
arch/riscv/net/bpf_jit_comp64.c: In function 'arch_prepare_bpf_trampoline':arch/riscv/net/bpf_jit_comp64.c:1064:9: error: implicit declaration of function 'bpf_flush_icache' [-Wimplicit-function-declaration] 1064 | bpf_flush_icache(ctx.insns, ctx.insns + ctx.ninsns);
| ^~~~~~~~~~~~~~~~
Reverting commit "bpf, riscv: Remove redundant bpf_flush_icache() after pack allocator finalize" commit id af7b502c916a4950d697b67f5e39c19cfeb5da4b resolves the issue.