From: John Stultz <jstultz(a)google.com>
mainline inclusion
from mainline-v6.7-rc1
commit bccdd808902f8c677317cec47c306e42b93b849e
category: bugfix
bugzilla: https://gitee.com/src-openeuler/kernel/issues/I9RFIG
CVE: CVE-2023-52836
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?id…
--------------------------------
In some cases running with the test-ww_mutex code, I was seeing
odd behavior where sometimes it seemed flush_workqueue was
returning before all the work threads were finished.
Often this would cause strange crashes as the mutexes would be
freed while they were being used.
Looking at the code, there is a lifetime problem as the
controlling thread that spawns the work allocates the
"struct stress" structures that are passed to the workqueue
threads. Then when the workqueue threads are finished,
they free the stress struct that was passed to them.
Unfortunately the workqueue work_struct node is in the stress
struct. Which means the work_struct is freed before the work
thread returns and while flush_workqueue is waiting.
It seems like a better idea to have the controlling thread
both allocate and free the stress structures, so that we can
be sure we don't corrupt the workqueue by freeing the structure
prematurely.
So this patch reworks the test to do so, and with this change
I no longer see the early flush_workqueue returns.
Signed-off-by: John Stultz <jstultz(a)google.com>
Signed-off-by: Ingo Molnar <mingo(a)kernel.org>
Link: https://lore.kernel.org/r/20230922043616.19282-3-jstultz@google.com
(cherry picked from commit bccdd808902f8c677317cec47c306e42b93b849e)
Signed-off-by: Xie XiuQi <xiexiuqi(a)huawei.com>
---
kernel/locking/test-ww_mutex.c | 20 ++++++++++++--------
1 file changed, 12 insertions(+), 8 deletions(-)
diff --git a/kernel/locking/test-ww_mutex.c b/kernel/locking/test-ww_mutex.c
index 65a3b7e55b9f..4fd05d9d5d6d 100644
--- a/kernel/locking/test-ww_mutex.c
+++ b/kernel/locking/test-ww_mutex.c
@@ -439,7 +439,6 @@ static void stress_inorder_work(struct work_struct *work)
} while (!time_after(jiffies, stress->timeout));
kfree(order);
- kfree(stress);
}
struct reorder_lock {
@@ -504,7 +503,6 @@ static void stress_reorder_work(struct work_struct *work)
list_for_each_entry_safe(ll, ln, &locks, link)
kfree(ll);
kfree(order);
- kfree(stress);
}
static void stress_one_work(struct work_struct *work)
@@ -525,8 +523,6 @@ static void stress_one_work(struct work_struct *work)
break;
}
} while (!time_after(jiffies, stress->timeout));
-
- kfree(stress);
}
#define STRESS_INORDER BIT(0)
@@ -537,15 +533,24 @@ static void stress_one_work(struct work_struct *work)
static int stress(int nlocks, int nthreads, unsigned int flags)
{
struct ww_mutex *locks;
- int n;
+ struct stress *stress_array;
+ int n, count;
locks = kmalloc_array(nlocks, sizeof(*locks), GFP_KERNEL);
if (!locks)
return -ENOMEM;
+ stress_array = kmalloc_array(nthreads, sizeof(*stress_array),
+ GFP_KERNEL);
+ if (!stress_array) {
+ kfree(locks);
+ return -ENOMEM;
+ }
+
for (n = 0; n < nlocks; n++)
ww_mutex_init(&locks[n], &ww_class);
+ count = 0;
for (n = 0; nthreads; n++) {
struct stress *stress;
void (*fn)(struct work_struct *work);
@@ -569,9 +574,7 @@ static int stress(int nlocks, int nthreads, unsigned int flags)
if (!fn)
continue;
- stress = kmalloc(sizeof(*stress), GFP_KERNEL);
- if (!stress)
- break;
+ stress = &stress_array[count++];
INIT_WORK(&stress->work, fn);
stress->locks = locks;
@@ -586,6 +589,7 @@ static int stress(int nlocks, int nthreads, unsigned int flags)
for (n = 0; n < nlocks; n++)
ww_mutex_destroy(&locks[n]);
+ kfree(stress_array);
kfree(locks);
return 0;
--
2.20.1
Hi Andrew,
FYI, the error/warning still remains.
tree: https://gitee.com/openeuler/kernel.git OLK-6.6
head: c0b6b4438dc70167c4c16f6436499cde257f782a
commit: f9b54a6714445cde83aeff0318cf767b3b81229d [701/9792] arm64:ilp32: add ARM64_ILP32 to Kconfig
config: arm64-randconfig-003-20240530 (https://download.01.org/0day-ci/archive/20240530/202405300401.Q7EpPsSe-lkp@…)
compiler: aarch64-linux-gcc (GCC) 13.2.0
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20240530/202405300401.Q7EpPsSe-lkp@…)
If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp(a)intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202405300401.Q7EpPsSe-lkp@intel.com/
All errors (new ones prefixed by >>):
scripts/genksyms/parse.y: warning: 9 shift/reduce conflicts [-Wconflicts-sr]
scripts/genksyms/parse.y: warning: 5 reduce/reduce conflicts [-Wconflicts-rr]
scripts/genksyms/parse.y: note: rerun with option '-Wcounterexamples' to generate conflict counterexamples
arch/arm64/kernel/vdso-ilp32/Makefile:87: FORCE prerequisite is missing
arch/arm64/kernel/vdso-ilp32/Makefile:84: FORCE prerequisite is missing
arch/arm64/kernel/vdso-ilp32/Makefile:90: FORCE prerequisite is missing
arch/arm64/kernel/vdso-ilp32/Makefile:68: FORCE prerequisite is missing
ld: arch/arm64/kernel/vdso-ilp32/vgettimeofday-ilp32.o: in function `__cvdso_gettimeofday_data.constprop.0':
>> vgettimeofday.c:(.text+0x28): undefined reference to `__tsan_volatile_read4'
ld: vgettimeofday.c:(.text+0x40): undefined reference to `__tsan_read4'
ld: vgettimeofday.c:(.text+0x6c): undefined reference to `__tsan_read8'
ld: vgettimeofday.c:(.text+0x7c): undefined reference to `__tsan_read8'
ld: vgettimeofday.c:(.text+0x88): undefined reference to `__tsan_read8'
ld: vgettimeofday.c:(.text+0x94): undefined reference to `__tsan_read4'
ld: vgettimeofday.c:(.text+0xa0): undefined reference to `__tsan_read4'
ld: vgettimeofday.c:(.text+0xb0): undefined reference to `__tsan_read8'
ld: vgettimeofday.c:(.text+0xc0): undefined reference to `__tsan_volatile_read4'
ld: vgettimeofday.c:(.text+0x120): undefined reference to `__tsan_write4'
ld: vgettimeofday.c:(.text+0x12c): undefined reference to `__tsan_write4'
ld: vgettimeofday.c:(.text+0x184): undefined reference to `__tsan_read4'
ld: vgettimeofday.c:(.text+0x190): undefined reference to `__tsan_write4'
ld: vgettimeofday.c:(.text+0x19c): undefined reference to `__tsan_read4'
ld: vgettimeofday.c:(.text+0x1a8): undefined reference to `__tsan_write4'
ld: arch/arm64/kernel/vdso-ilp32/vgettimeofday-ilp32.o: in function `__cvdso_clock_gettime_data.constprop.0':
vgettimeofday.c:(.text+0x24c): undefined reference to `__tsan_volatile_read4'
ld: vgettimeofday.c:(.text+0x264): undefined reference to `__tsan_read4'
ld: vgettimeofday.c:(.text+0x298): undefined reference to `__tsan_read8'
ld: vgettimeofday.c:(.text+0x2a8): undefined reference to `__tsan_read8'
ld: vgettimeofday.c:(.text+0x2b4): undefined reference to `__tsan_read8'
ld: vgettimeofday.c:(.text+0x2c4): undefined reference to `__tsan_read4'
ld: vgettimeofday.c:(.text+0x2d0): undefined reference to `__tsan_read4'
ld: vgettimeofday.c:(.text+0x2e0): undefined reference to `__tsan_read8'
ld: vgettimeofday.c:(.text+0x2f0): undefined reference to `__tsan_volatile_read4'
ld: vgettimeofday.c:(.text+0x350): undefined reference to `__tsan_write8'
ld: vgettimeofday.c:(.text+0x35c): undefined reference to `__tsan_write8'
ld: vgettimeofday.c:(.text+0x438): undefined reference to `__tsan_volatile_read4'
ld: vgettimeofday.c:(.text+0x44c): undefined reference to `__tsan_read8'
ld: vgettimeofday.c:(.text+0x458): undefined reference to `__tsan_write8'
ld: vgettimeofday.c:(.text+0x464): undefined reference to `__tsan_read8'
ld: vgettimeofday.c:(.text+0x470): undefined reference to `__tsan_write8'
ld: vgettimeofday.c:(.text+0x480): undefined reference to `__tsan_volatile_read4'
ld: arch/arm64/kernel/vdso-ilp32/vgettimeofday-ilp32.o: in function `__kernel_clock_getres':
>> vgettimeofday.c:(.text+0x584): undefined reference to `__tsan_write8'
ld: vgettimeofday.c:(.text+0x590): undefined reference to `__tsan_write8'
ld: vgettimeofday.c:(.text+0x5c0): undefined reference to `__tsan_volatile_read4'
ld: arch/arm64/kernel/vdso-ilp32/vgettimeofday-ilp32.o: in function `_sub_I_00099_0':
>> vgettimeofday.c:(.text.startup+0x8): undefined reference to `__tsan_init'
collect2: error: ld returned 1 exit status
make[3]: *** [arch/arm64/kernel/vdso-ilp32/Makefile:68: arch/arm64/kernel/vdso-ilp32/vdso-ilp32.so.dbg] Error 1 shuffle=1722226854
make[3]: Target 'include/generated/vdso-ilp32-offsets.h' not remade because of errors.
make[2]: *** [arch/arm64/Makefile:201: vdso_prepare] Error 2 shuffle=1722226854
make[2]: Target 'prepare' not remade because of errors.
make[1]: *** [Makefile:234: __sub-make] Error 2 shuffle=1722226854
make[1]: Target 'prepare' not remade because of errors.
make: *** [Makefile:234: __sub-make] Error 2 shuffle=1722226854
make: Target 'prepare' not remade because of errors.
Kconfig warnings: (for reference only)
WARNING: unmet direct dependencies detected for ARM64_ERRATUM_845719
Depends on [n]: AARCH32_EL0 [=n]
Selected by [y]:
- ARCH_MXC [=y] && ARCH_NXP [=y] && COMPAT [=y]
--
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki
tree: https://gitee.com/openeuler/kernel.git openEuler-1.0-LTS
head: aec283517697385e25d19ae7312a63bad805b4a7
commit: a6a7981cbf66d4951425d33cdce6ef39206eba83 [21121/22575] Net: ethernet: Support 3snic 3s9xx network card
config: x86_64-randconfig-015-20240530 (https://download.01.org/0day-ci/archive/20240530/202405300401.gTFtRxYB-lkp@…)
compiler: clang version 18.1.5 (https://github.com/llvm/llvm-project 617a15a9eac96088ae5e9134248d8236e34b91b1)
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20240530/202405300401.gTFtRxYB-lkp@…)
If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp(a)intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202405300401.gTFtRxYB-lkp@intel.com/
All errors (new ones prefixed by >>):
>> drivers/net/ethernet/3snic/sssnic/hw/sss_adapter_mgmt.c:234:30: error: no member named 'physfn' in 'struct pci_dev'
234 | pf_pdev = adapter->pcidev->physfn;
| ~~~~~~~~~~~~~~~ ^
1 error generated.
--
>> drivers/net/ethernet/3snic/sssnic/hw/sss_pci_probe.c:53:32: error: no member named 'physfn' in 'struct pci_dev'
53 | dev = pdev->is_virtfn ? pdev->physfn : pdev;
| ~~~~ ^
drivers/net/ethernet/3snic/sssnic/hw/sss_pci_probe.c:84:31: warning: shift count >= width of type [-Wshift-count-overflow]
84 | ret = pci_set_dma_mask(pdev, DMA_BIT_MASK(64));
| ^~~~~~~~~~~~~~~~
include/linux/dma-mapping.h:149:54: note: expanded from macro 'DMA_BIT_MASK'
149 | #define DMA_BIT_MASK(n) (((n) == 64) ? ~0ULL : ((1ULL<<(n))-1))
| ^ ~~~
drivers/net/ethernet/3snic/sssnic/hw/sss_pci_probe.c:95:42: warning: shift count >= width of type [-Wshift-count-overflow]
95 | ret = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(64));
| ^~~~~~~~~~~~~~~~
include/linux/dma-mapping.h:149:54: note: expanded from macro 'DMA_BIT_MASK'
149 | #define DMA_BIT_MASK(n) (((n) == 64) ? ~0ULL : ((1ULL<<(n))-1))
| ^ ~~~
drivers/net/ethernet/3snic/sssnic/hw/sss_pci_probe.c:276:5: warning: no previous prototype for function 'sss_attach_uld_driver' [-Wmissing-prototypes]
276 | int sss_attach_uld_driver(struct sss_pci_adapter *adapter,
| ^
drivers/net/ethernet/3snic/sssnic/hw/sss_pci_probe.c:276:1: note: declare 'static' if the function is not intended to be used outside of this translation unit
276 | int sss_attach_uld_driver(struct sss_pci_adapter *adapter,
| ^
| static
drivers/net/ethernet/3snic/sssnic/hw/sss_pci_probe.c:319:39: error: no member named 'physfn' in 'struct pci_dev'
319 | dev = (pdev->is_virtfn != 0) ? pdev->physfn : pdev;
| ~~~~ ^
drivers/net/ethernet/3snic/sssnic/hw/sss_pci_probe.c:548:5: warning: no previous prototype for function 'sss_pci_probe' [-Wmissing-prototypes]
548 | int sss_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
| ^
drivers/net/ethernet/3snic/sssnic/hw/sss_pci_probe.c:548:1: note: declare 'static' if the function is not intended to be used outside of this translation unit
548 | int sss_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
| ^
| static
4 warnings and 2 errors generated.
vim +234 drivers/net/ethernet/3snic/sssnic/hw/sss_adapter_mgmt.c
221
222 static unsigned char sss_get_pci_bus_id(struct sss_pci_adapter *adapter)
223 {
224 struct pci_dev *pf_pdev = NULL;
225 unsigned char bus_id = 0;
226
227 if (!pci_is_root_bus(adapter->pcidev->bus))
228 bus_id = adapter->pcidev->bus->number;
229
230 if (bus_id == 0)
231 return bus_id;
232
233 if (adapter->pcidev->is_virtfn) {
> 234 pf_pdev = adapter->pcidev->physfn;
235 bus_id = pf_pdev->bus->number;
236 }
237
238 return bus_id;
239 }
240
--
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki
tree: https://gitee.com/openeuler/kernel.git openEuler-1.0-LTS
head: aec283517697385e25d19ae7312a63bad805b4a7
commit: 211070f39ed4ec7390dca8351c9fee934b8179e7 [5041/22575] HID: i2c-hid: override HID descriptors for certain devices
config: x86_64-buildonly-randconfig-005-20240527 (https://download.01.org/0day-ci/archive/20240529/202405292306.oKi0pqkq-lkp@…)
compiler: gcc-13 (Ubuntu 13.2.0-4ubuntu3) 13.2.0
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20240529/202405292306.oKi0pqkq-lkp@…)
If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp(a)intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202405292306.oKi0pqkq-lkp@intel.com/
All warnings (new ones prefixed by >>):
In file included from drivers/hid/i2c-hid/i2c-hid-core.c:21:
include/linux/module.h:140:14: warning: 'cleanup_module' specifies less restrictive attribute than its target 'i2c_hid_driver_exit': 'cold' [-Wmissing-attributes]
140 | void cleanup_module(void) __attribute__((alias(#exitfn)));
| ^~~~~~~~~~~~~~
include/linux/device.h:1637:1: note: in expansion of macro 'module_exit'
1637 | module_exit(__driver##_exit);
| ^~~~~~~~~~~
include/linux/i2c.h:870:9: note: in expansion of macro 'module_driver'
870 | module_driver(__i2c_driver, i2c_add_driver, \
| ^~~~~~~~~~~~~
drivers/hid/i2c-hid/i2c-hid-core.c:1344:1: note: in expansion of macro 'module_i2c_driver'
1344 | module_i2c_driver(i2c_hid_driver);
| ^~~~~~~~~~~~~~~~~
In file included from include/linux/i2c.h:30,
from drivers/hid/i2c-hid/i2c-hid-core.c:22:
drivers/hid/i2c-hid/i2c-hid-core.c:1344:19: note: 'cleanup_module' target declared here
1344 | module_i2c_driver(i2c_hid_driver);
| ^~~~~~~~~~~~~~
include/linux/device.h:1633:20: note: in definition of macro 'module_driver'
1633 | static void __exit __driver##_exit(void) \
| ^~~~~~~~
drivers/hid/i2c-hid/i2c-hid-core.c:1344:1: note: in expansion of macro 'module_i2c_driver'
1344 | module_i2c_driver(i2c_hid_driver);
| ^~~~~~~~~~~~~~~~~
include/linux/module.h:134:13: warning: 'init_module' specifies less restrictive attribute than its target 'i2c_hid_driver_init': 'cold' [-Wmissing-attributes]
134 | int init_module(void) __attribute__((alias(#initfn)));
| ^~~~~~~~~~~
include/linux/device.h:1632:1: note: in expansion of macro 'module_init'
1632 | module_init(__driver##_init); \
| ^~~~~~~~~~~
include/linux/i2c.h:870:9: note: in expansion of macro 'module_driver'
870 | module_driver(__i2c_driver, i2c_add_driver, \
| ^~~~~~~~~~~~~
drivers/hid/i2c-hid/i2c-hid-core.c:1344:1: note: in expansion of macro 'module_i2c_driver'
1344 | module_i2c_driver(i2c_hid_driver);
| ^~~~~~~~~~~~~~~~~
drivers/hid/i2c-hid/i2c-hid-core.c:1344:19: note: 'init_module' target declared here
1344 | module_i2c_driver(i2c_hid_driver);
| ^~~~~~~~~~~~~~
include/linux/device.h:1628:19: note: in definition of macro 'module_driver'
1628 | static int __init __driver##_init(void) \
| ^~~~~~~~
drivers/hid/i2c-hid/i2c-hid-core.c:1344:1: note: in expansion of macro 'module_i2c_driver'
1344 | module_i2c_driver(i2c_hid_driver);
| ^~~~~~~~~~~~~~~~~
drivers/hid/i2c-hid/i2c-hid-core.c: In function '__i2c_hid_command':
drivers/hid/i2c-hid/i2c-hid-core.c:223:26: warning: array subscript 0 is outside array bounds of 'u8[0]' {aka 'unsigned char[]'} [-Warray-bounds=]
223 | cmd->data[0] = ihid->hdesc_buffer[registerIndex];
| ~~~~~~~~~^~~
drivers/hid/i2c-hid/i2c-hid-core.c:98:12: note: while referencing 'data'
98 | u8 data[0];
| ^~~~
drivers/hid/i2c-hid/i2c-hid-core.c:224:26: warning: array subscript 1 is outside array bounds of 'u8[0]' {aka 'unsigned char[]'} [-Warray-bounds=]
224 | cmd->data[1] = ihid->hdesc_buffer[registerIndex + 1];
| ~~~~~~~~~^~~
drivers/hid/i2c-hid/i2c-hid-core.c:98:12: note: while referencing 'data'
98 | u8 data[0];
| ^~~~
drivers/hid/i2c-hid/i2c-hid-core.c:327: warning: Function parameter or member 'data_len' not described in 'i2c_hid_set_or_send_report'
drivers/hid/i2c-hid/i2c-hid-core.c:327: warning: Excess function parameter 'len' description in 'i2c_hid_set_or_send_report'
>> drivers/hid/i2c-hid/.tmp_i2c-hid-core.o: warning: objtool: missing symbol for section .exit.text
--
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki