4.19.276-rc1 review
Subsystems (7)
Greg Kroah-Hartman
maintainerPATCH 166/252 ima: Align ima_file_mmap() parameters with mmap_file LSM hook
In reply to Greg Kroah-HartmanFrom: Roberto Sassu <[email protected]>
commit 4971c268b85e1c7a734a61622fc0813c86e2362e upstream.
Commit 98de59bfe4b2f ("take calculation of final prot in security_mmap_file() into a helper") moved the code to update prot, to be the actual protections applied to the kernel, to a new helper called mmap_prot().
However, while without the helper ima_file_mmap() was getting the updated prot, with the helper ima_file_mmap() gets the original prot, which contains the protections requested by the application.
A possible consequence of this change is that, if an application calls mmap() with only PROT_READ, and the kernel applies PROT_EXEC in addition, that application would have access to executable memory without having this event recorded in the IMA measurement list. This situation would occur for example if the application, before mmap(), calls the personality() system call with READ_IMPLIES_EXEC as the first argument.
Align ima_file_mmap() parameters with those of the mmap_file LSM hook, so that IMA can receive both the requested prot and the final prot. Since the requested protections are stored in a new variable, and the final protections are stored in the existing variable, this effectively restores the original behavior of the MMAP_CHECK hook.
--- include/linux/ima.h | 6 ++++-- security/integrity/ima/ima_main.c | 7 +++++-- security/security.c | 7 ++++--- 3 files changed, 13 insertions(+), 7 deletions(-)
include/linux/ima.h +4 -2
@@ -19,7 +19,8 @@ struct linux_binprm;extern int ima_bprm_check (struct linux_binprm *bprm);extern int ima_file_check (struct file *file,int mask);extern void ima_file_free (struct file *file); -extern int ima_file_mmap (struct file *file,unsigned long prot); +extern int ima_file_mmap (struct file *file,unsigned long reqprot, +unsigned long prot,unsigned long flags);extern int ima_load_data (enum kernel_load_data_id id);extern int ima_read_file (struct file *file,enum kernel_read_file_id id); extern int ima_post_read_file(struct file *file, void *buf, loff_t size,
@@ -46,7 +47,8 @@ static inline void ima_file_free(structreturn ; } -static inline int ima_file_mmap (struct file *file,unsigned long prot) +static inline int ima_file_mmap (struct file *file,unsigned long reqprot, +unsigned long prot,unsigned long flags) {return 0 ; }
security/integrity/ima/ima_main.c +5 -2
@@ -323,7 +323,9 @@ out:/** * ima_file_mmap - based on policy, collect/store measurement. * @file: pointer to the file to be measured (May be NULL) -* @prot: contains the protection that will be applied by the kernel. +* @reqprot: protection requested by the application +* @prot: protection that will be applied by the kernel +* @flags: operational flags * * Measure files being mmapped executable based on the ima_must_measure() * policy decision.
@@ -331,7 +333,8 @@ out:* On success return 0. On integrity appraisal error, assuming the file * is in policy and IMA-appraisal is in enforcing mode, return -EACCES. */ -int ima_file_mmap (struct file *file,unsigned long prot) +int ima_file_mmap (struct file *file,unsigned long reqprot, +unsigned long prot,unsigned long flags) {u32 secid;
security/security.c +4 -3
@@ -926,12 +926,13 @@ static inline unsigned long mmap_prot(stint security_mmap_file (struct file *file,unsigned long prot,unsigned long flags) { +unsigned long prot_adj =mmap_prot (file, prot);int ret; - ret =call_int_hook (mmap_file,0 , file, prot, -mmap_prot (file, prot), flags); + + ret =call_int_hook (mmap_file,0 , file, prot, prot_adj, flags);if (ret)return ret; -return ima_file_mmap (file, prot); +return ima_file_mmap (file, prot, prot_adj, flags); }int security_mmap_addr (unsigned long addr)
Greg Kroah-Hartman
maintainerPATCH 167/252 irqdomain: Fix association race
In reply to Greg Kroah-HartmanFrom: Johan Hovold <[email protected]>
commit b06730a571a9ff1ba5bd6b20bf9e50e5a12f1ec6 upstream.
The sanity check for an already mapped virq is done outside of the irq_domain_mutex-protected section which means that an (unlikely) racing association may not be detected.
Fix this by factoring out the association implementation, which will also be used in a follow-on change to fix a shared-interrupt mapping race.
--- kernel/irq/irqdomain.c | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-)
kernel/irq/irqdomain.c +14 -5
@@ -515,8 +515,8 @@ void irq_domain_disassociate(struct irq_irq_domain_clear_mapping (domain, hwirq); } -int irq_domain_associate (struct irq_domain *domain,unsigned int virq, -irq_hw_number_t hwirq) +static int irq_domain_associate_locked (struct irq_domain *domain,unsigned int virq, +irq_hw_number_t hwirq) {struct irq_data *irq_data =irq_get_irq_data (virq);int ret;
@@ -529,7 +529,6 @@ int irq_domain_associate(struct irq_domaif (WARN (irq_data->domain,"error: virq%i is already associated" , virq))return -EINVAL ; -mutex_lock (&irq_domain_mutex); irq_data->hwirq = hwirq; irq_data->domain = domain;if (domain->ops->map) {
@@ -546,7 +545,6 @@ int irq_domain_associate(struct irq_doma } irq_data->domain =NULL ; irq_data->hwirq =0 ; -mutex_unlock (&irq_domain_mutex);return ret; }
@@ -557,12 +555,23 @@ int irq_domain_associate(struct irq_doma domain->mapcount++;irq_domain_set_mapping (domain, hwirq, irq_data); -mutex_unlock (&irq_domain_mutex);irq_clear_status_flags (virq,IRQ_NOREQUEST );return 0 ; } + +int irq_domain_associate (struct irq_domain *domain,unsigned int virq, +irq_hw_number_t hwirq) +{ +int ret; + +mutex_lock (&irq_domain_mutex); + ret =irq_domain_associate_locked (domain, virq, hwirq); +mutex_unlock (&irq_domain_mutex); + +return ret; +}EXPORT_SYMBOL_GPL (irq_domain_associate); void irq_domain_associate_many(struct irq_domain *domain, unsigned int irq_base,
Greg Kroah-Hartman
maintainerPATCH 168/252 irqdomain: Fix disassociation race
In reply to Greg Kroah-HartmanFrom: Johan Hovold <[email protected]>
commit 3f883c38f5628f46b30bccf090faec054088e262 upstream.
The global irq_domain_mutex is held when mapping interrupts from non-hierarchical domains but currently not when disposing them.
This specifically means that updates of the domain mapcount is racy (currently only used for statistics in debugfs).
Make sure to hold the global irq_domain_mutex also when disposing mappings from non-hierarchical domains.
--- kernel/irq/irqdomain.c | 5 +++++ 1 file changed, 5 insertions(+)
kernel/irq/irqdomain.c +5 -0
@@ -494,6 +494,9 @@ void irq_domain_disassociate(struct irq_return ; hwirq = irq_data->hwirq; + +mutex_lock (&irq_domain_mutex); +irq_set_status_flags (irq,IRQ_NOREQUEST );/* remove chip and handler */
@@ -513,6 +516,8 @@ void irq_domain_disassociate(struct irq_/* Clear reverse map for this hwirq */ irq_domain_clear_mapping (domain, hwirq); + +mutex_unlock (&irq_domain_mutex); } static int irq_domain_associate_locked(struct irq_domain *domain, unsigned int virq,
Greg Kroah-Hartman
maintainerPATCH 169/252 irqdomain: Drop bogus fwspec-mapping error handling
In reply to Greg Kroah-HartmanFrom: Johan Hovold <[email protected]>
commit e3b7ab025e931accdc2c12acf9b75c6197f1c062 upstream.
In case a newly allocated IRQ ever ends up not having any associated struct irq_data it would not even be possible to dispose the mapping.
Replace the bogus disposal with a WARN_ON().
This will also be used to fix a shared-interrupt mapping race, hence the CC-stable tag.
--- kernel/irq/irqdomain.c | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-)
kernel/irq/irqdomain.c +1 -6
@@ -832,13 +832,8 @@ unsigned int irq_create_fwspec_mapping(s } irq_data =irq_get_irq_data (virq); -if (!irq_data) { -if (irq_domain_is_hierarchy (domain)) -irq_domain_free_irqs (virq,1 ); -else -irq_dispose_mapping (virq); +if (WARN_ON (!irq_data))return 0 ; - }/* Store trigger type */ irqd_set_trigger_type (irq_data, type);
Greg Kroah-Hartman
maintainerPATCH 170/252 ALSA: ice1712: Do not left ice->gpio_mutex locked in aureon_add_controls()
In reply to Greg Kroah-HartmanFrom: Dmitry Fomin <[email protected]>
commit 951606a14a8901e3551fe4d8d3cedd73fe954ce1 upstream.
If snd_ctl_add() fails in aureon_add_controls(), it immediately returns and leaves ice->gpio_mutex locked. ice->gpio_mutex locks in snd_ice1712_save_gpio_status and unlocks in snd_ice1712_restore_gpio_status(ice).
It seems that the mutex is required only for aureon_cs8415_get(), so snd_ice1712_restore_gpio_status(ice) can be placed just after that. Compile tested only.
Found by Linux Verification Center (linuxtesting.org) with SVACE.
--- sound/pci/ice1712/aureon.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
sound/pci/ice1712/aureon.c +1 -1
@@ -1906,6 +1906,7 @@ static int aureon_add_controls(struct snunsigned char id;snd_ice1712_save_gpio_status (ice); id =aureon_cs8415_get (ice,CS8415_ID ); +snd_ice1712_restore_gpio_status (ice);if (id !=0x41 )dev_info (ice->card->dev,"No CS8415 chip. Skipping CS8415 controls.\n" );
@@ -1923,7 +1924,6 @@ static int aureon_add_controls(struct sn kctl->id.device = ice->pcm->device; } } -snd_ice1712_restore_gpio_status (ice); }return 0 ;
Greg Kroah-Hartman
maintainerPATCH 171/252 ext4: optimize ea_inode block expansion
In reply to Greg Kroah-HartmanFrom: Jun Nie <[email protected]>
commit 1e9d62d252812575ded7c620d8fc67c32ff06c16 upstream.
Copy ea data from inode entry when expanding ea block if possible. Then remove the ea entry if expansion success. Thus memcpy to a temporary buffer may be avoided.
If the expansion fails, we do not need to recovery the removed ea entry neither in this way.
--- fs/ext4/xattr.c | 28 +++++++++++++++++----------- 1 file changed, 17 insertions(+), 11 deletions(-)
fs/ext4/xattr.c +17 -11
@@ -2583,9 +2583,8 @@ static int ext4_xattr_move_to_block(hand is =kzalloc (sizeof (struct ext4_xattr_ibody_find ),GFP_NOFS ); bs =kzalloc (sizeof (struct ext4_xattr_block_find ),GFP_NOFS ); - buffer =kvmalloc (value_size,GFP_NOFS ); b_entry_name =kmalloc (entry->e_name_len +1 ,GFP_NOFS ); -if (!is || !bs || !buffer || !b_entry_name) { +if (!is || !bs || !b_entry_name) { error = -ENOMEM ; goto out; }
@@ -2597,12 +2596,18 @@ static int ext4_xattr_move_to_block(hand/* Save the entry name and the entry value */ if (entry->e_value_inum) { + buffer =kvmalloc (value_size,GFP_NOFS ); +if (!buffer) { + error = -ENOMEM ; + goto out; + } + error =ext4_xattr_inode_get (inode, entry, buffer, value_size);if (error) goto out; }else {size_t value_offs =le16_to_cpu (entry->e_value_offs); -memcpy (buffer, (void *)IFIRST (header) + value_offs, value_size); + buffer = (void *)IFIRST (header) + value_offs; }memcpy (b_entry_name, entry->e_name, entry->e_name_len);
@@ -2617,25 +2622,26 @@ static int ext4_xattr_move_to_block(handif (error) goto out; -/* Remove the chosen entry from the inode */ - error =ext4_xattr_ibody_set (handle, inode, &i, is); -if (error) - goto out; - i.value = buffer; i.value_len = value_size; error =ext4_xattr_block_find (inode, &i, bs);if (error) goto out; -/* Add entry which was removed from the inode into the block */ +/* Move ea entry from the inode into the block */ error =ext4_xattr_block_set (handle, inode, &i, bs);if (error) goto out; - error =0 ; + +/* Remove the chosen entry from the inode */ + i.value =NULL ; + i.value_len =0 ; + error =ext4_xattr_ibody_set (handle, inode, &i, is); + out:kfree (b_entry_name); -kvfree (buffer); +if (entry->e_value_inum && buffer) +kvfree (buffer);if (is)brelse (is->iloc.bh);if (bs)
Greg Kroah-Hartman
maintainerPATCH 172/252 ext4: refuse to create ea block when umounted
In reply to Greg Kroah-HartmanFrom: Jun Nie <[email protected]>
commit f31173c19901a96bb2ebf6bcfec8a08df7095c91 upstream.
The ea block expansion need to access s_root while it is already set as NULL when umount is triggered. Refuse this request to avoid panic.
--- fs/ext4/xattr.c | 7 +++++++ 1 file changed, 7 insertions(+)
fs/ext4/xattr.c +7 -0
@@ -1436,6 +1436,13 @@ static struct inode *ext4_xattr_inode_cruid_t owner[2 ] = {i_uid_read (inode),i_gid_read (inode) };int err; +if (inode->i_sb->s_root ==NULL ) { +ext4_warning (inode->i_sb, +"refuse to create EA inode when umounting" ); +WARN_ON (1 ); +return ERR_PTR (-EINVAL ); + } +/* * Let the next inode be the goal, so we try and allocate the EA inode * in the same group, or nearby one.
Greg Kroah-Hartman
maintainerPATCH 173/252 wifi: rtl8xxxu: Use a longer retry limit of 48
In reply to Greg Kroah-HartmanFrom: Bitterblue Smith <[email protected]>
commit 2a86aa9a1892d60ef2e3f310f5b42b8b05546d65 upstream.
The Realtek rate control algorithm goes back and forth a lot between the highest and the lowest rate it's allowed to use. This is due to a lot of frames being dropped because the retry limits set by IEEE80211_CONF_CHANGE_RETRY_LIMITS are too low. (Experimentally, they are 4 for long frames and 7 for short frames.)
The vendor drivers hardcode the value 48 for both retry limits (for station mode), which makes dropped frames very rare and thus the rate control is more stable.
Because most Realtek chips handle the rate control in the firmware, which can't be modified, ignore the limits set by IEEE80211_CONF_CHANGE_RETRY_LIMITS and use the value 48 (set during chip initialisation), same as the vendor drivers.
--- drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c | 9 --------- 1 file changed, 9 deletions(-)
drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c +0 -9
@@ -5500,7 +5500,6 @@ static int rtl8xxxu_config(struct ieee80 {struct rtl8xxxu_priv *priv = hw->priv;struct device *dev = &priv->udev->dev; -u16 val16;int ret =0 , channel;bool ht40;
@@ -5510,14 +5509,6 @@ static int rtl8xxxu_config(struct ieee80 __func__, hw->conf.chandef.chan->hw_value, changed, hw->conf.chandef.width); -if (changed &IEEE80211_CONF_CHANGE_RETRY_LIMITS ) { - val16 = ((hw->conf.long_frame_max_tx_count << -RETRY_LIMIT_LONG_SHIFT ) &RETRY_LIMIT_LONG_MASK ) | - ((hw->conf.short_frame_max_tx_count << -RETRY_LIMIT_SHORT_SHIFT ) &RETRY_LIMIT_SHORT_MASK ); -rtl8xxxu_write16 (priv,REG_RETRY_LIMIT , val16); - } -if (changed &IEEE80211_CONF_CHANGE_CHANNEL ) {switch (hw->conf.chandef.width) {case NL80211_CHAN_WIDTH_20_NOHT :
Greg Kroah-Hartman
maintainerPATCH 174/252 wifi: cfg80211: Fix use after free for wext
In reply to Greg Kroah-HartmanFrom: Alexander Wetzel <[email protected]>
commit 015b8cc5e7c4d7bb671f1984d7b7338c310b185b upstream.
Key information in wext.connect is not reset on (re)connect and can hold data from a previous connection.
Reset key data to avoid that drivers or mac80211 incorrectly detect a WEP connection request and access the freed or already reused memory.
Additionally optimize cfg80211_sme_connect() and avoid an useless schedule of conn_work.
--- net/wireless/sme.c | 31 ++++++++++++++++++++++++++----- 1 file changed, 26 insertions(+), 5 deletions(-)
net/wireless/sme.c +26 -5
@@ -269,6 +269,15 @@ void cfg80211_conn_work(struct work_strurtnl_unlock (); } +static void cfg80211_step_auth_next (struct cfg80211_conn *conn, +struct cfg80211_bss *bss) +{ +memcpy (conn->bssid, bss->bssid,ETH_ALEN ); + conn->params.bssid = conn->bssid; + conn->params.channel = bss->channel; + conn->state =CFG80211_CONN_AUTHENTICATE_NEXT ; +} +/* Returned bss is reference counted and must be cleaned up appropriately. */ static struct cfg80211_bss *cfg80211_get_conn_bss (struct wireless_dev *wdev) {
@@ -286,10 +295,7 @@ static struct cfg80211_bss *cfg80211_getif (!bss)return NULL ; -memcpy (wdev->conn->bssid, bss->bssid,ETH_ALEN ); - wdev->conn->params.bssid = wdev->conn->bssid; - wdev->conn->params.channel = bss->channel; - wdev->conn->state =CFG80211_CONN_AUTHENTICATE_NEXT ; +cfg80211_step_auth_next (wdev->conn, bss);schedule_work (&rdev->conn_work);return bss;
@@ -568,7 +574,12 @@ static int cfg80211_sme_connect(struct w wdev->conn->params.ssid_len = wdev->ssid_len;/* see if we have the bss already */ - bss =cfg80211_get_conn_bss (wdev); + bss =cfg80211_get_bss (wdev->wiphy, wdev->conn->params.channel, + wdev->conn->params.bssid, + wdev->conn->params.ssid, + wdev->conn->params.ssid_len, + wdev->conn_bss_type, +IEEE80211_PRIVACY (wdev->conn->params.privacy));if (prev_bssid) {memcpy (wdev->conn->prev_bssid, prev_bssid,ETH_ALEN );
@@ -579,6 +590,7 @@ static int cfg80211_sme_connect(struct wif (bss) {enum nl80211_timeout_reason treason; +cfg80211_step_auth_next (wdev->conn, bss); err =cfg80211_conn_do_work (wdev, &treason);cfg80211_put_bss (wdev->wiphy, bss); }else {
@@ -1207,6 +1219,15 @@ int cfg80211_connect(struct cfg80211_reg }else {if (WARN_ON (connkeys))return -EINVAL ; + +/* connect can point to wdev->wext.connect which +* can hold key data from a previous connection +*/ + connect->key =NULL ; + connect->key_len =0 ; + connect->key_idx =0 ; + connect->crypto.cipher_group =0 ; + connect->crypto.n_ciphers_pairwise =0 ; } wdev->connect_keys = connkeys;
Greg Kroah-Hartman
maintainerPATCH 175/252 dm flakey: fix logic when corrupting a bio
In reply to Greg Kroah-HartmanFrom: Mikulas Patocka <[email protected]>
commit aa56b9b75996ff4c76a0a4181c2fa0206c3d91cc upstream.
If "corrupt_bio_byte" is set to corrupt reads and corrupt_bio_flags is used, dm-flakey would erroneously return all writes as errors. Likewise, if "corrupt_bio_byte" is set to corrupt writes, dm-flakey would return errors for all reads.
Fix the logic so that if fc->corrupt_bio_byte is non-zero, dm-flakey will not abort reads on writes with an error.
--- drivers/md/dm-flakey.c | 23 +++++++++++++---------- 1 file changed, 13 insertions(+), 10 deletions(-)
drivers/md/dm-flakey.c +13 -10
@@ -364,9 +364,11 @@ static int flakey_map(struct dm_target */* * Corrupt matching writes. */ -if (fc->corrupt_bio_byte && (fc->corrupt_bio_rw ==WRITE )) { -if (all_corrupt_bio_flags_match (bio, fc)) -corrupt_bio_data (bio, fc); +if (fc->corrupt_bio_byte) { +if (fc->corrupt_bio_rw ==WRITE ) { +if (all_corrupt_bio_flags_match (bio, fc)) +corrupt_bio_data (bio, fc); + } goto map_bio; }
@@ -397,13 +399,14 @@ static int flakey_end_io(struct dm_targe }if (!*error && pb->bio_submitted && (bio_data_dir (bio) ==READ )) { -if (fc->corrupt_bio_byte && (fc->corrupt_bio_rw ==READ ) && -all_corrupt_bio_flags_match (bio, fc)) { -/* -* Corrupt successful matching READs while in down state. -*/ -corrupt_bio_data (bio, fc); - +if (fc->corrupt_bio_byte) { +if ((fc->corrupt_bio_rw ==READ ) && +all_corrupt_bio_flags_match (bio, fc)) { +/* +* Corrupt successful matching READs while in down state. +*/ +corrupt_bio_data (bio, fc); + } }else if (!test_bit (DROP_WRITES , &fc->flags) && !test_bit (ERROR_WRITES , &fc->flags)) {/*
Greg Kroah-Hartman
maintainerPATCH 176/252 dm flakey: dont corrupt the zero page
In reply to Greg Kroah-HartmanFrom: Mikulas Patocka <[email protected]>
commit f50714b57aecb6b3dc81d578e295f86d9c73f078 upstream.
When we need to zero some range on a block device, the function __blkdev_issue_zero_pages submits a write bio with the bio vector pointing to the zero page. If we use dm-flakey with corrupt bio writes option, it will corrupt the content of the zero page which results in crashes of various userspace programs. Glibc assumes that memory returned by mmap is zeroed and it uses it for calloc implementation; if the newly mapped memory is not zeroed, calloc will return non-zeroed memory.
Fix this bug by testing if the page is equal to ZERO_PAGE(0) and avoiding the corruption in this case.
--- drivers/md/dm-flakey.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-)
drivers/md/dm-flakey.c +5 -2
@@ -301,8 +301,11 @@ static void corrupt_bio_data(struct bio*/ bio_for_each_segment (bvec, bio, iter) {if (bio_iter_len (bio, iter) > corrupt_bio_byte) { -char *segment = (page_address (bio_iter_page (bio, iter)) - +bio_iter_offset (bio, iter)); +char *segment; +struct page *page =bio_iter_page (bio, iter); +if (unlikely (page ==ZERO_PAGE (0 ))) +break ; + segment = (page_address (page) +bio_iter_offset (bio, iter)); segment[corrupt_bio_byte] = fc->corrupt_bio_value; DMDEBUG("Corrupting data bio=%p by writing %u to byte %u " "(rw=%c bi_opf=%u bi_sector=%llu size=%u)\n",
Greg Kroah-Hartman
maintainerPATCH 177/252 ARM: dts: exynos: correct TMU phandle in Exynos4
In reply to Greg Kroah-HartmanFrom: Krzysztof Kozlowski <[email protected]>
commit 8e4505e617a80f601e2f53a917611777f128f925 upstream.
TMU node uses 0 as thermal-sensor-cells, thus thermal zone referencing it must not have an argument to phandle.
--- arch/arm/boot/dts/exynos4-cpu-thermal.dtsi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
arch/arm/boot/dts/exynos4-cpu-thermal.dtsi +1 -1
@@ -10,7 +10,7 @@ / { thermal-zones { cpu_thermal: cpu-thermal { - thermal-sensors = <&tmu 0>; + thermal-sensors = <&tmu>; polling-delay-passive = <0>; polling-delay = <0>; trips {
Greg Kroah-Hartman
maintainerPATCH 178/252 ARM: dts: exynos: correct TMU phandle in Odroid XU
In reply to Greg Kroah-HartmanFrom: Krzysztof Kozlowski <[email protected]>
commit 9372eca505e7a19934d750b4b4c89a3652738e66 upstream.
TMU node uses 0 as thermal-sensor-cells, thus thermal zone referencing it must not have an argument to phandle. Since thermal-sensors property is already defined in included exynosi5410.dtsi, drop it from exynos5410-odroidxu.dts to fix the error and remoev redundancy.
--- arch/arm/boot/dts/exynos5410-odroidxu.dts | 1 - 1 file changed, 1 deletion(-)
arch/arm/boot/dts/exynos5410-odroidxu.dts +0 -1
@@ -113,7 +113,6 @@ }; &cpu0_thermal { - thermal-sensors = <&tmu_cpu0 0>; polling-delay-passive = <0>; polling-delay = <0>;
Greg Kroah-Hartman
maintainerPATCH 179/252 rbd: avoid use-after-free in do_rbd_add() when rbd_dev_create() fails
In reply to Greg Kroah-HartmanFrom: Ilya Dryomov <[email protected]>
commit f7c4d9b133c7a04ca619355574e96b6abf209fba upstream.
If getting an ID or setting up a work queue in rbd_dev_create() fails, use-after-free on rbd_dev->rbd_client, rbd_dev->spec and rbd_dev->opts is triggered in do_rbd_add(). The root cause is that the ownership of these structures is transfered to rbd_dev prematurely and they all end up getting freed when rbd_dev_create() calls rbd_dev_free() prior to returning to do_rbd_add().
Found by Linux Verification Center (linuxtesting.org) with SVACE, an incomplete patch submitted by Natalia Petrova <[email protected]>.
--- drivers/block/rbd.c | 20 +++++++++----------- 1 file changed, 9 insertions(+), 11 deletions(-)
drivers/block/rbd.c +9 -11
@@ -4381,8 +4381,7 @@ static void rbd_dev_release(struct devicmodule_put (THIS_MODULE ); } -static struct rbd_device *__rbd_dev_create (struct rbd_client *rbdc, -struct rbd_spec *spec) +static struct rbd_device *__rbd_dev_create (struct rbd_spec *spec) {struct rbd_device *rbd_dev;
@@ -4421,9 +4420,6 @@ static struct rbd_device *__rbd_dev_crea rbd_dev->dev.parent = &rbd_root_dev;device_initialize (&rbd_dev->dev); - rbd_dev->rbd_client = rbdc; - rbd_dev->spec = spec; -return rbd_dev; }
@@ -4436,12 +4432,10 @@ static struct rbd_device *rbd_dev_create {struct rbd_device *rbd_dev; - rbd_dev =__rbd_dev_create (rbdc, spec); + rbd_dev =__rbd_dev_create (spec);if (!rbd_dev)return NULL ; - rbd_dev->opts = opts; -/* get an id and fill in device name */ rbd_dev->dev_id = ida_simple_get(&rbd_dev_id_ida, 0, minor_to_rbd_dev_id(1 << MINORBITS),
@@ -4458,6 +4452,10 @@ static struct rbd_device *rbd_dev_create/* we have a ref from do_rbd_add() */ __module_get (THIS_MODULE ); + rbd_dev->rbd_client = rbdc; + rbd_dev->spec = spec; + rbd_dev->opts = opts; +dout ("%s rbd_dev %p dev_id %d\n" , __func__, rbd_dev, rbd_dev->dev_id);return rbd_dev;
@@ -5618,7 +5616,7 @@ static int rbd_dev_probe_parent(struct r goto out_err; } - parent =__rbd_dev_create (rbd_dev->rbd_client, rbd_dev->parent_spec); + parent =__rbd_dev_create (rbd_dev->parent_spec);if (!parent) { ret = -ENOMEM ; goto out_err;
@@ -5628,8 +5626,8 @@ static int rbd_dev_probe_parent(struct r* Images related by parent/child relationships always share * rbd_client and spec/parent_spec, so bump their refcounts. */ -__rbd_get_client (rbd_dev->rbd_client); -rbd_spec_get (rbd_dev->parent_spec); + parent->rbd_client =__rbd_get_client (rbd_dev->rbd_client); + parent->spec =rbd_spec_get (rbd_dev->parent_spec); ret =rbd_dev_image_probe (parent, depth);if (ret <0 )
Greg Kroah-Hartman
maintainerPATCH 180/252 alpha: fix FEN fault handling
In reply to Greg Kroah-HartmanFrom: Al Viro <[email protected]>
commit 977a3009547dad4a5bc95d91be4a58c9f7eedac0 upstream.
Type 3 instruction fault (FPU insn with FPU disabled) is handled by quietly enabling FPU and returning. Which is fine, except that we need to do that both for fault in userland and in the kernel; the latter *can* legitimately happen - all it takes is this:
.global _start_start:
call_pal 0xae lda $0, 0 ldq $0, 0($0)
- call_pal CLRFEN to clear "FPU enabled" flag and arrange for a signal delivery (SIGSEGV in this case).
Fixed by moving the handling of type 3 into the common part of do_entIF(), before we check for kernel vs. user mode.
Incidentally, the check for kernel mode is unidiomatic; the normal way to do that is !user_mode(regs). The difference is that the open-coded variant treats any of bits 63..3 of regs->ps being set as "it's user mode" while the normal approach is to check just the bit 3. PS is a 4-bit register and regs->ps always will have bits 63..4 clear, so the open-coded variant here is actually equivalent to !user_mode(regs). Harder to follow, though...
--- arch/alpha/kernel/traps.c | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-)
arch/alpha/kernel/traps.c +15 -15
@@ -235,7 +235,21 @@ do_entIF(unsigned long type, struct pt_r {int signo, code; -if ((regs->ps & ~IPL_MAX ) ==0 ) { +if (type ==3 ) {/* FEN fault */ +/* Irritating users can call PAL_clrfen to disable the +FPU for the process. The kernel will then trap in +do_switch_stack and undo_switch_stack when we try +to save and restore the FP registers. + +Given that GCC by default generates code that uses the +FP registers, PAL_clrfen is not useful except for DoS +attacks. So turn the bleeding FPU back on and be done +with it. */ +current_thread_info ()->pcb.flags |=1 ; +__reload_thread (¤t_thread_info ()->pcb); +return ; + } +if (!user_mode (regs)) {if (type ==1 ) {const unsigned int *data = (const unsigned int *) regs->pc;
@@ -368,20 +382,6 @@ do_entIF(unsigned long type, struct pt_r }break ; -case 3 :/* FEN fault */ -/* Irritating users can call PAL_clrfen to disable the -FPU for the process. The kernel will then trap in -do_switch_stack and undo_switch_stack when we try -to save and restore the FP registers. - -Given that GCC by default generates code that uses the -FP registers, PAL_clrfen is not useful except for DoS -attacks. So turn the bleeding FPU back on and be done -with it. */ -current_thread_info ()->pcb.flags |=1 ; -__reload_thread (¤t_thread_info ()->pcb); -return ; -case 5 :/* illoc */ default :/* unexpected instruction-fault type */ ;
Greg Kroah-Hartman
maintainerPATCH 181/252 mips: fix syscall_get_nr
In reply to Greg Kroah-HartmanFrom: Elvira Khabirova <[email protected]>
commit 85cc91e2ba4262a602ec65e2b76c4391a9e60d3d upstream.
The implementation of syscall_get_nr on mips used to ignore the task argument and return the syscall number of the calling thread instead of the target thread.
The bug was exposed to user space by commit 201766a20e30f ("ptrace: add PTRACE_GET_SYSCALL_INFO request") and detected by strace test suite.
--- arch/mips/include/asm/syscall.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
arch/mips/include/asm/syscall.h +1 -1
@@ -38,7 +38,7 @@ static inline bool mips_syscall_is_indirstatic inline long syscall_get_nr (struct task_struct *task,struct pt_regs *regs) { -return current_thread_info ()->syscall; +return task_thread_info (task)->syscall; } static inline void mips_syscall_update_nr(struct task_struct *task,
Greg Kroah-Hartman
maintainerPATCH 182/252 media: ipu3-cio2: Fix PM runtime usage_count in driver unbind
In reply to Greg Kroah-HartmanFrom: Sakari Ailus <[email protected]>
commit 909d3096ac99fa2289f9b8945a3eab2269947a0a upstream.
Get the PM runtime usage_count and forbid PM runtime at driver unbind. The opposite is being done in probe() already.
--- drivers/media/pci/intel/ipu3/ipu3-cio2.c | 3 +++ 1 file changed, 3 insertions(+)
drivers/media/pci/intel/ipu3/ipu3-cio2.c +3 -0
@@ -1860,6 +1860,9 @@ static void cio2_pci_remove(struct pci_dv4l2_device_unregister (&cio2->v4l2_dev);media_device_cleanup (&cio2->media_dev);mutex_destroy (&cio2->lock); + +pm_runtime_forbid (&pci_dev->dev); +pm_runtime_get_noresume (&pci_dev->dev); }static int __maybe_unused cio2_runtime_suspend (struct device *dev)
Greg Kroah-Hartman
maintainerPATCH 183/252 ktest.pl: Give back console on Ctrt^C on monitor
In reply to Greg Kroah-HartmanFrom: Steven Rostedt <[email protected]>
commit 83d29d439cd3ef23041570d55841f814af2ecac0 upstream.
When monitoring the console output, the stdout is being redirected to do so. If Ctrl^C is hit during this mode, the stdout is not back to the console, the user does not see anything they type (no echo).
Add "end_monitor" to the SIGINT interrupt handler to give back the console on Ctrl^C.
--- tools/testing/ktest/ktest.pl | 3 +++ 1 file changed, 3 insertions(+)
tools/testing/ktest/ktest.pl +3 -0
@@ -4243,6 +4243,9 @@ sub send_email { } sub cancel_test { + if ($monitor_cnt) { + end_monitor; + } if ($email_when_canceled) { send_email("KTEST: Your [$test_type] test was cancelled", "Your test started at $script_start_time was cancelled: sig int");
Greg Kroah-Hartman
maintainerPATCH 184/252 ktest.pl: Fix missing "end_monitor" when machine check fails
In reply to Greg Kroah-HartmanFrom: Steven Rostedt <[email protected]>
commit e8bf9b98d40dbdf4e39362e3b85a70c61da68cb7 upstream.
In the "reboot" command, it does a check of the machine to see if it is still alive with a simple "ssh echo" command. If it fails, it will assume that a normal "ssh reboot" is not possible and force a power cycle.
In this case, the "start_monitor" is executed, but the "end_monitor" is not, and this causes the screen will not be given back to the console. That is, after the test, a "reset" command needs to be performed, as "echo" is turned off.
--- tools/testing/ktest/ktest.pl | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
tools/testing/ktest/ktest.pl +2 -1
@@ -1419,7 +1419,8 @@ sub reboot { # Still need to wait for the reboot to finish wait_for_monitor($time, $reboot_success_line); - + } + if ($powercycle || $time) { end_monitor; } }
Greg Kroah-Hartman
maintainerPATCH 185/252 ktest.pl: Add RUN_TIMEOUT option with default unlimited
In reply to Greg Kroah-HartmanFrom: Steven Rostedt <[email protected]>
commit 4e7d2a8f0b52abf23b1dc13b3d88bc0923383cd5 upstream.
There is a disconnect between the run_command function and the wait_for_input. The wait_for_input has a default timeout of 2 minutes. But if that happens, the run_command loop will exit out to the waitpid() of the executing command. This fails in that it no longer monitors the command, and also, the ssh to the test box can hang when its finished, as it's waiting for the pipe it's writing to to flush, but the loop that reads that pipe has already exited, leaving the command stuck, and the test hangs.
Instead, make the default "wait_for_input" of the run_command infinite, and allow the user to override it if they want with a default timeout option "RUN_TIMEOUT".
But this fixes the hang that happens when the pipe is full and the ssh session never exits.
--- tools/testing/ktest/ktest.pl | 20 ++++++++++++++++---- tools/testing/ktest/sample.conf | 5 +++++ 2 files changed, 21 insertions(+), 4 deletions(-)
tools/testing/ktest/ktest.pl +16 -4
@@ -172,6 +172,7 @@ my $store_failures; my $store_successes; my $test_name; my $timeout; +my $run_timeout; my $connect_timeout; my $config_bisect_exec; my $booted_timeout;
@@ -330,6 +331,7 @@ my %option_map = ( "STORE_SUCCESSES" => \$store_successes, "TEST_NAME" => \$test_name, "TIMEOUT" => \$timeout, + "RUN_TIMEOUT" => \$run_timeout, "CONNECT_TIMEOUT" => \$connect_timeout, "CONFIG_BISECT_EXEC" => \$config_bisect_exec, "BOOTED_TIMEOUT" => \$booted_timeout,
@@ -1750,6 +1752,14 @@ sub run_command { $command =~ s/\$SSH_USER/$ssh_user/g; $command =~ s/\$MACHINE/$machine/g; + if (!defined($timeout)) { + $timeout = $run_timeout; + } + + if (!defined($timeout)) { + $timeout = -1; # tell wait_for_input to wait indefinitely + } + doprint("$command ... "); $start_time = time;
@@ -1778,13 +1788,10 @@ sub run_command { while (1) { my $fp = \*CMD; - if (defined($timeout)) { - doprint "timeout = $timeout\n"; - } my $line = wait_for_input($fp, $timeout); if (!defined($line)) { my $now = time; - if (defined($timeout) && (($now - $start_time) >= $timeout)) { + if ($timeout >= 0 && (($now - $start_time) >= $timeout)) { doprint "Hit timeout of $timeout, killing process\n"; $hit_timeout = 1; kill 9, $pid;
@@ -1989,6 +1996,11 @@ sub wait_for_input $time = $timeout; } + if ($time < 0) { + # Negative number means wait indefinitely + undef $time; + } + $rin = ''; vec($rin, fileno($fp), 1) = 1; vec($rin, fileno(\*STDIN), 1) = 1;
tools/testing/ktest/sample.conf +5 -0
@@ -775,6 +775,11 @@ # is issued instead of a reboot. # CONNECT_TIMEOUT = 25 +# The timeout in seconds for how long to wait for any running command +# to timeout. If not defined, it will let it go indefinitely. +# (default undefined) +#RUN_TIMEOUT = 600 + # In between tests, a reboot of the box may occur, and this # is the time to wait for the console after it stops producing # output. Some machines may not produce a large lag on reboot
Greg Kroah-Hartman
maintainerPATCH 186/252 scsi: qla2xxx: Fix link failure in NPIV environment
In reply to Greg Kroah-HartmanFrom: Quinn Tran <[email protected]>
commit b1ae65c082f74536ec292b15766f2846f0238373 upstream.
User experienced symptoms of adapter failure in NPIV environment. NPIV hosts were allowed to trigger chip reset back to back due to NPIV link state being slow to come online.
Fix link failure in NPIV environment by removing NPIV host from directly being able to perform chip reset.
kernel: qla2xxx [0000:04:00.1]-6009:261: Loop down - aborting ISP.
kernel: qla2xxx [0000:04:00.1]-6009:262: Loop down - aborting ISP.
kernel: qla2xxx [0000:04:00.1]-6009:281: Loop down - aborting ISP.
kernel: qla2xxx [0000:04:00.1]-6009:285: Loop down - aborting ISP
--- drivers/scsi/qla2xxx/qla_os.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/scsi/qla2xxx/qla_os.c +1 -1
@@ -6384,7 +6384,7 @@ qla2x00_timer(struct timer_list *t)/* if the loop has been down for 4 minutes, reinit adapter */ if (atomic_dec_and_test (&vha->loop_down_timer) !=0 ) { -if (!(vha->device_flags &DFLG_NO_CABLE )) { +if (!(vha->device_flags &DFLG_NO_CABLE ) && !vha->vp_idx) {ql_log (ql_log_warn, vha,0x6009 ,"Loop down - aborting ISP.\n" );
Greg Kroah-Hartman
maintainerPATCH 187/252 scsi: qla2xxx: Fix erroneous link down
In reply to Greg Kroah-HartmanFrom: Quinn Tran <[email protected]>
commit 3fbc74feb642deb688cc97f76d40b7287ddd4cb1 upstream.
If after an adapter reset the appearance of link is not recovered, the devices are not rediscovered. This is result of a race condition between adapter reset (abort_isp) and the topology scan. During adapter reset, the ABORT_ISP_ACTIVE flag is set. Topology scan usually occurred after adapter reset. In this case, the topology scan came earlier than usual where it ran into problem due to ABORT_ISP_ACTIVE flag was still set.
kernel: qla2xxx [0000:13:00.0]-1005:1: Cmd 0x6a aborted with timeout since ISP Abort is pending
kernel: qla2xxx [0000:13:00.0]-28a0:1: MBX_GET_PORT_NAME failed, No FL Port.
kernel: qla2xxx [0000:13:00.0]-286b:1: qla2x00_configure_loop: exiting normally. local port wwpn 51402ec0123d9a80 id 012300)
kernel: qla2xxx [0000:13:00.0]-8017:1: ADAPTER RESET SUCCEEDED nexus=1:0:15.
Allow adapter reset to complete before any scan can start.
--- drivers/scsi/qla2xxx/qla_os.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-)
drivers/scsi/qla2xxx/qla_os.c +5 -2
@@ -6149,9 +6149,12 @@ qla2x00_do_dpc(void *data) } } loop_resync_check: -if (test_and_clear_bit (LOOP_RESYNC_NEEDED , +if (!qla2x00_reset_active (base_vha) && +test_and_clear_bit (LOOP_RESYNC_NEEDED , &base_vha->dpc_flags)) { - +/* +* Allow abort_isp to complete before moving on to scanning. +*/ ql_dbg (ql_dbg_dpc, base_vha,0x400f ,"Loop resync scheduled.\n" );
Greg Kroah-Hartman
maintainerPATCH 188/252 scsi: ses: Dont attach if enclosure has no components
In reply to Greg Kroah-HartmanFrom: James Bottomley <[email protected]>
commit 3fe97ff3d94934649abb0652028dd7296170c8d0 upstream.
An enclosure with no components can't usefully be operated by the driver (since effectively it has nothing to manage), so report the problem and don't attach. Not attaching also fixes an oops which could occur if the driver tries to manage a zero component enclosure.
[mkp: Switched to KERN_WARNING since this scenario is common]
--- drivers/scsi/ses.c | 6 ++++++ 1 file changed, 6 insertions(+)
drivers/scsi/ses.c +6 -0
@@ -720,6 +720,12 @@ static int ses_intf_add(struct device *c type_ptr[0] == ENCLOSURE_COMPONENT_ARRAY_DEVICE) components += type_ptr[1 ]; } + +if (components ==0 ) { +sdev_printk (KERN_WARNING , sdev,"enclosure has no enumerated components\n" ); + goto err_free; + } + ses_dev->page1 = buf; ses_dev->page1_len = len; buf =NULL ;
Greg Kroah-Hartman
maintainerPATCH 189/252 scsi: ses: Fix slab-out-of-bounds in ses_enclosure_data_process()
In reply to Greg Kroah-HartmanFrom: Tomas Henzl <[email protected]>
commit 9b4f5028e493cb353a5c8f5c45073eeea0303abd upstream.
A fix for:
BUG: KASAN: slab-out-of-bounds in ses_enclosure_data_process+0x949/0xe30 [ses] Read of size 1 at addr ffff88a1b043a451 by task systemd-udevd/3271
Checking after (and before in next loop) addl_desc_ptr[1] is sufficient, we expect the size to be sanitized before first access to addl_desc_ptr[1]. Make sure we don't walk beyond end of page.
--- drivers/scsi/ses.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-)
drivers/scsi/ses.c +4 -2
@@ -619,9 +619,11 @@ static void ses_enclosure_data_process(s/* these elements are optional */ type_ptr[0] == ENCLOSURE_COMPONENT_SCSI_TARGET_PORT || type_ptr[0] == ENCLOSURE_COMPONENT_SCSI_INITIATOR_PORT || - type_ptr[0] == ENCLOSURE_COMPONENT_CONTROLLER_ELECTRONICS)) + type_ptr[0] == ENCLOSURE_COMPONENT_CONTROLLER_ELECTRONICS)) { addl_desc_ptr += addl_desc_ptr[1 ] +2 ; - +if (addl_desc_ptr +1 >= ses_dev->page10 + ses_dev->page10_len) + addl_desc_ptr =NULL ; + } } }kfree (buf);
Greg Kroah-Hartman
maintainerPATCH 190/252 scsi: ses: Fix possible addl_desc_ptr out-of-bounds accesses
In reply to Greg Kroah-HartmanFrom: Tomas Henzl <[email protected]>
commit db95d4df71cb55506425b6e4a5f8d68e3a765b63 upstream.
Sanitize possible addl_desc_ptr out-of-bounds accesses in ses_enclosure_data_process().
--- drivers/scsi/ses.c | 35 ++++++++++++++++++++++++++--------- 1 file changed, 26 insertions(+), 9 deletions(-)
drivers/scsi/ses.c +26 -9
@@ -449,8 +449,8 @@ int ses_match_host(struct enclosure_devi }#endif /* 0 */ -static void ses_process_descriptor (struct enclosure_component *ecomp, -unsigned char *desc) +static int ses_process_descriptor (struct enclosure_component *ecomp, +unsigned char *desc,int max_desc_len) {int eip = desc[0 ] &0x10 ;int invalid = desc[0 ] &0x80 ;
@@ -461,22 +461,32 @@ static void ses_process_descriptor(strucunsigned char *d;if (invalid) -return ; +return 0 ;switch (proto) {case SCSI_PROTOCOL_FCP :if (eip) { +if (max_desc_len <=7 ) +return 1 ; d = desc +4 ; slot = d[3 ]; }break ;case SCSI_PROTOCOL_SAS : +if (eip) { +if (max_desc_len <=27 ) +return 1 ; d = desc +4 ; slot = d[3 ]; d = desc +8 ; - }else + }else { +if (max_desc_len <=23 ) +return 1 ; d = desc +4 ; + } + +/* only take the phy0 addr */ addr = (u64 )d[12 ] <<56 | (u64)d[13] << 48 |
@@ -493,6 +503,8 @@ static void ses_process_descriptor(struc } ecomp->slot = slot; scomp->addr = addr; + +return 0 ; }struct efd {
@@ -565,7 +577,7 @@ static void ses_enclosure_data_process(s/* skip past overall descriptor */ desc_ptr += len +4 ; } -if (ses_dev->page10) +if (ses_dev->page10 && ses_dev->page10_len >9 ) addl_desc_ptr = ses_dev->page10 +8 ; type_ptr = ses_dev->page1_types; components =0 ;
@@ -573,6 +585,7 @@ static void ses_enclosure_data_process(sfor (j =0 ; j < type_ptr[1 ]; j++) {char *name =NULL ;struct enclosure_component *ecomp; +int max_desc_len;if (desc_ptr) {if (desc_ptr >= buf + page7_len) {
@@ -599,10 +612,14 @@ static void ses_enclosure_data_process(s ecomp = &edev->component[components++];if (!IS_ERR (ecomp)) { -if (addl_desc_ptr) -ses_process_descriptor ( - ecomp, - addl_desc_ptr); +if (addl_desc_ptr) { + max_desc_len = ses_dev->page10_len - + (addl_desc_ptr - ses_dev->page10); +if (ses_process_descriptor (ecomp, + addl_desc_ptr, + max_desc_len)) + addl_desc_ptr =NULL ; + }if (create)enclosure_component_register ( ecomp);
Greg Kroah-Hartman
maintainerPATCH 191/252 scsi: ses: Fix possible desc_ptr out-of-bounds accesses
In reply to Greg Kroah-HartmanFrom: Tomas Henzl <[email protected]>
commit 801ab13d50cf3d26170ee073ea8bb4eececb76ab upstream.
Sanitize possible desc_ptr out-of-bounds accesses in ses_enclosure_data_process().
--- drivers/scsi/ses.c | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-)
drivers/scsi/ses.c +9 -5
@@ -588,15 +588,19 @@ static void ses_enclosure_data_process(sint max_desc_len;if (desc_ptr) { -if (desc_ptr >= buf + page7_len) { +if (desc_ptr +3 >= buf + page7_len) { desc_ptr =NULL ; }else { len = (desc_ptr[2 ] <<8 ) + desc_ptr[3 ]; desc_ptr +=4 ; -/* Add trailing zero - pushes into -* reserved space */ - desc_ptr[len] ='\0' ; - name = desc_ptr; +if (desc_ptr + len > buf + page7_len) + desc_ptr =NULL ; +else { +/* Add trailing zero - pushes into +* reserved space */ + desc_ptr[len] ='\0' ; + name = desc_ptr; + } } } if (type_ptr[0] == ENCLOSURE_COMPONENT_DEVICE ||
Greg Kroah-Hartman
maintainerPATCH 192/252 scsi: ses: Fix slab-out-of-bounds in ses_intf_remove()
In reply to Greg Kroah-HartmanFrom: Tomas Henzl <[email protected]>
commit 578797f0c8cbc2e3ec5fc0dab87087b4c7073686 upstream.
A fix for:
BUG: KASAN: slab-out-of-bounds in ses_intf_remove+0x23f/0x270 [ses] Read of size 8 at addr ffff88a10d32e5d8 by task rmmod/12013
When edev->components is zero, accessing edev->component[0] members is wrong.
--- drivers/scsi/ses.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
drivers/scsi/ses.c +2 -1
@@ -872,7 +872,8 @@ static void ses_intf_remove_enclosure(stkfree (ses_dev->page2);kfree (ses_dev); -kfree (edev->component[0 ].scratch); +if (edev->components) +kfree (edev->component[0 ].scratch);put_device (&edev->edev);enclosure_unregister (edev);
Greg Kroah-Hartman
maintainerPATCH 193/252 PCI: Avoid FLR for AMD FCH AHCI adapters
In reply to Greg Kroah-HartmanFrom: Damien Le Moal <[email protected]>
commit 63ba51db24ed1b8f8088a897290eb6c036c5435d upstream.
PCI passthrough to VMs does not work with AMD FCH AHCI adapters: the guest OS fails to correctly probe devices attached to the controller due to FIS communication failures:
ata4: softreset failed (1st FIS failed)
...
ata4.00: qc timeout after 5000 msecs (cmd 0xec) ata4.00: failed to IDENTIFY (I/O error, err_mask=0x4)
Forcing the "bus" reset method before unbinding & binding the adapter to the vfio-pci driver solves this issue, e.g.:
echo "bus" > /sys/bus/pci/devices/<ID>/reset_method
gives a working guest OS, indicating that the default FLR reset method doesn't work correctly.
Apply quirk_no_flr() to AMD FCH AHCI devices to work around this issue.
--- drivers/pci/quirks.c | 1 + 1 file changed, 1 insertion(+)
drivers/pci/quirks.c +1 -0
@@ -5153,6 +5153,7 @@ static void quirk_no_flr(struct pci_devDECLARE_PCI_FIXUP_EARLY (PCI_VENDOR_ID_AMD ,0x1487 , quirk_no_flr);DECLARE_PCI_FIXUP_EARLY (PCI_VENDOR_ID_AMD ,0x148c , quirk_no_flr);DECLARE_PCI_FIXUP_EARLY (PCI_VENDOR_ID_AMD ,0x149c , quirk_no_flr); +DECLARE_PCI_FIXUP_EARLY (PCI_VENDOR_ID_AMD ,0x7901 , quirk_no_flr);DECLARE_PCI_FIXUP_EARLY (PCI_VENDOR_ID_INTEL ,0x1502 , quirk_no_flr);DECLARE_PCI_FIXUP_EARLY (PCI_VENDOR_ID_INTEL ,0x1503 , quirk_no_flr);
Greg Kroah-Hartman
maintainerPATCH 194/252 drm/radeon: Fix eDP for single-display iMac11,2
In reply to Greg Kroah-HartmanFrom: Mark Hawrylak <[email protected]>
commit 05eacc198c68cbb35a7281ce4011f8899ee1cfb8 upstream.
Apple iMac11,2 (mid 2010) also with Radeon HD-4670 that has the same issue as iMac10,1 (late 2009) where the internal eDP panel stays dark on driver load. This patch treats iMac11,2 the same as iMac10,1, so the eDP panel stays active.
Additional steps:
Kernel boot parameter radeon.nomodeset=0 required to keep the eDP panel active.
This patch is an extension of
commit 564d8a2cf3ab ("drm/radeon: Fix eDP for single-display iMac10,1 (v2)")
--- drivers/gpu/drm/radeon/atombios_encoders.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-)
drivers/gpu/drm/radeon/atombios_encoders.c +3 -2
@@ -2188,11 +2188,12 @@ int radeon_atom_pick_dig_encoder(struct/* * On DCE32 any encoder can drive any block so usually just use crtc id, -* but Apple thinks different at least on iMac10,1, so there use linkb, +* but Apple thinks different at least on iMac10,1 and iMac11,2, so there use linkb, * otherwise the internal eDP panel will stay dark. */ if (ASIC_IS_DCE32 (rdev)) { -if (dmi_match (DMI_PRODUCT_NAME ,"iMac10,1" )) +if (dmi_match (DMI_PRODUCT_NAME ,"iMac10,1" ) || +dmi_match (DMI_PRODUCT_NAME ,"iMac11,2" )) enc_idx = (dig->linkb) ?1 :0 ;else enc_idx = radeon_crtc->crtc_id;
Greg Kroah-Hartman
maintainerPATCH 195/252 wifi: ath9k: use proper statements in conditionals
In reply to Greg Kroah-HartmanFrom: Arnd Bergmann <[email protected]>
commit b7dc753fe33a707379e2254317794a4dad6c0fe2 upstream.
A previous cleanup patch accidentally broke some conditional expressions by replacing the safe "do {} while (0)" constructs with empty macros. gcc points this out when extra warnings are enabled:
drivers/net/wireless/ath/ath9k/hif_usb.c: In function 'ath9k_skb_queue_complete':drivers/net/wireless/ath/ath9k/hif_usb.c:251:57: error: suggest braces around empty body in an 'else' statement [-Werror=empty-body]
251 | TX_STAT_INC(hif_dev, skb_failed);
Make both sets of macros proper expressions again.
--- drivers/net/wireless/ath/ath9k/htc.h | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-)
drivers/net/wireless/ath/ath9k/htc.h +7 -7
@@ -325,9 +325,9 @@ static inline struct ath9k_htc_tx_ctl *H }#ifdef CONFIG_ATH9K_HTC_DEBUGFS -#define __STAT_SAFE (hif_dev, expr) ((hif_dev)->htc_handle->drv_priv ? (expr) : 0) -#define CAB_STAT_INC (priv) ((priv)->debug.tx_stats.cab_queued++) -#define TX_QSTAT_INC (priv, q) ((priv)->debug.tx_stats.queue_stats[q]++) +#define __STAT_SAFE (hif_dev, expr) do { ((hif_dev)->htc_handle->drv_priv ? (expr) : 0); } while (0) +#define CAB_STAT_INC (priv) do { ((priv)->debug.tx_stats.cab_queued++); } while (0) +#define TX_QSTAT_INC (priv, q) do { ((priv)->debug.tx_stats.queue_stats[q]++); } while (0)#define TX_STAT_INC (hif_dev, c) \ __STAT_SAFE((hif_dev), (hif_dev)->htc_handle->drv_priv->debug.tx_stats.c++)
@@ -376,10 +376,10 @@ void ath9k_htc_get_et_stats(struct ieee8 struct ethtool_stats *stats, u64 *data);#else -#define TX_STAT_INC (hif_dev, c) -#define TX_STAT_ADD (hif_dev, c, a) -#define RX_STAT_INC (hif_dev, c) -#define RX_STAT_ADD (hif_dev, c, a) +#define TX_STAT_INC (hif_dev, c) do { } while (0) +#define TX_STAT_ADD (hif_dev, c, a) do { } while (0) +#define RX_STAT_INC (hif_dev, c) do { } while (0) +#define RX_STAT_ADD (hif_dev, c, a) do { } while (0)#define CAB_STAT_INC (priv)#define TX_QSTAT_INC (priv, c)
Greg Kroah-Hartman
maintainerPATCH 196/252 kbuild: Port silent mode detection to future gnu make.
In reply to Greg Kroah-HartmanFrom: Dmitry Goncharov <[email protected]>
commit 4bf73588165ba7d32131a043775557a54b6e1db5 upstream.
Port silent mode detection to the future (post make-4.4) versions of gnu make.
Makefile contains the following piece of make code to detect if option -s is specified on the command line.
ifneq ($(findstring s,$(filter-out --%,$(MAKEFLAGS))),)
This code is executed by make at parse time and assumes that MAKEFLAGS does not contain command line variable definitions.
Currently if the user defines a=s on the command line, then at build only time MAKEFLAGS contains " -- a=s".
However, starting with commit dc2d963989b96161472b2cd38cef5d1f4851ea34 MAKEFLAGS contains command line definitions at both parse time and build time.
This '-s' detection code then confuses a command line variable definition which contains letter 's' with option -s.
$ # old make $ make net/wireless/ocb.o a=s CALL scripts/checksyscalls.sh DESCEND objtool $ # this a new make which defines makeflags at parse time $ ~/src/gmake/make/l64/make net/wireless/ocb.o a=s $
We can see here that the letter 's' from 'a=s' was confused with -s.
This patch checks for presence of -s using a method recommended by the make manual here
https://www.gnu.org/software/make/manual/make.html#Testing-Flags.
--- Makefile | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-)
Makefile +10 -3
@@ -88,10 +88,17 @@ endif # If the user is running make -s (silent mode), suppress echoing of # commands +# make-4.0 (and later) keep single letter options in the 1st word of MAKEFLAGS. -ifneq ($(findstring s,$(filter-out --%,$(MAKEFLAGS))),) - quiet=silent_ - tools_silent=s +ifeq ($(filter 3.%,$(MAKE_VERSION)),) +silence:=$(findstring s,$(firstword -$(MAKEFLAGS))) +else +silence:=$(findstring s,$(filter-out --%,$(MAKEFLAGS))) +endif + +ifeq ($(silence),s) +quiet=silent_ +tools_silent=s endif export quiet Q KBUILD_VERBOSE
Greg Kroah-Hartman
maintainerPATCH 197/252 net/sched: Retire tcindex classifier
In reply to Greg Kroah-HartmanFrom: Jamal Hadi Salim <[email protected]>
commit 8c710f75256bb3cf05ac7b1672c82b92c43f3d28 upstream.
The tcindex classifier has served us well for about a quarter of a century but has not been getting much TLC due to lack of known users. Most recently it has become easy prey to syzkaller. For this reason, we are retiring it.
--- net/sched/Kconfig | 11 net/sched/Makefile | 1 net/sched/cls_tcindex.c | 698 ------------------------------------------------ 3 files changed, 710 deletions(-) delete mode 100644 net/sched/cls_tcindex.c delete mode 100644 tools/testing/selftests/tc-testing/tc-tests/filters/tcindex.json
net/sched/Kconfig +0 -11
@@ -458,17 +458,6 @@ config NET_CLS_BASIC To compile this code as a module, choose M here: the module will be called cls_basic. -config NET_CLS_TCINDEX - tristate "Traffic-Control Index (TCINDEX)" - select NET_CLS - ---help--- - Say Y here if you want to be able to classify packets based on - traffic control indices. You will want this feature if you want - to implement Differentiated Services together with DSMARK. - - To compile this code as a module, choose M here: the - module will be called cls_tcindex. - config NET_CLS_ROUTE4 tristate "Routing decision (ROUTE)" depends on INET
net/sched/Makefile +0 -1
@@ -62,7 +62,6 @@ obj-$(CONFIG_NET_CLS_U32) += cls_u32.o obj-$(CONFIG_NET_CLS_ROUTE4) += cls_route.o obj-$(CONFIG_NET_CLS_FW) += cls_fw.o obj-$(CONFIG_NET_CLS_RSVP) += cls_rsvp.o -obj-$(CONFIG_NET_CLS_TCINDEX) += cls_tcindex.o obj-$(CONFIG_NET_CLS_RSVP6) += cls_rsvp6.o obj-$(CONFIG_NET_CLS_BASIC) += cls_basic.o obj-$(CONFIG_NET_CLS_FLOW) += cls_flow.o
net/sched/cls_tcindex.c deleted +0 -698
698 lines not on this page · raw message
Greg Kroah-Hartman
maintainerPATCH 198/252 fs/jfs: fix shift exponent db_agl2size negative
In reply to Greg Kroah-HartmanFrom: Liu Shixin via Jfs-discussion <[email protected]>
[ Upstream commit fad376fce0af58deebc5075b8539dc05bf639af3 ]
As a shift exponent, db_agl2size can not be less than 0. Add the missing check to fix the shift-out-of-bounds bug reported by syzkaller:
UBSAN: shift-out-of-bounds in fs/jfs/jfs_dmap.c:2227:15 shift exponent -744642816 is negative
--- fs/jfs/jfs_dmap.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
fs/jfs/jfs_dmap.c +2 -1
@@ -206,7 +206,8 @@ int dbMount(struct inode *ipbmap) bmp->db_agwidth =le32_to_cpu (dbmp_le->dn_agwidth); bmp->db_agstart =le32_to_cpu (dbmp_le->dn_agstart); bmp->db_agl2size =le32_to_cpu (dbmp_le->dn_agl2size); -if (bmp->db_agl2size >L2MAXL2SIZE -L2MAXAG ) { +if (bmp->db_agl2size >L2MAXL2SIZE -L2MAXAG || + bmp->db_agl2size <0 ) { err = -EINVAL ; goto err_release_metapage; }
Signature · 1 line
2.39.2
Greg Kroah-Hartman
maintainerPATCH 199/252 pwm: stm32-lp: fix the check on arr and cmp registers update
In reply to Greg Kroah-HartmanFrom: Fabrice Gasnier <[email protected]>
[ Upstream commit 3066bc2d58be31275afb51a589668f265e419c37 ]
The ARR (auto reload register) and CMP (compare) registers are successively written. The status bits to check the update of these registers are polled together with regmap_read_poll_timeout(). The condition to end the loop may become true, even if one of the register isn't correctly updated.
So ensure both status bits are set before clearing them.
--- drivers/pwm/pwm-stm32-lp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/pwm/pwm-stm32-lp.c +1 -1
@@ -126,7 +126,7 @@ static int stm32_pwm_lp_apply(struct pwm_chip *chip, struct pwm_device *pwm,/* ensure CMP & ARR registers are properly written */ ret =regmap_read_poll_timeout (priv->regmap,STM32_LPTIM_ISR , val, - (val &STM32_LPTIM_CMPOK_ARROK ), + (val &STM32_LPTIM_CMPOK_ARROK ) ==STM32_LPTIM_CMPOK_ARROK ,100 ,1000 );if (ret) {dev_err (priv->chip.dev,"ARR/CMP registers write issue\n" );
Signature · 1 line
2.39.2
Greg Kroah-Hartman
maintainerPATCH 200/252 um: vector: Fix memory leak in vector_config
In reply to Greg Kroah-HartmanFrom: Xiang Yang <[email protected]>
[ Upstream commit 8f88c73afe481f93d40801596927e8c0047b6d96 ]
If the return value of the uml_parse_vector_ifspec function is NULL, we should call kfree(params) to prevent memory leak.
--- arch/um/drivers/vector_kern.c | 1 + 1 file changed, 1 insertion(+)
arch/um/drivers/vector_kern.c +1 -0
@@ -741,6 +741,7 @@ static int vector_config(char *str, char **error_out)if (parsed ==NULL ) { *error_out ="vector_config failed to parse parameters" ; +kfree (params);return -EINVAL ; }
Signature · 1 line
2.39.2
Greg Kroah-Hartman
maintainerPATCH 201/252 ubi: ensure that VID header offset + VID header size <= alloc, size
In reply to Greg Kroah-HartmanFrom: George Kennedy <[email protected]>
[ Upstream commit 1b42b1a36fc946f0d7088425b90d491b4257ca3e ]
Ensure that the VID header offset + VID header size does not exceed the allocated area to avoid slab OOB.
BUG: KASAN: slab-out-of-bounds in crc32_body lib/crc32.c:111 [inline] BUG: KASAN: slab-out-of-bounds in crc32_le_generic lib/crc32.c:179 [inline] BUG: KASAN: slab-out-of-bounds in crc32_le_base+0x58c/0x626 lib/crc32.c:197 Read of size 4 at addr ffff88802bb36f00 by task syz-executor136/1555 CPU: 2 PID: 1555 Comm: syz-executor136 Tainted: G W 6.0.0-1868 #1 Hardware name: Red Hat KVM, BIOS 1.13.0-2.module+el8.3.0+7860+a7792d29 04/01/2014 Call Trace: <TASK> __dump_stack lib/dump_stack.c:88 [inline] dump_stack_lvl+0x85/0xad lib/dump_stack.c:106 print_address_description mm/kasan/report.c:317 [inline] print_report.cold.13+0xb6/0x6bb mm/kasan/report.c:433 kasan_report+0xa7/0x11b mm/kasan/report.c:495 crc32_body lib/crc32.c:111 [inline] crc32_le_generic lib/crc32.c:179 [inline] crc32_le_base+0x58c/0x626 lib/crc32.c:197 ubi_io_write_vid_hdr+0x1b7/0x472 drivers/mtd/ubi/io.c:1067 create_vtbl+0x4d5/0x9c4 drivers/mtd/ubi/vtbl.c:317 create_empty_lvol drivers/mtd/ubi/vtbl.c:500 [inline] ubi_read_volume_table+0x67b/0x288a drivers/mtd/ubi/vtbl.c:812 ubi_attach+0xf34/0x1603 drivers/mtd/ubi/attach.c:1601 ubi_attach_mtd_dev+0x6f3/0x185e drivers/mtd/ubi/build.c:965 ctrl_cdev_ioctl+0x2db/0x347 drivers/mtd/ubi/cdev.c:1043 vfs_ioctl fs/ioctl.c:51 [inline] __do_sys_ioctl fs/ioctl.c:870 [inline] __se_sys_ioctl fs/ioctl.c:856 [inline] __x64_sys_ioctl+0x193/0x213 fs/ioctl.c:856 do_syscall_x64 arch/x86/entry/common.c:50 [inline] do_syscall_64+0x3e/0x86 arch/x86/entry/common.c:80 entry_SYSCALL_64_after_hwframe+0x63/0x0 RIP: 0033:0x7f96d5cf753d
Code:
RSP: 002b:00007fffd72206f8 EFLAGS: 00000246 ORIG_RAX: 0000000000000010
RAX: ffffffffffffffda RBX: 0000000000000000 RCX: 00007f96d5cf753d
RDX: 0000000020000080 RSI: 0000000040186f40 RDI: 0000000000000003
RBP: 0000000000400cd0 R08: 0000000000000000 R09: 0000000000000000
R10: 0000000000000000 R11: 0000000000000246 R12: 0000000000400be0
R13: 00007fffd72207e0 R14: 0000000000000000 R15: 0000000000000000
</TASK> Allocated by task 1555: kasan_save_stack+0x20/0x3d mm/kasan/common.c:38 kasan_set_track mm/kasan/common.c:45 [inline] set_alloc_info mm/kasan/common.c:437 [inline] ____kasan_kmalloc mm/kasan/common.c:516 [inline] __kasan_kmalloc+0x88/0xa3 mm/kasan/common.c:525 kasan_kmalloc include/linux/kasan.h:234 [inline] __kmalloc+0x138/0x257 mm/slub.c:4429 kmalloc include/linux/slab.h:605 [inline] ubi_alloc_vid_buf drivers/mtd/ubi/ubi.h:1093 [inline] create_vtbl+0xcc/0x9c4 drivers/mtd/ubi/vtbl.c:295 create_empty_lvol drivers/mtd/ubi/vtbl.c:500 [inline] ubi_read_volume_table+0x67b/0x288a drivers/mtd/ubi/vtbl.c:812 ubi_attach+0xf34/0x1603 drivers/mtd/ubi/attach.c:1601 ubi_attach_mtd_dev+0x6f3/0x185e drivers/mtd/ubi/build.c:965 ctrl_cdev_ioctl+0x2db/0x347 drivers/mtd/ubi/cdev.c:1043 vfs_ioctl fs/ioctl.c:51 [inline] __do_sys_ioctl fs/ioctl.c:870 [inline] __se_sys_ioctl fs/ioctl.c:856 [inline] __x64_sys_ioctl+0x193/0x213 fs/ioctl.c:856 do_syscall_x64 arch/x86/entry/common.c:50 [inline] do_syscall_64+0x3e/0x86 arch/x86/entry/common.c:80 entry_SYSCALL_64_after_hwframe+0x63/0x0 The buggy address belongs to the object at ffff88802bb36e00 which belongs to the cache kmalloc-256 of size 256
The buggy address is located 0 bytes to the right of
256-byte region [ffff88802bb36e00, ffff88802bb36f00)
The buggy address belongs to the physical page:
page:00000000ea4d1263 refcount:1 mapcount:0 mapping:0000000000000000 index:0x0 pfn:0x2bb36
head:00000000ea4d1263 order:1 compound_mapcount:0 compound_pincount:0
flags: 0xfffffc0010200(slab|head|node=0|zone=1|lastcpupid=0x1fffff)
raw: 000fffffc0010200 ffffea000066c300 dead000000000003 ffff888100042b40
raw: 0000000000000000 0000000000100010 00000001ffffffff 0000000000000000
page dumped because: kasan: bad access detected
Memory state around the buggy address:
ffff88802bb36e00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
ffff88802bb36e80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
>ffff88802bb36f00: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc
^
ffff88802bb36f80: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc
ffff88802bb37000: fa fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
==================================================================--- drivers/mtd/ubi/build.c | 6 ++++++ 1 file changed, 6 insertions(+)
drivers/mtd/ubi/build.c +6 -0
@@ -656,6 +656,12 @@ static int io_init(struct ubi_device *ubi, int max_beb_per1024) ubi->ec_hdr_alsize =ALIGN (UBI_EC_HDR_SIZE , ubi->hdrs_min_io_size); ubi->vid_hdr_alsize =ALIGN (UBI_VID_HDR_SIZE , ubi->hdrs_min_io_size); +if (ubi->vid_hdr_offset && ((ubi->vid_hdr_offset +UBI_VID_HDR_SIZE ) > + ubi->vid_hdr_alsize)) { +ubi_err (ubi,"VID header offset %d too large." , ubi->vid_hdr_offset); +return -EINVAL ; + } +dbg_gen ("min_io_size %d" , ubi->min_io_size);dbg_gen ("max_write_size %d" , ubi->max_write_size);dbg_gen ("hdrs_min_io_size %d" , ubi->hdrs_min_io_size);
Signature · 1 line
2.39.2
Greg Kroah-Hartman
maintainerPATCH 202/252 ubifs: Rectify space budget for ubifs_symlink() if symlink is encrypted
In reply to Greg Kroah-HartmanFrom: Zhihao Cheng <[email protected]>
[ Upstream commit c2c36cc6ca23e614f9e4238d0ecf48549ee9002a ]
Fix bad space budget when symlink file is encrypted. Bad space budget may let make_reservation() return with -ENOSPC, which could turn ubifs to read-only mode in do_writepage() process.
Fetch a reproducer in [Link].
--- fs/ubifs/dir.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
fs/ubifs/dir.c +1 -1
@@ -1141,7 +1141,6 @@ static int ubifs_symlink(struct inode *dir, struct dentry *dentry,int err, sz_change, len =strlen (symname);struct fscrypt_str disk_link;struct ubifs_budget_req req = { .new_ino =1 , .new_dent =1 , - .new_ino_d =ALIGN (len,8 ), .dirtied_ino =1 };struct fscrypt_name nm;
@@ -1157,6 +1156,7 @@ static int ubifs_symlink(struct inode *dir, struct dentry *dentry,* Budget request settings: new inode, new direntry and changing parent * directory inode. */ + req.new_ino_d =ALIGN (disk_link.len -1 ,8 ); err =ubifs_budget_space (c, &req);if (err)return err;
Signature · 1 line
2.39.2
Greg Kroah-Hartman
maintainerPATCH 203/252 ubifs: Rectify space budget for ubifs_xrename()
In reply to Greg Kroah-HartmanFrom: Zhihao Cheng <[email protected]>
[ Upstream commit 1b2ba09060e41adb356b9ae58ef94a7390928004 ]
There is no space budget for ubifs_xrename(). It may let make_reservation() return with -ENOSPC, which could turn ubifs to read-only mode in do_writepage() process. Fix it by adding space budget for ubifs_xrename().
Fetch a reproducer in [Link].
--- fs/ubifs/dir.c | 5 +++++ 1 file changed, 5 insertions(+)
fs/ubifs/dir.c +5 -0
@@ -1549,6 +1549,10 @@ static int ubifs_xrename(struct inode *old_dir, struct dentry *old_dentry,return err; } + err =ubifs_budget_space (c, &req); +if (err) + goto out; +lock_4_inodes (old_dir, new_dir,NULL ,NULL ); time =current_time (old_dir);
@@ -1574,6 +1578,7 @@ static int ubifs_xrename(struct inode *old_dir, struct dentry *old_dentry,unlock_4_inodes (old_dir, new_dir,NULL ,NULL );ubifs_release_budget (c, &req); +out:fscrypt_free_filename (&fst_nm);fscrypt_free_filename (&snd_nm);return err;
Signature · 1 line
2.39.2
Greg Kroah-Hartman
maintainerPATCH 204/252 ubifs: Fix wrong dirty space budget for dirty inode
In reply to Greg Kroah-HartmanFrom: Zhihao Cheng <[email protected]>
[ Upstream commit b248eaf049d9cdc5eb76b59399e4d3de233f02ac ]
Each dirty inode should reserve 'c->bi.inode_budget' bytes in space budget calculation. Currently, space budget for dirty inode reports more space than what UBIFS actually needs to write.
--- fs/ubifs/budget.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
fs/ubifs/budget.c +1 -1
@@ -415,7 +415,7 @@ static int calc_dd_growth(const struct ubifs_info *c, dd_growth = req->dirtied_page ? c->bi.page_budget :0 ;if (req->dirtied_ino) - dd_growth += c->bi.inode_budget << (req->dirtied_ino -1 ); + dd_growth += c->bi.inode_budget * req->dirtied_ino;if (req->mod_dent) dd_growth += c->bi.dent_budget; dd_growth += req->dirtied_ino_d;
Signature · 1 line
2.39.2
Greg Kroah-Hartman
maintainerPATCH 205/252 ubifs: do_rename: Fix wrong space budget when target inodes nlink > 1
In reply to Greg Kroah-HartmanFrom: Zhihao Cheng <[email protected]>
[ Upstream commit 25fce616a61fc2f1821e4a9ce212d0e064707093 ]
If target inode is a special file (eg. block/char device) with nlink count greater than 1, the inode with ui->data will be re-written on disk. However, UBIFS losts target inode's data_len while doing space budget. Bad space budget may let make_reservation() return with -ENOSPC, which could turn ubifs to read-only mode in do_writepage() process.
Fetch a reproducer in [Link].
--- fs/ubifs/dir.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-)
fs/ubifs/dir.c +5 -1
@@ -1309,9 +1309,13 @@ static int do_rename(struct inode *old_dir, struct dentry *old_dentry, old_dentry, old_inode->i_ino, old_dir->i_ino, new_dentry, new_dir->i_ino, flags); -if (unlink) +if (unlink) {ubifs_assert (c,inode_is_locked (new_inode)); +/* Budget for old inode's data when its nlink > 1. */ + req.dirtied_ino_d =ALIGN (ubifs_inode (new_inode)->data_len,8 ); + } +if (unlink && is_dir) { err =ubifs_check_dir_empty (new_inode);if (err)
Signature · 1 line
2.39.2
Greg Kroah-Hartman
maintainerPATCH 206/252 ubifs: Reserve one leb for each journal head while doing budget
In reply to Greg Kroah-HartmanFrom: Zhihao Cheng <[email protected]>
[ Upstream commit e874dcde1cbf82c786c0e7f2899811c02630cc52 ]
UBIFS calculates available space by c->main_bytes - c->lst.total_used (which means non-index lebs' free and dirty space is accounted into total available), then index lebs and four lebs (one for gc_lnum, one for deletions, two for journal heads) are deducted.
In following situation, ubifs may get -ENOSPC from make_reservation():
LEB 84: DATAHD free 122880 used 1920 dirty 2176 dark 6144 LEB 110:DELETION free 126976 used 0 dirty 0 dark 6144 (empty) LEB 201:gc_lnum free 126976 used 0 dirty 0 dark 6144 LEB 272:GCHD free 77824 used 47672 dirty 1480 dark 6144
LEB 356:BASEHD free 0 used 39776 dirty 87200 dark 6144
OTHERS: index lebs, zero-available non-index lebs
UBIFS calculates the available bytes is 6888 (How to calculate it:
126976 * 5[remain main bytes] - 1920[used] - 47672[used] - 39776[used] - 126976 * 1[deletions] - 126976 * 1[gc_lnum] - 126976 * 2[journal heads]
- 6144 * 5[dark] = 6888) after doing budget, however UBIFS cannot use BASEHD's dirty space(87200), because UBIFS cannot find next BASEHD to reclaim current BASEHD. (c->bi.min_idx_lebs equals to c->lst.idx_lebs, the empty leb won't be found by ubifs_find_free_space(), and dirty index lebs won't be picked as gced lebs. All non-index lebs has dirty space less then c->dead_wm, non-index lebs won't be picked as gced lebs either. So new free lebs won't be produced.). See more details in Link.
To fix it, reserve one leb for each journal head while doing budget.
--- fs/ubifs/budget.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-)
fs/ubifs/budget.c +3 -4
@@ -224,11 +224,10 @@ long long ubifs_calc_available(const struct ubifs_info *c, int min_idx_lebs) subtract_lebs +=1 ;/* -* The GC journal head LEB is not really accessible. And since -* different write types go to different heads, we may count only on -* one head's space. +* Since different write types go to different heads, we should +* reserve one leb for each head. */ - subtract_lebs += c->jhead_cnt -1 ; + subtract_lebs += c->jhead_cnt;/* We also reserve one LEB for deletions, which bypass budgeting */ subtract_lebs +=1 ;
Signature · 1 line
2.39.2
Greg Kroah-Hartman
maintainerPATCH 207/252 ubi: Fix use-after-free when volume resizing failed
In reply to Greg Kroah-HartmanFrom: Li Zetao <[email protected]>
[ Upstream commit 9af31d6ec1a4be4caab2550096c6bd2ba8fba472 ]
There is an use-after-free problem reported by KASAN:
==================================================================
BUG: KASAN: use-after-free in ubi_eba_copy_table+0x11f/0x1c0 [ubi] Read of size 8 at addr ffff888101eec008 by task ubirsvol/4735 CPU: 2 PID: 4735 Comm: ubirsvol Not tainted 6.1.0-rc1-00003-g84fa3304a7fc-dirty #14 Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.14.0-1.fc33 04/01/2014 Call Trace: <TASK> dump_stack_lvl+0x34/0x44 print_report+0x171/0x472 kasan_report+0xad/0x130 ubi_eba_copy_table+0x11f/0x1c0 [ubi] ubi_resize_volume+0x4f9/0xbc0 [ubi] ubi_cdev_ioctl+0x701/0x1850 [ubi] __x64_sys_ioctl+0x11d/0x170 do_syscall_64+0x35/0x80 entry_SYSCALL_64_after_hwframe+0x46/0xb0 </TASK>
When ubi_change_vtbl_record() returns an error in ubi_resize_volume(), "new_eba_tbl" will be freed on error handing path, but it is holded by "vol->eba_tbl" in ubi_eba_replace_table(). It means that the liftcycle of "vol->eba_tbl" and "vol" are different, so when resizing volume in next time, it causing an use-after-free fault.
Fix it by not freeing "new_eba_tbl" after it replaced in ubi_eba_replace_table(), while will be freed in next volume resizing.
--- drivers/mtd/ubi/vmt.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
drivers/mtd/ubi/vmt.c +3 -1
@@ -477,7 +477,7 @@ int ubi_resize_volume(struct ubi_volume_desc *desc, int reserved_pebs)for (i =0 ; i < -pebs; i++) { err =ubi_eba_unmap_leb (ubi, vol, reserved_pebs + i);if (err) - goto out_acc; + goto out_free; }spin_lock (&ubi->volumes_lock); ubi->rsvd_pebs += pebs;
@@ -525,6 +525,8 @@ int ubi_resize_volume(struct ubi_volume_desc *desc, int reserved_pebs) ubi->avail_pebs += pebs;spin_unlock (&ubi->volumes_lock); } +return err; + out_free:kfree (new_eba_tbl);return err;
Signature · 1 line
2.39.2
Greg Kroah-Hartman
maintainerPATCH 208/252 ubi: Fix unreferenced object reported by kmemleak in ubi_resize_volume()
In reply to Greg Kroah-HartmanFrom: Li Zetao <[email protected]>
[ Upstream commit 1e591ea072df7211f64542a09482b5f81cb3ad27 ]
There is a memory leaks problem reported by kmemleak:
unreferenced object 0xffff888102007a00 (size 128):
comm "ubirsvol", pid 32090, jiffies 4298464136 (age 2361.231s) hex dump (first 32 bytes):
ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ................ ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ................
backtrace:
[<ffffffff8176cecd>] __kmalloc+0x4d/0x150 [<ffffffffa02a9a36>] ubi_eba_create_table+0x76/0x170 [ubi] [<ffffffffa029764e>] ubi_resize_volume+0x1be/0xbc0 [ubi] [<ffffffffa02a3321>] ubi_cdev_ioctl+0x701/0x1850 [ubi] [<ffffffff81975d2d>] __x64_sys_ioctl+0x11d/0x170 [<ffffffff83c142a5>] do_syscall_64+0x35/0x80 [<ffffffff83e0006a>] entry_SYSCALL_64_after_hwframe+0x46/0xb0
This is due to a mismatch between create and destroy interfaces, and in detail that "new_eba_tbl" created by ubi_eba_create_table() but destroyed by kfree(), while will causing "new_eba_tbl->entries" not freed.
Fix it by replacing kfree(new_eba_tbl) withubi_eba_destroy_table(new_eba_tbl)
--- drivers/mtd/ubi/vmt.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/mtd/ubi/vmt.c +1 -1
@@ -528,7 +528,7 @@ int ubi_resize_volume(struct ubi_volume_desc *desc, int reserved_pebs)return err; out_free: -kfree (new_eba_tbl); +ubi_eba_destroy_table (new_eba_tbl);return err; }
Signature · 1 line
2.39.2
Greg Kroah-Hartman
maintainerPATCH 209/252 ubi: Fix possible null-ptr-deref in ubi_free_volume()
In reply to Greg Kroah-HartmanFrom: Yang Yingliang <[email protected]>
[ Upstream commit c15859bfd326c10230f09cb48a17f8a35f190342 ]
It willl cause null-ptr-deref in the following case:
uif_init()
ubi_add_volume()
cdev_add() -> if it fails, call kill_volumes()
device_register()kill_volumes() -> if ubi_add_volume() fails call this function
ubi_free_volume()
cdev_del()
device_unregister() -> trying to delete a not added device,
it causes null-ptr-derefSo in ubi_free_volume(), it delete devices whether they are added or not, it will causes null-ptr-deref.
Handle the error case whlie calling ubi_add_volume() to fix this problem. If add volume fails, set the corresponding vol to null, so it can not be accessed in kill_volumes() and release the resource in ubi_add_volume() error path.
--- drivers/mtd/ubi/build.c | 1 + drivers/mtd/ubi/vmt.c | 12 ++++++------ 2 files changed, 7 insertions(+), 6 deletions(-)
drivers/mtd/ubi/build.c +1 -0
@@ -480,6 +480,7 @@ static int uif_init(struct ubi_device *ubi) err =ubi_add_volume (ubi, ubi->volumes[i]);if (err) {ubi_err (ubi,"cannot add volume %d" , i); + ubi->volumes[i] =NULL ; goto out_volumes; } }
drivers/mtd/ubi/vmt.c +6 -6
@@ -595,6 +595,7 @@ int ubi_add_volume(struct ubi_device *ubi, struct ubi_volume *vol)if (err) {ubi_err (ubi,"cannot add character device for volume %d, error %d" , vol_id, err); +vol_release (&vol->dev);return err; }
@@ -605,15 +606,14 @@ int ubi_add_volume(struct ubi_device *ubi, struct ubi_volume *vol) vol->dev.groups = volume_dev_groups;dev_set_name (&vol->dev,"%s_%d" , ubi->ubi_name, vol->vol_id); err =device_register (&vol->dev); -if (err) - goto out_cdev; +if (err) { +cdev_del (&vol->cdev); +put_device (&vol->dev); +return err; + }self_check_volumes (ubi);return err; - -out_cdev: -cdev_del (&vol->cdev); -return err; }/**
Signature · 1 line
2.39.2
Greg Kroah-Hartman
maintainerPATCH 210/252 ubifs: Re-statistic cleaned znode count if commit failed
In reply to Greg Kroah-HartmanFrom: Zhihao Cheng <[email protected]>
[ Upstream commit 944e096aa24071d3fe22822f6249d3ae309e39ea ]
Dirty znodes will be written on flash in committing process with following states:
process A | znode state
------------------------------------------------------do_commit | DIRTY_ZNODE
ubifs_tnc_start_commit | DIRTY_ZNODE
get_znodes_to_commit | DIRTY_ZNODE | COW_ZNODE
layout_commit | DIRTY_ZNODE | COW_ZNODE
fill_gap | 0
write master | 0 or OBSOLETE_ZNODE
process B | znode state
------------------------------------------------------do_commit | DIRTY_ZNODE[1]
ubifs_tnc_start_commit | DIRTY_ZNODE
get_znodes_to_commit | DIRTY_ZNODE | COW_ZNODE
ubifs_tnc_end_commit | DIRTY_ZNODE | COW_ZNODE
write_index | 0 write master | 0 or OBSOLETE_ZNODE[2] or | DIRTY_ZNODE[3]
[1] znode is dirtied without concurrent committing process
[2] znode is copied up (re-dirtied by other process) before cleaned up in committing process
[3] znode is re-dirtied after cleaned up in committing process
Currently, the clean znode count is updated in free_obsolete_znodes(), which is called only in normal path. If do_commit failed, clean znode count won't be updated, which triggers a failure ubifs assertion[4] in ubifs_tnc_close():
ubifs_assert_failed [ubifs]: UBIFS assert failed: freed == n
[4] Commit 380347e9ca7682 ("UBIFS: Add an assertion for clean_zn_cnt").
Fix it by re-statisticing cleaned znode count in tnc_destroy_cnext().
Fetch a reproducer in [Link].
--- fs/ubifs/tnc.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+)
fs/ubifs/tnc.c +15 -0
@@ -3046,6 +3046,21 @@ static void tnc_destroy_cnext(struct ubifs_info *c) cnext = cnext->cnext;if (ubifs_zn_obsolete (znode))kfree (znode); +else if (!ubifs_zn_cow (znode)) { +/* +* Don't forget to update clean znode count after +* committing failed, because ubifs will check this +* count while closing tnc. Non-obsolete znode could +* be re-dirtied during committing process, so dirty +* flag is untrustable. The flag 'COW_ZNODE' is set +* for each dirty znode before committing, and it is +* cleared as long as the znode become clean, so we +* can statistic clean znode count according to this +* flag. +*/ +atomic_long_inc (&c->clean_zn_cnt); +atomic_long_inc (&ubifs_clean_zn_cnt); + } }while (cnext && cnext != c->cnext); }
Signature · 1 line
2.39.2
Greg Kroah-Hartman
maintainerPATCH 211/252 ubifs: dirty_cow_znode: Fix memleak in error handling path
In reply to Greg Kroah-HartmanFrom: Zhihao Cheng <[email protected]>
[ Upstream commit 122deabfe1428bffe95e2bf364ff8a5059bdf089 ]
Following process will cause a memleak for copied up znode:
dirty_cow_znode
zn = copy_znode(c, znode);
err = insert_old_idx(c, zbr->lnum, zbr->offs);
if (unlikely(err))
return ERR_PTR(err); // No one refers to zn.
Fix it by adding copied znode back to tnc, then it will be freed by ubifs_destroy_tnc_subtree() while closing tnc.
Fetch a reproducer in [Link].
--- fs/ubifs/tnc.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-)
fs/ubifs/tnc.c +8 -1
@@ -279,11 +279,18 @@ static struct ubifs_znode *dirty_cow_znode(struct ubifs_info *c,if (zbr->len) { err =insert_old_idx (c, zbr->lnum, zbr->offs);if (unlikely (err)) -return ERR_PTR (err); +/* +* Obsolete znodes will be freed by tnc_destroy_cnext() +* or free_obsolete_znodes(), copied up znodes should +* be added back to tnc and freed by +* ubifs_destroy_tnc_subtree(). +*/ + goto out; err =add_idx_dirt (c, zbr->lnum, zbr->len); }else err =0 ; +out: zbr->znode = zn; zbr->lnum =0 ; zbr->offs =0 ;
Signature · 1 line
2.39.2
Greg Kroah-Hartman
maintainerPATCH 212/252 ubifs: ubifs_writepage: Mark page dirty after writing inode failed
In reply to Greg Kroah-HartmanFrom: Zhihao Cheng <[email protected]>
[ Upstream commit fb8bc4c74ae4526d9489362ab2793a936d072b84 ]
There are two states for ubifs writing pages:
1. Dirty, Private
2. Not Dirty, Not Private
There is a third possibility which maybe related to [1] that page is private but not dirty caused by following process:
PA
lock(page)ubifs_write_end
attach_page_private // set Private
__set_page_dirty_nobuffers // set Dirty
unlock(page)
write_cache_pages
lock(page)
clear_page_dirty_for_io(page) // clear Dirty
ubifs_writepage
write_inode
// fail, goto out, following codes are not executed
// do_writepage
// set_page_writeback // set Writeback
// detach_page_private // clear Private
// end_page_writeback // clear Writeback
out:
unlock(page) // Private, Not Dirty
PB
ksys_fadvise64_64
generic_fadvise
invalidate_inode_page
// page is neither Dirty nor Writeback
invalidate_complete_page
// page_has_private is true
try_to_release_page
ubifs_releasepage
ubifs_assert(c, 0) !!!Then we may get following assertion failed:
UBIFS error (ubi0:0 pid 1492): ubifs_assert_failed [ubifs]:
UBIFS assert failed: 0, in fs/ubifs/file.c:1499 UBIFS warning (ubi0:0 pid 1492): ubifs_ro_mode [ubifs]:
switched to read-only mode, error -22
CPU: 2 PID: 1492 Comm: aa Not tainted 5.16.0-rc2-00012-g7bb767dee0ba-dirty
Call Trace:
dump_stack+0x13/0x1b
ubifs_ro_mode+0x54/0x60 [ubifs]
ubifs_assert_failed+0x4b/0x80 [ubifs]
ubifs_releasepage+0x7e/0x1e0 [ubifs]
try_to_release_page+0x57/0xe0
invalidate_inode_page+0xfb/0x130
invalidate_mapping_pagevec+0x12/0x20
generic_fadvise+0x303/0x3c0
vfs_fadvise+0x35/0x40
ksys_fadvise64_64+0x4c/0xb0Jump [2] to find a reproducer.
[1] https://linux-mtd.infradead.narkive.com/NQoBeT1u/patch-rfc-ubifs-fix-assert-failed-in-ubifs-set-page-dirty
[2] https://bugzilla.kernel.org/show_bug.cgi?id=215357
--- fs/ubifs/file.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-)
fs/ubifs/file.c +9 -3
@@ -1043,7 +1043,7 @@ static int ubifs_writepage(struct page *page, struct writeback_control *wbc)if (page->index >= synced_i_size >>PAGE_SHIFT ) { err = inode->i_sb->s_op->write_inode (inode,NULL );if (err) - goto out_unlock; + goto out_redirty;/* * The inode has been written, but the write-buffer has * not been synchronized, so in case of an unclean
@@ -1071,11 +1071,17 @@ static int ubifs_writepage(struct page *page, struct writeback_control *wbc)if (i_size > synced_i_size) { err = inode->i_sb->s_op->write_inode (inode,NULL );if (err) - goto out_unlock; + goto out_redirty; }return do_writepage (page, len); - +out_redirty: +/* +* redirty_page_for_writepage() won't call ubifs_dirty_inode() because +* it passes I_DIRTY_PAGES flag while calling __mark_inode_dirty(), so +* there is no need to do space budget for dirty inode. +*/ +redirty_page_for_writepage (wbc, page); out_unlock:unlock_page (page);return err;
Signature · 1 line
2.39.2
Greg Kroah-Hartman
maintainerPATCH 213/252 ubi: Fix UAF wear-leveling entry in eraseblk_count_seq_show()
In reply to Greg Kroah-HartmanFrom: Zhihao Cheng <[email protected]>
[ Upstream commit a240bc5c43130c6aa50831d7caaa02a1d84e1bce ]
Wear-leveling entry could be freed in error path, which may be accessed again in eraseblk_count_seq_show(), for example:
__erase_worker eraseblk_count_seq_show
wl = ubi->lookuptbl[*block_number]
if (wl)
wl_entry_destroy
ubi->lookuptbl[e->pnum] = NULL
kmem_cache_free(ubi_wl_entry_slab, e)
erase_count = wl->ec // UAF!Wear-leveling entry updating/accessing in ubi->lookuptbl should be protected by ubi->wl_lock, fix it by adding ubi->wl_lock to serialize wl entry accessing between wl_entry_destroy() and eraseblk_count_seq_show().
Fetch a reproducer in [Link].
--- drivers/mtd/ubi/wl.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-)
drivers/mtd/ubi/wl.c +8 -1
@@ -865,8 +865,11 @@ static int wear_leveling_worker(struct ubi_device *ubi, struct ubi_work *wrk, err =do_sync_erase (ubi, e1, vol_id, lnum,0 );if (err) { -if (e2) +if (e2) { +spin_lock (&ubi->wl_lock);wl_entry_destroy (ubi, e2); +spin_unlock (&ubi->wl_lock); + } goto out_ro; }
@@ -1096,14 +1099,18 @@ static int __erase_worker(struct ubi_device *ubi, struct ubi_work *wl_wrk)/* Re-schedule the LEB for erasure */ err1 =schedule_erase (ubi, e, vol_id, lnum,0 , false);if (err1) { +spin_lock (&ubi->wl_lock);wl_entry_destroy (ubi, e); +spin_unlock (&ubi->wl_lock); err = err1; goto out_ro; }return err; } +spin_lock (&ubi->wl_lock);wl_entry_destroy (ubi, e); +spin_unlock (&ubi->wl_lock);if (err != -EIO )/* * If this is not %-EIO, we have no idea what to do. Scheduling
Signature · 1 line
2.39.2
Greg Kroah-Hartman
maintainerPATCH 214/252 ubi: ubi_wl_put_peb: Fix infinite loop when wear-leveling work failed
In reply to Greg Kroah-HartmanFrom: Zhihao Cheng <[email protected]>
[ Upstream commit 4d57a7333e26040f2b583983e1970d9d460e56b0 ]
Following process will trigger an infinite loop in ubi_wl_put_peb():
ubifs_bgt ubi_bgtubifs_leb_unmap
ubi_leb_unmap
ubi_eba_unmap_leb
ubi_wl_put_peb wear_leveling_worker
e1 = rb_entry(rb_first(&ubi->used)
e2 = get_peb_for_wl(ubi)
ubi_io_read_vid_hdr // return err (flash fault)
out_error:
ubi->move_from = ubi->move_to = NULL
wl_entry_destroy(ubi, e1)
ubi->lookuptbl[e->pnum] = NULL
retry:
e = ubi->lookuptbl[pnum]; // return NULL
if (e == ubi->move_from) { // NULL == NULL gets true
goto retry; // infinite loop !!!$ top PID USER PR NI VIRT RES SHR S %CPU %MEM COMMAND 7676 root 20 0 0 0 0 R 100.0 0.0 ubifs_bgt0_0
Fix it by:
1) Letting ubi_wl_put_peb() returns directly if wearl leveling entry has
been removed from 'ubi->lookuptbl'.
2) Using 'ubi->wl_lock' protecting wl entry deletion to preventing an use-after-free problem for wl entry in ubi_wl_put_peb().
Fetch a reproducer in [Link].
--- drivers/mtd/ubi/wl.c | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-)
drivers/mtd/ubi/wl.c +14 -2
@@ -951,11 +951,11 @@ static int wear_leveling_worker(struct ubi_device *ubi, struct ubi_work *wrk,spin_lock (&ubi->wl_lock); ubi->move_from = ubi->move_to =NULL ; ubi->move_to_put = ubi->wl_scheduled =0 ; +wl_entry_destroy (ubi, e1); +wl_entry_destroy (ubi, e2);spin_unlock (&ubi->wl_lock);ubi_free_vid_buf (vidb); -wl_entry_destroy (ubi, e1); -wl_entry_destroy (ubi, e2); out_ro:ubi_ro_mode (ubi);
@@ -1226,6 +1226,18 @@ int ubi_wl_put_peb(struct ubi_device *ubi, int vol_id, int lnum, retry:spin_lock (&ubi->wl_lock); e = ubi->lookuptbl[pnum]; +if (!e) { +/* +* This wl entry has been removed for some errors by other +* process (eg. wear leveling worker), corresponding process +* (except __erase_worker, which cannot concurrent with +* ubi_wl_put_peb) will set ubi ro_mode at the same time, +* just ignore this wl entry. +*/ +spin_unlock (&ubi->wl_lock); +up_read (&ubi->fm_protect); +return 0 ; + }if (e == ubi->move_from) {/* * User is putting the physical eraseblock which was selected to
Signature · 1 line
2.39.2
Greg Kroah-Hartman
maintainerPATCH 215/252 x86: um: vdso: Add %rcx and %r11 to the syscall clobber list
In reply to Greg Kroah-HartmanFrom: Ammar Faizi <[email protected]>
[ Upstream commit 5541992e512de8c9133110809f767bd1b54ee10d ]
The 'syscall' instruction clobbers '%rcx' and '%r11', but they are not listed in the inline Assembly that performs the syscall instruction.
No real bug is found. It wasn't buggy by luck because '%rcx' and '%r11' are caller-saved registers, and not used in the functions, and the functions are never inlined.
Add them to the clobber list for code correctness.
--- arch/x86/um/vdso/um_vdso.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-)
arch/x86/um/vdso/um_vdso.c +8 -4
@@ -20,8 +20,10 @@ int __vdso_clock_gettime(clockid_t clock, struct timespec *ts) {long ret; - asm("syscall" :"=a" (ret) : -"0" (__NR_clock_gettime),"D" (clock),"S" (ts) :"memory" ); + asm("syscall" + :"=a" (ret) + :"0" (__NR_clock_gettime),"D" (clock),"S" (ts) + :"rcx" ,"r11" ,"memory" );return ret; }
@@ -32,8 +34,10 @@ int __vdso_gettimeofday(struct timeval *tv, struct timezone *tz) {long ret; - asm("syscall" :"=a" (ret) : -"0" (__NR_gettimeofday),"D" (tv),"S" (tz) :"memory" ); + asm("syscall" + :"=a" (ret) + :"0" (__NR_gettimeofday),"D" (tv),"S" (tz) + :"rcx" ,"r11" ,"memory" );return ret; }
Signature · 1 line
2.39.2
Greg Kroah-Hartman
maintainerPATCH 216/252 watchdog: at91sam9_wdt: use devm_request_irq to avoid missing free_irq() in error path
In reply to Greg Kroah-HartmanFrom: ruanjinjie <[email protected]>
[ Upstream commit 07bec0e09c1afbab4c5674fd2341f4f52d594f30 ]
free_irq() is missing in case of error in at91_wdt_init(), use devm_request_irq to fix that.
--- drivers/watchdog/at91sam9_wdt.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-)
drivers/watchdog/at91sam9_wdt.c +3 -4
@@ -206,10 +206,9 @@ static int at91_wdt_init(struct platform_device *pdev, struct at91wdt *wdt) "min heartbeat and max heartbeat might be too close for the system to handle it correctly\n");if ((tmp &AT91_WDT_WDFIEN ) && wdt->irq) { - err =request_irq (wdt->irq, wdt_interrupt, -IRQF_SHARED |IRQF_IRQPOLL | -IRQF_NO_SUSPEND , - pdev->name, wdt); + err =devm_request_irq (dev, wdt->irq, wdt_interrupt, +IRQF_SHARED |IRQF_IRQPOLL |IRQF_NO_SUSPEND , + pdev->name, wdt);if (err)return err; }
Signature · 1 line
2.39.2
Greg Kroah-Hartman
maintainerPATCH 217/252 watchdog: Fix kmemleak in watchdog_cdev_register
In reply to Greg Kroah-HartmanFrom: Chen Jun <[email protected]>
[ Upstream commit 13721a2ac66b246f5802ba1b75ad8637e53eeecc ]
kmemleak reports memory leaks in watchdog_dev_register, as follows:
unreferenced object 0xffff888116233000 (size 2048):
comm ""modprobe"", pid 28147, jiffies 4353426116 (age 61.741s) hex dump (first 32 bytes):
80 fa b9 05 81 88 ff ff 08 30 23 16 81 88 ff ff .........0#.....
08 30 23 16 81 88 ff ff 00 00 00 00 00 00 00 00 .0#.............
backtrace:
[<000000007f001ffd>] __kmem_cache_alloc_node+0x157/0x220
[<000000006a389304>] kmalloc_trace+0x21/0x110
[<000000008d640eea>] watchdog_dev_register+0x4e/0x780 [watchdog]
[<0000000053c9f248>] __watchdog_register_device+0x4f0/0x680 [watchdog]
[<00000000b2979824>] watchdog_register_device+0xd2/0x110 [watchdog]
[<000000001f730178>] 0xffffffffc10880ae
[<000000007a1a8bcc>] do_one_initcall+0xcb/0x4d0
[<00000000b98be325>] do_init_module+0x1ca/0x5f0
[<0000000046d08e7c>] load_module+0x6133/0x70f0
...unreferenced object 0xffff888105b9fa80 (size 16):
comm ""modprobe"", pid 28147, jiffies 4353426116 (age 61.741s) hex dump (first 16 bytes):
77 61 74 63 68 64 6f 67 31 00 b9 05 81 88 ff ff watchdog1.......
backtrace:
[<000000007f001ffd>] __kmem_cache_alloc_node+0x157/0x220
[<00000000486ab89b>] __kmalloc_node_track_caller+0x44/0x1b0
[<000000005a39aab0>] kvasprintf+0xb5/0x140
[<0000000024806f85>] kvasprintf_const+0x55/0x180
[<000000009276cb7f>] kobject_set_name_vargs+0x56/0x150
[<00000000a92e820b>] dev_set_name+0xab/0xe0
[<00000000cec812c6>] watchdog_dev_register+0x285/0x780 [watchdog]
[<0000000053c9f248>] __watchdog_register_device+0x4f0/0x680 [watchdog]
[<00000000b2979824>] watchdog_register_device+0xd2/0x110 [watchdog]
[<000000001f730178>] 0xffffffffc10880ae
[<000000007a1a8bcc>] do_one_initcall+0xcb/0x4d0
[<00000000b98be325>] do_init_module+0x1ca/0x5f0
[<0000000046d08e7c>] load_module+0x6133/0x70f0
...The reason is that put_device is not be called if cdev_device_add fails and wdd->id != 0.
watchdog_cdev_register
wd_data = kzalloc [1]
err = dev_set_name [2]
..
err = cdev_device_add
if (err) {
if (wdd->id == 0) { // wdd->id != 0
..
}
return err; // [1],[2] would be leakedTo fix it, call put_device in all wdd->id cases.
--- drivers/watchdog/watchdog_dev.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/watchdog/watchdog_dev.c +1 -1
@@ -989,8 +989,8 @@ static int watchdog_cdev_register(struct watchdog_device *wdd)if (wdd->id ==0 ) {misc_deregister (&watchdog_miscdev); old_wd_data =NULL ; -put_device (&wd_data->dev); } +put_device (&wd_data->dev);return err; }
Signature · 1 line
2.39.2
Greg Kroah-Hartman
maintainerPATCH 218/252 watchdog: pcwd_usb: Fix attempting to access uninitialized memory
In reply to Greg Kroah-HartmanFrom: Li Hua <[email protected]>
[ Upstream commit 7d06c07c67100fd0f8e6b3ab7145ce789f788117 ]
The stack variable msb and lsb may be used uninitialized in function usb_pcwd_get_temperature and usb_pcwd_get_timeleft when usb card no response.
The build waring is:drivers/watchdog/pcwd_usb.c:336:22: error: ‘lsb’ is used uninitialized in this function [-Werror=uninitialized]
*temperature = (lsb * 9 / 5) + 32;
~~~~^~~
drivers/watchdog/pcwd_usb.c:328:21: note: ‘lsb’ was declared here
unsigned char msb, lsb;
^~~cc1: all warnings being treated as errorsscripts/Makefile.build:250: recipe for target 'drivers/watchdog/pcwd_usb.o' failed make[3]: *** [drivers/watchdog/pcwd_usb.o] Error 1
--- drivers/watchdog/pcwd_usb.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-)
drivers/watchdog/pcwd_usb.c +4 -2
@@ -329,7 +329,8 @@ static int usb_pcwd_set_heartbeat(struct usb_pcwd_private *usb_pcwd, int t)static int usb_pcwd_get_temperature (struct usb_pcwd_private *usb_pcwd,int *temperature) { -unsigned char msb, lsb; +unsigned char msb =0x00 ; +unsigned char lsb =0x00 ;usb_pcwd_send_command (usb_pcwd,CMD_READ_TEMP , &msb, &lsb);
@@ -345,7 +346,8 @@ static int usb_pcwd_get_temperature(struct usb_pcwd_private *usb_pcwd,static int usb_pcwd_get_timeleft (struct usb_pcwd_private *usb_pcwd,int *time_left) { -unsigned char msb, lsb; +unsigned char msb =0x00 ; +unsigned char lsb =0x00 ;/* Read the time that's left before rebooting */ /* Note: if the board is not yet armed then we will read 0xFFFF */
Signature · 1 line
2.39.2
Greg Kroah-Hartman
maintainerPATCH 219/252 netfilter: ctnetlink: fix possible refcount leak in ctnetlink_create_conntrack()
In reply to Greg Kroah-HartmanFrom: Hangyu Hua <[email protected]>
[ Upstream commit ac4893980bbe79ce383daf9a0885666a30fe4c83 ]
nf_ct_put() needs to be called to put the refcount got by nf_conntrack_find_get() to avoid refcount leak when nf_conntrack_hash_check_insert() fails.
--- net/netfilter/nf_conntrack_netlink.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-)
net/netfilter/nf_conntrack_netlink.c +4 -1
@@ -2056,12 +2056,15 @@ ctnetlink_create_conntrack(struct net *net, err =nf_conntrack_hash_check_insert (ct);if (err <0 ) - goto err2; + goto err3;rcu_read_unlock ();return ct; +err3: +if (ct->master) +nf_ct_put (ct->master); err2:rcu_read_unlock (); err1:
Signature · 1 line
2.39.2
Greg Kroah-Hartman
maintainerPATCH 220/252 net: fix __dev_kfree_skb_any() vs drop monitor
In reply to Greg Kroah-HartmanFrom: Eric Dumazet <[email protected]>
[ Upstream commit ac3ad19584b26fae9ac86e4faebe790becc74491 ]
dev_kfree_skb() is aliased to consume_skb().
When a driver is dropping a packet by calling dev_kfree_skb_any() we should propagate the drop reason instead of pretending the packet was consumed.
Note: Now we have enum skb_drop_reason we could remove enum skb_free_reason (for linux-6.4)
v2: added an unlikely(), suggested by Yunsheng Lin.
--- net/core/dev.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
net/core/dev.c +3 -1
@@ -2794,8 +2794,10 @@ void __dev_kfree_skb_any(struct sk_buff *skb, enum skb_free_reason reason) {if (in_irq () ||irqs_disabled ())__dev_kfree_skb_irq (skb, reason); +else if (unlikely (reason ==SKB_REASON_DROPPED )) +kfree_skb (skb);else -dev_kfree_skb (skb); +consume_skb (skb); }EXPORT_SYMBOL (__dev_kfree_skb_any);
Signature · 1 line
2.39.2
Greg Kroah-Hartman
maintainerPATCH 221/252 9p/xen: fix version parsing
In reply to Greg Kroah-HartmanFrom: Juergen Gross <[email protected]>
[ Upstream commit f1956f4ec15195ec60976d9b5625326285ab102e ]
When connecting the Xen 9pfs frontend to the backend, the "versions" Xenstore entry written by the backend is parsed in a wrong way.
The "versions" entry is defined to contain the versions supported by the backend separated by commas (e.g. "1,2"). Today only version "1" is defined. Unfortunately the frontend doesn't look for "1" being listed in the entry, but it is expecting the entry to have the value "1".
This will result in failure as soon as the backend will support e.g. versions "1" and "2".
Fix that by scanning the entry correctly.
--- net/9p/trans_xen.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-)
net/9p/trans_xen.c +8 -2
@@ -395,13 +395,19 @@ static int xen_9pfs_front_probe(struct xenbus_device *dev,int ret, i;struct xenbus_transaction xbt;struct xen_9pfs_front_priv *priv =NULL ; -char *versions; +char *versions, *v;unsigned int max_rings, max_ring_order, len =0 ; versions =xenbus_read (XBT_NIL , dev->otherend,"versions" , &len);if (IS_ERR (versions))return PTR_ERR (versions); -if (strcmp (versions,"1" )) { +for (v = versions; *v; v++) { +if (simple_strtoul (v, &v,10 ) ==1 ) { + v =NULL ; +break ; + } + } +if (v) {kfree (versions);return -EINVAL ; }
Signature · 1 line
2.39.2
Greg Kroah-Hartman
maintainerPATCH 222/252 9p/xen: fix connection sequence
In reply to Greg Kroah-HartmanFrom: Juergen Gross <[email protected]>
[ Upstream commit c15fe55d14b3b4ded5af2a3260877460a6ffb8ad ]
Today the connection sequence of the Xen 9pfs frontend doesn't match the documented sequence. It can work reliably only for a PV 9pfs device having been added at boot time already, as the frontend is not waiting for the backend to have set its state to "XenbusStateInitWait" before reading the backend properties from Xenstore.
Fix that by following the documented sequence [1] (the documentation has a bug, so the reference is for the patch fixing that).
[1]: https://lore.kernel.org/xen-devel/[email protected]/T/#u
--- net/9p/trans_xen.c | 38 +++++++++++++++++++++++--------------- 1 file changed, 23 insertions(+), 15 deletions(-)
net/9p/trans_xen.c +23 -15
@@ -389,12 +389,11 @@ static int xen_9pfs_front_alloc_dataring(struct xenbus_device *dev,return ret; } -static int xen_9pfs_front_probe (struct xenbus_device *dev, -const struct xenbus_device_id *id) +static int xen_9pfs_front_init (struct xenbus_device *dev) {int ret, i;struct xenbus_transaction xbt; -struct xen_9pfs_front_priv *priv =NULL ; +struct xen_9pfs_front_priv *priv =dev_get_drvdata (&dev->dev);char *versions, *v;unsigned int max_rings, max_ring_order, len =0 ;
@@ -420,11 +419,6 @@ static int xen_9pfs_front_probe(struct xenbus_device *dev,if (max_ring_order <XEN_9PFS_RING_ORDER )return -EINVAL ; - priv =kzalloc (sizeof (*priv),GFP_KERNEL ); -if (!priv) -return -ENOMEM ; - - priv->dev = dev; priv->num_rings =XEN_9PFS_NUM_RINGS ; priv->rings =kcalloc (priv->num_rings,sizeof (*priv->rings),GFP_KERNEL );
@@ -482,23 +476,35 @@ static int xen_9pfs_front_probe(struct xenbus_device *dev, goto error; } -write_lock (&xen_9pfs_lock); -list_add_tail (&priv->list, &xen_9pfs_devs); -write_unlock (&xen_9pfs_lock); -dev_set_drvdata (&dev->dev, priv); -xenbus_switch_state (dev, XenbusStateInitialised); -return 0 ; error_xenbus:xenbus_transaction_end (xbt,1 );xenbus_dev_fatal (dev, ret,"writing xenstore" ); error: -dev_set_drvdata (&dev->dev,NULL );xen_9pfs_front_free (priv);return ret; } +static int xen_9pfs_front_probe (struct xenbus_device *dev, +const struct xenbus_device_id *id) +{ +struct xen_9pfs_front_priv *priv =NULL ; + + priv =kzalloc (sizeof (*priv),GFP_KERNEL ); +if (!priv) +return -ENOMEM ; + + priv->dev = dev; +dev_set_drvdata (&dev->dev, priv); + +write_lock (&xen_9pfs_lock); +list_add_tail (&priv->list, &xen_9pfs_devs); +write_unlock (&xen_9pfs_lock); + +return 0 ; +} +static int xen_9pfs_front_resume (struct xenbus_device *dev) {dev_warn (&dev->dev,"suspend/resume unsupported\n" );
@@ -517,6 +523,8 @@ static void xen_9pfs_front_changed(struct xenbus_device *dev,break ;case XenbusStateInitWait: +if (!xen_9pfs_front_init (dev)) +xenbus_switch_state (dev, XenbusStateInitialised);break ;case XenbusStateConnected:
Signature · 1 line
2.39.2
Greg Kroah-Hartman
maintainerPATCH 223/252 9p/rdma: unmap receive dma buffer in rdma_request()/post_recv()
In reply to Greg Kroah-HartmanFrom: Zhengchao Shao <[email protected]>
[ Upstream commit 74a25e6e916cb57dab4267a96fbe8864ed21abdb ]
When down_interruptible() or ib_post_send() failed in rdma_request(), receive dma buffer is not unmapped. Add unmap action to error path. Also if ib_post_recv() failed in post_recv(), dma buffer is not unmapped. Add unmap action to error path.
--- net/9p/trans_rdma.c | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-)
net/9p/trans_rdma.c +12 -3
@@ -400,6 +400,7 @@ post_recv(struct p9_client *client, struct p9_rdma_context *c)struct p9_trans_rdma *rdma = client->trans;struct ib_recv_wr wr;struct ib_sge sge; +int ret; c->busa = ib_dma_map_single(rdma->cm_id->device, c->rc.sdata, client->msize,
@@ -417,7 +418,12 @@ post_recv(struct p9_client *client, struct p9_rdma_context *c) wr.wr_cqe = &c->cqe; wr.sg_list = &sge; wr.num_sge =1 ; -return ib_post_recv (rdma->qp, &wr,NULL ); + + ret =ib_post_recv (rdma->qp, &wr,NULL ); +if (ret) +ib_dma_unmap_single (rdma->cm_id->device, c->busa, + client->msize,DMA_FROM_DEVICE ); +return ret; error:p9_debug (P9_DEBUG_ERROR ,"EIO\n" );
@@ -514,7 +520,7 @@ static int rdma_request(struct p9_client *client, struct p9_req_t *req)if (down_interruptible (&rdma->sq_sem)) { err = -EINTR ; - goto send_error; + goto dma_unmap; }/* Mark request as `sent' *before* we actually send it,
@@ -524,11 +530,14 @@ static int rdma_request(struct p9_client *client, struct p9_req_t *req) req->status =REQ_STATUS_SENT ; err =ib_post_send (rdma->qp, &wr,NULL );if (err) - goto send_error; + goto dma_unmap;/* Success */ return 0 ; +dma_unmap: +ib_dma_unmap_single (rdma->cm_id->device, c->busa, + c->req->tc.size,DMA_TO_DEVICE );/* Handle errors that happened during or while preparing the send: */ send_error: req->status =REQ_STATUS_ERROR ;
Signature · 1 line
2.39.2
Greg Kroah-Hartman
maintainerPATCH 224/252 nfc: fix memory leak of se_io context in nfc_genl_se_io
In reply to Greg Kroah-HartmanFrom: Fedor Pchelkin <[email protected]>
[ Upstream commit 25ff6f8a5a3b8dc48e8abda6f013e8cc4b14ffea ]
The callback context for sending/receiving APDUs to/from the selected secure element is allocated inside nfc_genl_se_io and supposed to be eventually freed in se_io_cb callback function. However, there are several error paths where the bwi_timer is not charged to call se_io_cb later, and the cb_context is leaked.
The patch proposes to free the cb_context explicitly on those error paths.
At the moment we can't simply check 'dev->ops->se_io()' return value as it may be negative in both cases: when the timer was charged and was not.
--- drivers/nfc/st-nci/se.c | 6 ++++++ drivers/nfc/st21nfca/se.c | 6 ++++++ net/nfc/netlink.c | 4 ++++ 3 files changed, 16 insertions(+)
drivers/nfc/st-nci/se.c +6 -0
@@ -676,6 +676,12 @@ int st_nci_se_io(struct nci_dev *ndev, u32 se_idx,ST_NCI_EVT_TRANSMIT_DATA , apdu, apdu_length);default : +/* Need to free cb_context here as at the moment we can't +* clearly indicate to the caller if the callback function +* would be called (and free it) or not. In both cases a +* negative value may be returned to the caller. +*/ +kfree (cb_context);return -ENODEV ; } }
drivers/nfc/st21nfca/se.c +6 -0
@@ -247,6 +247,12 @@ int st21nfca_hci_se_io(struct nfc_hci_dev *hdev, u32 se_idx,ST21NFCA_EVT_TRANSMIT_DATA , apdu, apdu_length);default : +/* Need to free cb_context here as at the moment we can't +* clearly indicate to the caller if the callback function +* would be called (and free it) or not. In both cases a +* negative value may be returned to the caller. +*/ +kfree (cb_context);return -ENODEV ; } }
net/nfc/netlink.c +4 -0
@@ -1460,7 +1460,11 @@ static int nfc_se_io(struct nfc_dev *dev, u32 se_idx, rc = dev->ops->se_io (dev, se_idx, apdu, apdu_length, cb, cb_context); +device_unlock (&dev->dev); +return rc; + error: +kfree (cb_context);device_unlock (&dev->dev);return rc; }
Signature · 1 line
2.39.2
Greg Kroah-Hartman
maintainerPATCH 225/252 ARM: dts: spear320-hmi: correct STMPE GPIO compatible
In reply to Greg Kroah-HartmanFrom: Krzysztof Kozlowski <[email protected]>
[ Upstream commit 33a0c1b850c8c85f400531dab3a0b022cdb164b1 ]
The compatible is st,stmpe-gpio.
--- arch/arm/boot/dts/spear320-hmi.dts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
arch/arm/boot/dts/spear320-hmi.dts +1 -1
@@ -248,7 +248,7 @@ irq-trigger = <0x1>; stmpegpio: stmpe-gpio { - compatible = "stmpe,gpio"; + compatible = "st,stmpe-gpio"; reg = <0>; gpio-controller; #gpio-cells = <2>;
Signature · 1 line
2.39.2
Greg Kroah-Hartman
maintainerPATCH 226/252 tcp: tcp_check_req() can be called from process context
In reply to Greg Kroah-HartmanFrom: Eric Dumazet <[email protected]>
[ Upstream commit 580f98cc33a260bb8c6a39ae2921b29586b84fdf ]
This is a follow up of commit 0a375c822497 ("tcp: tcp_rtx_synack() can be called from process context").
Frederick Lawler reported another "__this_cpu_add() in preemptible" warning caused by the same reason.
In my former patch I took care of tcp_rtx_synack()
but forgot that tcp_check_req() also contained some SNMP updates.
Note that some parts of tcp_check_req() always run in BH context, I added a comment to clarify this.
--- net/ipv4/tcp_minisocks.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-)
net/ipv4/tcp_minisocks.c +5 -2
@@ -582,6 +582,9 @@ EXPORT_SYMBOL(tcp_create_openreq_child);* validation and inside tcp_v4_reqsk_send_ack(). Can we do better? * * We don't need to initialize tmp_opt.sack_ok as we don't use the results +* +* Note: If @fastopen is true, this can be called from process context. +* Otherwise, this is from BH context. */ struct sock *tcp_check_req(struct sock *sk, struct sk_buff *skb,
@@ -734,7 +737,7 @@ struct sock *tcp_check_req(struct sock *sk, struct sk_buff *skb, &tcp_rsk(req)->last_oow_ack_time)) req->rsk_ops->send_ack (sk, skb, req);if (paws_reject) -__NET_INC_STATS (sock_net (sk),LINUX_MIB_PAWSESTABREJECTED ); +NET_INC_STATS (sock_net (sk),LINUX_MIB_PAWSESTABREJECTED );return NULL ; }
@@ -753,7 +756,7 @@ struct sock *tcp_check_req(struct sock *sk, struct sk_buff *skb,* "fourth, check the SYN bit" */ if (flg & (TCP_FLAG_RST |TCP_FLAG_SYN )) { -__TCP_INC_STATS (sock_net (sk),TCP_MIB_ATTEMPTFAILS ); +TCP_INC_STATS (sock_net (sk),TCP_MIB_ATTEMPTFAILS ); goto embryonic_reset; }
Signature · 1 line
2.39.2
Greg Kroah-Hartman
maintainerPATCH 227/252 vc_screen: modify vcs_size() handling in vcs_read()
In reply to Greg Kroah-HartmanFrom: George Kennedy <[email protected]>
[ Upstream commit 46d733d0efc79bc8430d63b57ab88011806d5180 ]
Restore the vcs_size() handling in vcs_read() to what it had been in previous version.
--- drivers/tty/vt/vc_screen.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-)
drivers/tty/vt/vc_screen.c +1 -3
@@ -278,10 +278,8 @@ vcs_read(struct file *file, char __user *buf, size_t count, loff_t *ppos)*/ size =vcs_size (inode);if (size <0 ) { -if (read) -break ; ret = size; - goto unlock_out; +break ; }if (pos >= size)break ;
Signature · 1 line
2.39.2
Greg Kroah-Hartman
maintainerPATCH 228/252 scsi: ipr: Work around fortify-string warning
In reply to Greg Kroah-HartmanFrom: Arnd Bergmann <[email protected]>
[ Upstream commit ee4e7dfe4ffc9ca50c6875757bd119abfe22b5c5 ]
The ipr_log_vpd_compact() function triggers a fortified memcpy() warning about a potential string overflow with all versions of clang:
In file included from drivers/scsi/ipr.c:43:
In file included from include/linux/string.h:254:include/linux/fortify-string.h:520:4: error: call to '__write_overflow_field' declared with 'warning' attribute: detected write beyond size of field (1st parameter); maybe use struct_group()? [-Werror,-Wattribute-warning]
__write_overflow_field(p_size_field, size);
^include/linux/fortify-string.h:520:4: error: call to '__write_overflow_field' declared with 'warning' attribute: detected write beyond size of field (1st parameter); maybe use struct_group()? [-Werror,-Wattribute-warning] 2 errors generated.
I don't see anything actually wrong with the function, but this is the only instance I can reproduce of the fortification going wrong in the kernel at the moment, so the easiest solution may be to rewrite the function into something that does not trigger the warning.
Instead of having a combined buffer for vendor/device/serial strings, use three separate local variables and just truncate the whitespace individually.
--- drivers/scsi/ipr.c | 41 +++++++++++++++++++++-------------------- 1 file changed, 21 insertions(+), 20 deletions(-)
drivers/scsi/ipr.c +21 -20
@@ -1531,23 +1531,22 @@ static void ipr_process_ccn(struct ipr_cmnd *ipr_cmd) }/** -* strip_and_pad_whitespace - Strip and pad trailing whitespace. -* @i: index into buffer -* @buf: string to modify +* strip_whitespace - Strip and pad trailing whitespace. +* @i: size of buffer +* @buf: string to modify * -* This function will strip all trailing whitespace, pad the end -* of the string with a single space, and NULL terminate the string. +* This function will strip all trailing whitespace and +* NUL terminate the string. * -* Return value: -* new length of string **/ -static int strip_and_pad_whitespace (int i,char *buf) +static void strip_whitespace (int i,char *buf) { +if (i <1 ) +return ; + i--;while (i && buf[i] ==' ' ) i--; - buf[i+1 ] =' ' ; - buf[i+2 ] ='\0' ; -return i +2 ; + buf[i+1 ] ='\0' ; }/**
@@ -1562,19 +1561,21 @@ static int strip_and_pad_whitespace(int i, char *buf)static void ipr_log_vpd_compact (char *prefix,struct ipr_hostrcb *hostrcb,struct ipr_vpd *vpd) { -char buffer[IPR_VENDOR_ID_LEN +IPR_PROD_ID_LEN +IPR_SERIAL_NUM_LEN +3 ]; -int i =0 ; +char vendor_id[IPR_VENDOR_ID_LEN +1 ]; +char product_id[IPR_PROD_ID_LEN +1 ]; +char sn[IPR_SERIAL_NUM_LEN +1 ]; -memcpy (buffer, vpd->vpids.vendor_id,IPR_VENDOR_ID_LEN ); - i =strip_and_pad_whitespace (IPR_VENDOR_ID_LEN -1 , buffer); +memcpy (vendor_id, vpd->vpids.vendor_id,IPR_VENDOR_ID_LEN ); +strip_whitespace (IPR_VENDOR_ID_LEN , vendor_id); -memcpy (&buffer[i], vpd->vpids.product_id,IPR_PROD_ID_LEN ); - i =strip_and_pad_whitespace (i +IPR_PROD_ID_LEN -1 , buffer); +memcpy (product_id, vpd->vpids.product_id,IPR_PROD_ID_LEN ); +strip_whitespace (IPR_PROD_ID_LEN , product_id); -memcpy (&buffer[i], vpd->sn,IPR_SERIAL_NUM_LEN ); - buffer[IPR_SERIAL_NUM_LEN + i] ='\0' ; +memcpy (sn, vpd->sn,IPR_SERIAL_NUM_LEN ); +strip_whitespace (IPR_SERIAL_NUM_LEN , sn); -ipr_hcam_err (hostrcb,"%s VPID/SN: %s\n" , prefix, buffer); +ipr_hcam_err (hostrcb,"%s VPID/SN: %s %s %s\n" , prefix, + vendor_id, product_id, sn); }/**
Signature · 1 line
2.39.2
Greg Kroah-Hartman
maintainerPATCH 229/252 thermal: intel: quark_dts: fix error pointer dereference
In reply to Greg Kroah-HartmanFrom: Dan Carpenter <[email protected]>
[ Upstream commit f1b930e740811d416de4d2074da48b6633a672c8 ]
If alloc_soc_dts() fails, then we can just return. Trying to free "soc_dts" will lead to an Oops.
--- drivers/thermal/intel_quark_dts_thermal.c | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-)
drivers/thermal/intel_quark_dts_thermal.c +2 -10
@@ -440,22 +440,14 @@ MODULE_DEVICE_TABLE(x86cpu, qrk_thermal_ids);static int __init intel_quark_thermal_init (void ) { -int err =0 ; -if (!x86_match_cpu (qrk_thermal_ids) || !iosf_mbi_available ())return -ENODEV ; soc_dts =alloc_soc_dts (); -if (IS_ERR (soc_dts)) { - err =PTR_ERR (soc_dts); - goto err_free; - } +if (IS_ERR (soc_dts)) +return PTR_ERR (soc_dts);return 0 ; - -err_free: -free_soc_dts (soc_dts); -return err; } static void __exit intel_quark_thermal_exit(void)
Signature · 1 line
2.39.2
Greg Kroah-Hartman
maintainerPATCH 230/252 tracing: Add NULL checks for buffer in ring_buffer_free_read_page()
In reply to Greg Kroah-HartmanFrom: Jia-Ju Bai <[email protected]>
[ Upstream commit 3e4272b9954094907f16861199728f14002fcaf6 ]
In a previous commit 7433632c9ff6, buffer, buffer->buffers and buffer->buffers[cpu] in ring_buffer_wake_waiters() can be NULL, and thus the related checks are added.
However, in the same call stack, these variables are also used in ring_buffer_free_read_page():
tracing_buffers_release()
ring_buffer_wake_waiters(iter->array_buffer->buffer)
cpu_buffer = buffer->buffers[cpu] -> Add checks by previous commit
ring_buffer_free_read_page(iter->array_buffer->buffer)
cpu_buffer = buffer->buffers[cpu] -> No checkThus, to avod possible null-pointer derefernces, the related checks should be added.
These results are reported by a static tool designed by myself.
--- kernel/trace/ring_buffer.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-)
kernel/trace/ring_buffer.c +6 -1
@@ -4685,11 +4685,16 @@ EXPORT_SYMBOL_GPL(ring_buffer_alloc_read_page);*/ void ring_buffer_free_read_page (struct ring_buffer *buffer,int cpu,void *data) { -struct ring_buffer_per_cpu *cpu_buffer = buffer->buffers[cpu]; +struct ring_buffer_per_cpu *cpu_buffer;struct buffer_data_page *bpage = data;struct page *page =virt_to_page (bpage);unsigned long flags; +if (!buffer || !buffer->buffers || !buffer->buffers[cpu]) +return ; + + cpu_buffer = buffer->buffers[cpu]; +/* If the page is still in use someplace else, we can't reuse it */ if (page_ref_count (page) >1 ) goto out;
Signature · 1 line
2.39.2
Greg Kroah-Hartman
maintainerPATCH 231/252 firmware/efi sysfb_efi: Add quirk for Lenovo IdeaPad Duet 3
In reply to Greg Kroah-HartmanFrom: Darrell Kavanagh <[email protected]>
[ Upstream commit e1d447157f232c650e6f32c9fb89ff3d0207c69a ]
Another Lenovo convertable which reports a landscape resolution of 1920x1200 with a pitch of (1920 * 4) bytes, while the actual framebuffer has a resolution of 1200x1920 with a pitch of (1200 * 4) bytes.
--- arch/x86/kernel/sysfb_efi.c | 8 ++++++++ 1 file changed, 8 insertions(+)
arch/x86/kernel/sysfb_efi.c +8 -0
@@ -265,6 +265,14 @@ static const struct dmi_system_id efifb_dmi_swap_width_height[] __initconst = { "Lenovo ideapad D330-10IGM"), }, }, + { + /* Lenovo IdeaPad Duet 3 10IGL5 with 1200x1920 portrait screen */ + .matches = { + DMI_EXACT_MATCH(DMI_SYS_VENDOR, "LENOVO"), + DMI_EXACT_MATCH(DMI_PRODUCT_VERSION, + "IdeaPad Duet 3 10IGL5"), + }, + }, {}, };
Signature · 1 line
2.39.2
Greg Kroah-Hartman
maintainerPATCH 232/252 media: uvcvideo: Handle cameras with invalid descriptors
In reply to Greg Kroah-HartmanFrom: Ricardo Ribalda <[email protected]>
[ Upstream commit 41ddb251c68ac75c101d3a50a68c4629c9055e4c ]
If the source entity does not contain any pads, do not create a link.
--- drivers/media/usb/uvc/uvc_entity.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/media/usb/uvc/uvc_entity.c +1 -1
@@ -42,7 +42,7 @@ static int uvc_mc_create_links(struct uvc_video_chain *chain,continue ; remote =uvc_entity_by_id (chain->dev, entity->baSourceID[i]); -if (remote ==NULL ) +if (remote ==NULL || remote->num_pads ==0 )return -EINVAL ; source = (UVC_ENTITY_TYPE (remote) ==UVC_TT_STREAMING )
Signature · 1 line
2.39.2
Greg Kroah-Hartman
maintainerPATCH 233/252 media: uvcvideo: Handle errors from calls to usb_string
In reply to Greg Kroah-HartmanFrom: Guenter Roeck <[email protected]>
[ Upstream commit 4867bb590ae445bcfaa711a86b603c97e94574b3 ]
On a Webcam from Quanta, we see the following error.
usb 3-5: New USB device found, idVendor=0408, idProduct=30d2, bcdDevice= 0.03 usb 3-5: New USB device strings: Mfr=3, Product=1, SerialNumber=2 usb 3-5: Product: USB2.0 HD UVC WebCam
usb 3-5: Manufacturer: Quanta
usb 3-5: SerialNumber: 0x0001
...
uvcvideo: Found UVC 1.10 device USB2.0 HD UVC WebCam (0408:30d2)
uvcvideo: Failed to initialize entity for entity 5
uvcvideo: Failed to register entities (-22).
The Webcam reports an entity of type UVC_VC_EXTENSION_UNIT. It reports a string index of '7' associated with that entity. The attempt to read that string from the camera fails with error -32 (-EPIPE). usb_string() returns that error, but it is ignored. As result, the entity name is empty. This later causes v4l2_device_register_subdev() to return -EINVAL, and no entities are registered as result.
While this appears to be a firmware problem with the camera, the kernel should still handle the situation gracefully. To do that, check the return value from usb_string(). If it reports an error, assign the entity's default name.
--- drivers/media/usb/uvc/uvc_driver.c | 48 ++++++++++++------------------ 1 file changed, 19 insertions(+), 29 deletions(-)
drivers/media/usb/uvc/uvc_driver.c +19 -29
@@ -1033,10 +1033,8 @@ static int uvc_parse_vendor_control(struct uvc_device *dev, + n;memcpy (unit->extension.bmControls, &buffer[23 +p],2 *n); -if (buffer[24 +p+2 *n] !=0 ) -usb_string (udev, buffer[24 +p+2 *n], unit->name, -sizeof (unit->name)); -else +if (buffer[24 +p+2 *n] ==0 || +usb_string (udev, buffer[24 +p+2 *n], unit->name,sizeof (unit->name)) <0 )sprintf (unit->name,"Extension %u" , buffer[3 ]);list_add_tail (&unit->list, &dev->entities);
@@ -1161,15 +1159,15 @@ static int uvc_parse_standard_control(struct uvc_device *dev,memcpy (term->media.bmTransportModes, &buffer[10 +n], p); } -if (buffer[7 ] !=0 ) -usb_string (udev, buffer[7 ], term->name, -sizeof (term->name)); -else if (UVC_ENTITY_TYPE (term) ==UVC_ITT_CAMERA ) -sprintf (term->name,"Camera %u" , buffer[3 ]); -else if (UVC_ENTITY_TYPE (term) ==UVC_ITT_MEDIA_TRANSPORT_INPUT ) -sprintf (term->name,"Media %u" , buffer[3 ]); -else -sprintf (term->name,"Input %u" , buffer[3 ]); +if (buffer[7 ] ==0 || +usb_string (udev, buffer[7 ], term->name,sizeof (term->name)) <0 ) { +if (UVC_ENTITY_TYPE (term) ==UVC_ITT_CAMERA ) +sprintf (term->name,"Camera %u" , buffer[3 ]); +if (UVC_ENTITY_TYPE (term) ==UVC_ITT_MEDIA_TRANSPORT_INPUT ) +sprintf (term->name,"Media %u" , buffer[3 ]); +else +sprintf (term->name,"Input %u" , buffer[3 ]); + }list_add_tail (&term->list, &dev->entities);break ;
@@ -1201,10 +1199,8 @@ static int uvc_parse_standard_control(struct uvc_device *dev,memcpy (term->baSourceID, &buffer[7 ],1 ); -if (buffer[8 ] !=0 ) -usb_string (udev, buffer[8 ], term->name, -sizeof (term->name)); -else +if (buffer[8 ] ==0 || +usb_string (udev, buffer[8 ], term->name,sizeof (term->name)) <0 )sprintf (term->name,"Output %u" , buffer[3 ]);list_add_tail (&term->list, &dev->entities);
@@ -1226,10 +1222,8 @@ static int uvc_parse_standard_control(struct uvc_device *dev,memcpy (unit->baSourceID, &buffer[5 ], p); -if (buffer[5 +p] !=0 ) -usb_string (udev, buffer[5 +p], unit->name, -sizeof (unit->name)); -else +if (buffer[5 +p] ==0 || +usb_string (udev, buffer[5 +p], unit->name,sizeof (unit->name)) <0 )sprintf (unit->name,"Selector %u" , buffer[3 ]);list_add_tail (&unit->list, &dev->entities);
@@ -1259,10 +1253,8 @@ static int uvc_parse_standard_control(struct uvc_device *dev,if (dev->uvc_version >=0x0110 ) unit->processing.bmVideoStandards = buffer[9 +n]; -if (buffer[8 +n] !=0 ) -usb_string (udev, buffer[8 +n], unit->name, -sizeof (unit->name)); -else +if (buffer[8 +n] ==0 || +usb_string (udev, buffer[8 +n], unit->name,sizeof (unit->name)) <0 )sprintf (unit->name,"Processing %u" , buffer[3 ]);list_add_tail (&unit->list, &dev->entities);
@@ -1290,10 +1282,8 @@ static int uvc_parse_standard_control(struct uvc_device *dev, unit->extension.bmControls = (u8 *)unit +sizeof (*unit);memcpy (unit->extension.bmControls, &buffer[23 +p], n); -if (buffer[23 +p+n] !=0 ) -usb_string (udev, buffer[23 +p+n], unit->name, -sizeof (unit->name)); -else +if (buffer[23 +p+n] ==0 || +usb_string (udev, buffer[23 +p+n], unit->name,sizeof (unit->name)) <0 )sprintf (unit->name,"Extension %u" , buffer[3 ]);list_add_tail (&unit->list, &dev->entities);
Signature · 1 line
2.39.2
Greg Kroah-Hartman
maintainerPATCH 234/252 media: uvcvideo: Silence memcpy() run-time false positive warnings
In reply to Greg Kroah-HartmanFrom: Kees Cook <[email protected]>
[ Upstream commit b839212988575c701aab4d3d9ca15e44c87e383c ]
The memcpy() in uvc_video_decode_meta() intentionally copies across the length and flags members and into the trailing buf flexible array. Split the copy so that the compiler can better reason about (the lack of) buffer overflows here. Avoid the run-time false positive warning:
memcpy: detected field-spanning write (size 12) of single field "&meta->length" at drivers/media/usb/uvc/uvc_video.c:1355 (size 1)
Additionally fix a typo in the documentation for struct uvc_meta_buf.
--- drivers/media/usb/uvc/uvc_video.c | 4 +++- include/uapi/linux/uvcvideo.h | 2 +- 2 files changed, 4 insertions(+), 2 deletions(-)
drivers/media/usb/uvc/uvc_video.c +3 -1
@@ -1278,7 +1278,9 @@ static void uvc_video_decode_meta(struct uvc_streaming *stream,if (has_scr)memcpy (stream->clock.last_scr, scr,6 ); -memcpy (&meta->length, mem, length); + meta->length = mem[0 ]; + meta->flags = mem[1 ]; +memcpy (meta->buf, &mem[2 ], length -2 ); meta_buf->bytesused += length +sizeof (meta->ns) +sizeof (meta->sof); uvc_trace(UVC_TRACE_FRAME,
include/uapi/linux/uvcvideo.h +1 -1
@@ -86,7 +86,7 @@ struct uvc_xu_control_query {* struct. The first two fields are added by the driver, they can be used for * clock synchronisation. The rest is an exact copy of a UVC payload header. * Only complete objects with complete buffers are included. Therefore it's -* always sizeof(meta->ts) + sizeof(meta->sof) + meta->length bytes large. +* always sizeof(meta->ns) + sizeof(meta->sof) + meta->length bytes large. */ struct uvc_meta_buf {__u64 ns;
Signature · 1 line
2.39.2
Greg Kroah-Hartman
maintainerPATCH 235/252 tty: fix out-of-bounds access in tty_driver_lookup_tty()
In reply to Greg Kroah-HartmanFrom: Sven Schnelle <[email protected]>
[ Upstream commit db4df8e9d79e7d37732c1a1b560958e8dadfefa1 ]
When specifying an invalid console= device like console=tty3270, tty_driver_lookup_tty() returns the tty struct without checking whether index is a valid number.
To reproduce:
qemu-system-x86_64 -enable-kvm -nographic -serial mon:stdio \
-kernel ../linux-build-x86/arch/x86/boot/bzImage \
-append "console=ttyS0 console=tty3270"
This crashes with:
[ 0.770599] BUG: kernel NULL pointer dereference, address: 00000000000000ef [ 0.771265] #PF: supervisor read access in kernel mode [ 0.771773] #PF: error_code(0x0000) - not-present page [ 0.772609] Oops: 0000 [#1] PREEMPT SMP PTI [ 0.774878] RIP: 0010:tty_open+0x268/0x6f0 [ 0.784013] chrdev_open+0xbd/0x230 [ 0.784444] ? cdev_device_add+0x80/0x80 [ 0.784920] do_dentry_open+0x1e0/0x410 [ 0.785389] path_openat+0xca9/0x1050 [ 0.785813] do_filp_open+0xaa/0x150 [ 0.786240] file_open_name+0x133/0x1b0 [ 0.786746] filp_open+0x27/0x50 [ 0.787244] console_on_rootfs+0x14/0x4d [ 0.787800] kernel_init_freeable+0x1e4/0x20d [ 0.788383] ? rest_init+0xc0/0xc0 [ 0.788881] kernel_init+0x11/0x120 [ 0.789356] ret_from_fork+0x22/0x30
--- drivers/tty/tty_io.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-)
drivers/tty/tty_io.c +5 -3
@@ -1155,14 +1155,16 @@ static struct tty_struct *tty_driver_lookup_tty(struct tty_driver *driver, {struct tty_struct *tty; -if (driver->ops->lookup) +if (driver->ops->lookup) {if (!file) tty =ERR_PTR (-EIO );else tty = driver->ops->lookup (driver, file, idx); -else + }else { +if (idx >= driver->num) +return ERR_PTR (-EINVAL ); tty = driver->ttys[idx]; - + }if (!IS_ERR (tty))tty_kref_get (tty);return tty;
Signature · 1 line
2.39.2
Greg Kroah-Hartman
maintainerPATCH 236/252 tty: serial: fsl_lpuart: disable the CTS when send break signal
In reply to Greg Kroah-HartmanFrom: Sherry Sun <[email protected]>
[ Upstream commit c4c81db5cf8bc53d6160c3abf26d382c841aa434 ]
LPUART IP has a bug that it treats the CTS as higher priority than the break signal, which cause the break signal sending through UARTCTRL_SBK may impacted by the CTS input if the HW flow control is enabled.
Add this workaround patch to fix the IP bug, we can disable CTS before asserting SBK to avoid any interference from CTS, and re-enable it when break off.
Such as for the bluetooth chip power save feature, host can let the BT chip get into sleep state by sending a UART break signal, and wake it up by turning off the UART break. If the BT chip enters the sleep mode successfully, it will pull up the CTS line, if the BT chip is woken up, it will pull down the CTS line. If without this workaround patch, the UART TX pin cannot send the break signal successfully as it affected by the BT CTS pin. After adding this patch, the BT power save feature can work well.
--- drivers/tty/serial/fsl_lpuart.c | 24 ++++++++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-)
drivers/tty/serial/fsl_lpuart.c +22 -2
@@ -1195,12 +1195,32 @@ static void lpuart_break_ctl(struct uart_port *port, int break_state)static void lpuart32_break_ctl (struct uart_port *port,int break_state) { -unsigned long temp; +unsigned long temp, modem; +struct tty_struct *tty; +unsigned int cflag =0 ; + + tty =tty_port_tty_get (&port->state->port); +if (tty) { + cflag = tty->termios.c_cflag; +tty_kref_put (tty); + } temp =lpuart32_read (port,UARTCTRL ) & ~UARTCTRL_SBK ; + modem =lpuart32_read (port,UARTMODIR ); -if (break_state !=0 ) +if (break_state !=0 ) { temp |=UARTCTRL_SBK ; +/* +* LPUART CTS has higher priority than SBK, need to disable CTS before +* asserting SBK to avoid any interference if flow control is enabled. +*/ +if (cflag &CRTSCTS && modem &UARTMODIR_TXCTSE ) +lpuart32_write (port, modem & ~UARTMODIR_TXCTSE ,UARTMODIR ); + }else { +/* Re-enable the CTS when break off. */ +if (cflag &CRTSCTS && !(modem &UARTMODIR_TXCTSE )) +lpuart32_write (port, modem |UARTMODIR_TXCTSE ,UARTMODIR ); + }lpuart32_write (port, temp,UARTCTRL ); }
Signature · 1 line
2.39.2
Greg Kroah-Hartman
maintainerPATCH 237/252 mei: bus-fixup:upon error print return values of send and receive
In reply to Greg Kroah-HartmanFrom: Alexander Usyskin <[email protected]>
[ Upstream commit 4b8659e2c258e4fdac9ccdf06cc20c0677894ef9 ]
For easier debugging, upon error, print also return values from __mei_cl_recv() and __mei_cl_send() functions.
--- drivers/misc/mei/bus-fixup.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-)
drivers/misc/mei/bus-fixup.c +4 -4
@@ -174,7 +174,7 @@ static int mei_fwver(struct mei_cl_device *cldev) ret =__mei_cl_send (cldev->cl, buf,sizeof (struct mkhi_msg_hdr ),MEI_CL_IO_TX_BLOCKING );if (ret <0 ) { -dev_err (&cldev->dev,"Could not send ReqFWVersion cmd\n" ); +dev_err (&cldev->dev,"Could not send ReqFWVersion cmd ret = %d\n" , ret);return ret; }
@@ -186,7 +186,7 @@ static int mei_fwver(struct mei_cl_device *cldev)* Should be at least one version block, * error out if nothing found */ -dev_err (&cldev->dev,"Could not read FW version\n" ); +dev_err (&cldev->dev,"Could not read FW version ret = %d\n" , bytes_recv);return -EIO ; }
@@ -335,7 +335,7 @@ static int mei_nfc_if_version(struct mei_cl *cl, ret =__mei_cl_send (cl, (u8 *)&cmd,sizeof (struct mei_nfc_cmd ),MEI_CL_IO_TX_BLOCKING );if (ret <0 ) { -dev_err (bus->dev,"Could not send IF version cmd\n" ); +dev_err (bus->dev,"Could not send IF version cmd ret = %d\n" , ret);return ret; }
@@ -350,7 +350,7 @@ static int mei_nfc_if_version(struct mei_cl *cl, ret =0 ; bytes_recv =__mei_cl_recv (cl, (u8 *)reply, if_version_length,0 ,0 );if (bytes_recv <0 || (size_t )bytes_recv < if_version_length) { -dev_err (bus->dev,"Could not read IF version\n" ); +dev_err (bus->dev,"Could not read IF version ret = %d\n" , bytes_recv); ret = -EIO ; goto err; }
Signature · 1 line
2.39.2
Greg Kroah-Hartman
maintainerPATCH 238/252 tools/iio/iio_utils:fix memory leak
In reply to Greg Kroah-HartmanFrom: Yulong Zhang <[email protected]>
[ Upstream commit f2edf0c819a4823cd6c288801ce737e8d4fcde06 ]
1. fopen sysfs without fclose.
2. asprintf filename without free.
3. if asprintf return error,do not need to free the buffer.
--- tools/iio/iio_utils.c | 23 ++++++----------------- 1 file changed, 6 insertions(+), 17 deletions(-)
tools/iio/iio_utils.c +6 -17
@@ -265,6 +265,7 @@ int iioutils_get_param_float(float *output, const char *param_name,if (fscanf (sysfsfp,"%f" , output) !=1 ) ret = errno ? -errno : -ENODATA ; +fclose (sysfsfp);break ; } error_free_filename:
@@ -345,9 +346,9 @@ int build_channel_array(const char *device_dir, } sysfsfp =fopen (filename,"r" ); +free (filename);if (!sysfsfp) { ret = -errno; -free (filename); goto error_close_dir; }
@@ -357,7 +358,6 @@ int build_channel_array(const char *device_dir,if (fclose (sysfsfp))perror ("build_channel_array(): Failed to close file" ); -free (filename); goto error_close_dir; }if (ret ==1 )
@@ -365,11 +365,9 @@ int build_channel_array(const char *device_dir,if (fclose (sysfsfp)) { ret = -errno; -free (filename); goto error_close_dir; } -free (filename); } *ci_array =malloc (sizeof (**ci_array) * (*counter));
@@ -395,9 +393,9 @@ int build_channel_array(const char *device_dir, } sysfsfp =fopen (filename,"r" ); +free (filename);if (!sysfsfp) { ret = -errno; -free (filename); count--; goto error_cleanup_array; }
@@ -405,20 +403,17 @@ int build_channel_array(const char *device_dir, errno =0 ;if (fscanf (sysfsfp,"%i" , ¤t_enabled) !=1 ) { ret = errno ? -errno : -ENODATA ; -free (filename); count--; goto error_cleanup_array; }if (fclose (sysfsfp)) { ret = -errno; -free (filename); count--; goto error_cleanup_array; }if (!current_enabled) { -free (filename); count--;continue ; }
@@ -429,7 +424,6 @@ int build_channel_array(const char *device_dir,strlen (ent->d_name) - strlen("_en"));if (!current->name) { -free (filename); ret = -ENOMEM ; count--; goto error_cleanup_array;
@@ -439,7 +433,6 @@ int build_channel_array(const char *device_dir, ret =iioutils_break_up_name (current->name, ¤t->generic_name);if (ret) { -free (filename);free (current->name); count--; goto error_cleanup_array;
@@ -450,17 +443,16 @@ int build_channel_array(const char *device_dir, scan_el_dir, current->name);if (ret <0 ) { -free (filename); ret = -ENOMEM ; goto error_cleanup_array; } sysfsfp =fopen (filename,"r" ); +free (filename);if (!sysfsfp) { ret = -errno; -fprintf (stderr,"failed to open %s\n" , - filename); -free (filename); +fprintf (stderr,"failed to open %s/%s_index\n" , + scan_el_dir, current->name); goto error_cleanup_array; }
@@ -470,17 +462,14 @@ int build_channel_array(const char *device_dir,if (fclose (sysfsfp))perror ("build_channel_array(): Failed to close file" ); -free (filename); goto error_cleanup_array; }if (fclose (sysfsfp)) { ret = -errno; -free (filename); goto error_cleanup_array; } -free (filename);/* Find the scale */ ret = iioutils_get_param_float(¤t->scale, "scale",
Signature · 1 line
2.39.2
Greg Kroah-Hartman
maintainerPATCH 239/252 iio: accel: mma9551_core: Prevent uninitialized variable in mma9551_read_status_word()
In reply to Greg Kroah-HartmanFrom: Harshit Mogalapalli <[email protected]>
[ Upstream commit e56d2c34ce9dc122b1a618172ec0e05e50adb9e9 ]
Smatch Warns: drivers/iio/accel/mma9551_core.c:357
mma9551_read_status_word() error: uninitialized symbol 'v'.
When (offset >= 1 << 12) is true mma9551_transfer() will return -EINVAL without 'v' being initialized, so check for the error and return.
Note: Not a bug as such because the caller checks return value and doesn't not use this parameter in the problem case.
--- drivers/iio/accel/mma9551_core.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-)
drivers/iio/accel/mma9551_core.c +4 -1
@@ -362,9 +362,12 @@ int mma9551_read_status_word(struct i2c_client *client, u8 app_id, ret =mma9551_transfer (client, app_id,MMA9551_CMD_READ_STATUS , reg,NULL ,0 , (u8 *)&v,2 ); +if (ret <0 ) +return ret; + *val =be16_to_cpu (v); -return ret; +return 0 ; }EXPORT_SYMBOL (mma9551_read_status_word);
Signature · 1 line
2.39.2
Greg Kroah-Hartman
maintainerPATCH 240/252 iio: accel: mma9551_core: Prevent uninitialized variable in mma9551_read_config_word()
In reply to Greg Kroah-HartmanFrom: Harshit Mogalapalli <[email protected]>
[ Upstream commit 64a68158738ec8f520347144352f7a09bdb9e169 ]
Smatch Warns:drivers/iio/accel/mma9551_core.c:299
mma9551_read_config_word() error: uninitialized symbol 'v'.
When (offset >= 1 << 12) is true mma9551_transfer() will return -EINVAL without 'v' being initialized, so check for the error and return.
Note: No actual bug as caller checks the return value and does not use the parameter in the problem case.
--- drivers/iio/accel/mma9551_core.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-)
drivers/iio/accel/mma9551_core.c +4 -1
@@ -304,9 +304,12 @@ int mma9551_read_config_word(struct i2c_client *client, u8 app_id, ret =mma9551_transfer (client, app_id,MMA9551_CMD_READ_CONFIG , reg,NULL ,0 , (u8 *)&v,2 ); +if (ret <0 ) +return ret; + *val =be16_to_cpu (v); -return ret; +return 0 ; }EXPORT_SYMBOL (mma9551_read_config_word);
Signature · 1 line
2.39.2
Greg Kroah-Hartman
maintainerPATCH 241/252 usb: host: xhci: mvebu: Iterate over array indexes instead of using pointer math
In reply to Greg Kroah-HartmanFrom: Kees Cook <[email protected]>
[ Upstream commit 0fbd2cda92cdb00f72080665554a586f88bca821 ]
Walking the dram->cs array was seen as accesses beyond the first array item by the compiler. Instead, use the array index directly. This allows for run-time bounds checking under CONFIG_UBSAN_BOUNDS as well. Seen with GCC 13 with -fstrict-flex-arrays:
In function 'xhci_mvebu_mbus_config',
inlined from 'xhci_mvebu_mbus_init_quirk' at ../drivers/usb/host/xhci-mvebu.c:66:2:../drivers/usb/host/xhci-mvebu.c:37:28: warning: array subscript 0 is outside array bounds of 'const struct mbus_dram_window[0]' [-Warray-bounds=]
37 | writel(((cs->size - 1) & 0xffff0000) | (cs->mbus_attr << 8) |
| ~~^~~~~~
--- drivers/usb/host/xhci-mvebu.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/usb/host/xhci-mvebu.c +1 -1
@@ -31,7 +31,7 @@ static void xhci_mvebu_mbus_config(void __iomem *base,/* Program each DRAM CS in a seperate window */ for (win =0 ; win < dram->num_cs; win++) { -const struct mbus_dram_window *cs = dram->cs + win; +const struct mbus_dram_window *cs = &dram->cs[win]; writel(((cs->size - 1) & 0xffff0000) | (cs->mbus_attr << 8) | (dram->mbus_dram_target_id << 4) | 1,
Signature · 1 line
2.39.2
Greg Kroah-Hartman
maintainerPATCH 242/252 USB: ene_usb6250: Allocate enough memory for full object
In reply to Greg Kroah-HartmanFrom: Kees Cook <[email protected]>
[ Upstream commit ce33e64c1788912976b61314b56935abd4bc97ef ]
The allocation of PageBuffer is 512 bytes in size, but the dereferencing of struct ms_bootblock_idi (also size 512) happens at a calculated offset within the allocation, which means the object could potentially extend beyond the end of the allocation. Avoid this case by just allocating enough space to catch any accesses beyond the end. Seen with GCC 13:
../drivers/usb/storage/ene_ub6250.c: In function 'ms_lib_process_bootblock':../drivers/usb/storage/ene_ub6250.c:1050:44: warning: array subscript 'struct ms_bootblock_idi[0]' is partly outside array bounds of 'unsigned char[512]' [-Warray-bounds=]
1050 | if (le16_to_cpu(idi->wIDIgeneralConfiguration) != MS_IDI_GENERAL_CONF)
| ^~../include/uapi/linux/byteorder/little_endian.h:37:51: note: in definition of macro '__le16_to_cpu'
37 | #define __le16_to_cpu(x) ((__force __u16)(__le16)(x))
| ^../drivers/usb/storage/ene_ub6250.c:1050:29: note: in expansion of macro 'le16_to_cpu'
1050 | if (le16_to_cpu(idi->wIDIgeneralConfiguration) != MS_IDI_GENERAL_CONF)
| ^~~~~~~~~~~
In file included from ../drivers/usb/storage/ene_ub6250.c:5:
In function 'kmalloc',
inlined from 'ms_lib_process_bootblock' at ../drivers/usb/storage/ene_ub6250.c:942:15:
../include/linux/slab.h:580:24: note: at offset [256, 512] into object of size 512 allocated by 'kmalloc_trace'
580 | return kmalloc_trace(
| ^~~~~~~~~~~~~~
581 | kmalloc_caches[kmalloc_type(flags)][index],
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
582 | flags, size);
| ~~~~~~~~~~~~--- drivers/usb/storage/ene_ub6250.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/usb/storage/ene_ub6250.c +1 -1
@@ -937,7 +937,7 @@ static int ms_lib_process_bootblock(struct us_data *us, u16 PhyBlock, u8 *PageDastruct ms_lib_type_extdat ExtraData;struct ene_ub6250_info *info = (struct ene_ub6250_info *) us->extra; - PageBuffer =kmalloc (MS_BYTES_PER_PAGE ,GFP_KERNEL ); + PageBuffer =kzalloc (MS_BYTES_PER_PAGE *2 ,GFP_KERNEL );if (PageBuffer ==NULL )return (u32)-1 ;
Signature · 1 line
2.39.2
Greg Kroah-Hartman
maintainerPATCH 243/252 usb: uvc: Enumerate valid values for color matching
In reply to Greg Kroah-HartmanFrom: Daniel Scally <[email protected]>
[ Upstream commit e16cab9c1596e251761d2bfb5e1467950d616963 ]
The color matching descriptors defined in the UVC Specification contain 3 fields with discrete numeric values representing particular settings. Enumerate those values so that later code setting them can be more readable.
--- include/uapi/linux/usb/video.h | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+)
include/uapi/linux/usb/video.h +30 -0
@@ -179,6 +179,36 @@#define UVC_CONTROL_CAP_AUTOUPDATE (1 << 3)#define UVC_CONTROL_CAP_ASYNCHRONOUS (1 << 4) +/* 3.9.2.6 Color Matching Descriptor Values */ +enum uvc_color_primaries_values { +UVC_COLOR_PRIMARIES_UNSPECIFIED , +UVC_COLOR_PRIMARIES_BT_709_SRGB , +UVC_COLOR_PRIMARIES_BT_470_2_M , +UVC_COLOR_PRIMARIES_BT_470_2_B_G , +UVC_COLOR_PRIMARIES_SMPTE_170M , +UVC_COLOR_PRIMARIES_SMPTE_240M , +}; + +enum uvc_transfer_characteristics_values { +UVC_TRANSFER_CHARACTERISTICS_UNSPECIFIED , +UVC_TRANSFER_CHARACTERISTICS_BT_709 , +UVC_TRANSFER_CHARACTERISTICS_BT_470_2_M , +UVC_TRANSFER_CHARACTERISTICS_BT_470_2_B_G , +UVC_TRANSFER_CHARACTERISTICS_SMPTE_170M , +UVC_TRANSFER_CHARACTERISTICS_SMPTE_240M , +UVC_TRANSFER_CHARACTERISTICS_LINEAR , +UVC_TRANSFER_CHARACTERISTICS_SRGB , +}; + +enum uvc_matrix_coefficients { +UVC_MATRIX_COEFFICIENTS_UNSPECIFIED , +UVC_MATRIX_COEFFICIENTS_BT_709 , +UVC_MATRIX_COEFFICIENTS_FCC , +UVC_MATRIX_COEFFICIENTS_BT_470_2_B_G , +UVC_MATRIX_COEFFICIENTS_SMPTE_170M , +UVC_MATRIX_COEFFICIENTS_SMPTE_240M , +}; +/* ------------------------------------------------------------------------ * UVC structures */
Signature · 1 line
2.39.2
Greg Kroah-Hartman
maintainerPATCH 244/252 phy: rockchip-typec: Fix unsigned comparison with less than zero
In reply to Greg Kroah-HartmanFrom: Jiapeng Chong <[email protected]>
[ Upstream commit f765c59c5a72546a2d74a92ae5d0eb0329d8e247 ]
The dp and ufp are defined as bool type, the return value type of function extcon_get_state should be int, so the type of dp and ufp are modified to int.
./drivers/phy/rockchip/phy-rockchip-typec.c:827:12-14: WARNING: Unsigned expression compared with zero: dp > 0.
--- drivers/phy/rockchip/phy-rockchip-typec.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-)
drivers/phy/rockchip/phy-rockchip-typec.c +1 -2
@@ -817,9 +817,8 @@ static int tcphy_get_mode(struct rockchistruct extcon_dev *edev = tcphy->extcon;union extcon_property_value property;unsigned int id; -bool ufp, dp;u8 mode; -int ret; +int ret, ufp, dp;if (!edev)return MODE_DFP_USB ;
Greg Kroah-Hartman
maintainerPATCH 245/252 Bluetooth: hci_sock: purge socket queues in the destruct() callback
In reply to Greg Kroah-HartmanFrom: Nguyen Dinh Phi <[email protected]>
commit 709fca500067524381e28a5f481882930eebac88 upstream.
The receive path may take the socket right before hci_sock_release(), but it may enqueue the packets to the socket queues after the call to skb_queue_purge(), therefore the socket can be destroyed without clear its queues completely.
Moving these skb_queue_purge() to the hci_sock_destruct() will fix this issue, because nothing is referencing the socket at this point.
--- net/bluetooth/hci_sock.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-)
net/bluetooth/hci_sock.c +7 -4
@@ -881,10 +881,6 @@ static int hci_sock_release(struct socke }sock_orphan (sk); - -skb_queue_purge (&sk->sk_receive_queue); -skb_queue_purge (&sk->sk_write_queue); -release_sock (sk);sock_put (sk);return 0 ;
@@ -1985,6 +1981,12 @@ done:return err; } +static void hci_sock_destruct (struct sock *sk) +{ +skb_queue_purge (&sk->sk_receive_queue); +skb_queue_purge (&sk->sk_write_queue); +} +static const struct proto_ops hci_sock_ops = { .family =PF_BLUETOOTH , .owner =THIS_MODULE ,
@@ -2035,6 +2037,7 @@ static int hci_sock_create(struct net *n sock->state =SS_UNCONNECTED ; sk->sk_state =BT_OPEN ; + sk->sk_destruct = hci_sock_destruct;bt_sock_link (&hci_sk_list, sk);return 0 ;
Greg Kroah-Hartman
maintainerPATCH 246/252 s390/maccess: add no DAT mode to kernel_write
In reply to Greg Kroah-HartmanFrom: Vasily Gorbik <[email protected]>
commit d6df52e9996dcc2062c3d9c9123288468bb95b52 upstream.
To be able to patch kernel code before paging is initialized do plain memcpy if DAT is off. This is required to enable early jump label initialization.
--- arch/s390/mm/maccess.c | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-)
arch/s390/mm/maccess.c +11 -5
@@ -58,13 +58,19 @@ static notrace long s390_kernel_write_od*/ void notrace s390_kernel_write(void *dst, const void *src, size_t size) { +unsigned long flags;long copied; -while (size) { - copied =s390_kernel_write_odd (dst, src, size); - dst += copied; - src += copied; - size -= copied; + flags =arch_local_save_flags (); +if (!(flags &PSW_MASK_DAT )) { +memcpy (dst, src, size); + }else { +while (size) { + copied =s390_kernel_write_odd (dst, src, size); + dst += copied; + src += copied; + size -= copied; + } } }
Greg Kroah-Hartman
maintainerPATCH 247/252 s390/setup: init jump labels before command line parsing
In reply to Greg Kroah-HartmanFrom: Vasily Gorbik <[email protected]>
commit 95e61b1b5d6394b53d147c0fcbe2ae70fbe09446 upstream.
Command line parameters might set static keys. This is true for s390 at least since commit 6471384af2a6 ("mm: security: introduce init_on_alloc=1 and init_on_free=1 boot options"). To avoid the following WARN:
static_key_enable_cpuslocked(): static key 'init_on_alloc+0x0/0x40' used before call to jump_label_init()
call jump_label_init() just before parse_early_param(). jump_label_init() is safe to call multiple times (x86 does that), doesn't do any memory allocations and hence should be safe to call that early.
--- arch/s390/kernel/setup.c | 1 + 1 file changed, 1 insertion(+)
arch/s390/kernel/setup.c +1 -0
@@ -909,6 +909,7 @@ void __init setup_arch(char **cmdline_p)if (IS_ENABLED (CONFIG_EXPOLINE_AUTO ))nospec_auto_detect (); +jump_label_init ();parse_early_param ();#ifdef CONFIG_CRASH_DUMP /* Deactivate elfcorehdr= kernel parameter */
Greg Kroah-Hartman
maintainerPATCH 248/252 tcp: Fix listen() regression in 4.19.270
In reply to Greg Kroah-HartmanFrom: Kuniyuki Iwashima <[email protected]>
commit fdaf88531cfd17b2a710cceb3141ef6f9085ff40 upstream.
When we backport dadd0dcaa67d ("net/ulp: prevent ULP without clone op from entering the LISTEN status"), we have accidentally backported a part of 7a7160edf1bf ("net: Return errno in sk->sk_prot->get_port().") and removed err = -EADDRINUSE in inet_csk_listen_start().
Thus, listen() no longer returns -EADDRINUSE even if ->get_port() failed as reported in [0].
We set -EADDRINUSE to err just before ->get_port() to fix the regression.
[0]: https://lore.kernel.org/stable/[email protected]/
--- net/ipv4/inet_connection_sock.c | 1 + 1 file changed, 1 insertion(+)
net/ipv4/inet_connection_sock.c +1 -0
@@ -934,6 +934,7 @@ int inet_csk_listen_start(struct sock *s* It is OK, because this socket enters to hash table only * after validation is complete. */ + err = -EADDRINUSE ;inet_sk_state_store (sk,TCP_LISTEN );if (!sk->sk_prot->get_port (sk, inet->inet_num)) { inet->inet_sport =htons (inet->inet_num);
Greg Kroah-Hartman
maintainerPATCH 249/252 media: uvcvideo: Provide sync and async uvc_ctrl_status_event
In reply to Greg Kroah-HartmanFrom: Ricardo Ribalda <[email protected]>
commit d9c8763e61295be0a21dc04ad9c379d5d17c3d86 upstream.
Split the functionality of void uvc_ctrl_status_event_work in two, so it can be called by functions outside interrupt context and not part of an URB.
--- drivers/media/usb/uvc/uvc_ctrl.c | 25 +++++++++++++++---------- drivers/media/usb/uvc/uvc_status.c | 3 ++- drivers/media/usb/uvc/uvcvideo.h | 4 +++- 3 files changed, 20 insertions(+), 12 deletions(-)
drivers/media/usb/uvc/uvc_ctrl.c +15 -10
@@ -1280,17 +1280,12 @@ static void uvc_ctrl_send_slave_event(stuvc_ctrl_send_event (chain, handle, ctrl, mapping, val, changes); } -static void uvc_ctrl_status_event_work (struct work_struct *work) +void uvc_ctrl_status_event (struct uvc_video_chain *chain, +struct uvc_control *ctrl,const u8 *data) { - struct uvc_device *dev = container_of(work, struct uvc_device, - async_ctrl.work); -struct uvc_ctrl_work *w = &dev->async_ctrl; -struct uvc_video_chain *chain = w->chain;struct uvc_control_mapping *mapping; -struct uvc_control *ctrl = w->ctrl;struct uvc_fh *handle;unsigned int i; -int ret;mutex_lock (&chain->ctrl_mutex);
@@ -1298,7 +1293,7 @@ static void uvc_ctrl_status_event_work(s ctrl->handle =NULL ;list_for_each_entry (mapping, &ctrl->info.mappings, list) { -s32 value =__uvc_ctrl_get_value (mapping, w->data); +s32 value =__uvc_ctrl_get_value (mapping, data);/* * handle may be NULL here if the device sends auto-update
@@ -1317,6 +1312,16 @@ static void uvc_ctrl_status_event_work(s }mutex_unlock (&chain->ctrl_mutex); +} + +static void uvc_ctrl_status_event_work (struct work_struct *work) +{ + struct uvc_device *dev = container_of(work, struct uvc_device, + async_ctrl.work); +struct uvc_ctrl_work *w = &dev->async_ctrl; +int ret; + +uvc_ctrl_status_event (w->chain, w->ctrl, w->data);/* Resubmit the URB. */ w->urb->interval = dev->int_ep->desc.bInterval;
@@ -1326,8 +1331,8 @@ static void uvc_ctrl_status_event_work(s ret); } -bool uvc_ctrl_status_event (struct urb *urb,struct uvc_video_chain *chain, -struct uvc_control *ctrl,const u8 *data) +bool uvc_ctrl_status_event_async (struct urb *urb,struct uvc_video_chain *chain, +struct uvc_control *ctrl,const u8 *data) {struct uvc_device *dev = chain->dev;struct uvc_ctrl_work *w = &dev->async_ctrl;
drivers/media/usb/uvc/uvc_status.c +2 -1
@@ -184,7 +184,8 @@ static bool uvc_event_control(struct urbswitch (status->bAttribute) {case UVC_CTRL_VALUE_CHANGE : -return uvc_ctrl_status_event (urb, chain, ctrl, status->bValue); +return uvc_ctrl_status_event_async (urb, chain, ctrl, + status->bValue);case UVC_CTRL_INFO_CHANGE :case UVC_CTRL_FAILURE_CHANGE :
drivers/media/usb/uvc/uvcvideo.h +3 -1
@@ -768,7 +768,9 @@ int uvc_ctrl_add_mapping(struct uvc_videint uvc_ctrl_init_device (struct uvc_device *dev);void uvc_ctrl_cleanup_device (struct uvc_device *dev);int uvc_ctrl_restore_values (struct uvc_device *dev); -bool uvc_ctrl_status_event (struct urb *urb,struct uvc_video_chain *chain, +bool uvc_ctrl_status_event_async (struct urb *urb,struct uvc_video_chain *chain, +struct uvc_control *ctrl,const u8 *data); +void uvc_ctrl_status_event (struct uvc_video_chain *chain,struct uvc_control *ctrl,const u8 *data);int uvc_ctrl_begin (struct uvc_video_chain *chain);
Greg Kroah-Hartman
maintainerPATCH 250/252 media: uvcvideo: Fix race condition with usb_kill_urb
In reply to Greg Kroah-HartmanFrom: Ricardo Ribalda <[email protected]>
commit 619d9b710cf06f7a00a17120ca92333684ac45a8 upstream.
usb_kill_urb warranties that all the handlers are finished when it returns, but does not protect against threads that might be handling asynchronously the urb.
For UVC, the function uvc_ctrl_status_event_async() takes care of control changes asynchronously.
If the code is executed in the following order:
CPU 0 CPU 1
===== =====uvc_status_complete()
uvc_status_stop()uvc_ctrl_status_event_work()
uvc_status_start() -> FAIL
Then uvc_status_start will keep failing and this error will be shown:
<4>[ 5.540139] URB 0000000000000000 submitted while active
drivers/usb/core/urb.c:378 usb_submit_urb+0x4c3/0x528
Let's improve the current situation, by not re-submiting the urb if we are stopping the status event. Also process the queued work (if any) during stop.
CPU 0 CPU 1
===== =====uvc_status_complete()
uvc_status_stop() uvc_status_start()uvc_ctrl_status_event_work() -> FAIL
Hopefully, with the usb layer protection this should be enough to cover all the cases.
--- drivers/media/usb/uvc/uvc_ctrl.c | 5 +++++ drivers/media/usb/uvc/uvc_status.c | 37 +++++++++++++++++++++++++++++++++++++ drivers/media/usb/uvc/uvcvideo.h | 1 + 3 files changed, 43 insertions(+)
drivers/media/usb/uvc/uvc_ctrl.c +5 -0
@@ -11,6 +11,7 @@* */ +#include <asm/barrier.h> #include <linux/kernel.h> #include <linux/list.h> #include <linux/module.h>
@@ -1323,6 +1324,10 @@ static void uvc_ctrl_status_event_work(suvc_ctrl_status_event (w->chain, w->ctrl, w->data); +/* The barrier is needed to synchronize with uvc_status_stop(). */ +if (smp_load_acquire (&dev->flush_status)) +return ; +/* Resubmit the URB. */ w->urb->interval = dev->int_ep->desc.bInterval; ret =usb_submit_urb (w->urb,GFP_KERNEL );
drivers/media/usb/uvc/uvc_status.c +37 -0
@@ -11,6 +11,7 @@* */ +#include <asm/barrier.h> #include <linux/kernel.h> #include <linux/input.h> #include <linux/slab.h>
@@ -315,5 +316,41 @@ int uvc_status_start(struct uvc_device *void uvc_status_stop (struct uvc_device *dev) { +struct uvc_ctrl_work *w = &dev->async_ctrl; + +/* +* Prevent the asynchronous control handler from requeing the URB. The +* barrier is needed so the flush_status change is visible to other +* CPUs running the asynchronous handler before usb_kill_urb() is +* called below. +*/ +smp_store_release (&dev->flush_status, true); + +/* +* Cancel any pending asynchronous work. If any status event was queued, +* process it synchronously. +*/ +if (cancel_work_sync (&w->work)) +uvc_ctrl_status_event (w->chain, w->ctrl, w->data); + +/* Kill the urb. */ usb_kill_urb (dev->int_urb); + +/* +* The URB completion handler may have queued asynchronous work. This +* won't resubmit the URB as flush_status is set, but it needs to be +* cancelled before returning or it could then race with a future +* uvc_status_start() call. +*/ +if (cancel_work_sync (&w->work)) +uvc_ctrl_status_event (w->chain, w->ctrl, w->data); + +/* +* From this point, there are no events on the queue and the status URB +* is dead. No events will be queued until uvc_status_start() is called. +* The barrier is needed to make sure that flush_status is visible to +* uvc_ctrl_status_event_work() when uvc_status_start() will be called +* again. +*/ +smp_store_release (&dev->flush_status, false); }
drivers/media/usb/uvc/uvcvideo.h +1 -0
@@ -603,6 +603,7 @@ struct uvc_device {/* Status Interrupt Endpoint */ struct usb_host_endpoint *int_ep;struct urb *int_urb; +bool flush_status;u8 *status;struct input_dev *input;char input_phys[64 ];
Greg Kroah-Hartman
maintainerPATCH 251/252 f2fs: fix cgroup writeback accounting with fs-layer encryption
In reply to Greg Kroah-HartmanFrom: Eric Biggers <[email protected]>
commit 844545c51a5b2a524b22a2fe9d0b353b827d24b4 upstream.
When writing a page from an encrypted file that is using filesystem-layer encryption (not inline encryption), f2fs encrypts the pagecache page into a bounce page, then writes the bounce page.
It also passes the bounce page to wbc_account_cgroup_owner(). That's incorrect, because the bounce page is a newly allocated temporary page that doesn't have the memory cgroup of the original pagecache page. This makes wbc_account_cgroup_owner() not account the I/O to the owner of the pagecache page as it should.
Fix this by always passing the pagecache page towbc_account_cgroup_owner().
--- fs/f2fs/data.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
fs/f2fs/data.c +2 -2
@@ -464,7 +464,7 @@ int f2fs_submit_page_bio(struct f2fs_io_ }if (fio->io_wbc && !is_read_io (fio->op)) -wbc_account_io (fio->io_wbc, page,PAGE_SIZE ); +wbc_account_io (fio->io_wbc, fio->page,PAGE_SIZE );bio_set_op_attrs (bio, fio->op, fio->op_flags);
@@ -533,7 +533,7 @@ alloc_new: }if (fio->io_wbc) -wbc_account_io (fio->io_wbc, bio_page,PAGE_SIZE ); +wbc_account_io (fio->io_wbc, fio->page,PAGE_SIZE ); io->last_block_in_bio = fio->new_blkaddr;f2fs_trace_ios (fio,0 );
Greg Kroah-Hartman
maintainerPATCH 252/252 thermal: intel: powerclamp: Fix cur_state for multi package system
In reply to Greg Kroah-HartmanFrom: Srinivas Pandruvada <[email protected]>
commit 8e47363588377e1bdb65e2b020b409cfb44dd260 upstream.
The powerclamp cooling device cur_state shows actual idle observed by package C-state idle counters. But the implementation is not sufficient for multi package or multi die system. The cur_state value is incorrect. On these systems, these counters must be read from each package/die and somehow aggregate them. But there is no good method for aggregation.
It was not a problem when explicit CPU model addition was required to enable intel powerclamp. In this way certain CPU models could have been avoided. But with the removal of CPU model check with the availability of Package C-state counters, the driver is loaded on most of the recent systems.
For multi package/die systems, just show the actual target idle state, the system is trying to achieve. In powerclamp this is the user set state minus one.
Also there is no use of starting a worker thread for polling package C-state counters and applying any compensation for multiple package or multiple die systems.
--- drivers/thermal/intel_powerclamp.c | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-)
drivers/thermal/intel_powerclamp.c +16 -4
@@ -72,6 +72,7 @@static unsigned int target_mwait;static struct dentry *debug_dir; +static bool poll_pkg_cstate_enable;/* user selected target */ static unsigned int set_target_ratio;
@@ -280,6 +281,9 @@ static unsigned int get_compensation(int {unsigned int comp =0 ; +if (!poll_pkg_cstate_enable) +return 0 ; +/* we only use compensation if all adjacent ones are good */ if (ratio == 1 && cal_data[ratio].confidence >= CONFIDENCE_OK &&
@@ -552,7 +556,8 @@ static int start_power_clamp(void) control_cpu =cpumask_first (cpu_online_mask); clamping = true; -schedule_delayed_work (&poll_pkg_cstate_work,0 ); +if (poll_pkg_cstate_enable) +schedule_delayed_work (&poll_pkg_cstate_work,0 );/* start one kthread worker per online cpu */ for_each_online_cpu (cpu) {
@@ -621,11 +626,15 @@ static int powerclamp_get_max_state(strustatic int powerclamp_get_cur_state (struct thermal_cooling_device *cdev,unsigned long *state) { -if (true == clamping) - *state = pkg_cstate_ratio_cur; -else +if (clamping) { +if (poll_pkg_cstate_enable) + *state = pkg_cstate_ratio_cur; +else + *state = set_target_ratio; + }else {/* to save power, do not poll idle ratio while not clamping */ *state =-1 ;/* indicates invalid state */ + }return 0 ; }
@@ -770,6 +779,9 @@ static int __init powerclamp_init(void) goto exit_unregister; } +if (topology_max_packages () ==1 ) + poll_pkg_cstate_enable = true; + cooling_dev =thermal_cooling_device_register ("intel_powerclamp" ,NULL , &powerclamp_cooling_ops);if (IS_ERR (cooling_dev)) {
Quoted 9 lines · Greg Kroah-Hartman
This is the start of the stable review cycle for the 4.19.276 release. There are 252 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, 12 Mar 2023 13:36:38 +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.19.276-rc1.gzor in the git tree and branch at:
git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.gitlinux-4.19.y
and the diffstat can be found below.thanks,
greg k-h
All tests passing for Tegra ...
Test results for stable-v4.19:
10 builds: 10 pass, 0 fail
22 boots: 22 pass, 0 fail
40 tests: 40 pass, 0 failLinux version: 4.19.276-rc1-g70b2ca70b378
Boards tested: tegra124-jetson-tk1, tegra186-p2771-0000,
tegra194-p2972-0000, tegra20-ventana,
tegra210-p2371-2180, tegra30-cardhu-a04Jon
Quoted 9 lines · Greg Kroah-Hartman
This is the start of the stable review cycle for the 4.19.276 release. There are 252 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, 12 Mar 2023 13:36:38 +0000. Anything received after that time might be too late.
The whole patch series can be found in one patch at:
Quoted 9 lines
https://www.kernel.org/pub/linux/kernel/v4.x/stable-review/patch-4.19.276-rc1.gzor in the git tree and branch at:
git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.gitlinux-4.19.y
and the diffstat can be found below.thanks,
greg k-h
Compiled and booted on my test system. No dmesg regressions.
thanks,
-- Shuah
Quoted 8 lines · Greg Kroah-Hartman
This is the start of the stable review cycle for the 4.19.276 release. There are 252 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, 12 Mar 2023 13:36:38 +0000. Anything received after that time might be too late.
Build results:
total: 155 pass: 155 fail: 0 Qemu test results: total: 431 pass: 431 fail: 0
Guenter
Quoted 10 lines · Greg Kroah-Hartman
This is the start of the stable review cycle for the 4.19.276 release. There are 252 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, 12 Mar 2023 13:36:38 +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.19.276-rc1.gzor in the git tree and branch at:
git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.gitlinux-4.19.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.19.276-rc1
* git: https://gitlab.com/Linaro/lkft/mirrors/stable/linux-stable-rc
* git branch: linux-4.19.y
* git commit: 70b2ca70b378b14ffbcd349d80cdfc361e044b01
* git describe: v4.19.275-253-g70b2ca70b378
* test details:
https://qa-reports.linaro.org/lkft/linux-stable-rc-linux-4.19.y/build/v4.19.275-253-g70b2ca70b378
## Test Regressions (compared to v4.19.275)
## Metric Regressions (compared to v4.19.275)
## Test Fixes (compared to v4.19.275)
## Metric Fixes (compared to v4.19.275)
## Test result summary
total: 71771, pass: 52887, fail: 2333, skip: 16246, xfail: 305
## Build Summary
* arc: 10 total, 10 passed, 0 failed
* arm: 201 total, 200 passed, 1 failed
* arm64: 42 total, 41 passed, 1 failed
* i386: 29 total, 28 passed, 1 failed
* mips: 42 total, 42 passed, 0 failed
* parisc: 12 total, 12 passed, 0 failed
* powerpc: 51 total, 51 passed, 0 failed
* s390: 15 total, 15 passed, 0 failed
* sh: 24 total, 24 passed, 0 failed
* sparc: 12 total, 12 passed, 0 failed
* x86_64: 37 total, 36 passed, 1 failed
## Test suites summary
* boot
* fwts
* kselftest-android
* kselftest-arm64
* kselftest-breakpoints
* kselftest-capabilities
* kselftest-cgroup
* kselftest-clone3
* kselftest-core
* kselftest-cpu-hotplug
* kselftest-cpufreq
* kselftest-drivers-dma-buf
* kselftest-efivarfs
* kselftest-filesystems
* kselftest-filesystems-binderfs
* kselftest-firmware
* kselftest-fpu
* kselftest-ftrace
* kselftest-futex
* kselftest-gpio
* kselftest-intel_pstate
* kselftest-ipc
* kselftest-ir
* kselftest-kcmp
* kselftest-kexec
* kselftest-kvm
* kselftest-lib
* kselftest-livepatch
* kselftest-membarrier
* kselftest-memfd
* kselftest-memory-hotplug
* kselftest-mincore
* kselftest-mount
* kselftest-mqueue
* kselftest-net
* kselftest-net-forwarding
* kselftest-net-mptcp
* 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
* kunit
* libhugetlbfs
* log-parser-boot
* log-parser-test
* ltp-cap_bounds
* ltp-commands
* ltp-containers
* ltp-controllers
* ltp-cpuhotplug
* ltp-crypto
* ltp-cve
* ltp-dio
* ltp-fcntl-locktests
* ltp-filecaps
* ltp-fs
* ltp-fs_bind
* ltp-fs_perms_simple
* ltp-fsx
* ltp-hugetlb
* ltp-io
* ltp-ipc
* ltp-math
* ltp-mm
* ltp-nptl
* ltp-open-posix-tests
* ltp-pty
* ltp-sched
* ltp-securebits
* ltp-smoke
* ltp-syscalls
* ltp-tracing
* network-basic-tests
* packetdrill
* rcutorture
* v4l2-compliance
* vdso
--
Linaro LKFT
https://lkft.linaro.org
Hi Greg,
Quoted 7 lines · Greg Kroah-Hartman
This is the start of the stable review cycle for the 4.19.276 release. There are 252 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, 12 Mar 2023 13:36:38 +0000. Anything received after that time might be too late.
Build test (gcc version 11.3.1 20230210):
mips: 63 configs -> no failure
arm: 115 configs -> no failure
arm64: 2 configs -> no failurex86_64: 4 configs -> no failure
alpha allmodconfig -> no failure
powerpc allmodconfig -> no failure
riscv allmodconfig -> no failure
s390 allmodconfig -> no failure
xtensa allmodconfig -> no failure
Boot test:x86_64: Booted on my test laptop. No regression.x86_64: Booted on qemu. No regression. [1]
[1]. https://openqa.qa.codethink.co.uk/tests/3072
Signature · 2 lines
Regards Sudip