4.14.279-rc1 review
Subsystems (4)
Greg Kroah-Hartman
maintainercover 4.14.279-rc1 review
This is the start of the stable review cycle for the 4.14.279 release. There are 14 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 Sun, 15 May 2022 14:22:19 +0000. Anything received after that time might be too late.
The whole patch series can be found in one patch at:
https://www.kernel.org/pub/linux/kernel/v4.x/stable-review/patch-4.14.279-rc1.gz
or in the git tree and branch at:
git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.git linux-4.14.y
and the diffstat can be found below.
thanks,
greg k-h
-------------
Pseudo-Shortlog of commits:
Greg Kroah-Hartman <[email protected]>
Linux 4.14.279-rc1
ChenXiaoSong <[email protected]>
VFS: Fix memory leak caused by concurrently mounting fs with subtype
Takashi Iwai <[email protected]>
ALSA: pcm: Fix potential AB/BA lock with buffer_mutex and mmap_lock
Takashi Iwai <[email protected]>
ALSA: pcm: Fix races among concurrent prealloc proc writes
Takashi Iwai <[email protected]>
ALSA: pcm: Fix races among concurrent prepare and hw_params/hw_free calls
Takashi Iwai <[email protected]>
ALSA: pcm: Fix races among concurrent read/write and buffer changes
Takashi Iwai <[email protected]>
ALSA: pcm: Fix races among concurrent hw_params and hw_free calls
Muchun Song <[email protected]>
mm: userfaultfd: fix missing cache flush in mcopy_atomic_pte() and __mcopy_atomic()
Muchun Song <[email protected]>
mm: hugetlb: fix missing cache flush in copy_huge_page_from_user()
Ricky WU <[email protected]>
mmc: rtsx: add 74 Clocks in power on flow
Itay Iellin <[email protected]>
Bluetooth: Fix the creation of hdev->name
Andreas Larsson <[email protected]>
can: grcan: only use the NAPI poll budget for RX
Andreas Larsson <[email protected]>
can: grcan: grcan_probe(): fix broken system id check for errata workaround needs
Lee Jones <[email protected]>
block: drbd: drbd_nl: Make conversion to 'enum drbd_ret_code' explicit
Nathan Chancellor <[email protected]>
MIPS: Use address-of operator on section symbols
-------------
Diffstat:
Makefile | 4 +- arch/mips/bmips/setup.c | 2 +- arch/mips/lantiq/prom.c | 2 +- arch/mips/pic32/pic32mzda/init.c | 2 +- arch/mips/ralink/of.c | 2 +- drivers/block/drbd/drbd_nl.c | 13 +++-- drivers/mmc/host/rtsx_pci_sdmmc.c | 30 +++++++---- drivers/net/can/grcan.c | 38 +++++++------ fs/namespace.c | 9 ++-- include/net/bluetooth/hci_core.h | 3 ++ include/sound/pcm.h | 2 + mm/memory.c | 2 + mm/userfaultfd.c | 3 ++ net/bluetooth/hci_core.c | 6 +-- sound/core/pcm.c | 3 ++ sound/core/pcm_lib.c | 5 ++ sound/core/pcm_memory.c | 11 ++-- sound/core/pcm_native.c | 110 +++++++++++++++++++++++++++----------- 18 files changed, 164 insertions(+), 83 deletions(-)
Greg Kroah-Hartman
maintainerPATCH 1/14 MIPS: Use address-of operator on section symbols
From: Nathan Chancellor <[email protected]>
commit d422c6c0644bccbb1ebeefffa51f35cec3019517 upstream.
When building xway_defconfig with clang:
arch/mips/lantiq/prom.c:82:23: error: array comparison always evaluates to true [-Werror,-Wtautological-compare]
else if (__dtb_start != __dtb_end)
^1 error generated.
These are not true arrays, they are linker defined symbols, which are just addresses. Using the address of operator silences the warning and does not change the resulting assembly with either clang/ld.lld or gcc/ld (tested with diff + objdump -Dr). Do the same thing across the entire MIPS subsystem to ensure there are no more warnings around this type of comparison.
--- arch/mips/bmips/setup.c | 2 +- arch/mips/lantiq/prom.c | 2 +- arch/mips/pic32/pic32mzda/init.c | 2 +- arch/mips/ralink/of.c | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-)
arch/mips/bmips/setup.c +1 -1
@@ -174,7 +174,7 @@ void __init plat_mem_setup(void) dtb =phys_to_virt (fw_arg2); else if (fw_passed_dtb) /* UHI interface */ dtb = (void *)fw_passed_dtb; - else if (__dtb_start != __dtb_end) + else if (&__dtb_start != &__dtb_end) dtb = (void *)__dtb_start; else panic("no dtb found");
arch/mips/lantiq/prom.c +1 -1
@@ -82,7 +82,7 @@ void __init plat_mem_setup(void)if (fw_passed_dtb)/* UHI interface */ dtb = (void *)fw_passed_dtb; -else if (__dtb_start != __dtb_end) +else if (&__dtb_start != &__dtb_end) dtb = (void *)__dtb_start;else panic ("no dtb found" );
arch/mips/pic32/pic32mzda/init.c +1 -1
@@ -36,7 +36,7 @@ static ulong get_fdtaddr(void)if (fw_passed_dtb && !fw_arg2 && !fw_arg3)return (ulong )fw_passed_dtb; -if (__dtb_start < __dtb_end) +if (&__dtb_start < &__dtb_end) ftaddr = (ulong )__dtb_start;return ftaddr;
arch/mips/ralink/of.c +1 -1
@@ -79,7 +79,7 @@ void __init plat_mem_setup(void)*/ if (fw_passed_dtb) dtb = (void *)fw_passed_dtb; -else if (__dtb_start != __dtb_end) +else if (&__dtb_start != &__dtb_end) dtb = (void *)__dtb_start;__dt_setup_arch (dtb);
Greg Kroah-Hartman
maintainerPATCH 2/14 block: drbd: drbd_nl: Make conversion to enum drbd_ret_code explicit
In reply to Greg Kroah-HartmanFrom: Lee Jones <[email protected]>
commit 1f1e87b4dc4598eac57a69868534b92d65e47e82 upstream.
Fixes the following W=1 kernel build warning(s):
from drivers/block/drbd/drbd_nl.c:24:
drivers/block/drbd/drbd_nl.c: In function ‘drbd_adm_set_role’:
drivers/block/drbd/drbd_nl.c:793:11: warning: implicit conversion from ‘enum drbd_state_rv’ to ‘enum drbd_ret_code’ [-Wenum-conversion] drivers/block/drbd/drbd_nl.c:795:11: warning: implicit conversion from ‘enum drbd_state_rv’ to ‘enum drbd_ret_code’ [-Wenum-conversion] drivers/block/drbd/drbd_nl.c: In function ‘drbd_adm_attach’:
drivers/block/drbd/drbd_nl.c:1965:10: warning: implicit conversion from ‘enum drbd_state_rv’ to ‘enum drbd_ret_code’ [-Wenum-conversion] drivers/block/drbd/drbd_nl.c: In function ‘drbd_adm_connect’:
drivers/block/drbd/drbd_nl.c:2690:10: warning: implicit conversion from ‘enum drbd_state_rv’ to ‘enum drbd_ret_code’ [-Wenum-conversion] drivers/block/drbd/drbd_nl.c: In function ‘drbd_adm_disconnect’:
drivers/block/drbd/drbd_nl.c:2803:11: warning: implicit conversion from ‘enum drbd_state_rv’ to ‘enum drbd_ret_code’ [-Wenum-conversion]
--- drivers/block/drbd/drbd_nl.c | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-)
drivers/block/drbd/drbd_nl.c +8 -5
@@ -774,9 +774,11 @@ int drbd_adm_set_role(struct sk_buff *skmutex_lock (&adm_ctx.resource->adm_mutex);if (info->genlhdr->cmd ==DRBD_ADM_PRIMARY ) - retcode =drbd_set_role (adm_ctx.device,R_PRIMARY , parms.assume_uptodate); + retcode = (enum drbd_ret_code )drbd_set_role (adm_ctx.device, +R_PRIMARY , parms.assume_uptodate);else - retcode =drbd_set_role (adm_ctx.device,R_SECONDARY ,0 ); + retcode = (enum drbd_ret_code )drbd_set_role (adm_ctx.device, +R_SECONDARY ,0 );mutex_unlock (&adm_ctx.resource->adm_mutex);genl_lock ();
@@ -1941,7 +1943,7 @@ int drbd_adm_attach(struct sk_buff *skb,drbd_flush_workqueue (&connection->sender_work); rv =_drbd_request_state (device,NS (disk,D_ATTACHING ),CS_VERBOSE ); - retcode = rv;/* FIXME: Type mismatch. */ + retcode = (enum drbd_ret_code )rv;drbd_resume_io (device);if (rv <SS_SUCCESS ) goto fail;
@@ -2671,7 +2673,8 @@ int drbd_adm_connect(struct sk_buff *skb }rcu_read_unlock (); - retcode =conn_request_state (connection,NS (conn,C_UNCONNECTED ),CS_VERBOSE ); + retcode = (enum drbd_ret_code )conn_request_state (connection, +NS (conn,C_UNCONNECTED ),CS_VERBOSE );conn_reconfig_done (connection);mutex_unlock (&adm_ctx.resource->adm_mutex);
@@ -2777,7 +2780,7 @@ int drbd_adm_disconnect(struct sk_buff *mutex_lock (&adm_ctx.resource->adm_mutex); rv =conn_try_disconnect (connection, parms.force_disconnect);if (rv <SS_SUCCESS ) - retcode = rv;/* FIXME: Type mismatch. */ + retcode = (enum drbd_ret_code )rv;else retcode =NO_ERROR ;mutex_unlock (&adm_ctx.resource->adm_mutex);
Greg Kroah-Hartman
maintainerPATCH 3/14 can: grcan: grcan_probe(): fix broken system id check for errata workaround needs
In reply to Greg Kroah-HartmanFrom: Andreas Larsson <[email protected]>
commit 1e93ed26acf03fe6c97c6d573a10178596aadd43 upstream.
The systemid property was checked for in the wrong place of the device tree and compared to the wrong value.
--- drivers/net/can/grcan.c | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-)
drivers/net/can/grcan.c +11 -5
@@ -245,7 +245,7 @@ struct grcan_device_config { .rxsize = GRCAN_DEFAULT_BUFFER_SIZE, \ } -#define GRCAN_TXBUG_SAFE_GRLIB_VERSION 0x4100 +#define GRCAN_TXBUG_SAFE_GRLIB_VERSION 4100#define GRLIB_VERSION_MASK 0xffff/* GRCAN private data structure */
@@ -1665,6 +1665,7 @@ exit_free_candev:static int grcan_probe (struct platform_device *ofdev) {struct device_node *np = ofdev->dev.of_node; +struct device_node *sysid_parent;struct resource *res;u32 sysid, ambafreq;int irq, err;
@@ -1674,10 +1675,15 @@ static int grcan_probe(struct platform_d/* Compare GRLIB version number with the first that does not * have the tx bug (see start_xmit) */ - err =of_property_read_u32 (np,"systemid" , &sysid); -if (!err && ((sysid &GRLIB_VERSION_MASK ) - >=GRCAN_TXBUG_SAFE_GRLIB_VERSION )) - txbug = false; + sysid_parent =of_find_node_by_path ("/ambapp0" ); +if (sysid_parent) { +of_node_get (sysid_parent); + err =of_property_read_u32 (sysid_parent,"systemid" , &sysid); +if (!err && ((sysid &GRLIB_VERSION_MASK ) >= +GRCAN_TXBUG_SAFE_GRLIB_VERSION )) + txbug = false; +of_node_put (sysid_parent); + } err =of_property_read_u32 (np,"freq" , &ambafreq);if (err) {
Greg Kroah-Hartman
maintainerPATCH 4/14 can: grcan: only use the NAPI poll budget for RX
In reply to Greg Kroah-HartmanFrom: Andreas Larsson <[email protected]>
commit 2873d4d52f7c52d60b316ba6c47bd7122b5a9861 upstream.
The previous split budget between TX and RX made it return not using the entire budget but at the same time not having calling called napi_complete. This sometimes led to the poll to not be called, and at the same time having TX and RX interrupts disabled resulting in the driver getting stuck.
--- drivers/net/can/grcan.c | 22 +++++++--------------- 1 file changed, 7 insertions(+), 15 deletions(-)
drivers/net/can/grcan.c +7 -15
@@ -1141,7 +1141,7 @@ static int grcan_close(struct net_devicereturn 0 ; } -static int grcan_transmit_catch_up (struct net_device *dev,int budget) +static void grcan_transmit_catch_up (struct net_device *dev) {struct grcan_priv *priv =netdev_priv (dev);unsigned long flags;
@@ -1149,7 +1149,7 @@ static int grcan_transmit_catch_up(strucspin_lock_irqsave (&priv->lock, flags); - work_done =catch_up_echo_skb (dev, budget, true); + work_done =catch_up_echo_skb (dev,-1 , true);if (work_done) {if (!priv->resetting && !priv->closing && !(priv->can.ctrlmode &CAN_CTRLMODE_LISTENONLY ))
@@ -1163,8 +1163,6 @@ static int grcan_transmit_catch_up(struc }spin_unlock_irqrestore (&priv->lock, flags); - -return work_done; }static int grcan_receive (struct net_device *dev,int budget)
@@ -1246,19 +1244,13 @@ static int grcan_poll(struct napi_structstruct net_device *dev = priv->dev;struct grcan_registers __iomem *regs = priv->regs;unsigned long flags; -int tx_work_done, rx_work_done; -int rx_budget = budget /2 ; -int tx_budget = budget - rx_budget; +int work_done; -/* Half of the budget for receiveing messages */ - rx_work_done =grcan_receive (dev, rx_budget); + work_done =grcan_receive (dev, budget); -/* Half of the budget for transmitting messages as that can trigger echo -* frames being received -*/ - tx_work_done =grcan_transmit_catch_up (dev, tx_budget); +grcan_transmit_catch_up (dev); -if (rx_work_done < rx_budget && tx_work_done < tx_budget) { +if (work_done < budget) {napi_complete (napi);/* Guarantee no interference with a running reset that otherwise
@@ -1275,7 +1267,7 @@ static int grcan_poll(struct napi_structspin_unlock_irqrestore (&priv->lock, flags); } -return rx_work_done + tx_work_done; +return work_done; }/* Work tx bug by waiting while for the risky situation to clear. If that fails,
Greg Kroah-Hartman
maintainerPATCH 5/14 Bluetooth: Fix the creation of hdev->name
In reply to Greg Kroah-HartmanFrom: Itay Iellin <[email protected]>
commit 103a2f3255a95991252f8f13375c3a96a75011cd upstream.
Set a size limit of 8 bytes of the written buffer to "hdev->name" including the terminating null byte, as the size of "hdev->name" is 8 bytes. If an id value which is greater than 9999 is allocated, then the "snprintf(hdev->name, sizeof(hdev->name), "hci%d", id)" function call would lead to a truncation of the id value in decimal notation.
Set an explicit maximum id parameter in the id allocation function call. The id allocation function defines the maximum allocated id value as the maximum id parameter value minus one. Therefore, HCI_MAX_ID is defined as 10000.
--- include/net/bluetooth/hci_core.h | 3 +++ net/bluetooth/hci_core.c | 6 +++--- 2 files changed, 6 insertions(+), 3 deletions(-)
include/net/bluetooth/hci_core.h +3 -0
@@ -34,6 +34,9 @@/* HCI priority */ #define HCI_PRIO_MAX 7 +/* HCI maximum id value */ +#define HCI_MAX_ID 10000 +/* HCI Core structures */ struct inquiry_data {bdaddr_t bdaddr;
net/bluetooth/hci_core.c +3 -3
@@ -3100,10 +3100,10 @@ int hci_register_dev(struct hci_dev *hde*/ switch (hdev->dev_type) {case HCI_PRIMARY : - id =ida_simple_get (&hci_index_ida,0 ,0 ,GFP_KERNEL ); + id =ida_simple_get (&hci_index_ida,0 ,HCI_MAX_ID ,GFP_KERNEL );break ;case HCI_AMP : - id =ida_simple_get (&hci_index_ida,1 ,0 ,GFP_KERNEL ); + id =ida_simple_get (&hci_index_ida,1 ,HCI_MAX_ID ,GFP_KERNEL );break ;default :return -EINVAL ;
@@ -3112,7 +3112,7 @@ int hci_register_dev(struct hci_dev *hdeif (id <0 )return id; -sprintf (hdev->name,"hci%d" , id); +snprintf (hdev->name,sizeof (hdev->name),"hci%d" , id); hdev->id = id;BT_DBG ("%p name %s bus %d" , hdev, hdev->name, hdev->bus);
Greg Kroah-Hartman
maintainerPATCH 6/14 mmc: rtsx: add 74 Clocks in power on flow
In reply to Greg Kroah-HartmanFrom: Ricky WU <[email protected]>
commit 1f311c94aabdb419c28e3147bcc8ab89269f1a7e upstream.
SD spec definition:
"Host provides at least 74 Clocks before issuing first command" After 1ms for the voltage stable then start issuing the Clock signals
if POWER STATE isMMC_POWER_OFF to MMC_POWER_UP to issue Clock signal to card MMC_POWER_UP to MMC_POWER_ON to stop issuing signal to card
--- drivers/mmc/host/rtsx_pci_sdmmc.c | 30 ++++++++++++++++++++---------- 1 file changed, 20 insertions(+), 10 deletions(-)
drivers/mmc/host/rtsx_pci_sdmmc.c +20 -10
@@ -49,10 +49,7 @@ struct realtek_pci_sdmmc {bool double_clk;bool eject;bool initial_mode; -int power_state; -#define SDMMC_POWER_ON 1 -#define SDMMC_POWER_OFF 0 - +int prev_power_state;int sg_count;s32 cookie;int cookie_sg_count;
@@ -913,14 +910,21 @@ static int sd_set_bus_width(struct realtreturn err; } -static int sd_power_on (struct realtek_pci_sdmmc *host) +static int sd_power_on (struct realtek_pci_sdmmc *host,unsigned char power_mode) {struct rtsx_pcr *pcr = host->pcr;int err; -if (host->power_state ==SDMMC_POWER_ON ) +if (host->prev_power_state ==MMC_POWER_ON )return 0 ; +if (host->prev_power_state ==MMC_POWER_UP ) { +rtsx_pci_write_register (pcr,SD_BUS_STAT ,SD_CLK_TOGGLE_EN ,0 ); + goto finish; + } + +msleep (100 ); +rtsx_pci_init_cmd (pcr);rtsx_pci_add_cmd (pcr,WRITE_REG_CMD ,CARD_SELECT ,0x07 ,SD_MOD_SEL ); rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, CARD_SHARE_MODE,
@@ -939,11 +943,17 @@ static int sd_power_on(struct realtek_pcif (err <0 )return err; +mdelay (1 ); + err =rtsx_pci_write_register (pcr,CARD_OE ,SD_OUTPUT_EN ,SD_OUTPUT_EN );if (err <0 )return err; - host->power_state =SDMMC_POWER_ON ; +/* send at least 74 clocks */ +rtsx_pci_write_register (pcr,SD_BUS_STAT ,SD_CLK_TOGGLE_EN ,SD_CLK_TOGGLE_EN ); + +finish: + host->prev_power_state = power_mode;return 0 ; }
@@ -952,7 +962,7 @@ static int sd_power_off(struct realtek_pstruct rtsx_pcr *pcr = host->pcr;int err; - host->power_state =SDMMC_POWER_OFF ; + host->prev_power_state =MMC_POWER_OFF ;rtsx_pci_init_cmd (pcr);
@@ -978,7 +988,7 @@ static int sd_set_power_mode(struct realif (power_mode ==MMC_POWER_OFF ) err =sd_power_off (host);else - err =sd_power_on (host); + err =sd_power_on (host, power_mode);return err; }
@@ -1416,7 +1426,7 @@ static int rtsx_pci_sdmmc_drv_probe(stru host->mmc = mmc; host->pdev = pdev; host->cookie =-1 ; - host->power_state =SDMMC_POWER_OFF ; + host->prev_power_state =MMC_POWER_OFF ;INIT_WORK (&host->work, sd_request);platform_set_drvdata (pdev, host); pcr->slots[RTSX_SD_CARD ].p_dev = pdev;
Greg Kroah-Hartman
maintainerPATCH 7/14 mm: hugetlb: fix missing cache flush in copy_huge_page_from_user()
In reply to Greg Kroah-HartmanFrom: Muchun Song <[email protected]>
commit e763243cc6cb1fcc720ec58cfd6e7c35ae90a479 upstream.
userfaultfd calls copy_huge_page_from_user() which does not do any cache flushing for the target page. Then the target page will be mapped to the user space with a different address (user address), which might have an alias issue with the kernel address used to copy the data from the user to.
Fix this issue by flushing dcache in copy_huge_page_from_user().
--- mm/memory.c | 2 ++ 1 file changed, 2 insertions(+)
mm/memory.c +2 -0
@@ -4836,6 +4836,8 @@ long copy_huge_page_from_user(struct pagif (rc)break ; +flush_dcache_page (subpage); +cond_resched (); }return ret_val;
Greg Kroah-Hartman
maintainerPATCH 8/14 mm: userfaultfd: fix missing cache flush in mcopy_atomic_pte() and __mcopy_atomic()
In reply to Greg Kroah-HartmanFrom: Muchun Song <[email protected]>
commit 7c25a0b89a487878b0691e6524fb5a8827322194 upstream.
userfaultfd calls mcopy_atomic_pte() and __mcopy_atomic() which do not do any cache flushing for the target page. Then the target page will be mapped to the user space with a different address (user address), which might have an alias issue with the kernel address used to copy the data from the user to. Fix this by insert flush_dcache_page() after copy_from_user() succeeds.
--- mm/userfaultfd.c | 3 +++ 1 file changed, 3 insertions(+)
mm/userfaultfd.c +3 -0
@@ -56,6 +56,8 @@ static int mcopy_atomic_pte(struct mm_st/* don't free the page */ goto out; } + +flush_dcache_page (page); }else { page = *pagep; *pagep =NULL ;
@@ -565,6 +567,7 @@ retry: err = -EFAULT ; goto out; } +flush_dcache_page (page); goto retry; }else BUG_ON (page);
Greg Kroah-Hartman
maintainerPATCH 9/14 ALSA: pcm: Fix races among concurrent hw_params and hw_free calls
In reply to Greg Kroah-HartmanFrom: Takashi Iwai <[email protected]>
commit 92ee3c60ec9fe64404dc035e7c41277d74aa26cb upstream.
Currently we have neither proper check nor protection against the concurrent calls of PCM hw_params and hw_free ioctls, which may result in a UAF. Since the existing PCM stream lock can't be used for protecting the whole ioctl operations, we need a new mutex to protect those racy calls.
This patch introduced a new mutex, runtime->buffer_mutex, and applies it to both hw_params and hw_free ioctl code paths. Along with it, the both functions are slightly modified (the mmap_count check is moved into the state-check block) for code simplicity.
--- include/sound/pcm.h | 1 sound/core/pcm.c | 2 + sound/core/pcm_native.c | 55 +++++++++++++++++++++++++++++++----------------- 3 files changed, 39 insertions(+), 19 deletions(-)
include/sound/pcm.h +1 -0
@@ -396,6 +396,7 @@ struct snd_pcm_runtime {wait_queue_head_t sleep;/* poll sleep */ wait_queue_head_t tsleep;/* transfer sleep */ struct fasync_struct *fasync; +struct mutex buffer_mutex;/* protect for buffer changes */ /* -- private section -- */ void *private_data;
sound/core/pcm.c +2 -0
@@ -1032,6 +1032,7 @@ int snd_pcm_attach_substream(struct snd_init_waitqueue_head (&runtime->tsleep); runtime->status->state =SNDRV_PCM_STATE_OPEN ; +mutex_init (&runtime->buffer_mutex); substream->runtime = runtime; substream->private_data = pcm->private_data;
@@ -1063,6 +1064,7 @@ void snd_pcm_detach_substream(struct snd substream->runtime =NULL ;if (substream->timer)spin_unlock_irq (&substream->timer->lock); +mutex_destroy (&runtime->buffer_mutex);kfree (runtime);put_pid (substream->pid); substream->pid =NULL ;
sound/core/pcm_native.c +36 -19
105 lines not on this page · raw message
Greg Kroah-Hartman
maintainerPATCH 10/14 ALSA: pcm: Fix races among concurrent read/write and buffer changes
In reply to Greg Kroah-HartmanFrom: Takashi Iwai <[email protected]>
commit dca947d4d26dbf925a64a6cfb2ddbc035e831a3d upstream.
In the current PCM design, the read/write syscalls (as well as the equivalent ioctls) are allowed before the PCM stream is running, that is, at PCM PREPARED state. Meanwhile, we also allow to re-issue hw_params and hw_free ioctl calls at the PREPARED state that may change or free the buffers, too. The problem is that there is no protection against those mix-ups.
This patch applies the previously introduced runtime->buffer_mutex to the read/write operations so that the concurrent hw_params or hw_free call can no longer interfere during the operation. The mutex is unlocked before scheduling, so we don't take it too long.
--- sound/core/pcm_lib.c | 4 ++++ 1 file changed, 4 insertions(+)
sound/core/pcm_lib.c +4 -0
@@ -1878,9 +1878,11 @@ static int wait_for_avail(struct snd_pcmif (avail >= runtime->twake)break ;snd_pcm_stream_unlock_irq (substream); +mutex_unlock (&runtime->buffer_mutex); tout =schedule_timeout (wait_time); +mutex_lock (&runtime->buffer_mutex);snd_pcm_stream_lock_irq (substream);set_current_state (TASK_INTERRUPTIBLE );switch (runtime->status->state) {
@@ -2174,6 +2176,7 @@ snd_pcm_sframes_t __snd_pcm_lib_xfer(str nonblock = !!(substream->f_flags &O_NONBLOCK ); +mutex_lock (&runtime->buffer_mutex);snd_pcm_stream_lock_irq (substream); err =pcm_accessible_state (runtime);if (err <0 )
@@ -2259,6 +2262,7 @@ snd_pcm_sframes_t __snd_pcm_lib_xfer(strif (xfer >0 && err >=0 )snd_pcm_update_state (substream, runtime);snd_pcm_stream_unlock_irq (substream); +mutex_unlock (&runtime->buffer_mutex);return xfer >0 ? (snd_pcm_sframes_t )xfer : err; }EXPORT_SYMBOL (__snd_pcm_lib_xfer);
Greg Kroah-Hartman
maintainerPATCH 11/14 ALSA: pcm: Fix races among concurrent prepare and hw_params/hw_free calls
In reply to Greg Kroah-HartmanFrom: Takashi Iwai <[email protected]>
commit 3c3201f8c7bb77eb53b08a3ca8d9a4ddc500b4c0 upstream.
Like the previous fixes to hw_params and hw_free ioctl races, we need to paper over the concurrent prepare ioctl calls against hw_params and hw_free, too.
This patch implements the locking with the existing runtime->buffer_mutex for prepare ioctls. Unlike the previous case for snd_pcm_hw_hw_params() and snd_pcm_hw_free(), snd_pcm_prepare() is performed to the linked streams, hence the lock can't be applied simply on the top. For tracking the lock in each linked substream, we modify snd_pcm_action_group() slightly and apply the buffer_mutex for the case stream_lock=false (formerly there was no lock applied) there.
--- sound/core/pcm_native.c | 32 ++++++++++++++++++-------------- 1 file changed, 18 insertions(+), 14 deletions(-)
sound/core/pcm_native.c +18 -14
@@ -1046,15 +1046,17 @@ struct action_ops {*/ static int snd_pcm_action_group (const struct action_ops *ops,struct snd_pcm_substream *substream, -int state,int do_lock) +int state,int stream_lock) {struct snd_pcm_substream *s =NULL ;struct snd_pcm_substream *s1;int res =0 , depth =1 ;snd_pcm_group_for_each_entry (s, substream) { -if (do_lock && s != substream) { -if (s->pcm->nonatomic) +if (s != substream) { +if (!stream_lock) +mutex_lock_nested (&s->runtime->buffer_mutex, depth); +else if (s->pcm->nonatomic)mutex_lock_nested (&s->self_group.mutex, depth);else spin_lock_nested (&s->self_group.lock, depth);
@@ -1082,18 +1084,18 @@ static int snd_pcm_action_group(const st ops->post_action (s, state); } _unlock: -if (do_lock) { -/* unlock streams */ -snd_pcm_group_for_each_entry (s1, substream) { -if (s1 != substream) { -if (s1->pcm->nonatomic) -mutex_unlock (&s1->self_group.mutex); -else -spin_unlock (&s1->self_group.lock); - } -if (s1 == s)/* end */ -break ; +/* unlock streams */ +snd_pcm_group_for_each_entry (s1, substream) { +if (s1 != substream) { +if (!stream_lock) +mutex_unlock (&s1->runtime->buffer_mutex); +else if (s1->pcm->nonatomic) +mutex_unlock (&s1->self_group.mutex); +else +spin_unlock (&s1->self_group.lock); } +if (s1 == s)/* end */ +break ; }return res; }
@@ -1174,10 +1176,12 @@ static int snd_pcm_action_nonatomic(consint res;down_read (&snd_pcm_link_rwsem); +mutex_lock (&substream->runtime->buffer_mutex);if (snd_pcm_stream_linked (substream)) res =snd_pcm_action_group (ops, substream, state,0 );else res =snd_pcm_action_single (ops, substream, state); +mutex_unlock (&substream->runtime->buffer_mutex);up_read (&snd_pcm_link_rwsem);return res; }
Greg Kroah-Hartman
maintainerPATCH 12/14 ALSA: pcm: Fix races among concurrent prealloc proc writes
In reply to Greg Kroah-HartmanFrom: Takashi Iwai <[email protected]>
commit 69534c48ba8ce552ce383b3dfdb271ffe51820c3 upstream.
We have no protection against concurrent PCM buffer preallocation changes via proc files, and it may potentially lead to UAF or some weird problem. This patch applies the PCM open_mutex to the proc write operation for avoiding the racy proc writes and the PCM stream open (and further operations).
--- sound/core/pcm_memory.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-)
sound/core/pcm_memory.c +7 -4
@@ -160,19 +160,20 @@ static void snd_pcm_lib_preallocate_procsize_t size;struct snd_dma_buffer new_dmab; +mutex_lock (&substream->pcm->open_mutex);if (substream->runtime) { buffer->error = -EBUSY ; -return ; + goto unlock; }if (!snd_info_get_line (buffer, line,sizeof (line))) {snd_info_get_str (str, line,sizeof (str)); size =simple_strtoul (str,NULL ,10 ) *1024 ;if ((size !=0 && size <8192 ) || size > substream->dma_max) { buffer->error = -EINVAL ; -return ; + goto unlock; }if (substream->dma_buffer.bytes == size) -return ; + goto unlock;memset (&new_dmab,0 ,sizeof (new_dmab)); new_dmab.dev = substream->dma_buffer.dev;if (size >0 ) {
@@ -180,7 +181,7 @@ static void snd_pcm_lib_preallocate_proc substream->dma_buffer.dev.dev, size, &new_dmab) < 0) { buffer->error = -ENOMEM ; -return ; + goto unlock; } substream->buffer_bytes_max = size; }else {
@@ -192,6 +193,8 @@ static void snd_pcm_lib_preallocate_proc }else { buffer->error = -EINVAL ; } + unlock: +mutex_unlock (&substream->pcm->open_mutex); }static inline void preallocate_info_init (struct snd_pcm_substream *substream)
Greg Kroah-Hartman
maintainerPATCH 13/14 ALSA: pcm: Fix potential AB/BA lock with buffer_mutex and mmap_lock
In reply to Greg Kroah-HartmanFrom: Takashi Iwai <[email protected]>
commit bc55cfd5718c7c23e5524582e9fa70b4d10f2433 upstream.
syzbot caught a potential deadlock between the PCM runtime->buffer_mutex and the mm->mmap_lock. It was brought by the recent fix to cover the racy read/write and other ioctls, and in that commit, I overlooked a (hopefully only) corner case that may take the revert lock, namely, the OSS mmap. The OSS mmap operation exceptionally allows to re-configure the parameters inside the OSS mmap syscall, where mm->mmap_mutex is already held. Meanwhile, the copy_from/to_user calls at read/write operations also take the mm->mmap_lock internally, hence it may lead to a AB/BA deadlock.
A similar problem was already seen in the past and we fixed it with a refcount (in commit b248371628aa). The former fix covered only the call paths with OSS read/write and OSS ioctls, while we need to cover the concurrent access via both ALSA and OSS APIs now.
This patch addresses the problem above by replacing the buffer_mutex lock in the read/write operations with a refcount similar as we've used for OSS. The new field, runtime->buffer_accessing, keeps the number of concurrent read/write operations. Unlike the former buffer_mutex protection, this protects only around the copy_from/to_user() calls; the other codes are basically protected by the PCM stream lock. The refcount can be a negative, meaning blocked by the ioctls. If a negative value is seen, the read/write aborts with -EBUSY. In the ioctl side, OTOH, they check this refcount, too, and set to a negative value for blocking unless it's already being accessed.
--- include/sound/pcm.h | 1 + sound/core/pcm.c | 1 + sound/core/pcm_lib.c | 9 +++++---- sound/core/pcm_native.c | 39 ++++++++++++++++++++++++++++++++------- 4 files changed, 39 insertions(+), 11 deletions(-)
include/sound/pcm.h +1 -0
@@ -397,6 +397,7 @@ struct snd_pcm_runtime {wait_queue_head_t tsleep;/* transfer sleep */ struct fasync_struct *fasync;struct mutex buffer_mutex;/* protect for buffer changes */ +atomic_t buffer_accessing;/* >0: in r/w operation, <0: blocked */ /* -- private section -- */ void *private_data;
sound/core/pcm.c +1 -0
@@ -1033,6 +1033,7 @@ int snd_pcm_attach_substream(struct snd_ runtime->status->state =SNDRV_PCM_STATE_OPEN ;mutex_init (&runtime->buffer_mutex); +atomic_set (&runtime->buffer_accessing,0 ); substream->runtime = runtime; substream->private_data = pcm->private_data;
sound/core/pcm_lib.c +5 -4
@@ -1878,11 +1878,9 @@ static int wait_for_avail(struct snd_pcmif (avail >= runtime->twake)break ;snd_pcm_stream_unlock_irq (substream); -mutex_unlock (&runtime->buffer_mutex); tout =schedule_timeout (wait_time); -mutex_lock (&runtime->buffer_mutex);snd_pcm_stream_lock_irq (substream);set_current_state (TASK_INTERRUPTIBLE );switch (runtime->status->state) {
@@ -2176,7 +2174,6 @@ snd_pcm_sframes_t __snd_pcm_lib_xfer(str nonblock = !!(substream->f_flags &O_NONBLOCK ); -mutex_lock (&runtime->buffer_mutex);snd_pcm_stream_lock_irq (substream); err =pcm_accessible_state (runtime);if (err <0 )
@@ -2229,10 +2226,15 @@ snd_pcm_sframes_t __snd_pcm_lib_xfer(strsnd_pcm_stream_unlock_irq (substream);return -EINVAL ; } +if (!atomic_inc_unless_negative (&runtime->buffer_accessing)) { + err = -EBUSY ; + goto _end_unlock; + }snd_pcm_stream_unlock_irq (substream); err =writer (substream, appl_ofs, data, offset, frames, transfer);snd_pcm_stream_lock_irq (substream); +atomic_dec (&runtime->buffer_accessing);if (err <0 ) goto _end_unlock; err =pcm_accessible_state (runtime);
@@ -2262,7 +2264,6 @@ snd_pcm_sframes_t __snd_pcm_lib_xfer(strif (xfer >0 && err >=0 )snd_pcm_update_state (substream, runtime);snd_pcm_stream_unlock_irq (substream); -mutex_unlock (&runtime->buffer_mutex);return xfer >0 ? (snd_pcm_sframes_t )xfer : err; }EXPORT_SYMBOL (__snd_pcm_lib_xfer);
sound/core/pcm_native.c +32 -7
@@ -634,6 +634,24 @@ static int snd_pcm_hw_params_choose(strureturn 0 ; } +/* acquire buffer_mutex; if it's in r/w operation, return -EBUSY, otherwise +* block the further r/w operations +*/ +static int snd_pcm_buffer_access_lock (struct snd_pcm_runtime *runtime) +{ +if (!atomic_dec_unless_positive (&runtime->buffer_accessing)) +return -EBUSY ; +mutex_lock (&runtime->buffer_mutex); +return 0 ;/* keep buffer_mutex, unlocked by below */ +} + +/* release buffer_mutex and clear r/w access flag */ +static void snd_pcm_buffer_access_unlock (struct snd_pcm_runtime *runtime) +{ +mutex_unlock (&runtime->buffer_mutex); +atomic_inc (&runtime->buffer_accessing); +} +#if IS_ENABLED (CONFIG_SND_PCM_OSS )#define is_oss_stream (substream) ((substream)->oss.oss)#else
@@ -644,14 +662,16 @@ static int snd_pcm_hw_params(struct snd_ struct snd_pcm_hw_params *params) {struct snd_pcm_runtime *runtime; -int err =0 , usecs; +int err, usecs;unsigned int bits;snd_pcm_uframes_t frames;if (PCM_RUNTIME_CHECK (substream))return -ENXIO ; runtime = substream->runtime; -mutex_lock (&runtime->buffer_mutex); + err =snd_pcm_buffer_access_lock (runtime); +if (err <0 ) +return err;snd_pcm_stream_lock_irq (substream);switch (runtime->status->state) {case SNDRV_PCM_STATE_OPEN :
@@ -756,7 +776,7 @@ static int snd_pcm_hw_params(struct snd_ substream->ops->hw_free (substream); } unlock: -mutex_unlock (&runtime->buffer_mutex); +snd_pcm_buffer_access_unlock (runtime);return err; }
@@ -789,7 +809,9 @@ static int snd_pcm_hw_free(struct snd_pcif (PCM_RUNTIME_CHECK (substream))return -ENXIO ; runtime = substream->runtime; -mutex_lock (&runtime->buffer_mutex); + result =snd_pcm_buffer_access_lock (runtime); +if (result <0 ) +return result;snd_pcm_stream_lock_irq (substream);switch (runtime->status->state) {case SNDRV_PCM_STATE_SETUP :
@@ -809,7 +831,7 @@ static int snd_pcm_hw_free(struct snd_pcsnd_pcm_set_state (substream,SNDRV_PCM_STATE_OPEN );pm_qos_remove_request (&substream->latency_pm_qos_req); unlock: -mutex_unlock (&runtime->buffer_mutex); +snd_pcm_buffer_access_unlock (runtime);return result; }
@@ -1176,12 +1198,15 @@ static int snd_pcm_action_nonatomic(consint res;down_read (&snd_pcm_link_rwsem); -mutex_lock (&substream->runtime->buffer_mutex); + res =snd_pcm_buffer_access_lock (substream->runtime); +if (res <0 ) + goto unlock;if (snd_pcm_stream_linked (substream)) res =snd_pcm_action_group (ops, substream, state,0 );else res =snd_pcm_action_single (ops, substream, state); -mutex_unlock (&substream->runtime->buffer_mutex); +snd_pcm_buffer_access_unlock (substream->runtime); + unlock:up_read (&snd_pcm_link_rwsem);return res; }
Greg Kroah-Hartman
maintainerPATCH 14/14 VFS: Fix memory leak caused by concurrently mounting fs with subtype
In reply to Greg Kroah-HartmanFrom: ChenXiaoSong <[email protected]>
If two processes mount same superblock, memory leak occurs:
CPU0 | CPU1
do_new_mount | do_new_mount
fs_set_subtype | fs_set_subtype
kstrdup |
| kstrdup
memrory leak |The following reproducer triggers the problem:
1. shell command: mount -t ntfs /dev/sda1 /mnt &
2. c program: mount("/dev/sda1", "/mnt", "fuseblk", 0, "...")
with kmemleak report being along the lines of
unreferenced object 0xffff888235f1a5c0 (size 8):
comm "mount.ntfs", pid 2860, jiffies 4295757824 (age 43.423s) hex dump (first 8 bytes):
00 a5 f1 35 82 88 ff ff ...5....
backtrace:
[<00000000656e30cc>] __kmalloc_track_caller+0x16e/0x430
[<000000008e591727>] kstrdup+0x3e/0x90
[<000000008430d12b>] do_mount.cold+0x7b/0xd9
[<0000000078d639cd>] ksys_mount+0xb2/0x150
[<000000006015988d>] __x64_sys_mount+0x29/0x40
[<00000000e0a7c118>] do_syscall_64+0xc1/0x1d0
[<00000000bcea7df5>] entry_SYSCALL_64_after_hwframe+0x44/0xa9
[<00000000803a4067>] 0xffffffffffffffffLinus's tree already have refactoring patchset [1], one of them can fix this bug:
c30da2e981a7 ("fuse: convert to use the new mount API")
After refactoring, init super_block->s_subtype in fuse_fill_super.
Since we did not merge the refactoring patchset in this branch, I create this patch. This patch fix this by adding a write lock while calling fs_set_subtype.
[1] https://patchwork.kernel.org/project/linux-fsdevel/patch/[email protected]/
---
v1: Can not mount sshfs ([PATCH linux-4.19.y] VFS: Fix fuseblk memory leak caused by mount concurrency)
v2: Use write lock while writing superblock ([PATCH 4.19,v2] VFS: Fix fuseblk memory leak caused by mount concurrency)
v3: Update commit message
fs/namespace.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-)
fs/namespace.c +6 -3
@@ -2570,9 +2570,12 @@ static int do_new_mount(struct path *patreturn -ENODEV ; mnt =vfs_kern_mount (type, sb_flags, name, data); -if (!IS_ERR (mnt) && (type->fs_flags &FS_HAS_SUBTYPE ) && - !mnt->mnt_sb->s_subtype) - mnt =fs_set_subtype (mnt, fstype); +if (!IS_ERR (mnt) && (type->fs_flags &FS_HAS_SUBTYPE )) { +down_write (&mnt->mnt_sb->s_umount); +if (!mnt->mnt_sb->s_subtype) + mnt =fs_set_subtype (mnt, fstype); +up_write (&mnt->mnt_sb->s_umount); + }put_filesystem (type);if (IS_ERR (mnt))
Quoted 9 lines · Greg Kroah-Hartman
This is the start of the stable review cycle for the 4.14.279 release. There are 14 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 Sun, 15 May 2022 14:22:19 +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/v4.x/stable-review/patch-4.14.279-rc1.gzor in the git tree and branch at:
git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.gitlinux-4.14.y
and the diffstat can be found below.thanks,
greg k-h
All tests passing for Tegra ...
Test results for stable-v4.14:
8 builds: 8 pass, 0 fail
16 boots: 16 pass, 0 fail
32 tests: 32 pass, 0 failLinux version: 4.14.279-rc1-g4477341b2b19
Boards tested: tegra124-jetson-tk1, tegra20-ventana,
tegra210-p2371-2180, tegra30-cardhu-a04
Jon
Quoted 8 lines · Greg Kroah-Hartman
This is the start of the stable review cycle for the 4.14.279 release. There are 14 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 Sun, 15 May 2022 14:22:19 +0000. Anything received after that time might be too late.
Build results:
total: 168 pass: 168 fail: 0 Qemu test results: total: 424 pass: 424 fail: 0
Guenter
Quoted 10 lines · Greg Kroah-Hartman
This is the start of the stable review cycle for the 4.14.279 release. There are 14 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 Sun, 15 May 2022 14:22:19 +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/v4.x/stable-review/patch-4.14.279-rc1.gzor in the git tree and branch at:
git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.gitlinux-4.14.y
and the diffstat can be found below.thanks,
greg k-h
Results from Linaro’s test farm.
No regressions on arm64, arm, x86_64, and i386.
## Build
* kernel: 4.14.279-rc1
* git: https://gitlab.com/Linaro/lkft/mirrors/stable/linux-stable-rc
* git branch: linux-4.14.y
* git commit: 4477341b2b1996b745937de9d99ff53095c7a679
* git describe: v4.14.278-15-g4477341b2b19
* test details:
https://qa-reports.linaro.org/lkft/linux-stable-rc-linux-4.14.y/build/v4.14.278-15-g4477341b2b19
## Test Regressions (compared to v4.14.278)
No test regressions found.
## Metric Regressions (compared to v4.14.278)
No metric regressions found.
## Test Fixes (compared to v4.14.278)
No test fixes found.
## Metric Fixes (compared to v4.14.278)
No metric fixes found.
## Test result summary
total: 67829, pass: 54211, fail: 882, skip: 11056, xfail: 1680
## Build Summary
* arm: 270 total, 270 passed, 0 failed
* arm64: 35 total, 35 passed, 0 failed
* dragonboard-410c: 1 total, 1 passed, 0 failed
* hi6220-hikey: 1 total, 1 passed, 0 failed
* i386: 19 total, 19 passed, 0 failed
* juno-r2: 1 total, 1 passed, 0 failed
* mips: 22 total, 22 passed, 0 failed
* powerpc: 16 total, 16 passed, 0 failed
* sparc: 12 total, 12 passed, 0 failed
* x15: 1 total, 1 passed, 0 failed
* x86: 1 total, 1 passed, 0 failed
* x86_64: 34 total, 34 passed, 0 failed
## Test suites summary
* fwts
* kselftest-android
* kselftest-arm64
* kselftest-bpf
* kselftest-breakpoints
* kselftest-capabilities
* kselftest-cgroup
* kselftest-clone3
* kselftest-core
* kselftest-cpu-hotplug
* kselftest-cpufreq
* kselftest-drivers
* kselftest-efivarfs
* kselftest-filesystems
* kselftest-firmware
* kselftest-fpu
* kselftest-futex
* kselftest-gpio
* kselftest-intel_pstate
* kselftest-ipc
* kselftest-ir
* kselftest-kcmp
* kselftest-kexec
* kselftest-kvm
* kselftest-lib
* kselftest-livepatch
* kselftest-membarrier
* kselftest-net
* kselftest-netfilter
* kselftest-nsfs
* kselftest-openat2
* kselftest-pid_namespace
* kselftest-pidfd
* kselftest-proc
* kselftest-pstore
* kselftest-ptrace
* kselftest-rseq
* kselftest-rtc
* kselftest-seccomp
* kselftest-sigaltstack
* kselftest-size
* kselftest-splice
* kselftest-static_keys
* kselftest-sync
* kselftest-sysctl
* kselftest-tc-testing
* kselftest-timens
* kselftest-timers
* kselftest-tmpfs
* kselftest-tpm2
* kselftest-user
* kselftest-vm
* kselftest-x86
* kselftest-zram
* kvm-unit-tests
* libhugetlbfs
* linux-log-parser
* ltp-cap_bounds-tests
* ltp-commands-tests
* ltp-containers-tests
* ltp-controllers-tests
* ltp-cpuhotplug-tests
* ltp-crypto-tests
* ltp-cve-tests
* ltp-dio-tests
* ltp-fcntl-locktests-tests
* ltp-filecaps-tests
* ltp-fs-tests
* ltp-fs_bind-tests
* ltp-fs_perms_simple-tests
* ltp-fsx-tests
* ltp-hugetlb-tests
* ltp-io-tests
* ltp-ipc-tests
* ltp-math-tests
* ltp-mm-tests
* ltp-nptl-tests
* ltp-open-posix-tests
* ltp-pty-tests
* ltp-sched-tests
* ltp-securebits-tests
* ltp-syscalls-tests
* ltp-tracing-tests
* network-basic-tests
* packetdrill
* perf
* rcutorture
* ssuite
* v4l2-compliance
* vdso
--
Linaro LKFT
https://lkft.linaro.org