5.15.35-rc1 review
Greg Kroah-Hartman
maintainerPATCH 167/189 genirq/affinity: Consider that CPUs on nodes can be unbalanced
In reply to Greg Kroah-HartmanFrom: Rei Yamamoto <[email protected]>
commit 08d835dff916bfe8f45acc7b92c7af6c4081c8a7 upstream.
If CPUs on a node are offline at boot time, the number of nodes is different when building affinity masks for present cpus and when building affinity masks for possible cpus. This causes the following problem:
In the case that the number of vectors is less than the number of nodes there are cases where bits of masks for present cpus are overwritten when building masks for possible cpus.
Fix this by excluding CPUs, which are not part of the current build mask (present/possible).
[ tglx: Massaged changelog and added comment ]
--- kernel/irq/affinity.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-)
kernel/irq/affinity.c +3 -2
@@ -269,8 +269,9 @@ static int __irq_build_affinity_masks(un*/ if (numvecs <= nodes) {for_each_node_mask (n, nodemsk) { -cpumask_or (&masks[curvec].mask, &masks[curvec].mask, - node_to_cpumask[n]); +/* Ensure that only CPUs which are in both masks are set */ +cpumask_and (nmsk, cpu_mask, node_to_cpumask[n]); +cpumask_or (&masks[curvec].mask, &masks[curvec].mask, nmsk);if (++curvec == last_affv) curvec = firstvec; }
Greg Kroah-Hartman
maintainerPATCH 168/189 tick/nohz: Use WARN_ON_ONCE() to prevent console saturation
In reply to Greg Kroah-HartmanFrom: Paul Gortmaker <[email protected]>
commit 40e97e42961f8c6cc7bd5fe67cc18417e02d78f1 upstream.
While running some testing on code that happened to allow the variable tick_nohz_full_running to get set but with no "possible" NOHZ cores to back up that setting, this warning triggered:
if (unlikely(tick_do_timer_cpu == TICK_DO_TIMER_NONE))
WARN_ON(tick_nohz_full_running);The console was overwhemled with an endless stream of one WARN per tick per core and there was no way to even see what was going on w/o using a serial console to capture it and then trace it back to this.
Change it to WARN_ON_ONCE().
--- kernel/time/tick-sched.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
kernel/time/tick-sched.c +1 -1
@@ -186,7 +186,7 @@ static void tick_sched_do_timer(struct t*/ if (unlikely (tick_do_timer_cpu ==TICK_DO_TIMER_NONE )) {#ifdef CONFIG_NO_HZ_FULL -WARN_ON (tick_nohz_full_running); +WARN_ON_ONCE (tick_nohz_full_running);#endif tick_do_timer_cpu = cpu; }
Greg Kroah-Hartman
maintainerPATCH 169/189 ARM: davinci: da850-evm: Avoid NULL pointer dereference
In reply to Greg Kroah-HartmanFrom: Nathan Chancellor <[email protected]>
commit 83a1cde5c74bfb44b49cb2a940d044bb2380f4ea upstream.
With newer versions of GCC, there is a panic in da850_evm_config_emac() when booting multi_v5_defconfig in QEMU under the palmetto-bmc machine:
Unable to handle kernel NULL pointer dereference at virtual address 00000020 pgd = (ptrval) [00000020] *pgd=00000000 Internal error: Oops: 5 [#1] PREEMPT ARM Modules linked in: CPU: 0 PID: 1 Comm: swapper Not tainted 5.15.0 #1 Hardware name: Generic DT based system PC is at da850_evm_config_emac+0x1c/0x120 LR is at do_one_initcall+0x50/0x1e0
The emac_pdata pointer in soc_info is NULL because davinci_soc_info only gets populated on davinci machines but da850_evm_config_emac() is called on all machines via device_initcall().
Move the rmii_en assignment below the machine check so that it is only dereferenced when running on a supported SoC.
--- arch/arm/mach-davinci/board-da850-evm.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
arch/arm/mach-davinci/board-da850-evm.c +3 -1
@@ -1101,11 +1101,13 @@ static int __init da850_evm_config_emac(int ret;u32 val;struct davinci_soc_info *soc_info = &davinci_soc_info; -u8 rmii_en = soc_info->emac_pdata->rmii_en; +u8 rmii_en;if (!machine_is_davinci_da850_evm ())return 0 ; + rmii_en = soc_info->emac_pdata->rmii_en; + cfg_chip3_base =DA8XX_SYSCFG0_VIRT (DA8XX_CFGCHIP3_REG ); val =__raw_readl (cfg_chip3_base);
Greg Kroah-Hartman
maintainerPATCH 170/189 dm integrity: fix memory corruption when tag_size is less than digest size
In reply to Greg Kroah-HartmanFrom: Mikulas Patocka <[email protected]>
commit 08c1af8f1c13bbf210f1760132f4df24d0ed46d6 upstream.
It is possible to set up dm-integrity in such a way that the "tag_size" parameter is less than the actual digest size. In this situation, a part of the digest beyond tag_size is ignored.
In this case, dm-integrity would write beyond the end of the ic->recalc_tags array and corrupt memory. The corruption happened in integrity_recalc->integrity_sector_checksum->crypto_shash_final.
Fix this corruption by increasing the tags array so that it has enough padding at the end to accomodate the loop in integrity_recalc() being able to write a full digest size for the last member of the tags array.
--- drivers/md/dm-integrity.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-)
drivers/md/dm-integrity.c +5 -2
@@ -4383,6 +4383,7 @@ try_smaller_buffer: }if (ic->internal_hash) { +size_t recalc_tags_size; ic->recalc_wq =alloc_workqueue ("dm-integrity-recalc" ,WQ_MEM_RECLAIM ,1 );if (!ic->recalc_wq ) { ti->error ="Cannot allocate workqueue" ;
@@ -4396,8 +4397,10 @@ try_smaller_buffer: r = -ENOMEM ; goto bad; } - ic->recalc_tags =kvmalloc_array (RECALC_SECTORS >> ic->sb->log2_sectors_per_block, - ic->tag_size,GFP_KERNEL ); + recalc_tags_size = (RECALC_SECTORS >> ic->sb->log2_sectors_per_block) * ic->tag_size; +if (crypto_shash_digestsize (ic->internal_hash) > ic->tag_size) + recalc_tags_size +=crypto_shash_digestsize (ic->internal_hash) - ic->tag_size; + ic->recalc_tags =kvmalloc (recalc_tags_size,GFP_KERNEL );if (!ic->recalc_tags) { ti->error ="Cannot allocate tags for recalculating" ; r = -ENOMEM ;
Greg Kroah-Hartman
maintainerPATCH 171/189 i2c: dev: check return value when calling dev_set_name()
In reply to Greg Kroah-HartmanFrom: Andy Shevchenko <[email protected]>
commit 993eb48fa199b5f476df8204e652eff63dd19361 upstream.
If dev_set_name() fails, the dev_name() is null, check the return value of dev_set_name() to avoid the null-ptr-deref.
--- drivers/i2c/i2c-dev.c | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-)
drivers/i2c/i2c-dev.c +10 -5
@@ -668,16 +668,21 @@ static int i2cdev_attach_adapter(struct i2c_dev->dev.class = i2c_dev_class; i2c_dev->dev.parent = &adap->dev; i2c_dev->dev.release = i2cdev_dev_release; -dev_set_name (&i2c_dev->dev,"i2c-%d" , adap->nr); + + res =dev_set_name (&i2c_dev->dev,"i2c-%d" , adap->nr); +if (res) + goto err_put_i2c_dev; res =cdev_device_add (&i2c_dev->cdev, &i2c_dev->dev); -if (res) { -put_i2c_dev (i2c_dev, false); -return res; - } +if (res) + goto err_put_i2c_dev;pr_debug ("adapter [%s] registered as minor %d\n" , adap->name, adap->nr);return 0 ; + +err_put_i2c_dev: +put_i2c_dev (i2c_dev, false); +return res; }static int i2cdev_detach_adapter (struct device *dev,void *dummy)
Greg Kroah-Hartman
maintainerPATCH 172/189 smp: Fix offline cpu check in flush_smp_call_function_queue()
In reply to Greg Kroah-HartmanFrom: Nadav Amit <[email protected]>
commit 9e949a3886356fe9112c6f6f34a6e23d1d35407f upstream.
The check in flush_smp_call_function_queue() for callbacks that are sent to offline CPUs currently checks whether the queue is empty.
However, flush_smp_call_function_queue() has just deleted all the callbacks from the queue and moved all the entries into a local list. This checks would only be positive if some callbacks were added in the short time after llist_del_all() was called. This does not seem to be the intention of this check.
Change the check to look at the local list to which the entries were moved instead of the queue from which all the callbacks were just removed.
--- kernel/smp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
kernel/smp.c +1 -1
@@ -579,7 +579,7 @@ static void flush_smp_call_function_queu/* There shouldn't be any pending callbacks on an offline CPU. */ if (unlikely (warn_cpu_offline && !cpu_online (smp_processor_id ()) && - !warned && !llist_empty (head))) { + !warned && entry !=NULL )) { warned = true;WARN (1 ,"IPI on offline CPU %d\n" ,smp_processor_id ());
Greg Kroah-Hartman
maintainerPATCH 173/189 i2c: pasemi: Wait for write xfers to finish
In reply to Greg Kroah-HartmanFrom: Martin Povišer <[email protected]>
commit bd8963e602c77adc76dbbbfc3417c3cf14fed76b upstream.
Wait for completion of write transfers before returning from the driver. At first sight it may seem advantageous to leave write transfers queued for the controller to carry out on its own time, but there's a couple of issues with it:
* Driver doesn't check for FIFO space.
* The queued writes can complete while the driver is in its I2C read transfer path which means it will get confused by the raising of XEN (the 'transaction ended' signal). This can cause a spurious ENODATA error due to premature reading of the MRXFIFO register.
Adding the wait fixes some unreliability issues with the driver. There's some efficiency cost to it (especially with pasemi_smb_waitready doing its polling), but that will be alleviated once the driver receives interrupt support.
--- drivers/i2c/busses/i2c-pasemi.c | 6 ++++++ 1 file changed, 6 insertions(+)
drivers/i2c/busses/i2c-pasemi.c +6 -0
@@ -137,6 +137,12 @@ static int pasemi_i2c_xfer_msg(struct i2TXFIFO_WR (smbus, msg->buf[msg->len-1 ] | (stop ?MTXFIFO_STOP :0 )); + +if (stop) { + err =pasemi_smb_waitready (smbus); +if (err) + goto reset_out; + } }return 0 ;
Greg Kroah-Hartman
maintainerPATCH 174/189 dt-bindings: net: snps: remove duplicate name
In reply to Greg Kroah-HartmanFrom: Dongjin Yang <[email protected]>
commit ce8b3ad1071b764e963d9b08ac34ffddddf12da6 upstream.
snps,dwmac has duplicated name for loongson,ls2k-dwmac and loongson,ls7a-dwmac.
--- Documentation/devicetree/bindings/net/snps,dwmac.yaml | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-)
Documentation/devicetree/bindings/net/snps,dwmac.yaml +2 -4
@@ -53,20 +53,18 @@ properties: - allwinner,sun8i-r40-emac - allwinner,sun8i-v3s-emac - allwinner,sun50i-a64-emac - - loongson,ls2k-dwmac - - loongson,ls7a-dwmac - amlogic,meson6-dwmac - amlogic,meson8b-dwmac - amlogic,meson8m2-dwmac - amlogic,meson-gxbb-dwmac - amlogic,meson-axg-dwmac - - loongson,ls2k-dwmac - - loongson,ls7a-dwmac - ingenic,jz4775-mac - ingenic,x1000-mac - ingenic,x1600-mac - ingenic,x1830-mac - ingenic,x2000-mac + - loongson,ls2k-dwmac + - loongson,ls7a-dwmac - rockchip,px30-gmac - rockchip,rk3128-gmac - rockchip,rk3228-gmac
Greg Kroah-Hartman
maintainerPATCH 175/189 timers: Fix warning condition in __run_timers()
In reply to Greg Kroah-HartmanFrom: Anna-Maria Behnsen <[email protected]>
commit c54bc0fc84214b203f7a0ebfd1bd308ce2abe920 upstream.
When the timer base is empty, base::next_expiry is set to base::clk + NEXT_TIMER_MAX_DELTA and base::next_expiry_recalc is false. When no timer is queued until jiffies reaches base::next_expiry value, the warning for not finding any expired timer and base::next_expiry_recalc is false in __run_timers() triggers.
To prevent triggering the warning in this valid scenario base::timers_pending needs to be added to the warning condition.
--- kernel/time/timer.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-)
kernel/time/timer.c +7 -4
@@ -1722,11 +1722,14 @@ static inline void __run_timers(struct t time_after_eq(jiffies, base->next_expiry)) { levels =collect_expired_timers (base, heads);/* -* The only possible reason for not finding any expired -* timer at this clk is that all matching timers have been -* dequeued. +* The two possible reasons for not finding any expired +* timer at this clk are that all matching timers have been +* dequeued or no timer has been queued since +* base::next_expiry was set to base::clk + +* NEXT_TIMER_MAX_DELTA. */ -WARN_ON_ONCE (!levels && !base->next_expiry_recalc); +WARN_ON_ONCE (!levels && !base->next_expiry_recalc + && base->timers_pending); base->clk++; base->next_expiry =__next_timer_interrupt (base);
Greg Kroah-Hartman
maintainerPATCH 176/189 dma-direct: avoid redundant memory sync for swiotlb
In reply to Greg Kroah-HartmanFrom: Chao Gao <[email protected]>
commit 9e02977bfad006af328add9434c8bffa40e053bb upstream.
When we looked into FIO performance with swiotlb enabled in VM, we found swiotlb_bounce() is always called one more time than expected for each DMA read request.
It turns out that the bounce buffer is copied to original DMA buffer twice after the completion of a DMA request (one is done by in dma_direct_sync_single_for_cpu(), the other by swiotlb_tbl_unmap_single()). But the content in bounce buffer actually doesn't change between the two rounds of copy. So, one round of copy is redundant.
Pass DMA_ATTR_SKIP_CPU_SYNC flag to swiotlb_tbl_unmap_single() to skip the memory copy in it.
This fix increases FIO 64KB sequential read throughput in a guest with swiotlb=force by 5.6%.
--- kernel/dma/direct.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
kernel/dma/direct.h +2 -1
@@ -114,6 +114,7 @@ static inline void dma_direct_unmap_pagedma_direct_sync_single_for_cpu (dev, addr, size, dir);if (unlikely (is_swiotlb_buffer (dev, phys))) - swiotlb_tbl_unmap_single(dev, phys, size, dir, attrs); +swiotlb_tbl_unmap_single (dev, phys, size, dir, + attrs | DMA_ATTR_SKIP_CPU_SYNC); }#endif /* _KERNEL_DMA_DIRECT_H */
Greg Kroah-Hartman
maintainerPATCH 177/189 drm/i915: Sunset igpu legacy mmap support based on GRAPHICS_VER_FULL
In reply to Greg Kroah-HartmanFrom: Matt Roper <[email protected]>
commit 1acb34e7dd7720a1fff00cbd4d000ec3219dc9d6 upstream.
The intent of the version check in the mmap ioctl was to maintain support for existing platforms (i.e., ADL/RPL and earlier), but drop support on all future igpu platforms. As we've seen on the dgpu side, the hardware teams are using a more fine-grained numbering system for IP version numbers these days, so it's possible the version number associated with our next igpu could be some form of "12.xx" rather than 13 or higher. Comparing against the full ver.release number will ensure the intent of the check is maintained no matter what numbering the hardware teams settle on.
--- drivers/gpu/drm/i915/gem/i915_gem_mman.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/gpu/drm/i915/gem/i915_gem_mman.c +1 -1
@@ -66,7 +66,7 @@ i915_gem_mmap_ioctl(struct drm_device *d* mmap ioctl is disallowed for all discrete platforms, * and for all platforms with GRAPHICS_VER > 12. */ -if (IS_DGFX (i915) ||GRAPHICS_VER (i915) >12 ) +if (IS_DGFX (i915) ||GRAPHICS_VER_FULL (i915) >IP_VER (12 ,0 ))return -EOPNOTSUPP ;if (args->flags & ~(I915_MMAP_WC ))
Greg Kroah-Hartman
maintainerPATCH 178/189 cpu/hotplug: Remove the cpu member of cpuhp_cpu_state
In reply to Greg Kroah-HartmanFrom: Steven Price <[email protected]>
commit b7ba6d8dc3569e49800ef0136799f26f43e237e8 upstream.
Currently the setting of the 'cpu' member of struct cpuhp_cpu_state in cpuhp_create() is too late as it is used earlier in _cpu_up().
If kzalloc_node() in __smpboot_create_thread() fails then the rollback will be done with st->cpu==0 causing CPU0 to be erroneously set to be dying, causing the scheduler to get mightily confused and throw its toys out of the pram.
However the cpu number is actually available directly, so simply remove the 'cpu' member and avoid the problem in the first place.
--- kernel/cpu.c | 36 ++++++++++++++++++------------------ 1 file changed, 18 insertions(+), 18 deletions(-)
kernel/cpu.c +18 -18
@@ -70,7 +70,6 @@ struct cpuhp_cpu_state {bool rollback;bool single;bool bringup; -int cpu;struct hlist_node *node;struct hlist_node *last;enum cpuhp_state cb_state;
@@ -474,7 +473,7 @@ static inline bool cpu_smt_allowed(unsig#endif static inline enum cpuhp_state -cpuhp_set_state (struct cpuhp_cpu_state *st,enum cpuhp_state target) +cpuhp_set_state (int cpu,struct cpuhp_cpu_state *st,enum cpuhp_state target) {enum cpuhp_state prev_state = st->state;bool bringup = st->state < target;
@@ -485,14 +484,15 @@ cpuhp_set_state(struct cpuhp_cpu_state * st->target = target; st->single = false; st->bringup = bringup; -if (cpu_dying (st->cpu) != !bringup) -set_cpu_dying (st->cpu, !bringup); +if (cpu_dying (cpu) != !bringup) +set_cpu_dying (cpu, !bringup);return prev_state; }static inline void -cpuhp_reset_state (struct cpuhp_cpu_state *st,enum cpuhp_state prev_state) +cpuhp_reset_state (int cpu,struct cpuhp_cpu_state *st, +enum cpuhp_state prev_state) {bool bringup = !st->bringup;
@@ -519,8 +519,8 @@ cpuhp_reset_state(struct cpuhp_cpu_state } st->bringup = bringup; -if (cpu_dying (st->cpu) != !bringup) -set_cpu_dying (st->cpu, !bringup); +if (cpu_dying (cpu) != !bringup) +set_cpu_dying (cpu, !bringup); }/* Regular hotplug invocation of the AP hotplug thread */
@@ -540,15 +540,16 @@ static void __cpuhp_kick_ap(struct cpuhpwait_for_ap_thread (st, st->bringup); } -static int cpuhp_kick_ap (struct cpuhp_cpu_state *st,enum cpuhp_state target) +static int cpuhp_kick_ap (int cpu,struct cpuhp_cpu_state *st, +enum cpuhp_state target) {enum cpuhp_state prev_state;int ret; - prev_state =cpuhp_set_state (st, target); + prev_state =cpuhp_set_state (cpu, st, target);__cpuhp_kick_ap (st);if ((ret = st->result)) { -cpuhp_reset_state (st, prev_state); +cpuhp_reset_state (cpu, st, prev_state);__cpuhp_kick_ap (st); }
@@ -580,7 +581,7 @@ static int bringup_wait_for_ap(unsignedif (st->target <=CPUHP_AP_ONLINE_IDLE )return 0 ; -return cpuhp_kick_ap (st, st->target); +return cpuhp_kick_ap (cpu, st, st->target); }static int bringup_cpu (unsigned int cpu)
@@ -703,7 +704,7 @@ static int cpuhp_up_callbacks(unsigned i ret, cpu,cpuhp_get_step (st->state)->name, st->state); -cpuhp_reset_state (st, prev_state); +cpuhp_reset_state (cpu, st, prev_state);if (can_rollback_cpu (st))WARN_ON (cpuhp_invoke_callback_range (false, cpu, st, prev_state));
@@ -720,7 +721,6 @@ static void cpuhp_create(unsigned int cpinit_completion (&st->done_up);init_completion (&st->done_down); - st->cpu = cpu; }static int cpuhp_should_run (unsigned int cpu)
@@ -874,7 +874,7 @@ static int cpuhp_kick_ap_work(unsigned icpuhp_lock_release (true);trace_cpuhp_enter (cpu, st->target, prev_state, cpuhp_kick_ap_work); - ret =cpuhp_kick_ap (st, st->target); + ret =cpuhp_kick_ap (cpu, st, st->target);trace_cpuhp_exit (cpu, st->state, prev_state, ret);return ret;
@@ -1106,7 +1106,7 @@ static int cpuhp_down_callbacks(unsigned ret, cpu,cpuhp_get_step (st->state)->name, st->state); -cpuhp_reset_state (st, prev_state); +cpuhp_reset_state (cpu, st, prev_state);if (st->state < prev_state) WARN_ON(cpuhp_invoke_callback_range(true, cpu, st,
@@ -1133,7 +1133,7 @@ static int __ref _cpu_down(unsigned int cpuhp_tasks_frozen = tasks_frozen; - prev_state =cpuhp_set_state (st, target); + prev_state =cpuhp_set_state (cpu, st, target);/* * If the current CPU state is in the range of the AP hotplug thread, * then we need to kick the thread.
@@ -1164,7 +1164,7 @@ static int __ref _cpu_down(unsigned int ret =cpuhp_down_callbacks (cpu, st, target);if (ret && st->state < prev_state) {if (st->state ==CPUHP_TEARDOWN_CPU ) { -cpuhp_reset_state (st, prev_state); +cpuhp_reset_state (cpu, st, prev_state);__cpuhp_kick_ap (st); }else {WARN (1 ,"DEAD callback error for CPU%d" , cpu);
@@ -1351,7 +1351,7 @@ static int _cpu_up(unsigned int cpu, int cpuhp_tasks_frozen = tasks_frozen; -cpuhp_set_state (st, target); +cpuhp_set_state (cpu, st, target);/* * If the current CPU state is in the range of the AP hotplug thread, * then we need to kick the thread once more.
Greg Kroah-Hartman
maintainerPATCH 179/189 soc: qcom: aoss: Fix missing put_device call in qmp_get
In reply to Greg Kroah-HartmanFrom: Miaoqian Lin <[email protected]>
commit 4b41a9d0fe3db5f91078a380f62f0572c3ecf2dd upstream.
The reference taken by 'of_find_device_by_node()' must be released when not needed anymore.
Add the corresponding 'put_device()' in the error handling paths.
--- drivers/soc/qcom/qcom_aoss.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-)
drivers/soc/qcom/qcom_aoss.c +5 -1
@@ -551,7 +551,11 @@ struct qmp *qmp_get(struct device *dev) qmp =platform_get_drvdata (pdev); -return qmp ? qmp :ERR_PTR (-EPROBE_DEFER ); +if (!qmp) { +put_device (&pdev->dev); +return ERR_PTR (-EPROBE_DEFER ); + } +return qmp; }EXPORT_SYMBOL (qmp_get);
Greg Kroah-Hartman
maintainerPATCH 180/189 net: ipa: fix a build dependency
In reply to Greg Kroah-HartmanFrom: Alex Elder <[email protected]>
commit caef14b7530c065fb85d54492768fa48fdb5093e upstream.
An IPA build problem arose in the linux-next tree the other day. The problem is that a recent commit adds a new dependency on some code, and the Kconfig file for IPA doesn't reflect that dependency. As a result, some configurations can fail to build (particularly when COMPILE_TEST is enabled).
The recent patch adds calls to qmp_get(), qmp_put(), and qmp_send(), and those are built based on the QCOM_AOSS_QMP config option. If that symbol is not defined, stubs are defined, so we just need to ensure QCOM_AOSS_QMP is compatible with QCOM_IPA, or it's not defined.
--- drivers/net/ipa/Kconfig | 1 + 1 file changed, 1 insertion(+)
drivers/net/ipa/Kconfig +1 -0
@@ -4,6 +4,7 @@ config QCOM_IPA depends on ARCH_QCOM || COMPILE_TEST depends on INTERCONNECT depends on QCOM_RPROC_COMMON || (QCOM_RPROC_COMMON=n && COMPILE_TEST) + depends on QCOM_AOSS_QMP || QCOM_AOSS_QMP=n select QCOM_MDT_LOADER if ARCH_QCOM select QCOM_SCM select QCOM_QMI_HELPERS
Greg Kroah-Hartman
maintainerPATCH 181/189 cpufreq: intel_pstate: ITMT support for overclocked system
In reply to Greg Kroah-HartmanFrom: Srinivas Pandruvada <[email protected]>
commit 03c83982a0278207709143ba78c5a470179febee upstream.
On systems with overclocking enabled, CPPC Highest Performance can be hard coded to 0xff. In this case even if we have cores with different highest performance, ITMT can't be enabled as the current implementation depends on CPPC Highest Performance.
On such systems we can use MSR_HWP_CAPABILITIES maximum performance field when CPPC.Highest Performance is 0xff.
Due to legacy reasons, we can't solely depend on MSR_HWP_CAPABILITIES as in some older systems CPPC Highest Performance is the only way to identify different performing cores.
--- drivers/cpufreq/intel_pstate.c | 10 ++++++++++ 1 file changed, 10 insertions(+)
drivers/cpufreq/intel_pstate.c +10 -0
@@ -335,6 +335,8 @@ static void intel_pstste_sched_itmt_work static DECLARE_WORK(sched_itmt_work, intel_pstste_sched_itmt_work_fn); +#define CPPC_MAX_PERF U8_MAX +static void intel_pstate_set_itmt_prio (int cpu) {struct cppc_perf_caps cppc_perf;
@@ -346,6 +348,14 @@ static void intel_pstate_set_itmt_prio(ireturn ;/* +* On some systems with overclocking enabled, CPPC.highest_perf is hardcoded to 0xff. +* In this case we can't use CPPC.highest_perf to enable ITMT. +* In this case we can look at MSR_HWP_CAPABILITIES bits [8:0] to decide. +*/ +if (cppc_perf.highest_perf ==CPPC_MAX_PERF ) + cppc_perf.highest_perf =HWP_HIGHEST_PERF (READ_ONCE (all_cpu_data[cpu]->hwp_cap_cached)); + +/* * The priorities can be set regardless of whether or not * sched_set_itmt_support(true) has been called and it is valid to * update them at any time after it has been called.
Greg Kroah-Hartman
maintainerPATCH 182/189 ax25: add refcount in ax25_dev to avoid UAF bugs
In reply to Greg Kroah-HartmanFrom: Duoming Zhou <[email protected]>
commit d01ffb9eee4af165d83b08dd73ebdf9fe94a519b upstream.
If we dereference ax25_dev after we call kfree(ax25_dev) in ax25_dev_device_down(), it will lead to concurrency UAF bugs. There are eight syscall functions suffer from UAF bugs, include ax25_bind(), ax25_release(), ax25_connect(), ax25_ioctl(), ax25_getname(), ax25_sendmsg(), ax25_getsockopt() and ax25_info_show().
One of the concurrency UAF can be shown as below:
(USE) | (FREE)
| ax25_device_event
| ax25_dev_device_down
ax25_bind | ...
... | kfree(ax25_dev)
ax25_fillin_cb() | ...
ax25_fillin_cb_from_dev() |
... |The root cause of UAF bugs is that kfree(ax25_dev) in ax25_dev_device_down() is not protected by any locks. When ax25_dev, which there are still pointers point to, is released, the concurrency UAF bug will happen.
This patch introduces refcount into ax25_dev in order to guarantee that there are no pointers point to it when ax25_dev is released.
--- include/net/ax25.h | 10 ++++++++++ net/ax25/af_ax25.c | 2 ++ net/ax25/ax25_dev.c | 12 ++++++++++-- net/ax25/ax25_route.c | 3 +++ 4 files changed, 25 insertions(+), 2 deletions(-)
include/net/ax25.h +10 -0
@@ -236,6 +236,7 @@ typedef struct ax25_dev {#if defined(CONFIG_AX25_DAMA_SLAVE ) || defined(CONFIG_AX25_DAMA_MASTER )ax25_dama_info dama;#endif +refcount_t refcount; } ax25_dev; typedef struct ax25_cb {
@@ -290,6 +291,15 @@ static __inline__ void ax25_cb_put(ax25_ } } +#define ax25_dev_hold (__ax25_dev) \ + refcount_inc(&((__ax25_dev)->refcount)) + +static __inline__void ax25_dev_put (ax25_dev *ax25_dev) +{ +if (refcount_dec_and_test (&ax25_dev->refcount)) { +kfree (ax25_dev); + } +}static inline __be16 ax25_type_trans (struct sk_buff *skb,struct net_device *dev) { skb->dev = dev;
net/ax25/af_ax25.c +2 -0
@@ -98,6 +98,7 @@ again:spin_unlock_bh (&ax25_list_lock);lock_sock (sk); s->ax25_dev =NULL ; +ax25_dev_put (ax25_dev);release_sock (sk);ax25_disconnect (s,ENETUNREACH );spin_lock_bh (&ax25_list_lock);
@@ -446,6 +447,7 @@ static int ax25_ctl_ioctl(const unsigned } out_put: +ax25_dev_put (ax25_dev);ax25_cb_put (ax25);return ret;
net/ax25/ax25_dev.c +10 -2
@@ -37,6 +37,7 @@ ax25_dev *ax25_addr_ax25dev(ax25_addressfor (ax25_dev = ax25_dev_list; ax25_dev !=NULL ; ax25_dev = ax25_dev->next)if (ax25cmp (addr, (ax25_address *)ax25_dev->dev->dev_addr) ==0 ) { res = ax25_dev; +ax25_dev_hold (ax25_dev); }spin_unlock_bh (&ax25_dev_lock);
@@ -56,6 +57,7 @@ void ax25_dev_device_up(struct net_devicreturn ; } +refcount_set (&ax25_dev->refcount,1 ); dev->ax25_ptr = ax25_dev; ax25_dev->dev = dev;dev_hold (dev);
@@ -83,6 +85,7 @@ void ax25_dev_device_up(struct net_devicspin_lock_bh (&ax25_dev_lock); ax25_dev->next = ax25_dev_list; ax25_dev_list = ax25_dev; +ax25_dev_hold (ax25_dev);spin_unlock_bh (&ax25_dev_lock);ax25_register_dev_sysctl (ax25_dev);
@@ -112,20 +115,22 @@ void ax25_dev_device_down(struct net_devif ((s = ax25_dev_list) == ax25_dev) { ax25_dev_list = s->next; +ax25_dev_put (ax25_dev);spin_unlock_bh (&ax25_dev_lock); dev->ax25_ptr =NULL ;dev_put (dev); -kfree (ax25_dev); +ax25_dev_put (ax25_dev);return ; }while (s !=NULL && s->next !=NULL ) {if (s->next == ax25_dev) { s->next = ax25_dev->next; +ax25_dev_put (ax25_dev);spin_unlock_bh (&ax25_dev_lock); dev->ax25_ptr =NULL ;dev_put (dev); -kfree (ax25_dev); +ax25_dev_put (ax25_dev);return ; }
@@ -133,6 +138,7 @@ void ax25_dev_device_down(struct net_dev }spin_unlock_bh (&ax25_dev_lock); dev->ax25_ptr =NULL ; +ax25_dev_put (ax25_dev); }int ax25_fwd_ioctl (unsigned int cmd,struct ax25_fwd_struct *fwd)
@@ -149,6 +155,7 @@ int ax25_fwd_ioctl(unsigned int cmd, strif (ax25_dev->forward !=NULL )return -EINVAL ; ax25_dev->forward = fwd_dev->dev; +ax25_dev_put (fwd_dev);break ;case SIOCAX25DELFWD :
@@ -161,6 +168,7 @@ int ax25_fwd_ioctl(unsigned int cmd, strreturn -EINVAL ; } +ax25_dev_put (ax25_dev);return 0 ; }
net/ax25/ax25_route.c +3 -0
@@ -116,6 +116,7 @@ static int __must_check ax25_rt_add(stru ax25_rt->dev = ax25_dev->dev; ax25_rt->digipeat =NULL ; ax25_rt->ip_mode =' ' ; +ax25_dev_put (ax25_dev);if (route->digi_count !=0 ) {if ((ax25_rt->digipeat =kmalloc (sizeof (ax25_digi),GFP_ATOMIC )) ==NULL ) {write_unlock_bh (&ax25_route_lock);
@@ -172,6 +173,7 @@ static int ax25_rt_del(struct ax25_route } } } +ax25_dev_put (ax25_dev);write_unlock_bh (&ax25_route_lock);return 0 ;
@@ -214,6 +216,7 @@ static int ax25_rt_opt(struct ax25_route } out: +ax25_dev_put (ax25_dev);write_unlock_bh (&ax25_route_lock);return err; }
Greg Kroah-Hartman
maintainerPATCH 183/189 ax25: fix reference count leaks of ax25_dev
In reply to Greg Kroah-HartmanFrom: Duoming Zhou <[email protected]>
commit 87563a043cef044fed5db7967a75741cc16ad2b1 upstream.
The previous commit d01ffb9eee4a ("ax25: add refcount in ax25_dev to avoid UAF bugs") introduces refcount into ax25_dev, but there are reference leak paths in ax25_ctl_ioctl(), ax25_fwd_ioctl(), ax25_rt_add(), ax25_rt_del() and ax25_rt_opt().
This patch uses ax25_dev_put() and adjusts the position of ax25_addr_ax25dev() to fix reference cout leaks of ax25_dev.
--- include/net/ax25.h | 8 +++++--- net/ax25/af_ax25.c | 12 ++++++++---- net/ax25/ax25_dev.c | 24 +++++++++++++++++------- net/ax25/ax25_route.c | 16 +++++++++++----- 4 files changed, 41 insertions(+), 19 deletions(-)
include/net/ax25.h +5 -3
@@ -291,10 +291,12 @@ static __inline__ void ax25_cb_put(ax25_ } } -#define ax25_dev_hold (__ax25_dev) \ - refcount_inc(&((__ax25_dev)->refcount)) +static inline void ax25_dev_hold (ax25_dev *ax25_dev) +{ +refcount_inc (&ax25_dev->refcount); +} -static __inline__void ax25_dev_put (ax25_dev *ax25_dev) +static inline void ax25_dev_put (ax25_dev *ax25_dev) {if (refcount_dec_and_test (&ax25_dev->refcount)) {kfree (ax25_dev);
net/ax25/af_ax25.c +8 -4
@@ -366,21 +366,25 @@ static int ax25_ctl_ioctl(const unsignedif (copy_from_user (&ax25_ctl, arg,sizeof (ax25_ctl)))return -EFAULT ; -if ((ax25_dev =ax25_addr_ax25dev (&ax25_ctl.port_addr)) ==NULL ) -return -ENODEV ; -if (ax25_ctl.digi_count >AX25_MAX_DIGIS )return -EINVAL ;if (ax25_ctl.arg >ULONG_MAX /HZ && ax25_ctl.cmd !=AX25_KILL )return -EINVAL ; + ax25_dev =ax25_addr_ax25dev (&ax25_ctl.port_addr); +if (!ax25_dev) +return -ENODEV ; + digi.ndigi = ax25_ctl.digi_count;for (k =0 ; k < digi.ndigi; k++) digi.calls[k] = ax25_ctl.digi_addr[k]; -if ((ax25 =ax25_find_cb (&ax25_ctl.source_addr, &ax25_ctl.dest_addr, &digi, ax25_dev->dev)) ==NULL ) + ax25 =ax25_find_cb (&ax25_ctl.source_addr, &ax25_ctl.dest_addr, &digi, ax25_dev->dev); +if (!ax25) { +ax25_dev_put (ax25_dev);return -ENOTCONN ; + }switch (ax25_ctl.cmd) {case AX25_KILL :
net/ax25/ax25_dev.c +17 -7
@@ -85,8 +85,8 @@ void ax25_dev_device_up(struct net_devicspin_lock_bh (&ax25_dev_lock); ax25_dev->next = ax25_dev_list; ax25_dev_list = ax25_dev; -ax25_dev_hold (ax25_dev);spin_unlock_bh (&ax25_dev_lock); +ax25_dev_hold (ax25_dev);ax25_register_dev_sysctl (ax25_dev); }
@@ -115,8 +115,8 @@ void ax25_dev_device_down(struct net_devif ((s = ax25_dev_list) == ax25_dev) { ax25_dev_list = s->next; -ax25_dev_put (ax25_dev);spin_unlock_bh (&ax25_dev_lock); +ax25_dev_put (ax25_dev); dev->ax25_ptr =NULL ;dev_put (dev);ax25_dev_put (ax25_dev);
@@ -126,8 +126,8 @@ void ax25_dev_device_down(struct net_devwhile (s !=NULL && s->next !=NULL ) {if (s->next == ax25_dev) { s->next = ax25_dev->next; -ax25_dev_put (ax25_dev);spin_unlock_bh (&ax25_dev_lock); +ax25_dev_put (ax25_dev); dev->ax25_ptr =NULL ;dev_put (dev);ax25_dev_put (ax25_dev);
@@ -150,25 +150,35 @@ int ax25_fwd_ioctl(unsigned int cmd, strswitch (cmd) {case SIOCAX25ADDFWD : -if ((fwd_dev =ax25_addr_ax25dev (&fwd->port_to)) ==NULL ) + fwd_dev =ax25_addr_ax25dev (&fwd->port_to); +if (!fwd_dev) { +ax25_dev_put (ax25_dev);return -EINVAL ; -if (ax25_dev->forward !=NULL ) + } +if (ax25_dev->forward) { +ax25_dev_put (fwd_dev); +ax25_dev_put (ax25_dev);return -EINVAL ; + } ax25_dev->forward = fwd_dev->dev;ax25_dev_put (fwd_dev); +ax25_dev_put (ax25_dev);break ;case SIOCAX25DELFWD : -if (ax25_dev->forward ==NULL ) +if (!ax25_dev->forward) { +ax25_dev_put (ax25_dev);return -EINVAL ; + } ax25_dev->forward =NULL ; +ax25_dev_put (ax25_dev);break ;default : +ax25_dev_put (ax25_dev);return -EINVAL ; } -ax25_dev_put (ax25_dev);return 0 ; }
net/ax25/ax25_route.c +11 -5
@@ -75,11 +75,13 @@ static int __must_check ax25_rt_add(struax25_dev *ax25_dev;int i; -if ((ax25_dev =ax25_addr_ax25dev (&route->port_addr)) ==NULL ) -return -EINVAL ;if (route->digi_count >AX25_MAX_DIGIS )return -EINVAL ; + ax25_dev =ax25_addr_ax25dev (&route->port_addr); +if (!ax25_dev) +return -EINVAL ; +write_lock_bh (&ax25_route_lock); ax25_rt = ax25_route_list;
@@ -91,6 +93,7 @@ static int __must_check ax25_rt_add(struif (route->digi_count !=0 ) {if ((ax25_rt->digipeat =kmalloc (sizeof (ax25_digi),GFP_ATOMIC )) ==NULL ) {write_unlock_bh (&ax25_route_lock); +ax25_dev_put (ax25_dev);return -ENOMEM ; } ax25_rt->digipeat->lastrepeat =-1 ;
@@ -101,6 +104,7 @@ static int __must_check ax25_rt_add(stru } }write_unlock_bh (&ax25_route_lock); +ax25_dev_put (ax25_dev);return 0 ; } ax25_rt = ax25_rt->next;
@@ -108,6 +112,7 @@ static int __must_check ax25_rt_add(struif ((ax25_rt =kmalloc (sizeof (ax25_route),GFP_ATOMIC )) ==NULL ) {write_unlock_bh (&ax25_route_lock); +ax25_dev_put (ax25_dev);return -ENOMEM ; }
@@ -116,11 +121,11 @@ static int __must_check ax25_rt_add(stru ax25_rt->dev = ax25_dev->dev; ax25_rt->digipeat =NULL ; ax25_rt->ip_mode =' ' ; -ax25_dev_put (ax25_dev);if (route->digi_count !=0 ) {if ((ax25_rt->digipeat =kmalloc (sizeof (ax25_digi),GFP_ATOMIC )) ==NULL ) {write_unlock_bh (&ax25_route_lock);kfree (ax25_rt); +ax25_dev_put (ax25_dev);return -ENOMEM ; } ax25_rt->digipeat->lastrepeat =-1 ;
@@ -133,6 +138,7 @@ static int __must_check ax25_rt_add(stru ax25_rt->next = ax25_route_list; ax25_route_list = ax25_rt;write_unlock_bh (&ax25_route_lock); +ax25_dev_put (ax25_dev);return 0 ; }
@@ -173,8 +179,8 @@ static int ax25_rt_del(struct ax25_route } } } -ax25_dev_put (ax25_dev);write_unlock_bh (&ax25_route_lock); +ax25_dev_put (ax25_dev);return 0 ; }
@@ -216,8 +222,8 @@ static int ax25_rt_opt(struct ax25_route } out: -ax25_dev_put (ax25_dev);write_unlock_bh (&ax25_route_lock); +ax25_dev_put (ax25_dev);return err; }
Greg Kroah-Hartman
maintainerPATCH 184/189 ax25: fix UAF bugs of net_device caused by rebinding operation
In reply to Greg Kroah-HartmanFrom: Duoming Zhou <[email protected]>
commit feef318c855a361a1eccd880f33e88c460eb63b4 upstream.
The ax25_kill_by_device() will set s->ax25_dev = NULL and call ax25_disconnect() to change states of ax25_cb and sock, if we call ax25_bind() before ax25_kill_by_device().
However, if we call ax25_bind() again between the window of ax25_kill_by_device() and ax25_dev_device_down(), the values and states changed by ax25_kill_by_device() will be reassigned.
Finally, ax25_dev_device_down() will deallocate net_device. If we dereference net_device in syscall functions such as ax25_release(), ax25_sendmsg(), ax25_getsockopt(), ax25_getname() and ax25_info_show(), a UAF bug will occur.
One of the possible race conditions is shown below:
(USE) | (FREE)
ax25_bind() |
| ax25_kill_by_device()
ax25_bind() |
ax25_connect() | ...
| ax25_dev_device_down()
| ...
| dev_put_track(dev, ...) //FREE
ax25_release() | ...
ax25_send_control() |
alloc_skb() //USE |the corresponding fail log is shown below:
===============================================================
BUG: KASAN: use-after-free in ax25_send_control+0x43/0x210 ... Call Trace: ... ax25_send_control+0x43/0x210 ax25_release+0x2db/0x3b0 __sock_release+0x6d/0x120 sock_close+0xf/0x20 __fput+0x11f/0x420 ... Allocated by task 1283: ... __kasan_kmalloc+0x81/0xa0 alloc_netdev_mqs+0x5a/0x680 mkiss_open+0x6c/0x380 tty_ldisc_open+0x55/0x90 ... Freed by task 1969: ... kfree+0xa3/0x2c0 device_release+0x54/0xe0 kobject_put+0xa5/0x120 tty_ldisc_kill+0x3e/0x80 ...
In order to fix these UAF bugs caused by rebinding operation, this patch adds dev_hold_track() into ax25_bind() and corresponding dev_put_track() into ax25_kill_by_device().
[OP: backport to 5.15: adjust dev_put_track()->dev_put() and dev_hold_track()->dev_hold()]
--- net/ax25/af_ax25.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-)
net/ax25/af_ax25.c +4 -1
@@ -98,6 +98,7 @@ again:spin_unlock_bh (&ax25_list_lock);lock_sock (sk); s->ax25_dev =NULL ; +dev_put (ax25_dev->dev);ax25_dev_put (ax25_dev);release_sock (sk);ax25_disconnect (s,ENETUNREACH );
@@ -1123,8 +1124,10 @@ static int ax25_bind(struct socket *sock } } -if (ax25_dev !=NULL ) +if (ax25_dev) {ax25_fillin_cb (ax25, ax25_dev); +dev_hold (ax25_dev->dev); + } done:ax25_cb_add (ax25);
Greg Kroah-Hartman
maintainerPATCH 185/189 ax25: Fix refcount leaks caused by ax25_cb_del()
In reply to Greg Kroah-HartmanFrom: Duoming Zhou <[email protected]>
commit 9fd75b66b8f68498454d685dc4ba13192ae069b0 upstream.
The previous commit d01ffb9eee4a ("ax25: add refcount in ax25_dev to avoid UAF bugs") and commit feef318c855a ("ax25: fix UAF bugs of net_device caused by rebinding operation") increase the refcounts of ax25_dev and net_device in ax25_bind() and decrease the matching refcounts in ax25_kill_by_device() in order to prevent UAF bugs, but there are reference count leaks.
The root cause of refcount leaks is shown below:
(Thread 1) | (Thread 2)
ax25_bind() |
... |
ax25_addr_ax25dev() |
ax25_dev_hold() //(1) |
... |
dev_hold_track() //(2) |
... | ax25_destroy_socket()
| ax25_cb_del()
| ...
| hlist_del_init() //(3)
|
|
(Thread 3) |
ax25_kill_by_device() |
... |
ax25_for_each(s, &ax25_list) { |
if (s->ax25_dev == ax25_dev) //(4) |
... |Firstly, we use ax25_bind() to increase the refcount of ax25_dev in position (1) and increase the refcount of net_device in position (2). Then, we use ax25_cb_del() invoked by ax25_destroy_socket() to delete ax25_cb in hlist in position (3) before calling ax25_kill_by_device(). Finally, the decrements of refcounts in ax25_kill_by_device() will not be executed, because no s->ax25_dev equals to ax25_dev in position (4).
This patch adds decrements of refcounts in ax25_release() and use lock_sock() to do synchronization. If refcounts decrease in ax25_release(), the decrements of refcounts in ax25_kill_by_device() will not be executed and vice versa.
--- net/ax25/af_ax25.c | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-)
net/ax25/af_ax25.c +11 -3
@@ -98,8 +98,10 @@ again:spin_unlock_bh (&ax25_list_lock);lock_sock (sk); s->ax25_dev =NULL ; -dev_put (ax25_dev->dev); -ax25_dev_put (ax25_dev); +if (sk->sk_socket) { +dev_put (ax25_dev->dev); +ax25_dev_put (ax25_dev); + }release_sock (sk);ax25_disconnect (s,ENETUNREACH );spin_lock_bh (&ax25_list_lock);
@@ -979,14 +981,20 @@ static int ax25_release(struct socket *s {struct sock *sk = sock->sk;ax25_cb *ax25; +ax25_dev *ax25_dev;if (sk ==NULL )return 0 ;sock_hold (sk); -sock_orphan (sk);lock_sock (sk); +sock_orphan (sk); ax25 =sk_to_ax25 (sk); + ax25_dev = ax25->ax25_dev; +if (ax25_dev) { +dev_put (ax25_dev->dev); +ax25_dev_put (ax25_dev); + }if (sk->sk_type ==SOCK_SEQPACKET ) {switch (ax25->state) {
Greg Kroah-Hartman
maintainerPATCH 186/189 ax25: fix UAF bug in ax25_send_control()
In reply to Greg Kroah-HartmanFrom: Duoming Zhou <[email protected]>
commit 5352a761308397a0e6250fdc629bb3f615b94747 upstream.
There are UAF bugs in ax25_send_control(), when we call ax25_release() to deallocate ax25_dev. The possible race condition is shown below:
(Thread 1) | (Thread 2)
ax25_dev_device_up() //(1) |
| ax25_kill_by_device()
ax25_bind() //(2) |
ax25_connect() | ...
ax25->state = AX25_STATE_1 |
... | ax25_dev_device_down() //(3)(Thread 3) ax25_release() | ax25_dev_put() //(4) FREE | case AX25_STATE_1: | ax25_send_control() | alloc_skb() //USE |
The refcount of ax25_dev increases in position (1) and (2), and decreases in position (3) and (4). The ax25_dev will be freed before dereference sites in ax25_send_control().
The following is part of the report:
[ 102.297448] BUG: KASAN: use-after-free in ax25_send_control+0x33/0x210 [ 102.297448] Read of size 8 at addr ffff888009e6e408 by task ax25_close/602 [ 102.297448] Call Trace: [ 102.303751] ax25_send_control+0x33/0x210 [ 102.303751] ax25_release+0x356/0x450 [ 102.305431] __sock_release+0x6d/0x120 [ 102.305431] sock_close+0xf/0x20 [ 102.305431] __fput+0x11f/0x420 [ 102.305431] task_work_run+0x86/0xd0 [ 102.307130] get_signal+0x1075/0x1220 [ 102.308253] arch_do_signal_or_restart+0x1df/0xc00 [ 102.308253] exit_to_user_mode_prepare+0x150/0x1e0 [ 102.308253] syscall_exit_to_user_mode+0x19/0x50 [ 102.308253] do_syscall_64+0x48/0x90 [ 102.308253] entry_SYSCALL_64_after_hwframe+0x44/0xae [ 102.308253] RIP: 0033:0x405ae7
This patch defers the free operation of ax25_dev and net_device after all corresponding dereference sites in ax25_release() to avoid UAF.
--- net/ax25/af_ax25.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-)
net/ax25/af_ax25.c +4 -4
@@ -991,10 +991,6 @@ static int ax25_release(struct socket *ssock_orphan (sk); ax25 =sk_to_ax25 (sk); ax25_dev = ax25->ax25_dev; -if (ax25_dev) { -dev_put (ax25_dev->dev); -ax25_dev_put (ax25_dev); - }if (sk->sk_type ==SOCK_SEQPACKET ) {switch (ax25->state) {
@@ -1056,6 +1052,10 @@ static int ax25_release(struct socket *s sk->sk_state_change (sk);ax25_destroy_socket (ax25); } +if (ax25_dev) { +dev_put (ax25_dev->dev); +ax25_dev_put (ax25_dev); + } sock->sk =NULL ;release_sock (sk);
Greg Kroah-Hartman
maintainerPATCH 187/189 ax25: fix NPD bug in ax25_disconnect
In reply to Greg Kroah-HartmanFrom: Duoming Zhou <[email protected]>
commit 7ec02f5ac8a5be5a3f20611731243dc5e1d9ba10 upstream.
The ax25_disconnect() in ax25_kill_by_device() is not protected by any locks, thus there is a race condition between ax25_disconnect() and ax25_destroy_socket(). when ax25->sk is assigned as NULL by ax25_destroy_socket(), a NULL pointer dereference bug will occur if site (1) or (2) dereferences ax25->sk.
ax25_kill_by_device() | ax25_release()
ax25_disconnect() | ax25_destroy_socket()
... |
if(ax25->sk != NULL) | ...
... | ax25->sk = NULL;
bh_lock_sock(ax25->sk); //(1) | ...
... |
bh_unlock_sock(ax25->sk); //(2)|This patch moves ax25_disconnect() into lock_sock(), which can synchronize with ax25_destroy_socket() in ax25_release().
Fail log:
===============================================================
BUG: kernel NULL pointer dereference, address: 0000000000000088 ... RIP: 0010:_raw_spin_lock+0x7e/0xd0 ... Call Trace: ax25_disconnect+0xf6/0x220 ax25_device_event+0x187/0x250 raw_notifier_call_chain+0x5e/0x70 dev_close_many+0x17d/0x230 rollback_registered_many+0x1f1/0x950 unregister_netdevice_queue+0x133/0x200 unregister_netdev+0x13/0x20
...
--- net/ax25/af_ax25.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
net/ax25/af_ax25.c +1 -1
@@ -102,8 +102,8 @@ again:dev_put (ax25_dev->dev);ax25_dev_put (ax25_dev); } -release_sock (sk);ax25_disconnect (s,ENETUNREACH ); +release_sock (sk);spin_lock_bh (&ax25_list_lock);sock_put (sk);/* The entry could have been deleted from the
Greg Kroah-Hartman
maintainerPATCH 188/189 ax25: Fix NULL pointer dereferences in ax25 timers
In reply to Greg Kroah-HartmanFrom: Duoming Zhou <[email protected]>
commit fc6d01ff9ef03b66d4a3a23b46fc3c3d8cf92009 upstream.
The previous commit 7ec02f5ac8a5 ("ax25: fix NPD bug in ax25_disconnect") move ax25_disconnect into lock_sock() in order to prevent NPD bugs. But there are race conditions that may lead to null pointer dereferences in ax25_heartbeat_expiry(), ax25_t1timer_expiry(), ax25_t2timer_expiry(), ax25_t3timer_expiry() and ax25_idletimer_expiry(), when we use ax25_kill_by_device() to detach the ax25 device.
One of the race conditions that cause null pointer dereferences can be shown as below:
(Thread 1) | (Thread 2)
ax25_connect() |
ax25_std_establish_data_link() |
ax25_start_t1timer() |
mod_timer(&ax25->t1timer,..) |
| ax25_kill_by_device()
(wait a time) | ...
| s->ax25_dev = NULL; //(1)
ax25_t1timer_expiry() |
ax25->ax25_dev->values[..] //(2)| ...
... |We set null to ax25_cb->ax25_dev in position (1) and dereference the null pointer in position (2).
The corresponding fail log is shown below:
===============================================================
BUG: kernel NULL pointer dereference, address: 0000000000000050 CPU: 1 PID: 0 Comm: swapper/1 Not tainted 5.17.0-rc6-00794-g45690b7d0 RIP: 0010:ax25_t1timer_expiry+0x12/0x40 ... Call Trace: call_timer_fn+0x21/0x120 __run_timers.part.0+0x1ca/0x250 run_timer_softirq+0x2c/0x60 __do_softirq+0xef/0x2f3 irq_exit_rcu+0xb6/0x100 sysvec_apic_timer_interrupt+0xa2/0xd0
...
This patch moves ax25_disconnect() before s->ax25_dev = NULL and uses del_timer_sync() to delete timers in ax25_disconnect(). If ax25_disconnect() is called by ax25_kill_by_device() or ax25->ax25_dev is NULL, the reason in ax25_disconnect() will be equal to ENETUNREACH, it will wait all timers to stop before we set null to s->ax25_dev in ax25_kill_by_device().
--- net/ax25/af_ax25.c | 4 ++-- net/ax25/ax25_subr.c | 20 ++++++++++++++------ 2 files changed, 16 insertions(+), 8 deletions(-)
net/ax25/af_ax25.c +2 -2
@@ -89,20 +89,20 @@ again: sk = s->sk;if (!sk) {spin_unlock_bh (&ax25_list_lock); - s->ax25_dev =NULL ;ax25_disconnect (s,ENETUNREACH ); + s->ax25_dev =NULL ;spin_lock_bh (&ax25_list_lock); goto again; }sock_hold (sk);spin_unlock_bh (&ax25_list_lock);lock_sock (sk); +ax25_disconnect (s,ENETUNREACH ); s->ax25_dev =NULL ;if (sk->sk_socket) {dev_put (ax25_dev->dev);ax25_dev_put (ax25_dev); } -ax25_disconnect (s,ENETUNREACH );release_sock (sk);spin_lock_bh (&ax25_list_lock);sock_put (sk);
net/ax25/ax25_subr.c +14 -6
@@ -261,12 +261,20 @@ void ax25_disconnect(ax25_cb *ax25, int {ax25_clear_queues (ax25); -if (!ax25->sk || !sock_flag (ax25->sk,SOCK_DESTROY )) -ax25_stop_heartbeat (ax25); -ax25_stop_t1timer (ax25); -ax25_stop_t2timer (ax25); -ax25_stop_t3timer (ax25); -ax25_stop_idletimer (ax25); +if (reason ==ENETUNREACH ) { +del_timer_sync (&ax25->timer); +del_timer_sync (&ax25->t1timer); +del_timer_sync (&ax25->t2timer); +del_timer_sync (&ax25->t3timer); +del_timer_sync (&ax25->idletimer); + }else { +if (!ax25->sk || !sock_flag (ax25->sk,SOCK_DESTROY )) +ax25_stop_heartbeat (ax25); +ax25_stop_t1timer (ax25); +ax25_stop_t2timer (ax25); +ax25_stop_t3timer (ax25); +ax25_stop_idletimer (ax25); + } ax25->state =AX25_STATE_0 ;
Greg Kroah-Hartman
maintainerPATCH 189/189 ax25: Fix UAF bugs in ax25 timers
In reply to Greg Kroah-HartmanFrom: Duoming Zhou <[email protected]>
commit 82e31755e55fbcea6a9dfaae5fe4860ade17cbc0 upstream.
There are race conditions that may lead to UAF bugs in ax25_heartbeat_expiry(), ax25_t1timer_expiry(), ax25_t2timer_expiry(), ax25_t3timer_expiry() and ax25_idletimer_expiry(), when we call ax25_release() to deallocate ax25_dev.
One of the UAF bugs caused by ax25_release() is shown below:
(Thread 1) | (Thread 2)
ax25_dev_device_up() //(1) |
... | ax25_kill_by_device()
ax25_bind() //(2) |
ax25_connect() | ...
ax25_std_establish_data_link() |
ax25_start_t1timer() | ax25_dev_device_down() //(3)
mod_timer(&ax25->t1timer,..) |
| ax25_release()
(wait a time) | ...
| ax25_dev_put(ax25_dev) //(4)FREE
ax25_t1timer_expiry() |
ax25->ax25_dev->values[..] //USE| ...
... |We increase the refcount of ax25_dev in position (1) and (2), and decrease the refcount of ax25_dev in position (3) and (4). The ax25_dev will be freed in position (4) and be used in ax25_t1timer_expiry().
The fail log is shown below:
==============================================================
[ 106.116942] BUG: KASAN: use-after-free in ax25_t1timer_expiry+0x1c/0x60 [ 106.116942] Read of size 8 at addr ffff88800bda9028 by task swapper/0/0 [ 106.116942] CPU: 0 PID: 0 Comm: swapper/0 Not tainted 5.17.0-06123-g0905eec574 [ 106.116942] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS rel-14 [ 106.116942] Call Trace: ... [ 106.116942] ax25_t1timer_expiry+0x1c/0x60 [ 106.116942] call_timer_fn+0x122/0x3d0 [ 106.116942] __run_timers.part.0+0x3f6/0x520 [ 106.116942] run_timer_softirq+0x4f/0xb0 [ 106.116942] __do_softirq+0x1c2/0x651
...
This patch adds del_timer_sync() in ax25_release(), which could ensure that all timers stop before we deallocate ax25_dev.
--- net/ax25/af_ax25.c | 5 +++++ 1 file changed, 5 insertions(+)
net/ax25/af_ax25.c +5 -0
@@ -1053,6 +1053,11 @@ static int ax25_release(struct socket *sax25_destroy_socket (ax25); }if (ax25_dev) { +del_timer_sync (&ax25->timer); +del_timer_sync (&ax25->t1timer); +del_timer_sync (&ax25->t2timer); +del_timer_sync (&ax25->t3timer); +del_timer_sync (&ax25->idletimer);dev_put (ax25_dev->dev);ax25_dev_put (ax25_dev); }
Quoted 4 lines · Greg Kroah-Hartman
This is the start of the stable review cycle for the 5.15.35 release. There are 189 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.
drivers/gpu/drm/amd/amdgpu/../display/dc/dcn31/dcn31_hubbub.c: In function hubbub31_verify_allow_pstate_change_high':drivers/gpu/drm/amd/amdgpu/../display/dc/dcn31/dcn31_hubbub.c:994:17: error: implicit declaration of function 'udelay' [-Werror=implicit-function-declaration]
994 | udelay(1);
| ^~~~~~Caused by "drm-amd-display-add-pstate-verification-and-recovery-for-dcn31.patch". Explicitly includng <linux/delay.h> in dcn31_hubbub.c fixes it.
Current mainline version of dcn31_hubbub.c does not explicitly include <linux/delay.h>, so there seems to be some general inconsistency wrt. which dcn module includes what.
CC'ing Nicholas Kazlauskas.
-h
Quoted 11 lines · Holger Hoffstätte
Quoted 4 lines · Greg Kroah-Hartman
This is the start of the stable review cycle for the 5.15.35 release. There are 189 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.
drivers/gpu/drm/amd/amdgpu/../display/dc/dcn31/dcn31_hubbub.c: In functionhubbub31_verify_allow_pstate_change_high':drivers/gpu/drm/amd/amdgpu/../display/dc/dcn31/dcn31_hubbub.c:994:17: error: implicit declaration of function 'udelay' [-Werror=implicit-function-declaration]
994 | udelay(1);
| ^~~~~~
Quoted 9 lines
Caused by "drm-amd-display-add-pstate-verification-and-recovery-for-dcn31.patch". Explicitly includng <
linux/delay.h> indcn31_hubbub.cfixes it.Current mainline version of
dcn31_hubbub.cdoes not explicitly include <linux/delay.h>, so there seems to be some general inconsistency wrt. which dcn module includes what.CC'ing Nicholas Kazlauskas.
Should add: The problem is only seen with 32-bit (i386) builds.
Guenter
Quoted 15 lines · Guenter Roeck
Quoted 14 lines · Holger Hoffstätte
Quoted 4 lines · Greg Kroah-Hartman
This is the start of the stable review cycle for the 5.15.35 release. There are 189 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.
drivers/gpu/drm/amd/amdgpu/../display/dc/dcn31/dcn31_hubbub.c: In functionhubbub31_verify_allow_pstate_change_high':drivers/gpu/drm/amd/amdgpu/../display/dc/dcn31/dcn31_hubbub.c:994:17: error: implicit declaration of function 'udelay' [-Werror=implicit-function-declaration] 994 | udelay(1);
| ^~~~~~Caused by "drm-amd-display-add-pstate-verification-and-recovery-for-dcn31.patch". Explicitly includng <
linux/delay.h> indcn31_hubbub.cfixes it.
Quoted 7 lines
Quoted 6 lines
Current mainline version of
dcn31_hubbub.cdoes not explicitly include <linux/delay.h>, so there seems to be some general inconsistency wrt. which dcn module includes what.CC'ing Nicholas Kazlauskas.
Should add: The problem is only seen with 32-bit (i386) builds.
I found this while building on my Zen2 Thinkpad, which is definitely 64 bits. :)
-h
Quoted 20 lines · Holger Hoffstätte
Quoted 19 lines · Guenter Roeck
Quoted 18 lines · Holger Hoffstätte
Quoted 4 lines · Greg Kroah-Hartman
This is the start of the stable review cycle for the 5.15.35 release. There are 189 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.
drivers/gpu/drm/amd/amdgpu/../display/dc/dcn31/dcn31_hubbub.c: In functionhubbub31_verify_allow_pstate_change_high':drivers/gpu/drm/amd/amdgpu/../display/dc/dcn31/dcn31_hubbub.c:994:17: error: implicit declaration of function 'udelay' [-Werror=implicit-function-declaration] 994 | udelay(1);
| ^~~~~~Caused by "drm-amd-display-add-pstate-verification-and-recovery-for-dcn31.patch". Explicitly includng <
linux/delay.h> indcn31_hubbub.cfixes it.Current mainline version of
dcn31_hubbub.cdoes not explicitly include <linux/delay.h>, so there seems to be some general inconsistency wrt. which dcn module includes what.
Quoted 6 lines
Quoted 3 lines
Quoted 2 lines
CC'ing Nicholas Kazlauskas.
Should add: The problem is only seen with 32-bit (i386) builds.
I found this while building on my Zen2 Thinkpad, which is definitely 64 bits. :)
Interesting. I see it with i386:allmodconfig and i386:allyesconfig.
Anyway, I suspect that commit 178fbb6d552f2 ("drm/amd/display:
Implement DPIA training loop") may "fix" the problem; it adds the include of linux/delay.h to drivers/gpu/drm/amd/display/dc/os_types.h. I don't think it would be appropriate to backport this patch to v5.15.y, though.
Guenter
Quoted 15 lines · Guenter Roeck
Quoted 14 lines · Holger Hoffstätte
Quoted 4 lines · Greg Kroah-Hartman
This is the start of the stable review cycle for the 5.15.35 release. There are 189 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.
drivers/gpu/drm/amd/amdgpu/../display/dc/dcn31/dcn31_hubbub.c: In functionhubbub31_verify_allow_pstate_change_high':drivers/gpu/drm/amd/amdgpu/../display/dc/dcn31/dcn31_hubbub.c:994:17: error: implicit declaration of function 'udelay' [-Werror=implicit-function-declaration] 994 | udelay(1);
| ^~~~~~Caused by "drm-amd-display-add-pstate-verification-and-recovery-for-dcn31.patch". Explicitly includng <
linux/delay.h> indcn31_hubbub.cfixes it.
Quoted 8 lines
Quoted 6 lines
Current mainline version of
dcn31_hubbub.cdoes not explicitly include <linux/delay.h>, so there seems to be some general inconsistency wrt. which dcn module includes what.CC'ing Nicholas Kazlauskas.
Should add: The problem is only seen with 32-bit (i386) builds.
I am seeing the same build failure on x86_64 build on AMD Ryzen 7 4700Gtest system
drivers/gpu/drm/amd/amdgpu/../display/dc/dcn31/dcn31_hubbub.c:994:17: error: implicit declaration of function ‘udelay’ [-Werror=implicit-function-declaration]
cc1: all warnings being treated as errors
thanks,
-- Shuah
Greg Kroah-Hartman
maintainerQuoted 11 lines · Holger Hoffstätte
Quoted 4 lines · Greg Kroah-Hartman
This is the start of the stable review cycle for the 5.15.35 release. There are 189 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.
drivers/gpu/drm/amd/amdgpu/../display/dc/dcn31/dcn31_hubbub.c: In functionhubbub31_verify_allow_pstate_change_high':drivers/gpu/drm/amd/amdgpu/../display/dc/dcn31/dcn31_hubbub.c:994:17: error: implicit declaration of function 'udelay' [-Werror=implicit-function-declaration]994 | udelay(1); | ^~~~~~
Quoted 6 lines
Caused by "drm-amd-display-add-pstate-verification-and-recovery-for-dcn31.patch". Explicitly includng <
linux/delay.h> indcn31_hubbub.cfixes it.Current mainline version of
dcn31_hubbub.cdoes not explicitly include <linux/delay.h>, so there seems to be some general inconsistency wrt. which dcn module includes what.
Odd that my build testing didn't find that 'allmodconfig' doesn't catch it :(
Anyway, thanks for letting me know, I've pushed out a -rc2 now with this fix. Or hopeful fix...
greg k-h
Quoted 8 lines · Greg Kroah-Hartman
This is the start of the stable review cycle for the 5.15.35 release. There are 189 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 Wed, 20 Apr 2022 12:11:14 +0000. Anything received after that time might be too late.
Build results:
total: 156 pass: 154 fail: 2
Failed builds:
i386:allyesconfig
i386:allmodconfig
Qemu test results:
total: 488 pass: 488 fail: 0
Build error as already reported.
drivers/gpu/drm/amd/amdgpu/../display/dc/dcn31/dcn31_hubbub.c:
In function 'hubbub31_verify_allow_pstate_change_high':drivers/gpu/drm/amd/amdgpu/../display/dc/dcn31/dcn31_hubbub.c:994:17:
error: implicit declaration of function 'udelay'
Guenter
Quoted 9 lines · Greg Kroah-Hartman
This is the start of the stable review cycle for the 5.15.35 release. There are 189 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 Wed, 20 Apr 2022 12:11:14 +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/v5.x/stable-review/patch-5.15.35-rc1.gzor in the git tree and branch at:
git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.gitlinux-5.15.y
and the diffstat can be found below.thanks,
greg k-h
Built and booted successfully on RISC-V RV64 (HiFive Unmatched).
Quoted 10 lines · Greg Kroah-Hartman
This is the start of the stable review cycle for the 5.15.35 release. There are 189 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 Wed, 20 Apr 2022 12:11:14 +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/v5.x/stable-review/patch-5.15.35-rc1.gzor in the git tree and branch at:
git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.gitlinux-5.15.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: 5.15.35-rc1
* git: https://gitlab.com/Linaro/lkft/mirrors/stable/linux-stable-rc
* git branch: linux-5.15.y
* git commit: 4a9761edfcec9b095619311472fac014067f802d
* git describe: v5.15.34-190-g4a9761edfcec
* test details:
https://qa-reports.linaro.org/lkft/linux-stable-rc-linux-5.15.y/build/v5.15.34-190-g4a9761edfcec
## Test Regressions (compared to v5.15.33-278-g1ad810a5a764) No test regressions found.
## Metric Regressions (compared to v5.15.33-278-g1ad810a5a764) No metric regressions found.
## Test Fixes (compared to v5.15.33-278-g1ad810a5a764) No metric fixes found.
## Metric Fixes (compared to v5.15.33-278-g1ad810a5a764) No metric fixes found.
## Test result summary
total: 103748, pass: 88080, fail: 617, skip: 14029, xfail: 1022
## Build Summary
* arc: 10 total, 10 passed, 0 failed
* arm: 291 total, 291 passed, 0 failed
* arm64: 41 total, 41 passed, 0 failed
* i386: 39 total, 39 passed, 0 failed
* mips: 37 total, 37 passed, 0 failed
* parisc: 12 total, 12 passed, 0 failed
* powerpc: 60 total, 54 passed, 6 failed
* riscv: 27 total, 22 passed, 5 failed
* s390: 21 total, 21 passed, 0 failed
* sh: 24 total, 24 passed, 0 failed
* sparc: 12 total, 12 passed, 0 failed
* x86_64: 41 total, 41 passed, 0 failed
## Test suites summary
* fwts
* igt-gpu-tools
* kselftest-android
* kselftest-arm64
* kselftest-breakpoints
* kselftest-capabilities
* kselftest-cgroup
* kselftest-clone3
* kselftest-core
* kselftest-cpu-hotplug
* kselftest-cpufreq
* kselftest-drivers
* kselftest-efivarfs
* kselftest-filesystems
* kselftest-firmware
* kselftest-fpu
* kselftest-futex
* kselftest-gpio
* kselftest-intel_pstate
* kselftest-ipc
* kselftest-ir
* kselftest-kcmp
* kselftest-kexec
* kselftest-kvm
* kselftest-lib
* kselftest-livepatch
* kselftest-membarrier
* kselftest-memfd
* kselftest-memory-hotplug
* kselftest-mincore
* kselftest-mount
* kselftest-mqueue
* kselftest-net
* 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-timens
* kselftest-timers
* kselftest-tmpfs
* kselftest-tpm2
* kselftest-user
* kselftest-vm
* kselftest-x86
* kselftest-zram
* kunit
* kvm-unit-tests
* libgpiod
* libhugetlbfs
* linux-log-parser
* ltp-cap_bounds-tests
* ltp-commands-tests
* ltp-containers-tests
* ltp-controllers-tests
* ltp-cpuhotplug-tests
* ltp-crypto-tests
* ltp-cve-tests
* ltp-dio-tests
* ltp-fcntl-locktests-tests
* ltp-filecaps-tests
* ltp-fs-tests
* ltp-fs_bind-tests
* ltp-fs_perms_simple-tests
* ltp-fsx-tests
* ltp-hugetlb-tests
* ltp-io-tests
* ltp-ipc-tests
* ltp-math-tests
* ltp-mm-tests
* ltp-npt[
* ltp-nptl-tests
* ltp-open-posix-tests
* ltp-pty-tests
* ltp-sched-tests
* ltp-securebits-tests
* ltp-syscalls-tests
* ltp-tracing-tests
* network-basic-tests
* packetdrill
* perf
* rcutorture
* ssuite
* v4l2-com[
* v4l2-compliance
* vdso
--
Linaro LKFT
https://lkft.linaro.org