diff --git a/patches/factory-drop-kernel-write-danctnix/0001-bes2600-drop-kernel_write-persistence-from-factory-c.patch b/patches/factory-drop-kernel-write-danctnix/0001-bes2600-drop-kernel_write-persistence-from-factory-c.patch new file mode 100644 index 000000000..e1555cba2 --- /dev/null +++ b/patches/factory-drop-kernel-write-danctnix/0001-bes2600-drop-kernel_write-persistence-from-factory-c.patch @@ -0,0 +1,156 @@ +From 5f475a9624490b07c305329f12016ff4a4df3b47 Mon Sep 17 00:00:00 2001 +From: Markus Fritsche +Date: Thu, 23 Apr 2026 19:31:25 +0200 +Subject: [PATCH] bes2600: drop kernel_write() persistence from factory cali + save + +Following the conversion of the factory-calibration READ path to +request_firmware() (earlier in this series), the factory-calibration +WRITE path in factory_section_write_file() was still using +filp_open(O_CREAT | O_TRUNC | O_RDWR) + kernel_write() to persist +updated calibration data back to FACTORY_PATH +(default /lib/firmware/bes2600/bes2600_factory.txt). + +Writing to files under /lib/firmware/ from kernel code is a +standing upstream blocker for staging and for drivers/net/wireless/ +submission generally: + + - filp_open()/kernel_write() bypass the firmware-class abstraction, + the LSM framework, and user/group/mode enforcement that governs + the firmware search paths. They have been repeatedly called out + in staging-prep reviews. + - The kernel runs with capabilities that userspace does not (CAP_ + DAC_OVERRIDE effectively); quietly rewriting firmware blobs that + userspace owns is a surprise contract. + - A module unload / reboot immediately after the write races the + writeback and can leave a truncated calibration file on disk. + +Remove factory_section_write_file() and its two call sites in +bes2600_wifi_cali_table_save(). The in-memory factory_save_p +remains authoritative for the duration of the session: the WSM +command handlers that triggered this path (power-cali-table, +freq-cali, efuse-flag, power-cali-flag) already update the live +struct factory_t, and reads served from file_buffer pick up the +rebuilt serialised form immediately. On the next probe the +firmware-class file is re-read read-only via request_firmware(), +as set up by the earlier patch. + +If cross-reboot persistence of runtime-updated calibration becomes +a requirement, the expected route is a userspace-visible dump +interface -- a read-only debugfs file exporting the serialised +blob, or an nl80211 vendor command -- that lets userspace copy the +values to a chosen location under its own privileges. Such a +facility can land as a follow-up without touching the core driver +write path again. + +Signed-off-by: Markus Fritsche +--- + bes2600/bes2600_factory.c | 63 +++++++++++---------------------------- + 1 file changed, 17 insertions(+), 46 deletions(-) + +diff --git a/drivers/staging/bes2600/bes2600_factory.c b/drivers/staging/bes2600/bes2600_factory.c +index 1cda447..1b43b41 100644 +--- a/drivers/staging/bes2600/bes2600_factory.c ++++ b/drivers/staging/bes2600/bes2600_factory.c +@@ -179,34 +179,6 @@ static int factory_section_read_file(char *path, void *buffer) + return ret; + } + +-/** +- * factory_section_write_file - Write data of specified length to file +- * @path: path of the file +- * @buffer: storage of write data +- * @size: length of data to write +- * +- * Return: length on success, negative error code otherwise. +- */ +-static int factory_section_write_file(char *path, void *buffer, int size) +-{ +- int ret = 0; +- struct file *fp; +- +- bes_devel("writing %s \n", path); +- +- fp = filp_open(path, O_TRUNC | O_CREAT | O_RDWR, S_IRUSR); +- if (IS_ERR(fp)) { +- bes_devel("BES2600 : can't open %s\n",path); +- return -1; +- } +- +- ret = kernel_write(fp, buffer, size, &fp->f_pos); +- +- filp_close(fp,NULL); +- +- return ret; +-} +- + static inline int factory_parse(uint8_t *source_buf, struct factory_t *factory) + { + int ret = 0; +@@ -898,9 +870,22 @@ static inline int factory_build(uint8_t *dest_buf, struct factory_t *factory) + #endif + } + ++/* ++ * Rebuild the serialised calibration blob in file_buffer from the live ++ * in-memory factory_save_p. Previously this function also persisted the ++ * blob back to FACTORY_PATH via filp_open(O_CREAT) + kernel_write(); that ++ * is not acceptable in mainline, so the persistence step has been removed. ++ * ++ * The in-memory factory_save_p remains authoritative for the duration of ++ * the session; on the next probe the firmware-class file is read back ++ * read-only via request_firmware(). If cross-reboot persistence of runtime ++ * calibration updates becomes a requirement, the expected route is a ++ * userspace-facing dump interface (debugfs read-only blob, or nl80211 ++ * vendor command) that lets userspace read the serialised form and store ++ * it under its own privileges. ++ */ + static int bes2600_wifi_cali_table_save(u8 *file_buffer, struct factory_t *factory_save_p) + { +- int ret = 0; + int w_size; + u32 crc_len = sizeof(factory_data_t); + #ifndef STANDARD_FACTORY_EFUSE_FLAG +@@ -909,13 +894,11 @@ static int bes2600_wifi_cali_table_save(u8 *file_buffer, struct factory_t *facto + + bes_devel("enter %s\n", __func__); + +- if (!file_buffer) { ++ if (!file_buffer) + return -ENOMEM; +- } + +- if (!factory_save_p) { ++ if (!factory_save_p) + return -ENOENT; +- } + + /* All initialized to space */ + memset(file_buffer, 32, FACTORY_MAX_SIZE); +@@ -927,22 +910,10 @@ static int bes2600_wifi_cali_table_save(u8 *file_buffer, struct factory_t *facto + w_size = factory_build(file_buffer, factory_save_p); + + if (w_size < 0 || w_size > FACTORY_MAX_SIZE) { +- bes_err("%s: build failed! ret = %d.", __func__, ret); ++ bes_err("%s: build failed! w_size = %d.", __func__, w_size); + return -ETXTBSY; + } + +-#ifdef FACTORY_SAVE_MULTI_PATH +- /* avoid trailing characters '\0' */ +- file_buffer[w_size] = 32; +- ret = factory_section_write_file(FACTORY_PATH, file_buffer, FACTORY_MAX_SIZE); +-#else +- ret = factory_section_write_file(FACTORY_PATH, file_buffer, w_size); +-#endif +- if(ret < 0) { +- bes_err("%s: write failed! ret = %d.", __func__, ret); +- return ret; +- } +- + return 0; + } + +-- +2.53.0 + diff --git a/patches/factory-drop-kernel-write/0001-bes2600-drop-kernel_write-persistence-from-factory-c.patch b/patches/factory-drop-kernel-write/0001-bes2600-drop-kernel_write-persistence-from-factory-c.patch new file mode 100644 index 000000000..294ab4d50 --- /dev/null +++ b/patches/factory-drop-kernel-write/0001-bes2600-drop-kernel_write-persistence-from-factory-c.patch @@ -0,0 +1,156 @@ +From 5f475a9624490b07c305329f12016ff4a4df3b47 Mon Sep 17 00:00:00 2001 +From: Markus Fritsche +Date: Thu, 23 Apr 2026 19:31:25 +0200 +Subject: [PATCH] bes2600: drop kernel_write() persistence from factory cali + save + +Following the conversion of the factory-calibration READ path to +request_firmware() (earlier in this series), the factory-calibration +WRITE path in factory_section_write_file() was still using +filp_open(O_CREAT | O_TRUNC | O_RDWR) + kernel_write() to persist +updated calibration data back to FACTORY_PATH +(default /lib/firmware/bes2600/bes2600_factory.txt). + +Writing to files under /lib/firmware/ from kernel code is a +standing upstream blocker for staging and for drivers/net/wireless/ +submission generally: + + - filp_open()/kernel_write() bypass the firmware-class abstraction, + the LSM framework, and user/group/mode enforcement that governs + the firmware search paths. They have been repeatedly called out + in staging-prep reviews. + - The kernel runs with capabilities that userspace does not (CAP_ + DAC_OVERRIDE effectively); quietly rewriting firmware blobs that + userspace owns is a surprise contract. + - A module unload / reboot immediately after the write races the + writeback and can leave a truncated calibration file on disk. + +Remove factory_section_write_file() and its two call sites in +bes2600_wifi_cali_table_save(). The in-memory factory_save_p +remains authoritative for the duration of the session: the WSM +command handlers that triggered this path (power-cali-table, +freq-cali, efuse-flag, power-cali-flag) already update the live +struct factory_t, and reads served from file_buffer pick up the +rebuilt serialised form immediately. On the next probe the +firmware-class file is re-read read-only via request_firmware(), +as set up by the earlier patch. + +If cross-reboot persistence of runtime-updated calibration becomes +a requirement, the expected route is a userspace-visible dump +interface -- a read-only debugfs file exporting the serialised +blob, or an nl80211 vendor command -- that lets userspace copy the +values to a chosen location under its own privileges. Such a +facility can land as a follow-up without touching the core driver +write path again. + +Signed-off-by: Markus Fritsche +--- + bes2600/bes2600_factory.c | 63 +++++++++++---------------------------- + 1 file changed, 17 insertions(+), 46 deletions(-) + +diff --git a/bes2600/bes2600_factory.c b/bes2600/bes2600_factory.c +index 1cda447..1b43b41 100644 +--- a/bes2600/bes2600_factory.c ++++ b/bes2600/bes2600_factory.c +@@ -179,34 +179,6 @@ static int factory_section_read_file(char *path, void *buffer) + return ret; + } + +-/** +- * factory_section_write_file - Write data of specified length to file +- * @path: path of the file +- * @buffer: storage of write data +- * @size: length of data to write +- * +- * Return: length on success, negative error code otherwise. +- */ +-static int factory_section_write_file(char *path, void *buffer, int size) +-{ +- int ret = 0; +- struct file *fp; +- +- bes_devel("writing %s \n", path); +- +- fp = filp_open(path, O_TRUNC | O_CREAT | O_RDWR, S_IRUSR); +- if (IS_ERR(fp)) { +- bes_devel("BES2600 : can't open %s\n",path); +- return -1; +- } +- +- ret = kernel_write(fp, buffer, size, &fp->f_pos); +- +- filp_close(fp,NULL); +- +- return ret; +-} +- + static inline int factory_parse(uint8_t *source_buf, struct factory_t *factory) + { + int ret = 0; +@@ -898,9 +870,22 @@ static inline int factory_build(uint8_t *dest_buf, struct factory_t *factory) + #endif + } + ++/* ++ * Rebuild the serialised calibration blob in file_buffer from the live ++ * in-memory factory_save_p. Previously this function also persisted the ++ * blob back to FACTORY_PATH via filp_open(O_CREAT) + kernel_write(); that ++ * is not acceptable in mainline, so the persistence step has been removed. ++ * ++ * The in-memory factory_save_p remains authoritative for the duration of ++ * the session; on the next probe the firmware-class file is read back ++ * read-only via request_firmware(). If cross-reboot persistence of runtime ++ * calibration updates becomes a requirement, the expected route is a ++ * userspace-facing dump interface (debugfs read-only blob, or nl80211 ++ * vendor command) that lets userspace read the serialised form and store ++ * it under its own privileges. ++ */ + static int bes2600_wifi_cali_table_save(u8 *file_buffer, struct factory_t *factory_save_p) + { +- int ret = 0; + int w_size; + u32 crc_len = sizeof(factory_data_t); + #ifndef STANDARD_FACTORY_EFUSE_FLAG +@@ -909,13 +894,11 @@ static int bes2600_wifi_cali_table_save(u8 *file_buffer, struct factory_t *facto + + bes_devel("enter %s\n", __func__); + +- if (!file_buffer) { ++ if (!file_buffer) + return -ENOMEM; +- } + +- if (!factory_save_p) { ++ if (!factory_save_p) + return -ENOENT; +- } + + /* All initialized to space */ + memset(file_buffer, 32, FACTORY_MAX_SIZE); +@@ -927,22 +910,10 @@ static int bes2600_wifi_cali_table_save(u8 *file_buffer, struct factory_t *facto + w_size = factory_build(file_buffer, factory_save_p); + + if (w_size < 0 || w_size > FACTORY_MAX_SIZE) { +- bes_err("%s: build failed! ret = %d.", __func__, ret); ++ bes_err("%s: build failed! w_size = %d.", __func__, w_size); + return -ETXTBSY; + } + +-#ifdef FACTORY_SAVE_MULTI_PATH +- /* avoid trailing characters '\0' */ +- file_buffer[w_size] = 32; +- ret = factory_section_write_file(FACTORY_PATH, file_buffer, FACTORY_MAX_SIZE); +-#else +- ret = factory_section_write_file(FACTORY_PATH, file_buffer, w_size); +-#endif +- if(ret < 0) { +- bes_err("%s: write failed! ret = %d.", __func__, ret); +- return ret; +- } +- + return 0; + } + +-- +2.53.0 + diff --git a/patches/staging-prep-series-danctnix/0001-bes2600-use-request_firmware-for-factory.txt-read.patch b/patches/staging-prep-series-danctnix/0001-bes2600-use-request_firmware-for-factory.txt-read.patch index 34031bf8c..0c43a84f8 100644 --- a/patches/staging-prep-series-danctnix/0001-bes2600-use-request_firmware-for-factory.txt-read.patch +++ b/patches/staging-prep-series-danctnix/0001-bes2600-use-request_firmware-for-factory.txt-read.patch @@ -65,7 +65,7 @@ Signed-off-by: Markus Fritsche drivers/staging/bes2600/bes2600_factory.c | 33 ++++++++++++++------------------- 2 files changed, 15 insertions(+), 20 deletions(-) -diff --git a/drivers/staging/bes2600/Makefile b/bes2600/Makefile +diff --git a/drivers/staging/bes2600/Makefile b/drivers/staging/bes2600/Makefile index 300912b..788aee2 100644 --- a/drivers/staging/bes2600/Makefile +++ b/drivers/staging/bes2600/Makefile @@ -78,7 +78,7 @@ index 300912b..788aee2 100644 endif # basic function -diff --git a/drivers/staging/bes2600/bes2600_factory.c b/bes2600/bes2600_factory.c +diff --git a/drivers/staging/bes2600/bes2600_factory.c b/drivers/staging/bes2600/bes2600_factory.c index dc5d3da..8d60b7c 100644 --- a/drivers/staging/bes2600/bes2600_factory.c +++ b/drivers/staging/bes2600/bes2600_factory.c diff --git a/patches/staging-prep-series-danctnix/0002-bes2600-default-STANDARD_FACTORY_EFUSE_FLAG-off-for-.patch b/patches/staging-prep-series-danctnix/0002-bes2600-default-STANDARD_FACTORY_EFUSE_FLAG-off-for-.patch index 2af11a2f3..389ece97e 100644 --- a/patches/staging-prep-series-danctnix/0002-bes2600-default-STANDARD_FACTORY_EFUSE_FLAG-off-for-.patch +++ b/patches/staging-prep-series-danctnix/0002-bes2600-default-STANDARD_FACTORY_EFUSE_FLAG-off-for-.patch @@ -56,7 +56,7 @@ Signed-off-by: Markus Fritsche drivers/staging/bes2600/wsm.h | 2 -- 2 files changed, 1 insertion(+), 3 deletions(-) -diff --git a/drivers/staging/bes2600/Makefile b/bes2600/Makefile +diff --git a/drivers/staging/bes2600/Makefile b/drivers/staging/bes2600/Makefile index 788aee2..2dcba09 100644 --- a/drivers/staging/bes2600/Makefile +++ b/drivers/staging/bes2600/Makefile @@ -69,7 +69,7 @@ index 788aee2..2dcba09 100644 FACTORY_PATH ?= drivers/staging/bes2600/bes2600_factory.txt endif -diff --git a/drivers/staging/bes2600/wsm.h b/bes2600/wsm.h +diff --git a/drivers/staging/bes2600/wsm.h b/drivers/staging/bes2600/wsm.h index 0673131..22845ac 100644 --- a/drivers/staging/bes2600/wsm.h +++ b/drivers/staging/bes2600/wsm.h diff --git a/patches/staging-prep-series-danctnix/0003-bes2600-thread-struct-device-through-factory-request.patch b/patches/staging-prep-series-danctnix/0003-bes2600-thread-struct-device-through-factory-request.patch index 28966a2f6..dcb58ad67 100644 --- a/patches/staging-prep-series-danctnix/0003-bes2600-thread-struct-device-through-factory-request.patch +++ b/patches/staging-prep-series-danctnix/0003-bes2600-thread-struct-device-through-factory-request.patch @@ -46,7 +46,7 @@ Signed-off-by: Markus Fritsche drivers/staging/bes2600/bes2600_sdio.c | 4 ++++ 3 files changed, 20 insertions(+), 1 deletion(-) -diff --git a/drivers/staging/bes2600/bes2600_factory.c b/bes2600/bes2600_factory.c +diff --git a/drivers/staging/bes2600/bes2600_factory.c b/drivers/staging/bes2600/bes2600_factory.c index 8d60b7c..1cda447 100644 --- a/drivers/staging/bes2600/bes2600_factory.c +++ b/drivers/staging/bes2600/bes2600_factory.c @@ -78,7 +78,7 @@ index 8d60b7c..1cda447 100644 if (ret) { bes_devel("BES2600: request_firmware(%s) failed: %d\n", path, ret); return -1; -diff --git a/drivers/staging/bes2600/bes2600_factory.h b/bes2600/bes2600_factory.h +diff --git a/drivers/staging/bes2600/bes2600_factory.h b/drivers/staging/bes2600/bes2600_factory.h index 3835b0d..7dbe9f8 100644 --- a/drivers/staging/bes2600/bes2600_factory.h +++ b/drivers/staging/bes2600/bes2600_factory.h @@ -92,7 +92,7 @@ index 3835b0d..7dbe9f8 100644 /* read wifi & bt factory cali value*/ u8* bes2600_get_factory_cali_data(u8 *file_buffer, u32 *data_len, char *path); void factory_little_endian_cvrt(u8 *data); -diff --git a/drivers/staging/bes2600/bes2600_sdio.c b/bes2600/bes2600_sdio.c +diff --git a/drivers/staging/bes2600/bes2600_sdio.c b/drivers/staging/bes2600/bes2600_sdio.c index b595365..371ef4f 100644 --- a/drivers/staging/bes2600/bes2600_sdio.c +++ b/drivers/staging/bes2600/bes2600_sdio.c diff --git a/patches/staging-prep-series-danctnix/0004-bes2600-gate-device-LP-mode-entry-on-successful-per-.patch b/patches/staging-prep-series-danctnix/0004-bes2600-gate-device-LP-mode-entry-on-successful-per-.patch index 965f0eeed..f583852fd 100644 --- a/patches/staging-prep-series-danctnix/0004-bes2600-gate-device-LP-mode-entry-on-successful-per-.patch +++ b/patches/staging-prep-series-danctnix/0004-bes2600-gate-device-LP-mode-entry-on-successful-per-.patch @@ -52,7 +52,7 @@ Signed-off-by: Markus Fritsche drivers/staging/bes2600/bes_pwr.c | 20 +++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) -diff --git a/drivers/staging/bes2600/bes_pwr.c b/bes2600/bes_pwr.c +diff --git a/drivers/staging/bes2600/bes_pwr.c b/drivers/staging/bes2600/bes_pwr.c index e7a1045..f62ae22 100644 --- a/drivers/staging/bes2600/bes_pwr.c +++ b/drivers/staging/bes2600/bes_pwr.c diff --git a/patches/staging-prep-series-danctnix/0005-bes2600-remove-userspace-dev-bes2600-character-devic.patch b/patches/staging-prep-series-danctnix/0005-bes2600-remove-userspace-dev-bes2600-character-devic.patch index c32880575..93808cad5 100644 --- a/patches/staging-prep-series-danctnix/0005-bes2600-remove-userspace-dev-bes2600-character-devic.patch +++ b/patches/staging-prep-series-danctnix/0005-bes2600-remove-userspace-dev-bes2600-character-devic.patch @@ -79,7 +79,7 @@ Signed-off-by: Markus Fritsche drivers/staging/bes2600/bes_chardev.c | 519 ------------------------------------------ 1 file changed, 519 deletions(-) -diff --git a/drivers/staging/bes2600/bes_chardev.c b/bes2600/bes_chardev.c +diff --git a/drivers/staging/bes2600/bes_chardev.c b/drivers/staging/bes2600/bes_chardev.c index 9038e48..e2e4f1b 100644 --- a/drivers/staging/bes2600/bes_chardev.c +++ b/drivers/staging/bes2600/bes_chardev.c diff --git a/patches/staging-prep-series-danctnix/0006-bes2600-enable-CONFIG_BES2600_TESTMODE-by-default-fi.patch b/patches/staging-prep-series-danctnix/0006-bes2600-enable-CONFIG_BES2600_TESTMODE-by-default-fi.patch index c20de2663..04688a6e5 100644 --- a/patches/staging-prep-series-danctnix/0006-bes2600-enable-CONFIG_BES2600_TESTMODE-by-default-fi.patch +++ b/patches/staging-prep-series-danctnix/0006-bes2600-enable-CONFIG_BES2600_TESTMODE-by-default-fi.patch @@ -66,7 +66,7 @@ Signed-off-by: Markus Fritsche drivers/staging/bes2600/sta.c | 6 +++--- 3 files changed, 27 insertions(+), 4 deletions(-) -diff --git a/drivers/staging/bes2600/Makefile b/bes2600/Makefile +diff --git a/drivers/staging/bes2600/Makefile b/drivers/staging/bes2600/Makefile index 2dcba09..2c1a850 100644 --- a/drivers/staging/bes2600/Makefile +++ b/drivers/staging/bes2600/Makefile @@ -79,7 +79,7 @@ index 2dcba09..2c1a850 100644 CONFIG_BES2600_ENABLE_DEVEL_LOGS ?= n -diff --git a/drivers/staging/bes2600/bes_log.h b/bes2600/bes_log.h +diff --git a/drivers/staging/bes2600/bes_log.h b/drivers/staging/bes2600/bes_log.h index 605cea8..65cf703 100644 --- a/drivers/staging/bes2600/bes_log.h +++ b/drivers/staging/bes2600/bes_log.h @@ -110,7 +110,7 @@ index 605cea8..65cf703 100644 + if (_cond) \ + bes_err(fmt, ##__VA_ARGS__); \ + } while (0) -diff --git a/drivers/staging/bes2600/sta.c b/bes2600/sta.c +diff --git a/drivers/staging/bes2600/sta.c b/drivers/staging/bes2600/sta.c index aa69eb8..5f1a456 100644 --- a/drivers/staging/bes2600/sta.c +++ b/drivers/staging/bes2600/sta.c diff --git a/patches/staging-prep-series-danctnix/0007-bes2600-bounce-SDIO-TX-buffers-to-avoid-DMA-OOB-read.patch b/patches/staging-prep-series-danctnix/0007-bes2600-bounce-SDIO-TX-buffers-to-avoid-DMA-OOB-read.patch index eb045c402..262e4da39 100644 --- a/patches/staging-prep-series-danctnix/0007-bes2600-bounce-SDIO-TX-buffers-to-avoid-DMA-OOB-read.patch +++ b/patches/staging-prep-series-danctnix/0007-bes2600-bounce-SDIO-TX-buffers-to-avoid-DMA-OOB-read.patch @@ -50,7 +50,7 @@ Signed-off-by: Markus Fritsche drivers/staging/bes2600/bes2600_sdio.c | 39 ++++++++++++++++++++++++++++++++++++++- 1 file changed, 38 insertions(+), 1 deletion(-) -diff --git a/drivers/staging/bes2600/bes2600_sdio.c b/bes2600/bes2600_sdio.c +diff --git a/drivers/staging/bes2600/bes2600_sdio.c b/drivers/staging/bes2600/bes2600_sdio.c index 371ef4f..3e04e8c 100644 --- a/drivers/staging/bes2600/bes2600_sdio.c +++ b/drivers/staging/bes2600/bes2600_sdio.c