mail archive of the barebox mailing list
 help / color / mirror / Atom feed
* [PATCH 0/7] add proper strdup_const support
@ 2024-11-25 15:29 Ahmad Fatoum
  2024-11-25 15:29 ` [PATCH 1/7] sandbox: hostfile: strdup device tree node names Ahmad Fatoum
                   ` (7 more replies)
  0 siblings, 8 replies; 9+ messages in thread
From: Ahmad Fatoum @ 2024-11-25 15:29 UTC (permalink / raw)
  To: barebox

We currently implement strdup_const as strdup, which is correct, but
leaves the benefits of a proper implementation on the table:
Reducing allocations for .rodata strings, which have static storage
duration anyway.

This series implements a proper strdup_const that avoids allocations in
that case.

Ahmad Fatoum (7):
  sandbox: hostfile: strdup device tree node names
  lds: implement is_barebox_rodata
  string: implement proper strdup_const/free_const
  treewide: replace basename with kbasename
  treewide: use strdup_const where appropriate
  fs: efi: replace allocation with local buffer
  cdev: fix string leaks in devfs links

 arch/arm/lib/pbl.lds.S                   |  4 ++-
 arch/arm/lib32/barebox.lds.S             |  4 ++-
 arch/arm/lib64/barebox.lds.S             |  4 ++-
 arch/kvx/cpu/barebox.lds.S               |  5 +++-
 arch/mips/lib/barebox.lds.S              |  4 ++-
 arch/mips/lib/pbl.lds.S                  |  4 ++-
 arch/mips/pbl/zbarebox.lds.S             |  4 ++-
 arch/openrisc/cpu/barebox.lds.S          |  4 ++-
 arch/powerpc/boards/pcm030/barebox.lds.S |  2 ++
 arch/powerpc/mach-mpc85xx/barebox.lds.S  |  2 ++
 arch/riscv/lib/barebox.lds.S             |  4 ++-
 arch/riscv/lib/pbl.lds.S                 |  4 ++-
 arch/sandbox/board/barebox.lds.S         |  2 ++
 arch/sandbox/board/hostfile.c            |  4 +--
 arch/x86/mach-efi/elf_ia32_efi.lds.S     |  2 ++
 arch/x86/mach-efi/elf_x86_64_efi.lds.S   |  2 ++
 commands/magicvar.c                      | 12 ++++----
 commands/menu.c                          |  6 ++--
 commands/nand.c                          |  4 +--
 commands/of_property.c                   | 12 ++++----
 commands/partition.c                     |  6 ++--
 commands/tftp.c                          |  5 ++--
 common/blspec.c                          |  8 ++---
 common/boot.c                            | 24 +++++++--------
 common/bootchooser.c                     |  6 ++--
 common/complete.c                        |  8 ++---
 common/elf.c                             |  2 +-
 common/env.c                             | 28 ++++++++---------
 common/file-list.c                       | 14 +++++----
 common/globalvar.c                       |  4 +--
 common/menu.c                            | 38 +++++++++++++-----------
 common/menutree.c                        |  4 +--
 common/poller.c                          |  4 +--
 common/resource.c                        |  8 ++---
 common/restart.c                         |  2 +-
 common/slice.c                           |  4 +--
 common/state/backend_storage.c           |  4 +--
 common/state/state.h                     |  2 +-
 common/state/state_variables.c           |  4 +--
 drivers/led/led-gpio.c                   |  6 ++--
 drivers/led/led-pwm.c                    |  2 +-
 drivers/nvmem/core.c                     |  4 +--
 drivers/of/base.c                        | 12 ++++----
 drivers/of/of_net.c                      |  2 +-
 drivers/regulator/core.c                 |  4 +--
 drivers/soc/kvx/kvx_socinfo.c            |  2 +-
 fs/bpkfs.c                               |  8 ++---
 fs/devfs-core.c                          |  5 +++-
 fs/efi.c                                 | 18 ++++++-----
 include/asm-generic/sections.h           | 18 +++++++++++
 include/blspec.h                         |  4 +--
 include/boot.h                           |  2 +-
 include/console.h                        |  2 +-
 include/digest.h                         |  4 +--
 include/dma.h                            |  5 ++++
 include/elf.h                            |  2 +-
 include/environment.h                    |  8 ++---
 include/file-list.h                      |  4 +--
 include/led.h                            |  2 +-
 include/linux/clk.h                      |  4 ++-
 include/linux/slab.h                     |  7 +++--
 include/linux/string.h                   |  5 ++++
 include/mci.h                            |  2 +-
 include/menu.h                           | 20 ++++++++-----
 include/net.h                            |  2 +-
 include/of.h                             |  6 ++--
 include/param.h                          |  2 +-
 include/poller.h                         |  2 +-
 include/slice.h                          |  2 +-
 include/stringlist.h                     |  4 +--
 lib/glob.c                               | 19 +++++++-----
 lib/parameter.c                          |  6 ++--
 lib/string.c                             | 28 +++++++++++++++++
 lib/stringlist.c                         |  6 ++--
 net/eth.c                                |  4 +--
 net/nfs.c                                |  8 ++---
 scripts/checkpatch.pl                    |  2 +-
 77 files changed, 309 insertions(+), 198 deletions(-)

-- 
2.39.5




^ permalink raw reply	[flat|nested] 9+ messages in thread

* [PATCH 1/7] sandbox: hostfile: strdup device tree node names
  2024-11-25 15:29 [PATCH 0/7] add proper strdup_const support Ahmad Fatoum
@ 2024-11-25 15:29 ` Ahmad Fatoum
  2024-11-25 15:29 ` [PATCH 2/7] lds: implement is_barebox_rodata Ahmad Fatoum
                   ` (6 subsequent siblings)
  7 siblings, 0 replies; 9+ messages in thread
From: Ahmad Fatoum @ 2024-11-25 15:29 UTC (permalink / raw)
  To: barebox; +Cc: Ahmad Fatoum

Later commits will change struct device_node::name to have a type of
const char *, leading to a warning here.

A nicer fix would be to use strdup_const here, but this needs some more
work, so for now duplicate the string.

Signed-off-by: Ahmad Fatoum <a.fatoum@pengutronix.de>
---
 arch/sandbox/board/hostfile.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/arch/sandbox/board/hostfile.c b/arch/sandbox/board/hostfile.c
index 7afad95b6d8b..9122ff9da2f1 100644
--- a/arch/sandbox/board/hostfile.c
+++ b/arch/sandbox/board/hostfile.c
@@ -156,7 +156,7 @@ static int hf_probe(struct device *dev)
 	cdev_set_of_node(cdev, np);
 
 	if (is_blockdev) {
-		cdev->name = np->name;
+		cdev->name = strdup(np->name);
 		priv->blk.dev = dev;
 		priv->blk.ops = &hf_blk_ops;
 		priv->blk.blockbits = SECTOR_SHIFT;
@@ -169,7 +169,7 @@ static int hf_probe(struct device *dev)
 
 		dev_info(dev, "registered as block device\n");
 	} else {
-		cdev->name = np->name;
+		cdev->name = strdup(np->name);
 		cdev->dev = dev;
 		cdev->ops = &hf_cdev_ops;
 		cdev->size = reg[1];
-- 
2.39.5




^ permalink raw reply	[flat|nested] 9+ messages in thread

* [PATCH 2/7] lds: implement is_barebox_rodata
  2024-11-25 15:29 [PATCH 0/7] add proper strdup_const support Ahmad Fatoum
  2024-11-25 15:29 ` [PATCH 1/7] sandbox: hostfile: strdup device tree node names Ahmad Fatoum
@ 2024-11-25 15:29 ` Ahmad Fatoum
  2024-11-25 15:29 ` [PATCH 3/7] string: implement proper strdup_const/free_const Ahmad Fatoum
                   ` (5 subsequent siblings)
  7 siblings, 0 replies; 9+ messages in thread
From: Ahmad Fatoum @ 2024-11-25 15:29 UTC (permalink / raw)
  To: barebox; +Cc: Ahmad Fatoum

Linux defines is_kernel_rodata(), which is mainly used to implement
kstrdup_const/kfree_const, which are useful to avoid duplication of
strings that already have static storage duration.

Implement the same for barebox on all architectures.

Note that this is of limited use on sandbox, because we don't define all
of the linker script ourselves, but this only means that we will have
some unneeded allocations there, which is a non-issue.

Signed-off-by: Ahmad Fatoum <a.fatoum@pengutronix.de>
---
 arch/arm/lib/pbl.lds.S                   |  4 +++-
 arch/arm/lib32/barebox.lds.S             |  4 +++-
 arch/arm/lib64/barebox.lds.S             |  4 +++-
 arch/kvx/cpu/barebox.lds.S               |  5 ++++-
 arch/mips/lib/barebox.lds.S              |  4 +++-
 arch/mips/lib/pbl.lds.S                  |  4 +++-
 arch/mips/pbl/zbarebox.lds.S             |  4 +++-
 arch/openrisc/cpu/barebox.lds.S          |  4 +++-
 arch/powerpc/boards/pcm030/barebox.lds.S |  2 ++
 arch/powerpc/mach-mpc85xx/barebox.lds.S  |  2 ++
 arch/riscv/lib/barebox.lds.S             |  4 +++-
 arch/riscv/lib/pbl.lds.S                 |  4 +++-
 arch/sandbox/board/barebox.lds.S         |  2 ++
 arch/x86/mach-efi/elf_ia32_efi.lds.S     |  2 ++
 arch/x86/mach-efi/elf_x86_64_efi.lds.S   |  2 ++
 include/asm-generic/sections.h           | 18 ++++++++++++++++++
 16 files changed, 59 insertions(+), 10 deletions(-)

diff --git a/arch/arm/lib/pbl.lds.S b/arch/arm/lib/pbl.lds.S
index f097ac1fdd46..dad37c9e9bca 100644
--- a/arch/arm/lib/pbl.lds.S
+++ b/arch/arm/lib/pbl.lds.S
@@ -62,6 +62,7 @@ SECTIONS
 	BAREBOX_PBL_SIZE
 
 	. = ALIGN(ASM_SZPTR);
+	__start_rodata = .;
 	__pbl_board_stack_top = .;
 	.rodata.pbl_board_stack_top : {
 		*(.pbl_board_stack_top_*)
@@ -76,7 +77,8 @@ SECTIONS
 	.barebox_imd : { BAREBOX_IMD }
 
 	. = ALIGN(PBL_SEGMENT_ALIGN);
-	_etext = .;			/* End of text and rodata section */
+	__end_rodata = .;
+	_etext = .;
 	_sdata = .;
 
 	. = ALIGN(4);
diff --git a/arch/arm/lib32/barebox.lds.S b/arch/arm/lib32/barebox.lds.S
index 97f41f72fef7..a52556a35696 100644
--- a/arch/arm/lib32/barebox.lds.S
+++ b/arch/arm/lib32/barebox.lds.S
@@ -31,6 +31,7 @@ SECTIONS
 	BAREBOX_BARE_INIT_SIZE
 
 	. = ALIGN(4);
+	__start_rodata = .;
 	.rodata : {
 		*(.rodata*)
 		RO_DATA_SECTION
@@ -52,7 +53,8 @@ SECTIONS
 		__stop_unwind_tab = .;
 	}
 #endif
-	_etext = .;			/* End of text and rodata section */
+	__end_rodata = .;
+	_etext = .;
 	_sdata = .;
 
 	. = ALIGN(4);
diff --git a/arch/arm/lib64/barebox.lds.S b/arch/arm/lib64/barebox.lds.S
index 1d0cc6dc543e..50e4b6f42cb8 100644
--- a/arch/arm/lib64/barebox.lds.S
+++ b/arch/arm/lib64/barebox.lds.S
@@ -29,12 +29,14 @@ SECTIONS
 	BAREBOX_BARE_INIT_SIZE
 
 	. = ALIGN(4);
+	__start_rodata = .;
 	.rodata : {
 		*(.rodata*)
 		RO_DATA_SECTION
 	}
 
-	_etext = .;			/* End of text and rodata section */
+	__end_rodata = .;
+	_etext = .;
 	_sdata = .;
 
 	. = ALIGN(4);
diff --git a/arch/kvx/cpu/barebox.lds.S b/arch/kvx/cpu/barebox.lds.S
index 1edaeae18824..b05c1f36e595 100644
--- a/arch/kvx/cpu/barebox.lds.S
+++ b/arch/kvx/cpu/barebox.lds.S
@@ -45,13 +45,16 @@ SECTIONS
 		KEEP(*(.exception.syscall));
 	}
 
+	__start_rodata = .;
+
 	.rodata ALIGN(8) : {
 		*(.rodata*)
 		. = ALIGN(8);
 		RO_DATA_SECTION
 	}
 
-	_etext = .; /* End of text and rodata section */
+	__end_rodata = .;
+	_etext = .;
 
 	.data ALIGN(4): {
 		sdata = .;
diff --git a/arch/mips/lib/barebox.lds.S b/arch/mips/lib/barebox.lds.S
index 0720f9295dff..bbb9b114993d 100644
--- a/arch/mips/lib/barebox.lds.S
+++ b/arch/mips/lib/barebox.lds.S
@@ -29,12 +29,14 @@ SECTIONS
 	PRE_IMAGE
 
 	. = ALIGN(4);
+	__start_rodata = .;
 	.rodata : {
 		*(.rodata*)
 		RO_DATA_SECTION
 	}
 
-	_etext = .;			/* End of text and rodata section */
+	__end_rodata = .;
+	_etext = .;
 	_sdata = .;
 
 	. = ALIGN(4);
diff --git a/arch/mips/lib/pbl.lds.S b/arch/mips/lib/pbl.lds.S
index 4cf0398f33d1..cca980c35fdf 100644
--- a/arch/mips/lib/pbl.lds.S
+++ b/arch/mips/lib/pbl.lds.S
@@ -32,11 +32,13 @@ SECTIONS
 	BAREBOX_BARE_INIT_SIZE
 
 	. = ALIGN(4);
+	__start_rodata = .;
 	.rodata : { *(.rodata*) }
 
 	.barebox_imd : { BAREBOX_IMD }
 
-	_etext = .;			/* End of text and rodata section */
+	__end_rodata = .;
+	_etext = .;
 
 	. = ALIGN(4);
 	.data : { *(.data*) }
diff --git a/arch/mips/pbl/zbarebox.lds.S b/arch/mips/pbl/zbarebox.lds.S
index e3114dfe2230..97d77229b6fb 100644
--- a/arch/mips/pbl/zbarebox.lds.S
+++ b/arch/mips/pbl/zbarebox.lds.S
@@ -29,11 +29,13 @@ SECTIONS
 	BAREBOX_BARE_INIT_SIZE
 
 	. = ALIGN(4);
+	__start_rodata = .;
 	.rodata : { *(.rodata*) }
 
 	.barebox_imd : { BAREBOX_IMD }
 
-	_etext = .;			/* End of text and rodata section */
+	__end_rodata = .;
+	_etext = .;
 
 	. = ALIGN(4);
 	.data : { *(.data*) }
diff --git a/arch/openrisc/cpu/barebox.lds.S b/arch/openrisc/cpu/barebox.lds.S
index 3fae1af37594..26bb622edc27 100644
--- a/arch/openrisc/cpu/barebox.lds.S
+++ b/arch/openrisc/cpu/barebox.lds.S
@@ -46,6 +46,7 @@ SECTIONS
 	}  > ram
 
 	. = ALIGN(4);
+	__start_rodata = .;
 	.rodata : {
 		*(.rodata);
 		*(.rodata.*)
@@ -53,7 +54,8 @@ SECTIONS
 		RO_DATA_SECTION
 	} > ram
 
-	__etext = .; /* End of text and rodata section */
+	__end_rodata = .;
+	__etext = .;
 
 	. = ALIGN(4);
 	.data : {
diff --git a/arch/powerpc/boards/pcm030/barebox.lds.S b/arch/powerpc/boards/pcm030/barebox.lds.S
index 146b63fe8889..07c2a671a8a9 100644
--- a/arch/powerpc/boards/pcm030/barebox.lds.S
+++ b/arch/powerpc/boards/pcm030/barebox.lds.S
@@ -32,6 +32,7 @@ SECTIONS
     *(.text*)
     *(.got1*)
     . = ALIGN(16);
+    __start_rodata = .;
     *(.rodata*)
     *(.rodata1*)
     *(.rodata.str1.4)
@@ -70,6 +71,7 @@ SECTIONS
 
   /* Read-write section, merged into data segment: */
   . = (. + 0x0FFF) & 0xFFFFF000;
+  __end_rodata = .;
   _etext = .;
   PROVIDE (erotext = .);
   _sdata = .;
diff --git a/arch/powerpc/mach-mpc85xx/barebox.lds.S b/arch/powerpc/mach-mpc85xx/barebox.lds.S
index 6e348d4db363..5407ecc7e295 100644
--- a/arch/powerpc/mach-mpc85xx/barebox.lds.S
+++ b/arch/powerpc/mach-mpc85xx/barebox.lds.S
@@ -68,6 +68,7 @@ SECTIONS
     PROVIDE (etext = .);
     _sdata = .;
 
+    __start_rodata = .;
    .barebox_imd : { BAREBOX_IMD }
 
    .rodata    :
@@ -79,6 +80,7 @@ SECTIONS
   /* Read-write section, merged into data segment: */
   . = (. + 0x00FF) & 0xFFFFFF00;
 
+  __end_rodata = .;
   _erotext = .;
   PROVIDE (erotext = .);
   .reloc   :
diff --git a/arch/riscv/lib/barebox.lds.S b/arch/riscv/lib/barebox.lds.S
index 101615ab052a..2d220e48142b 100644
--- a/arch/riscv/lib/barebox.lds.S
+++ b/arch/riscv/lib/barebox.lds.S
@@ -39,12 +39,14 @@ SECTIONS
 	BAREBOX_BARE_INIT_SIZE
 
 	. = ALIGN(4);
+	__start_rodata = .;
 	.rodata : {
 		*(.rodata*)
 		RO_DATA_SECTION
 	}
 
-	_etext = .;			/* End of text and rodata section */
+	__end_rodata = .;
+	_etext = .;
 	_sdata = .;
 
 	. = ALIGN(4);
diff --git a/arch/riscv/lib/pbl.lds.S b/arch/riscv/lib/pbl.lds.S
index 0fe7dfda8eb4..3a37d01475b2 100644
--- a/arch/riscv/lib/pbl.lds.S
+++ b/arch/riscv/lib/pbl.lds.S
@@ -29,11 +29,13 @@ SECTIONS
 	BAREBOX_PBL_SIZE
 
 	. = ALIGN(4);
+	__start_rodata = .;
 	.rodata : { *(.rodata*) }
 
 	.barebox_imd : { BAREBOX_IMD }
 
-	_etext = .;			/* End of text and rodata section */
+	__end_rodata = .;
+	_etext = .;
 
 	.data : { *(.data*) }
 
diff --git a/arch/sandbox/board/barebox.lds.S b/arch/sandbox/board/barebox.lds.S
index 0102b9333174..60bd9a533ce6 100644
--- a/arch/sandbox/board/barebox.lds.S
+++ b/arch/sandbox/board/barebox.lds.S
@@ -5,9 +5,11 @@
 SECTIONS
 {
 	. = ALIGN(64);
+	__start_rodata = .;
 	.barebox_rodata () : {
 		RO_DATA_SECTION
 	}
+	__end_rodata = .;
 }
 
 INSERT BEFORE .data;
diff --git a/arch/x86/mach-efi/elf_ia32_efi.lds.S b/arch/x86/mach-efi/elf_ia32_efi.lds.S
index 4b1300724300..0a3b6ef947b9 100644
--- a/arch/x86/mach-efi/elf_ia32_efi.lds.S
+++ b/arch/x86/mach-efi/elf_ia32_efi.lds.S
@@ -36,8 +36,10 @@ SECTIONS
 	_sdata = .;
 
 	.data : {
+		__start_rodata = .;
 		*(.rodata*)
 		RO_DATA_SECTION
+		__end_rodata = .;
 		*(.data)
 		*(.data1)
 		*(.data.*)
diff --git a/arch/x86/mach-efi/elf_x86_64_efi.lds.S b/arch/x86/mach-efi/elf_x86_64_efi.lds.S
index cb6a31101eab..ed2ddd52482a 100644
--- a/arch/x86/mach-efi/elf_x86_64_efi.lds.S
+++ b/arch/x86/mach-efi/elf_x86_64_efi.lds.S
@@ -39,8 +39,10 @@ SECTIONS
 	_sdata = .;
 
 	.data : {
+		__start_rodata = .;
 		*(.rodata*)
 		RO_DATA_SECTION
+		__end_rodata = .;
 		*(.got.plt)
 		*(.got)
 		*(.data*)
diff --git a/include/asm-generic/sections.h b/include/asm-generic/sections.h
index 0b2ed5615bd6..35b0dd8cac1a 100644
--- a/include/asm-generic/sections.h
+++ b/include/asm-generic/sections.h
@@ -3,7 +3,10 @@
 #ifndef _ASM_GENERIC_SECTIONS_H_
 #define _ASM_GENERIC_SECTIONS_H_
 
+#include <linux/types.h>
+
 extern char _text[], _stext[], _etext[];
+extern char __start_rodata[], __end_rodata[];
 extern char __bss_start[], __bss_stop[];
 extern char _sdata[], _edata[];
 extern char __bare_init_start[], __bare_init_end[];
@@ -21,4 +24,19 @@ extern char __ctors_start[], __ctors_end[];
 #define barebox_image_size	(__image_end - __image_start)
 #define barebox_bare_init_size	(unsigned int)&_barebox_bare_init_size
 #define barebox_pbl_size	(__piggydata_start - __image_start)
+
+/**
+ * is_barebox_rodata - checks if the pointer address is located in the
+ *                    .rodata section
+ *
+ * @addr: address to check
+ *
+ * Returns: true if the address is located in .rodata, false otherwise.
+ */
+static inline bool is_barebox_rodata(unsigned long addr)
+{
+	return addr >= (unsigned long)__start_rodata &&
+	       addr < (unsigned long)__end_rodata;
+}
+
 #endif /* _ASM_GENERIC_SECTIONS_H_ */
-- 
2.39.5




^ permalink raw reply	[flat|nested] 9+ messages in thread

* [PATCH 3/7] string: implement proper strdup_const/free_const
  2024-11-25 15:29 [PATCH 0/7] add proper strdup_const support Ahmad Fatoum
  2024-11-25 15:29 ` [PATCH 1/7] sandbox: hostfile: strdup device tree node names Ahmad Fatoum
  2024-11-25 15:29 ` [PATCH 2/7] lds: implement is_barebox_rodata Ahmad Fatoum
@ 2024-11-25 15:29 ` Ahmad Fatoum
  2024-11-25 15:29 ` [PATCH 4/7] treewide: replace basename with kbasename Ahmad Fatoum
                   ` (4 subsequent siblings)
  7 siblings, 0 replies; 9+ messages in thread
From: Ahmad Fatoum @ 2024-11-25 15:29 UTC (permalink / raw)
  To: barebox; +Cc: Ahmad Fatoum

We currently implement strdup_const as strdup, which is correct, but
leaves the benefits of a proper implementation on the table:
Reducing allocations for .rodata strings, which have static storage
duration anyway.

Let's implement it properly using the newly added is_barebox_rodata
and add free_const, dma_free_const and kfree_const that go along with
it.

There will be a slight difference to Linux in our API though: In Linux
devm_kfree can be used with devm_kstrdup_const, but kfree can't be used
with kstrdup_const and instead kfree_const needs to be used.

In barebox, we kfree and kfree_const is identical. This is because Linux
gives kfree a const void * parameter and we have existing code that uses
const pointers to the heap and passes them to kfree and it's not worth
risking memory corruption in this case.

Signed-off-by: Ahmad Fatoum <a.fatoum@pengutronix.de>
---
 include/dma.h          |  5 +++++
 include/linux/slab.h   |  7 ++++---
 include/linux/string.h |  5 +++++
 lib/string.c           | 28 ++++++++++++++++++++++++++++
 4 files changed, 42 insertions(+), 3 deletions(-)

diff --git a/include/dma.h b/include/dma.h
index 1f650aecb950..5877f4b13c0d 100644
--- a/include/dma.h
+++ b/include/dma.h
@@ -46,6 +46,11 @@ static inline void dma_free(void *mem)
 	free(mem);
 }
 
+static inline void dma_free_const(const void *mem)
+{
+	free_const(mem);
+}
+
 static inline void dma_free_sensitive(void *mem)
 {
 	free_sensitive(mem);
diff --git a/include/linux/slab.h b/include/linux/slab.h
index 5e08c7697daf..93ce25a58299 100644
--- a/include/linux/slab.h
+++ b/include/linux/slab.h
@@ -59,9 +59,11 @@ static inline void kmem_cache_destroy(struct kmem_cache *cache)
 
 static inline void kfree(const void *mem)
 {
-	dma_free((void *)mem);
+	dma_free_const(mem);
 }
 
+#define kfree_const(ptr) dma_free_const(ptr)
+
 static inline void kfree_sensitive(const void *objp)
 {
 	dma_free_sensitive((void *)objp);
@@ -112,7 +114,6 @@ static inline char *kstrdup(const char *str, gfp_t flags)
 	return strdup(str);
 }
 
-#define kstrdup_const(str, flags) strdup(str)
-#define kfree_const(ptr) kfree((void *)ptr)
+#define kstrdup_const(str, flags) strdup_const(str)
 
 #endif /* _LINUX_SLAB_H */
diff --git a/include/linux/string.h b/include/linux/string.h
index 5d5824b61bf0..0fa84f095e02 100644
--- a/include/linux/string.h
+++ b/include/linux/string.h
@@ -93,6 +93,11 @@ extern __kernel_size_t strnlen(const char *,__kernel_size_t);
 #ifndef __HAVE_ARCH_STRDUP
 extern char * strdup(const char *);
 #endif
+
+extern void free_const(const void *x);
+extern const char *strdup_const(const char *s);
+const char *xstrdup_const(const char *s);
+
 #ifndef __HAVE_ARCH_STRNDUP
 extern char *strndup(const char *, size_t);
 #endif
diff --git a/lib/string.c b/lib/string.c
index cab543baf38d..f2272be37e76 100644
--- a/lib/string.c
+++ b/lib/string.c
@@ -24,6 +24,7 @@
 #include <linux/ctype.h>
 #include <asm/word-at-a-time.h>
 #include <malloc.h>
+#include <asm-generic/sections.h>
 
 #ifndef __HAVE_ARCH_STRCASECMP
 int strcasecmp(const char *s1, const char *s2)
@@ -1055,6 +1056,33 @@ char *strjoin(const char *separator, char **arr, size_t arrlen)
 }
 EXPORT_SYMBOL(strjoin);
 
+const char *xstrdup_const(const char *str)
+{
+	if (is_barebox_rodata((ulong)str))
+		return str;
+
+	return xstrdup(str);
+}
+EXPORT_SYMBOL(xstrdup_const);
+
+const char *strdup_const(const char *str)
+{
+	if (is_barebox_rodata((ulong)str))
+		return str;
+
+	return strdup(str);
+}
+EXPORT_SYMBOL(strdup_const);
+
+void free_const(const void *str)
+{
+	if (is_barebox_rodata((ulong)str))
+		return;
+
+	free((void *)str);
+}
+EXPORT_SYMBOL(free_const);
+
 /**
  * strreplace - Replace all occurrences of character in string.
  * @str: The string to operate on.
-- 
2.39.5




^ permalink raw reply	[flat|nested] 9+ messages in thread

* [PATCH 4/7] treewide: replace basename with kbasename
  2024-11-25 15:29 [PATCH 0/7] add proper strdup_const support Ahmad Fatoum
                   ` (2 preceding siblings ...)
  2024-11-25 15:29 ` [PATCH 3/7] string: implement proper strdup_const/free_const Ahmad Fatoum
@ 2024-11-25 15:29 ` Ahmad Fatoum
  2024-11-25 15:29 ` [PATCH 5/7] treewide: use strdup_const where appropriate Ahmad Fatoum
                   ` (3 subsequent siblings)
  7 siblings, 0 replies; 9+ messages in thread
From: Ahmad Fatoum @ 2024-11-25 15:29 UTC (permalink / raw)
  To: barebox; +Cc: Ahmad Fatoum

barebox has three functions for basename():

  - posix_basename: This is basename() as specified by POSIX and
    may modify the buffer pointed at by its char * argument.

  - kbasename: The Linux kernel version never modifies the input and
    takes a const char * to indicate this

  - basename: The GNU version of basename behaves like the kernel
    version, but takes a char * as argument, which is internally casted
    away.

Let's improve const-safety in barebox by explicitly using kbasename.

Signed-off-by: Ahmad Fatoum <a.fatoum@pengutronix.de>
---
 commands/nand.c      | 4 ++--
 commands/partition.c | 6 +++---
 commands/tftp.c      | 5 +++--
 common/boot.c        | 2 +-
 common/complete.c    | 8 ++++----
 fs/bpkfs.c           | 8 ++++----
 net/nfs.c            | 8 ++++----
 7 files changed, 21 insertions(+), 20 deletions(-)

diff --git a/commands/nand.c b/commands/nand.c
index d80ec24a7b92..d756092c64c0 100644
--- a/commands/nand.c
+++ b/commands/nand.c
@@ -71,7 +71,7 @@ static int do_nand(int argc, char *argv[])
 
 	if (command == NAND_ADD) {
 		while (optind < argc) {
-			if (dev_add_bb_dev(basename(argv[optind]), NULL))
+			if (dev_add_bb_dev(kbasename(argv[optind]), NULL))
 				return 1;
 
 			optind++;
@@ -82,7 +82,7 @@ static int do_nand(int argc, char *argv[])
 
 	if (command == NAND_DEL) {
 		while (optind < argc) {
-			if (dev_remove_bb_dev(basename(argv[optind])))
+			if (dev_remove_bb_dev(kbasename(argv[optind])))
 				return 1;
 			optind++;
 		}
diff --git a/commands/partition.c b/commands/partition.c
index 14f400ccb433..1b655f853b3b 100644
--- a/commands/partition.c
+++ b/commands/partition.c
@@ -27,7 +27,7 @@
 
 static int do_addpart(int argc, char *argv[])
 {
-	char *devname;
+	const char *devname;
 	loff_t devsize;
 	struct stat s;
 	int opt;
@@ -50,7 +50,7 @@ static int do_addpart(int argc, char *argv[])
 	}
 	devsize = s.st_size;
 
-	devname = basename(argv[optind]);
+	devname = kbasename(argv[optind]);
 
 	return cmdlinepart_do_parse(devname, argv[optind + 1], devsize, flags);
 }
@@ -84,7 +84,7 @@ static int do_delpart(int argc, char *argv[])
 	int i, err;
 
 	for (i = 1; i < argc; i++) {
-		err = devfs_del_partition(basename(argv[i]));
+		err = devfs_del_partition(kbasename(argv[i]));
 		if (err) {
 			printf("cannot delete %s: %s\n", argv[i], strerror(-err));
 			break;
diff --git a/commands/tftp.c b/commands/tftp.c
index 6ac822c9e832..5e8d8d17761d 100644
--- a/commands/tftp.c
+++ b/commands/tftp.c
@@ -18,7 +18,8 @@
 
 static int do_tftpb(int argc, char *argv[])
 {
-	char *source, *dest, *freep;
+	const char *source, *dest;
+	char *freep;
 	int opt;
 	int tftp_push = 0;
 	int port = -1;
@@ -50,7 +51,7 @@ static int do_tftpb(int argc, char *argv[])
 	source = argv[optind++];
 
 	if (argc == optind)
-		dest = basename(source);
+		dest = kbasename(source);
 	else
 		dest = argv[optind];
 
diff --git a/common/boot.c b/common/boot.c
index cbfe6649b3a3..89eb7a974566 100644
--- a/common/boot.c
+++ b/common/boot.c
@@ -204,7 +204,7 @@ static int bootscript_create_entry(struct bootentries *bootentries, const char *
 	bs->entry.release = bootscript_entry_release;
 	bs->entry.boot = bootscript_boot;
 	bs->scriptpath = xstrdup(name);
-	bs->entry.title = xstrdup(basename(bs->scriptpath));
+	bs->entry.title = xstrdup(kbasename(bs->scriptpath));
 	bs->entry.description = basprintf("script: %s", name);
 	bootentries_add_entry(bootentries, &bs->entry);
 
diff --git a/common/complete.c b/common/complete.c
index 3911535621b1..5b8b499ed38f 100644
--- a/common/complete.c
+++ b/common/complete.c
@@ -43,9 +43,9 @@ static int file_complete(struct string_list *sl, char *instr,
 	DIR *dir;
 	struct dirent *d;
 	char tmp[PATH_MAX];
-	char *base;
+	const char *base;
 
-	base = basename(instr);
+	base = kbasename(instr);
 	dirn = dirn ?: dirname(path);
 
 	dir = opendir(dirn);
@@ -236,12 +236,12 @@ EXPORT_SYMBOL(devicetree_alias_complete);
 int devicetree_nodepath_complete(struct string_list *sl, char *instr)
 {
 	struct device_node *node, *child;
-	char *dirn, *base;
+	const char *dirn, *base;
 	char *path = strdup(instr);
 
 	if (*instr == '/') {
 		dirn = dirname(path);
-		base = basename(instr);
+		base = kbasename(instr);
 		node = of_find_node_by_path(dirn);
 		if (!node)
 			goto out;
diff --git a/fs/bpkfs.c b/fs/bpkfs.c
index ea2c27958520..7b714de66158 100644
--- a/fs/bpkfs.c
+++ b/fs/bpkfs.c
@@ -132,7 +132,7 @@ static int bpkfs_open(struct device *dev, FILE *f, const char *filename)
 	struct bpkfs_handle *priv = dev->priv;
 	struct bpkfs_handle_data *d;
 	struct bpkfs_handle_hw *h;
-	char *dir, *file;
+	const char *dir, *file;
 	int ret = -EINVAL;
 	char *tmp = xstrdup(filename);
 	char *tmp2 = xstrdup(filename);
@@ -146,7 +146,7 @@ static int bpkfs_open(struct device *dev, FILE *f, const char *filename)
 	if (!h)
 		goto out;
 
-	file = basename(tmp2);
+	file = kbasename(tmp2);
 	d = bpkfs_data_get_by_name(h, file);
 	if (!d)
 		goto out;
@@ -284,7 +284,7 @@ static int bpkfs_stat(struct device *dev, const char *filename,
 	struct bpkfs_handle *priv = dev->priv;
 	struct bpkfs_handle_data *d;
 	struct bpkfs_handle_hw *h;
-	char *dir, *file;
+	const char *dir, *file;
 	int ret = -EINVAL;
 	char *tmp = xstrdup(filename);
 	char *tmp2 = xstrdup(filename);
@@ -311,7 +311,7 @@ static int bpkfs_stat(struct device *dev, const char *filename,
 	if (!h)
 		goto out;
 
-	file = basename(tmp2);
+	file = kbasename(tmp2);
 	d = bpkfs_data_get_by_name(h, file);
 	if (!d)
 		goto out;
diff --git a/net/nfs.c b/net/nfs.c
index df0840e4e7dc..68c35e11f6a9 100644
--- a/net/nfs.c
+++ b/net/nfs.c
@@ -147,7 +147,7 @@ static int	nfs_state;
 #define STATE_READLINK_REQ		7
 #define STATE_DONE			8
 
-static char *nfs_filename;
+static const char *nfs_filename;
 static char *nfs_path;
 static char nfs_path_buff[2048];
 
@@ -322,7 +322,7 @@ static void nfs_readlink_req(void)
 /**************************************************************************
 NFS_LOOKUP - Lookup Pathname
 **************************************************************************/
-static void nfs_lookup_req(char *fname)
+static void nfs_lookup_req(const char *fname)
 {
 	uint32_t data[1024];
 	uint32_t *p;
@@ -621,7 +621,7 @@ static void nfs_handler(void *ctx, char *packet, unsigned len)
 
 		debug("Symlink --> %s\n", nfs_path);
 
-		nfs_filename = basename(nfs_path);
+		nfs_filename = kbasename(nfs_path);
 		nfs_path     = dirname(nfs_path);
 
 		nfs_state = STATE_MOUNT_REQ;
@@ -664,7 +664,7 @@ static void nfs_start(char *p)
 
 	strcpy(nfs_path, p);
 
-	nfs_filename = basename (nfs_path);
+	nfs_filename = kbasename (nfs_path);
 	nfs_path     = dirname (nfs_path);
 
 	printf("\nFilename '%s/%s'.\n", nfs_path, nfs_filename);
-- 
2.39.5




^ permalink raw reply	[flat|nested] 9+ messages in thread

* [PATCH 5/7] treewide: use strdup_const where appropriate
  2024-11-25 15:29 [PATCH 0/7] add proper strdup_const support Ahmad Fatoum
                   ` (3 preceding siblings ...)
  2024-11-25 15:29 ` [PATCH 4/7] treewide: replace basename with kbasename Ahmad Fatoum
@ 2024-11-25 15:29 ` Ahmad Fatoum
  2024-11-25 15:29 ` [PATCH 6/7] fs: efi: replace allocation with local buffer Ahmad Fatoum
                   ` (2 subsequent siblings)
  7 siblings, 0 replies; 9+ messages in thread
From: Ahmad Fatoum @ 2024-11-25 15:29 UTC (permalink / raw)
  To: barebox; +Cc: Ahmad Fatoum

There are many places where we are using strdup and end up often
duplicating strings, when all we needed is extending lifetime of
some of the strings.

Let's make use of strdup_const instead.

Signed-off-by: Ahmad Fatoum <a.fatoum@pengutronix.de>
---
 commands/magicvar.c            | 12 +++++------
 commands/menu.c                |  6 +++---
 commands/of_property.c         | 12 +++++------
 common/blspec.c                |  8 +++----
 common/boot.c                  | 24 ++++++++++-----------
 common/bootchooser.c           |  6 +++---
 common/elf.c                   |  2 +-
 common/env.c                   | 28 ++++++++++++-------------
 common/file-list.c             | 14 ++++++++-----
 common/globalvar.c             |  4 ++--
 common/menu.c                  | 38 ++++++++++++++++++----------------
 common/menutree.c              |  4 ++--
 common/poller.c                |  4 ++--
 common/resource.c              |  8 +++----
 common/restart.c               |  2 +-
 common/slice.c                 |  4 ++--
 common/state/backend_storage.c |  4 ++--
 common/state/state.h           |  2 +-
 common/state/state_variables.c |  4 ++--
 drivers/led/led-gpio.c         |  6 +++---
 drivers/led/led-pwm.c          |  2 +-
 drivers/nvmem/core.c           |  4 ++--
 drivers/of/base.c              | 12 +++++------
 drivers/of/of_net.c            |  2 +-
 drivers/regulator/core.c       |  4 ++--
 drivers/soc/kvx/kvx_socinfo.c  |  2 +-
 include/blspec.h               |  4 ++--
 include/boot.h                 |  2 +-
 include/console.h              |  2 +-
 include/digest.h               |  4 ++--
 include/elf.h                  |  2 +-
 include/environment.h          |  8 +++----
 include/file-list.h            |  4 ++--
 include/led.h                  |  2 +-
 include/linux/clk.h            |  4 +++-
 include/mci.h                  |  2 +-
 include/menu.h                 | 20 +++++++++++-------
 include/net.h                  |  2 +-
 include/of.h                   |  6 +++---
 include/param.h                |  2 +-
 include/poller.h               |  2 +-
 include/slice.h                |  2 +-
 include/stringlist.h           |  4 ++--
 lib/glob.c                     | 19 ++++++++++-------
 lib/parameter.c                |  6 +++---
 lib/stringlist.c               |  6 +++---
 net/eth.c                      |  4 ++--
 scripts/checkpatch.pl          |  2 +-
 48 files changed, 171 insertions(+), 156 deletions(-)

diff --git a/commands/magicvar.c b/commands/magicvar.c
index 01acc741ac5d..02a9237b1da9 100644
--- a/commands/magicvar.c
+++ b/commands/magicvar.c
@@ -10,8 +10,8 @@
 static LIST_HEAD(magicvars);
 
 struct magicvar_dyn {
-	char *name;
-	char *description;
+	const char *name;
+	const char *description;
 	struct list_head list;
 };
 
@@ -39,8 +39,8 @@ static struct magicvar_dyn *magicvar_find(const char *name)
 
 static void magicvar_remove(struct magicvar_dyn *md)
 {
-	free(md->name);
-	free(md->description);
+	free_const(md->name);
+	free_const(md->description);
 	list_del(&md->list);
 	free(md);
 }
@@ -62,8 +62,8 @@ static int magicvar_add(const char *name, const char *description)
 		magicvar_remove(md);
 
 	md = xzalloc(sizeof(*md));
-	md->name = xstrdup(name);
-	md->description = xstrdup(description);
+	md->name = xstrdup_const(name);
+	md->description = xstrdup_const(description);
 
 	list_add_sort(&md->list, &magicvars, compare);
 
diff --git a/commands/menu.c b/commands/menu.c
index e0fe09b5088b..b715d85c123f 100644
--- a/commands/menu.c
+++ b/commands/menu.c
@@ -128,7 +128,7 @@ static int do_menu_add(struct cmd_menu *cm)
 	if (!m)
 		goto free;
 
-	m->name = strdup(cm->menu);
+	m->name = strdup_const(cm->menu);
 	if (!m->name)
 		goto free;
 
@@ -216,9 +216,9 @@ static int do_menu_show(struct cmd_menu *cm)
 	if (cm->auto_select != -EINVAL) {
 		menu_set_auto_select(m, cm->auto_select);
 
-		free(m->auto_display);
+		free_const(m->auto_display);
 
-		m->auto_display = strdup(cm->description);
+		m->auto_display = strdup_const(cm->description);
 	}
 
 	return menu_show(m);
diff --git a/commands/of_property.c b/commands/of_property.c
index 0c914c55c6bf..c1c2b343bccc 100644
--- a/commands/of_property.c
+++ b/commands/of_property.c
@@ -187,8 +187,8 @@ static int of_parse_prop(struct device_node *root, char * const *newval, int cou
 }
 
 struct of_fixup_property_data {
-	char *path;
-	char *propname;
+	const char *path;
+	const char *propname;
 	void *data;
 	int len;
 };
@@ -219,8 +219,8 @@ static int do_of_property_set_fixup(const char *path, const char *propname,
 	struct of_fixup_property_data *fixup;
 
 	fixup = xzalloc(sizeof(*fixup));
-	fixup->path = xstrdup(path);
-	fixup->propname = xstrdup(propname);
+	fixup->path = xstrdup_const(path);
+	fixup->propname = xstrdup_const(propname);
 	fixup->data = data;
 	fixup->len = len;
 
@@ -232,8 +232,8 @@ static int do_of_property_delete_fixup(const char *path, const char *propname)
 	struct of_fixup_property_data *fixup;
 
 	fixup = xzalloc(sizeof(*fixup));
-	fixup->path = xstrdup(path);
-	fixup->propname = xstrdup(propname);
+	fixup->path = xstrdup_const(path);
+	fixup->propname = xstrdup_const(propname);
 	fixup->data = NULL;
 	fixup->len = 0;
 
diff --git a/common/blspec.c b/common/blspec.c
index 23a24c63db15..ea334e18718a 100644
--- a/common/blspec.c
+++ b/common/blspec.c
@@ -186,8 +186,8 @@ static void blspec_entry_free(struct bootentry *be)
 	struct blspec_entry *entry = container_of(be, struct blspec_entry, entry);
 
 	of_delete_node(entry->node);
-	free(entry->configpath);
-	free(entry->rootpath);
+	free_const(entry->configpath);
+	free_const(entry->rootpath);
 	free(entry);
 }
 
@@ -517,8 +517,8 @@ int blspec_scan_file(struct bootentries *bootentries, const char *root,
 		return PTR_ERR(entry);
 
 	root = root ?: get_mounted_path(configname);
-	entry->rootpath = xstrdup(root);
-	entry->configpath = xstrdup(configname);
+	entry->rootpath = xstrdup_const(root);
+	entry->configpath = xstrdup_const(configname);
 	entry->cdev = get_cdev_by_mountpath(root);
 
 	if (!entry_is_of_compatible(entry)) {
diff --git a/common/boot.c b/common/boot.c
index 89eb7a974566..f6ac4779cc33 100644
--- a/common/boot.c
+++ b/common/boot.c
@@ -44,17 +44,17 @@ void bootentries_free(struct bootentries *bootentries)
 
 	list_for_each_entry_safe(be, tmp, &bootentries->entries, list) {
 		list_del(&be->list);
-		free(be->title);
+		free_const(be->title);
 		free(be->description);
-		free(be->me.display);
+		free_const(be->me.display);
 		be->release(be);
 	}
 
 	if (bootentries->menu) {
 		int i;
 		for (i = 0; i < bootentries->menu->display_lines; i++)
-			free(bootentries->menu->display[i]);
-		free(bootentries->menu->display);
+			free_const(bootentries->menu->display[i]);
+		free_const(bootentries->menu->display);
 	}
 	free(bootentries->menu);
 	free(bootentries);
@@ -62,7 +62,7 @@ void bootentries_free(struct bootentries *bootentries)
 
 struct bootentry_script {
 	struct bootentry entry;
-	char *scriptpath;
+	const char *scriptpath;
 };
 
 /*
@@ -179,7 +179,7 @@ static void bootscript_entry_release(struct bootentry *entry)
 {
 	struct bootentry_script *bs = container_of(entry, struct bootentry_script, entry);
 
-	free(bs->scriptpath);
+	free_const(bs->scriptpath);
 	free(bs);
 }
 
@@ -203,8 +203,8 @@ static int bootscript_create_entry(struct bootentries *bootentries, const char *
 	bs->entry.me.type = MENU_ENTRY_NORMAL;
 	bs->entry.release = bootscript_entry_release;
 	bs->entry.boot = bootscript_boot;
-	bs->scriptpath = xstrdup(name);
-	bs->entry.title = xstrdup(kbasename(bs->scriptpath));
+	bs->scriptpath = xstrdup_const(name);
+	bs->entry.title = xstrdup_const(kbasename(bs->scriptpath));
 	bs->entry.description = basprintf("script: %s", name);
 	bootentries_add_entry(bootentries, &bs->entry);
 
@@ -305,18 +305,18 @@ int bootentry_create_from_name(struct bootentries *bootentries,
 	}
 
 	if (IS_ENABLED(CONFIG_COMMAND_SUPPORT) && !found) {
-		char *path;
+		const char *path;
 
 		if (*name != '/')
 			path = basprintf("/env/boot/%s", name);
 		else
-			path = xstrdup(name);
+			path = xstrdup_const(name);
 
 		ret = bootscript_scan_path(bootentries, path);
 		if (ret > 0)
 			found += ret;
 
-		free(path);
+		free_const(path);
 	}
 
 	return found;
@@ -339,7 +339,7 @@ void bootsources_menu(struct bootentries *bootentries,
 
 	bootentries_for_each_entry(bootentries, entry) {
 		if (!entry->me.display)
-			entry->me.display = xstrdup(entry->title);
+			entry->me.display = xstrdup_const(entry->title);
 		entry->me.action = bootsource_action;
 		menu_add_entry(bootentries->menu, &entry->me);
 
diff --git a/common/bootchooser.c b/common/bootchooser.c
index 65291c5e59d3..ed3db0092ddb 100644
--- a/common/bootchooser.c
+++ b/common/bootchooser.c
@@ -64,7 +64,7 @@ struct bootchooser_target {
 	int id;
 
 	/* spec */
-	char *name;
+	const char *name;
 	unsigned int default_attempts;
 	unsigned int default_priority;
 
@@ -228,7 +228,7 @@ static struct bootchooser_target *bootchooser_target_new(struct bootchooser *bc,
 	const char *val;
 	int ret;
 
-	target->name = xstrdup(name);
+	target->name = xstrdup_const(name);
 	target->prefix = basprintf("%s.%s", BOOTCHOOSER_PREFIX, name);
 	target->state_prefix = basprintf("%s.%s", bc->state_prefix, name);
 	target->default_attempts = global_default_attempts;
@@ -574,7 +574,7 @@ int bootchooser_put(struct bootchooser *bc)
 		free(target->boot);
 		free(target->prefix);
 		free(target->state_prefix);
-		free(target->name);
+		free_const(target->name);
 		free(target);
 	}
 
diff --git a/common/elf.c b/common/elf.c
index 62f793010fad..ec78e45bf180 100644
--- a/common/elf.c
+++ b/common/elf.c
@@ -340,7 +340,7 @@ void elf_close(struct elf_image *elf)
 
 	if (elf->filename) {
 		free(elf->hdr_buf);
-		free(elf->filename);
+		free_const(elf->filename);
 	}
 
 	free(elf);
diff --git a/common/env.c b/common/env.c
index 1e57e09e9de7..e34e3ac078d6 100644
--- a/common/env.c
+++ b/common/env.c
@@ -35,15 +35,15 @@ static void free_context(struct env_context *c)
 	struct variable_d *v, *tmp;
 
 	list_for_each_entry_safe(v, tmp, &c->local, list) {
-		free(v->name);
-		free(v->data);
+		free_const(v->name);
+		free_const(v->data);
 		list_del(&v->list);
 		free(v);
 	}
 
 	list_for_each_entry_safe(v, tmp, &c->global, list) {
-		free(v->name);
-		free(v->data);
+		free_const(v->name);
+		free_const(v->data);
 		list_del(&v->list);
 		free(v);
 	}
@@ -96,7 +96,7 @@ int env_pop_context(void)
  * @param[in] var Variable of interest
  * @return Value as text
  */
-char *var_val(struct variable_d *var)
+const char *var_val(struct variable_d *var)
 {
 	return var->data;
 }
@@ -106,7 +106,7 @@ char *var_val(struct variable_d *var)
  * @param[in] var Variable of interest
  * @return Name as text
  */
-char *var_name(struct variable_d *var)
+const char *var_name(struct variable_d *var)
 {
 	return var->name;
 }
@@ -186,14 +186,14 @@ static int setenv_raw(struct list_head *l, const char *name, const char *value)
 	list_for_each_entry(v, l, list) {
 		if (!strcmp(v->name, name)) {
 			if (value) {
-				free(v->data);
-				v->data = xstrdup(value);
+				free_const(v->data);
+				v->data = xstrdup_const(value);
 
 				return 0;
 			} else {
 				list_del(&v->list);
-				free(v->name);
-				free(v->data);
+				free_const(v->name);
+				free_const(v->data);
 				free(v);
 
 				return 0;
@@ -203,8 +203,8 @@ static int setenv_raw(struct list_head *l, const char *name, const char *value)
 
 	if (value) {
 		v = xzalloc(sizeof(*v));
-		v->name = xstrdup(name);
-		v->data = xstrdup(value);
+		v->name = xstrdup_const(name);
+		v->data = xstrdup_const(value);
 		list_add_tail(&v->list, l);
 	}
 
@@ -252,7 +252,7 @@ static int dev_setenv(const char *name, const char *val)
  */
 int setenv(const char *_name, const char *value)
 {
-	char *name = strdup(_name);
+	const char *name = strdup_const(_name);
 	int ret = 0;
 	struct list_head *list;
 	const char *dot;
@@ -278,7 +278,7 @@ int setenv(const char *_name, const char *value)
 
 	ret = setenv_raw(list, name, value);
 out:
-	free(name);
+	free_const(name);
 
 	return ret;
 }
diff --git a/common/file-list.c b/common/file-list.c
index 3867e79c0972..40ccfa97ec44 100644
--- a/common/file-list.c
+++ b/common/file-list.c
@@ -27,7 +27,9 @@ struct file_list_entry *file_list_entry_by_name(struct file_list *files, const c
 	return NULL;
 }
 
-static int __file_list_add_entry(struct file_list *files, char *name, char *filename,
+static int __file_list_add_entry(struct file_list *files,
+				 const char *name,
+				 const char *filename,
 				 unsigned long flags)
 {
 	struct file_list_entry *entry;
@@ -50,13 +52,15 @@ static int __file_list_add_entry(struct file_list *files, char *name, char *file
 int file_list_add_entry(struct file_list *files, const char *name, const char *filename,
 			unsigned long flags)
 {
-	return __file_list_add_entry(files, xstrdup(name), xstrdup(filename), flags);
+	return __file_list_add_entry(files,
+				     xstrdup_const(name), xstrdup_const(filename),
+				     flags);
 }
 
 int file_list_add_cdev_entry(struct file_list *files, struct cdev *cdev,
 			     unsigned long flags)
 {
-	return __file_list_add_entry(files, xstrdup(cdev->name),
+	return __file_list_add_entry(files, xstrdup_const(cdev->name),
 				     xasprintf("/dev/%s", cdev->name), flags);
 }
 
@@ -227,8 +231,8 @@ void file_list_free(struct file_list *files)
 		return;
 
 	list_for_each_entry_safe(entry, tmp, &files->list, list) {
-		free(entry->name);
-		free(entry->filename);
+		free_const(entry->name);
+		free_const(entry->filename);
 		free(entry);
 	}
 
diff --git a/common/globalvar.c b/common/globalvar.c
index ab224a27a130..5f5b7d44ae62 100644
--- a/common/globalvar.c
+++ b/common/globalvar.c
@@ -189,7 +189,7 @@ static int nv_set(struct device *dev, struct param_d *p, const char *name,
 	}
 
 	if (p) {
-		free(p->value);
+		free_const(p->value);
 		p->value = xstrdup(val);
 	}
 
@@ -246,7 +246,7 @@ static int __nvvar_add(const char *name, const char *value)
 		value = dev_get_param(&global_device, name);
 
 	if (value && p) {
-		free(p->value);
+		free_const(p->value);
 		p->value = xstrdup(value);
 	}
 
diff --git a/common/menu.c b/common/menu.c
index 4007c476c3d9..128043c225df 100644
--- a/common/menu.c
+++ b/common/menu.c
@@ -34,11 +34,11 @@ void menu_free(struct menu *m)
 
 	if (!m)
 		return;
-	free(m->name);
+	free_const(m->name);
 	for (i = 0; i < m->display_lines; i++)
-		free(m->display[i]);
+		free_const(m->display[i]);
 	free(m->display);
-	free(m->auto_display);
+	free_const(m->auto_display);
 
 	list_for_each_entry_safe(me, tmp, &m->entries, list)
 		menu_entry_free(me);
@@ -98,7 +98,7 @@ void menu_remove_entry(struct menu *m, struct menu_entry *me)
 }
 EXPORT_SYMBOL(menu_remove_entry);
 
-struct menu* menu_get_by_name(char *name)
+struct menu* menu_get_by_name(const char *name)
 {
 	struct menu* m;
 
@@ -387,7 +387,7 @@ void menu_action_exit(struct menu *m, struct menu_entry *me) {}
 EXPORT_SYMBOL(menu_action_exit);
 
 struct submenu {
-	char *submenu;
+	const char *submenu;
 	struct menu_entry entry;
 };
 
@@ -410,12 +410,14 @@ static void submenu_free(struct menu_entry *me)
 {
 	struct submenu *s = container_of(me, struct submenu, entry);
 
-	free(s->entry.display);
-	free(s->submenu);
+	free_const(s->entry.display);
+	free_const(s->submenu);
 	free(s);
 }
 
-struct menu_entry *menu_add_submenu(struct menu *parent, char *submenu, char *display)
+struct menu_entry *menu_add_submenu(struct menu *parent,
+				    const char *submenu,
+				    const char *display)
 {
 	struct submenu *s = calloc(1, sizeof(*s));
 	int ret;
@@ -423,10 +425,10 @@ struct menu_entry *menu_add_submenu(struct menu *parent, char *submenu, char *di
 	if (!s)
 		return ERR_PTR(-ENOMEM);
 
-	s->submenu = strdup(submenu);
+	s->submenu = strdup_const(submenu);
 	s->entry.action = menu_action_show;
 	s->entry.free = submenu_free;
-	s->entry.display = strdup(display);
+	s->entry.display = strdup_const(display);
 	if (!s->entry.display || !s->submenu) {
 		ret = -ENOMEM;
 		goto err_free;
@@ -445,7 +447,7 @@ struct menu_entry *menu_add_submenu(struct menu *parent, char *submenu, char *di
 EXPORT_SYMBOL(menu_add_submenu);
 
 struct action_entry {
-	char *command;
+	const char *command;
 	struct menu_entry entry;
 };
 
@@ -469,14 +471,14 @@ static void menu_command_free(struct menu_entry *me)
 {
 	struct action_entry *e = container_of(me, struct action_entry, entry);
 
-	free(e->entry.display);
-	free(e->command);
+	free_const(e->entry.display);
+	free_const(e->command);
 
 	free(e);
 }
 
-struct menu_entry *menu_add_command_entry(struct menu *m, char *display,
-					  char *command, menu_entry_type type)
+struct menu_entry *menu_add_command_entry(struct menu *m, const  char *display,
+					  const char *command, menu_entry_type type)
 {
 	struct action_entry *e = calloc(1, sizeof(*e));
 	int ret;
@@ -484,11 +486,11 @@ struct menu_entry *menu_add_command_entry(struct menu *m, char *display,
 	if (!e)
 		return ERR_PTR(-ENOMEM);
 
-	e->command = strdup(command);
+	e->command = strdup_const(command);
 	e->entry.action = menu_action_command;
 	e->entry.free = menu_command_free;
 	e->entry.type = type;
-	e->entry.display = strdup(display);
+	e->entry.display = strdup_const(display);
 
 	if (!e->entry.display || !e->command) {
 		ret = -ENOMEM;
@@ -555,7 +557,7 @@ void menu_add_title(struct menu *m, const char *display)
 	m->display_lines = lines;
 
 	for (src = tmp, i = 0; i < lines; i++) {
-		m->display[i] = xstrdup(src);
+		m->display[i] = xstrdup_const(src);
 		/* Go to the next line */
 		src += strlen(src) + 1;
 	}
diff --git a/common/menutree.c b/common/menutree.c
index 751350d75455..196c2f49fa58 100644
--- a/common/menutree.c
+++ b/common/menutree.c
@@ -49,7 +49,7 @@ static void menutree_entry_free(struct menu_entry *me)
 	struct menutree *mt = container_of(me, struct menutree, me);
 
 	free(mt->action);
-	free(mt->me.display);
+	free_const(mt->me.display);
 	free(mt);
 }
 
@@ -153,7 +153,7 @@ int menutree(const char *path, int toplevel)
 
 	if (!toplevel) {
 		mt = xzalloc(sizeof(*mt));
-		mt->me.display = xstrdup("back");
+		mt->me.display = xstrdup_const("back");
 		mt->me.type = MENU_ENTRY_NORMAL;
 		mt->me.non_re_ent = 1;
 		mt->me.free = menutree_entry_free;
diff --git a/common/poller.c b/common/poller.c
index 77d93ae8ccdf..83f7205e5d57 100644
--- a/common/poller.c
+++ b/common/poller.c
@@ -33,7 +33,7 @@ int poller_register(struct poller_struct *poller, const char *name)
 	if (poller->registered)
 		return -EBUSY;
 
-	poller->name = xstrdup(name);
+	poller->name = xstrdup_const(name);
 	list_add_tail(&poller->list, &poller_list);
 	poller->registered = 1;
 
@@ -48,7 +48,7 @@ int poller_unregister(struct poller_struct *poller)
 
 	list_del(&poller->list);
 	poller->registered = 0;
-	free(poller->name);
+	free_const(poller->name);
 
 	return 0;
 }
diff --git a/common/resource.c b/common/resource.c
index 436a0488ddf0..c233b106c17b 100644
--- a/common/resource.c
+++ b/common/resource.c
@@ -23,7 +23,7 @@ static int init_resource(struct resource *res, const char *name)
 {
 	INIT_LIST_HEAD(&res->children);
 	res->parent = NULL;
-	res->name = xstrdup(name);
+	res->name = xstrdup_const(name);
 
 	return 0;
 }
@@ -101,7 +101,7 @@ int release_region(struct resource *res)
 		return -EBUSY;
 
 	list_del(&res->sibling);
-	free((char *)res->name);
+	free_const(res->name);
 	free(res);
 
 	return 0;
@@ -122,8 +122,8 @@ int __merge_regions(const char *name,
 	else
 		resa->start = resb->start;
 
-	free((char *)resa->name);
-	resa->name = xstrdup(name);
+	free_const(resa->name);
+	resa->name = xstrdup_const(name);
 	release_region(resb);
 
 	return 0;
diff --git a/common/restart.c b/common/restart.c
index 2bdee289831c..e54b4d7c5b82 100644
--- a/common/restart.c
+++ b/common/restart.c
@@ -62,7 +62,7 @@ int restart_handler_register_fn(const char *name,
 
 	rst = xzalloc(sizeof(*rst));
 
-	rst->name = xstrdup(name);
+	rst->name = xstrdup_const(name);
 	rst->restart = restart_fn;
 
 	ret = restart_handler_register(rst);
diff --git a/common/slice.c b/common/slice.c
index 9d7e0d16cfa2..a63d290d4ee4 100644
--- a/common/slice.c
+++ b/common/slice.c
@@ -198,7 +198,7 @@ static LIST_HEAD(slices);
 void slice_init(struct slice *slice, const char *name)
 {
 	INIT_LIST_HEAD(&slice->deps);
-	slice->name = xstrdup(name);
+	slice->name = xstrdup_const(name);
 	list_add_tail(&slice->list, &slices);
 }
 
@@ -229,7 +229,7 @@ void slice_exit(struct slice *slice)
 		}
 	}
 
-	free(slice->name);
+	free_const(slice->name);
 }
 
 struct slice command_slice;
diff --git a/common/state/backend_storage.c b/common/state/backend_storage.c
index df81902bf7be..d8d7c71a8a2b 100644
--- a/common/state/backend_storage.c
+++ b/common/state/backend_storage.c
@@ -386,7 +386,7 @@ int state_storage_init(struct state *state, const char *path,
 	storage->stridesize = stridesize;
 	storage->offset = offset;
 	storage->max_size = max_size;
-	storage->path = xstrdup(path);
+	storage->path = xstrdup_const(path);
 
 	if (IS_ENABLED(CONFIG_MTD))
 		ret = mtd_get_meminfo(path, &meminfo);
@@ -432,5 +432,5 @@ void state_storage_free(struct state_backend_storage *storage)
 		bucket->free(bucket);
 	}
 
-	free(storage->path);
+	free_const(storage->path);
 }
diff --git a/common/state/state.h b/common/state/state.h
index f0c5b1de4123..473717a379a6 100644
--- a/common/state/state.h
+++ b/common/state/state.h
@@ -97,7 +97,7 @@ struct state_backend_storage {
 	uint32_t stridesize;
 	off_t offset;
 	size_t max_size;
-	char *path;
+	const char *path;
 
 	bool readonly;
 };
diff --git a/common/state/state_variables.c b/common/state/state_variables.c
index 77946206cd02..7d99207e8863 100644
--- a/common/state/state_variables.c
+++ b/common/state/state_variables.c
@@ -251,7 +251,7 @@ static struct state_variable *state_enum32_create(struct state *state,
 		ret = of_property_read_string_index(node, "names", i, &name);
 		if (ret)
 			goto out;
-		enum32->names[i] = xstrdup(name);
+		enum32->names[i] = xstrdup_const(name);
 	}
 
 	param = dev_add_param_enum(&state->dev, name, state_set_dirty,
@@ -265,7 +265,7 @@ static struct state_variable *state_enum32_create(struct state *state,
 	return &enum32->var;
 out:
 	for (i--; i >= 0; i--)
-		free((char *)enum32->names[i]);
+		free_const(enum32->names[i]);
 	free(enum32->names);
 	free(enum32);
 	return ERR_PTR(ret);
diff --git a/drivers/led/led-gpio.c b/drivers/led/led-gpio.c
index c0d14256d3a1..0dda8f404e51 100644
--- a/drivers/led/led-gpio.c
+++ b/drivers/led/led-gpio.c
@@ -28,7 +28,7 @@ static void led_gpio_set(struct led *led, unsigned int value)
 int led_gpio_register(struct gpio_led *led)
 {
 	int ret;
-	char *name = led->led.name;
+	const char *name = led->led.name;
 
 	ret = gpio_request(led->gpio, name ? name : "led");
 	if (ret)
@@ -86,7 +86,7 @@ static void led_gpio_bicolor_set(struct led *led, unsigned int value)
 int led_gpio_bicolor_register(struct gpio_bicolor_led *led)
 {
 	int ret;
-	char *name = led->led.name;
+	const char *name = led->led.name;
 
 	ret = gpio_request(led->gpio_c0, name ? name : "led_c0");
 	if (ret)
@@ -146,7 +146,7 @@ static void led_gpio_rgb_set(struct led *led, unsigned int value)
 int led_gpio_rgb_register(struct gpio_rgb_led *led)
 {
 	int ret;
-	char *name = led->led.name;
+	const char *name = led->led.name;
 
 	ret = gpio_request(led->gpio_r, name ? name : "led_r");
 	if (ret)
diff --git a/drivers/led/led-pwm.c b/drivers/led/led-pwm.c
index 6f4abf97c8b7..7d16edea6017 100644
--- a/drivers/led/led-pwm.c
+++ b/drivers/led/led-pwm.c
@@ -53,7 +53,7 @@ static int led_pwm_of_probe(struct device *dev)
 			continue;
 
 		pwmled = xzalloc(sizeof(*pwmled));
-		pwmled->led.name = xstrdup(child->name);
+		pwmled->led.name = xstrdup_const(child->name);
 		pwmled->pwm = pwm;
 
 		ret = of_property_read_u32(child, "max-brightness", &pwmled->led.max_value);
diff --git a/drivers/nvmem/core.c b/drivers/nvmem/core.c
index 67276cf3b57b..4e69b3fa582b 100644
--- a/drivers/nvmem/core.c
+++ b/drivers/nvmem/core.c
@@ -150,7 +150,7 @@ static struct nvmem_cell *nvmem_find_cell(const char *cell_id)
 static void nvmem_cell_drop(struct nvmem_cell *cell)
 {
 	list_del(&cell->node);
-	kfree(cell->id);
+	kfree_const(cell->id);
 	kfree(cell);
 }
 
@@ -841,7 +841,7 @@ int nvmem_cell_read_variable_le_u32(struct device *dev, const char *cell_id,
 				    u32 *val)
 {
 	size_t len;
-	const u8 *buf;
+	u8 *buf;
 	int i;
 
 	len = sizeof(*val);
diff --git a/drivers/of/base.c b/drivers/of/base.c
index 960a9327aed2..4f25f0760a8b 100644
--- a/drivers/of/base.c
+++ b/drivers/of/base.c
@@ -2417,12 +2417,12 @@ struct device_node *of_new_node(struct device_node *parent, const char *name)
 	INIT_LIST_HEAD(&node->properties);
 
 	if (parent) {
-		node->name = xstrdup(name);
+		node->name = xstrdup_const(name);
 		node->full_name = basprintf("%pOF/%s",
 					      node->parent, name);
 		list_add(&node->list, &parent->list);
 	} else {
-		node->name = xstrdup("");
+		node->name = xstrdup_const("");
 		node->full_name = xstrdup("");
 		INIT_LIST_HEAD(&node->list);
 	}
@@ -2436,7 +2436,7 @@ struct property *__of_new_property(struct device_node *node, const char *name,
 	struct property *prop;
 
 	prop = xzalloc(sizeof(*prop));
-	prop->name = xstrdup(name);
+	prop->name = xstrdup_const(name);
 	prop->length = len;
 	prop->value = data;
 
@@ -2505,7 +2505,7 @@ void of_delete_property(struct property *pp)
 
 	list_del(&pp->list);
 
-	free(pp->name);
+	free_const(pp->name);
 	free(pp->value);
 	free(pp);
 }
@@ -2521,7 +2521,7 @@ struct property *of_rename_property(struct device_node *np,
 
 	of_property_write_bool(np, new_name, false);
 
-	free(pp->name);
+	free_const(pp->name);
 	pp->name = xstrdup(new_name);
 	return pp;
 }
@@ -2903,7 +2903,7 @@ void of_delete_node(struct device_node *node)
 		list_del(&node->list);
 	}
 
-	free(node->name);
+	free_const(node->name);
 	free(node->full_name);
 	free(node);
 }
diff --git a/drivers/of/of_net.c b/drivers/of/of_net.c
index 75a24073da51..58b4f99da111 100644
--- a/drivers/of/of_net.c
+++ b/drivers/of/of_net.c
@@ -82,7 +82,7 @@ static int of_get_mac_addr(struct device_node *np, const char *name, u8 *addr)
 int of_get_mac_addr_nvmem(struct device_node *np, u8 *addr)
 {
 	struct nvmem_cell *cell;
-	const void *mac;
+	void *mac;
 	size_t len;
 
 	if (!IS_ENABLED(CONFIG_NVMEM))
diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c
index 30ae270b518c..2c3b009ea66d 100644
--- a/drivers/regulator/core.c
+++ b/drivers/regulator/core.c
@@ -257,7 +257,7 @@ static int __regulator_register(struct regulator_dev *rdev, const char *name)
 	list_add_tail(&rdev->list, &regulator_list);
 
 	if (name)
-		rdev->name = xstrdup(name);
+		rdev->name = xstrdup_const(name);
 
 	ret = regulator_init_voltage(rdev);
 	if (ret)
@@ -276,7 +276,7 @@ static int __regulator_register(struct regulator_dev *rdev, const char *name)
 	return 0;
 err:
 	list_del(&rdev->list);
-	free((char *)rdev->name);
+	free_const(rdev->name);
 
 	return ret;
 }
diff --git a/drivers/soc/kvx/kvx_socinfo.c b/drivers/soc/kvx/kvx_socinfo.c
index 4b193ebac98c..014b3521eceb 100644
--- a/drivers/soc/kvx/kvx_socinfo.c
+++ b/drivers/soc/kvx/kvx_socinfo.c
@@ -140,7 +140,7 @@ static int kvx_read_board_sn(struct device_node *socinfo)
 		return PTR_ERR(cell);
 	}
 
-	sn = (char *)nvmem_cell_read(cell, &len);
+	sn = nvmem_cell_read(cell, &len);
 	nvmem_cell_put(cell);
 	if (IS_ERR(sn)) {
 		pr_debug("Fail to read board_sn\n");
diff --git a/include/blspec.h b/include/blspec.h
index 8297b9fdc1b6..affcea9a0ad5 100644
--- a/include/blspec.h
+++ b/include/blspec.h
@@ -10,8 +10,8 @@ struct blspec_entry {
 
 	struct device_node *node;
 	struct cdev *cdev;
-	char *rootpath;
-	char *configpath;
+	const char *rootpath;
+	const char *configpath;
 };
 
 int blspec_entry_var_set(struct blspec_entry *entry, const char *name,
diff --git a/include/boot.h b/include/boot.h
index 0f97901a9a72..53ad1360a5f3 100644
--- a/include/boot.h
+++ b/include/boot.h
@@ -29,7 +29,7 @@ struct bootentries {
 struct bootentry {
 	struct list_head list;
 	struct menu_entry me;
-	char *title;
+	const char *title;
 	char *description;
 	int (*boot)(struct bootentry *entry, int verbose, int dryrun);
 	void (*release)(struct bootentry *entry);
diff --git a/include/console.h b/include/console.h
index 62d13d7aa02c..8d3ec33bfac6 100644
--- a/include/console.h
+++ b/include/console.h
@@ -40,7 +40,7 @@ struct console_device {
 	int (*open)(struct console_device *cdev);
 	int (*close)(struct console_device *cdev);
 
-	char *devname;
+	const char *devname;
 	int devid;
 
 	struct list_head list;
diff --git a/include/digest.h b/include/digest.h
index 2816ddffaed2..b88256886c74 100644
--- a/include/digest.h
+++ b/include/digest.h
@@ -40,8 +40,8 @@ enum hash_algo {
 };
 
 struct crypto_alg {
-	char *name;
-	char *driver_name;
+	const char *name;
+	const char *driver_name;
 	int priority;
 #define DIGEST_ALGO_NEED_KEY	(1 << 0)
 	unsigned int flags;
diff --git a/include/elf.h b/include/elf.h
index de1549ee8620..8805eb4a2fc9 100644
--- a/include/elf.h
+++ b/include/elf.h
@@ -406,7 +406,7 @@ struct elf_image {
 	void *low_addr;
 	void *high_addr;
 	void *hdr_buf;
-	char *filename;
+	const char *filename;
 };
 
 static inline size_t elf_get_mem_size(struct elf_image *elf)
diff --git a/include/environment.h b/include/environment.h
index bd863ad3f425..f26c68ba3e34 100644
--- a/include/environment.h
+++ b/include/environment.h
@@ -15,8 +15,8 @@
  */
 struct variable_d {
 	struct list_head list;
-	char *name;
-	char *data;
+	const char *name;
+	const char *data;
 };
 
 struct env_context {
@@ -26,8 +26,8 @@ struct env_context {
 };
 
 struct env_context *get_current_context(void);
-char *var_val(struct variable_d *);
-char *var_name(struct variable_d *);
+const char *var_val(struct variable_d *);
+const char *var_name(struct variable_d *);
 
 #if IS_ENABLED(CONFIG_ENVIRONMENT_VARIABLES) && IN_PROPER
 const char *getenv(const char *);
diff --git a/include/file-list.h b/include/file-list.h
index 1625f116a0e6..2fcb2e8e5b79 100644
--- a/include/file-list.h
+++ b/include/file-list.h
@@ -13,8 +13,8 @@ struct cdev;
 #define FILE_LIST_FLAG_OPTIONAL (1 << 4)
 
 struct file_list_entry {
-	char *name;
-	char *filename;
+	const char *name;
+	const char *filename;
 	unsigned long flags;
 	struct list_head list;
 };
diff --git a/include/led.h b/include/led.h
index 6b6aff922a86..08bda19c1cf4 100644
--- a/include/led.h
+++ b/include/led.h
@@ -10,7 +10,7 @@
 struct led {
 	void (*set)(struct led *, unsigned int value);
 	int max_value;
-	char *name;
+	const char *name;
 	int num;
 	struct list_head list;
 
diff --git a/include/linux/clk.h b/include/linux/clk.h
index 7e777b67f486..733ba356dd4b 100644
--- a/include/linux/clk.h
+++ b/include/linux/clk.h
@@ -13,6 +13,7 @@
 #include <linux/err.h>
 #include <linux/spinlock.h>
 #include <linux/stringify.h>
+#include <linux/string.h>
 #include <linux/container_of.h>
 #include <deep-probe.h>
 #include <xfuncs.h>
@@ -690,7 +691,8 @@ static inline struct clk_hw *clk_hw_register_gate(struct device *dev,
 						  u8 clk_gate_flags,
 						  spinlock_t *lock)
 {
-	return clk_to_clk_hw(clk_register_gate(dev, xstrdup(name), xstrdup(parent_name),
+	return clk_to_clk_hw(clk_register_gate(dev, xstrdup_const(name),
+					       xstrdup_const(parent_name),
 					       flags, reg, bit_idx,
 					       clk_gate_flags, lock));
 }
diff --git a/include/mci.h b/include/mci.h
index f607ef1b74d5..1e3757027406 100644
--- a/include/mci.h
+++ b/include/mci.h
@@ -611,7 +611,7 @@ struct mci_part {
 	struct mci		*mci;
 	uint64_t		size;		/* partition size (in bytes) */
 	unsigned int		part_cfg;	/* partition type */
-	char			*name;
+	const char		*name;
 	int			idx;
 	unsigned int		area_type;
 #define MMC_BLK_DATA_AREA_MAIN	(1<<0)
diff --git a/include/menu.h b/include/menu.h
index bf1f6c48a834..eeeb8423061a 100644
--- a/include/menu.h
+++ b/include/menu.h
@@ -18,7 +18,7 @@ typedef enum {
 
 struct menu_entry {
 	int num;
-	char *display;
+	const char *display;
 	void (*action)(struct menu *m, struct menu_entry *me);
 	void (*free)(struct menu_entry *me);
 	int non_re_ent;
@@ -33,14 +33,14 @@ struct menu_entry {
 };
 
 struct menu {
-	char *name;
+	const char *name;
 	/* Multiline title */
-	char **display;
+	const char **display;
 	/* Number of lines */
 	int display_lines;
 
 	int auto_select;
-	char *auto_display;
+	const char *auto_display;
 
 	struct list_head list;
 	struct list_head entries;
@@ -66,13 +66,17 @@ static inline struct menu* menu_alloc(void)
 	}
 	return m;
 }
-struct menu_entry *menu_add_submenu(struct menu *parent, char *submenu, char *display);
-struct menu_entry *menu_add_command_entry(struct menu *m, char *display,
-					  char *command, menu_entry_type type);
+struct menu_entry *menu_add_submenu(struct menu *parent,
+				    const char *submenu,
+				    const char *display);
+struct menu_entry *menu_add_command_entry(struct menu *m,
+					  const char *display,
+					  const char *command,
+					  menu_entry_type type);
 void menu_free(struct menu *m);
 int menu_add(struct menu* m);
 void menu_remove(struct menu *m);
-struct menu* menu_get_by_name(char *name);
+struct menu* menu_get_by_name(const char *name);
 int menu_show(struct menu *m);
 int menu_set_selected_entry(struct menu *m, struct menu_entry* me);
 int menu_set_selected(struct menu *m, int num);
diff --git a/include/net.h b/include/net.h
index a04ed5b0ab92..a3c466784630 100644
--- a/include/net.h
+++ b/include/net.h
@@ -58,7 +58,7 @@ struct eth_device {
 	struct device dev;
 	char *devname;
 	struct device *parent;
-	char *nodepath;
+	const char *nodepath;
 
 	IPaddr_t ipaddr;
 	IPaddr_t netmask;
diff --git a/include/of.h b/include/of.h
index 3d24e17e43a0..708b3a32556a 100644
--- a/include/of.h
+++ b/include/of.h
@@ -20,7 +20,7 @@
 typedef u32 phandle;
 
 struct property {
-	char *name;
+	const char *name;
 	int length;
 	void *value;
 	const void *value_const;
@@ -28,7 +28,7 @@ struct property {
 };
 
 struct device_node {
-	char *name;
+	const char *name;
 	char *full_name;
 
 	struct list_head properties;
@@ -1308,7 +1308,7 @@ static inline struct device_node *of_find_root_node(struct device_node *node)
 struct of_overlay_filter {
 	bool (*filter_filename)(struct of_overlay_filter *, const char *filename);
 	bool (*filter_content)(struct of_overlay_filter *, struct device_node *);
-	char *name;
+	const char *name;
 	struct list_head list;
 };
 
diff --git a/include/param.h b/include/param.h
index 1ccb6a26eb78..1b0315999e39 100644
--- a/include/param.h
+++ b/include/param.h
@@ -32,7 +32,7 @@ struct param_d {
 	int (*set)(struct device *, struct param_d *param, const char *val);
 	void (*info)(struct param_d *param);
 	unsigned int flags;
-	char *name;
+	const char *name;
 	char *value;
 	struct device *dev;
 	void *driver_priv;
diff --git a/include/poller.h b/include/poller.h
index 31db907ba5b8..d09968df1664 100644
--- a/include/poller.h
+++ b/include/poller.h
@@ -14,7 +14,7 @@ struct poller_struct {
 	u16 registered:1;
 	u16 overtime;
 	struct list_head list;
-	char *name;
+	const char *name;
 };
 
 int poller_register(struct poller_struct *poller, const char *name);
diff --git a/include/slice.h b/include/slice.h
index 800c5b2de08c..eb33d50339bf 100644
--- a/include/slice.h
+++ b/include/slice.h
@@ -15,7 +15,7 @@ enum slice_action {
 struct slice {
 	int acquired;
 	struct list_head deps;
-	char *name;
+	const char *name;
 	struct list_head list;
 };
 
diff --git a/include/stringlist.h b/include/stringlist.h
index 60b96ecb8319..dcfd33c6e064 100644
--- a/include/stringlist.h
+++ b/include/stringlist.h
@@ -7,7 +7,7 @@
 
 struct string_list {
 	struct list_head list;
-	char *str;
+	const char *str;
 };
 
 int string_list_add(struct string_list *sl, const char *str);
@@ -29,7 +29,7 @@ static inline void string_list_free(struct string_list *sl)
 	struct string_list *entry, *safe;
 
 	list_for_each_entry_safe(entry, safe, &sl->list, list) {
-		free(entry->str);
+		free_const(entry->str);
 		free(entry);
 	}
 }
diff --git a/lib/glob.c b/lib/glob.c
index 389580b0ed79..a077f2702b2d 100644
--- a/lib/glob.c
+++ b/lib/glob.c
@@ -77,8 +77,7 @@ static int collated_compare(const void *a, const void *b)
 int glob(const char *pattern, int flags,
 		int (*errfunc) (const char *, int), glob_t *pglob)
 {
-	const char *filename;
-	char *dirname = NULL;
+	const char *filename, *dirname = NULL;
 	size_t dirlen;
 	int status;
 	int oldcount;
@@ -92,19 +91,23 @@ int glob(const char *pattern, int flags,
 	filename = strrchr(pattern, '/');
 	if (filename == NULL) {
 		filename = pattern;
-		dirname = strdup(".");
+		dirname = strdup_const(".");
 		dirlen = 0;
 	} else if (filename == pattern) {
 		/* "/pattern".  */
-		dirname = strdup("/");
+		dirname = strdup_const("/");
 		dirlen = 1;
 		++filename;
 	} else {
+		char *buf;
+
 		dirlen = filename - pattern;
-		dirname = (char *)xmalloc(dirlen + 1);
-		memcpy(dirname, pattern, dirlen);
-		dirname[dirlen] = '\0';
+		buf = (char *)xmalloc(dirlen + 1);
+		memcpy(buf, pattern, dirlen);
+		buf[dirlen] = '\0';
 		++filename;
+
+		dirname = buf;
 	}
 
 	if (filename[0] == '\0' && dirlen > 1) {
@@ -231,7 +234,7 @@ int glob(const char *pattern, int flags,
 #endif
 	status = 0;
 out:
-	free(dirname);
+	free_const(dirname);
 
 	return status;
 }
diff --git a/lib/parameter.c b/lib/parameter.c
index bf9e83152b77..39a245242337 100644
--- a/lib/parameter.c
+++ b/lib/parameter.c
@@ -153,7 +153,7 @@ static int __dev_add_param(struct param_d *param, struct device *dev,
 	if (get_param_by_name(dev, name))
 		return -EEXIST;
 
-	param->name = strdup(name);
+	param->name = strdup_const(name);
 	if (!param->name)
 		return -ENOMEM;
 
@@ -1014,7 +1014,7 @@ void dev_remove_param(struct param_d *p)
 {
 	p->set(p->dev, p, NULL);
 	list_del(&p->list);
-	free(p->name);
+	free_const(p->name);
 	free(p);
 }
 
@@ -1030,7 +1030,7 @@ void dev_remove_parameters(struct device *dev)
 	list_for_each_entry_safe(p, n, &dev->parameters, list) {
 		p->set(dev, p, NULL);
 		list_del(&p->list);
-		free(p->name);
+		free_const(p->name);
 		free(p);
 	}
 }
diff --git a/lib/stringlist.c b/lib/stringlist.c
index bb2ba54a6c80..908fa3683c36 100644
--- a/lib/stringlist.c
+++ b/lib/stringlist.c
@@ -21,7 +21,7 @@ int string_list_add(struct string_list *sl, const char *str)
 	struct string_list *new;
 
 	new = xmalloc(sizeof(*new));
-	new->str = xstrdup(str);
+	new->str = xstrdup_const(str);
 
 	list_add_tail(&new->list, &sl->list);
 
@@ -56,7 +56,7 @@ int string_list_add_sorted(struct string_list *sl, const char *str)
 	struct string_list *new;
 
 	new = xmalloc(sizeof(*new));
-	new->str = xstrdup(str);
+	new->str = xstrdup_const(str);
 
 	list_add_sort(&new->list, &sl->list, string_list_compare);
 
@@ -79,7 +79,7 @@ int string_list_add_sort_uniq(struct string_list *sl, const char *str)
 	}
 
 	new = xmalloc(sizeof(*new));
-	new->str = xstrdup(str);
+	new->str = xstrdup_const(str);
 
 	list_add_tail(&new->list, &entry->list);
 
diff --git a/net/eth.c b/net/eth.c
index 7229530c055b..e4025753518c 100644
--- a/net/eth.c
+++ b/net/eth.c
@@ -489,7 +489,7 @@ int eth_register(struct eth_device *edev)
 
 	if (IS_ENABLED(CONFIG_OFDEVICE) && edev->parent &&
 			edev->parent->of_node)
-		edev->nodepath = xstrdup(edev->parent->of_node->full_name);
+		edev->nodepath = xstrdup_const(edev->parent->of_node->full_name);
 
 	return 0;
 }
@@ -537,7 +537,7 @@ void eth_unregister(struct eth_device *edev)
 	}
 
 	if (IS_ENABLED(CONFIG_OFDEVICE))
-		free(edev->nodepath);
+		free_const(edev->nodepath);
 
 	class_remove_device(&eth_class, &edev->dev);
 
diff --git a/scripts/checkpatch.pl b/scripts/checkpatch.pl
index dccc3c3fe79b..ce1c9b48476c 100755
--- a/scripts/checkpatch.pl
+++ b/scripts/checkpatch.pl
@@ -469,7 +469,7 @@ our $logFunctions = qr{(?x:
 our $allocFunctions = qr{(?x:
 	(?:(?:devm_)?
 		(?:kv|k|v)[czm]alloc(?:_node|_array)? |
-		kstrdup(?:_const)? |
+		[kx]?strdup(?:_const)? |
 		kmemdup(?:_nul)?) |
 	(?:\w+)?alloc_skb(?:ip_align)? |
 				# dev_alloc_skb/netdev_alloc_skb, et al
-- 
2.39.5




^ permalink raw reply	[flat|nested] 9+ messages in thread

* [PATCH 6/7] fs: efi: replace allocation with local buffer
  2024-11-25 15:29 [PATCH 0/7] add proper strdup_const support Ahmad Fatoum
                   ` (4 preceding siblings ...)
  2024-11-25 15:29 ` [PATCH 5/7] treewide: use strdup_const where appropriate Ahmad Fatoum
@ 2024-11-25 15:29 ` Ahmad Fatoum
  2024-11-25 15:29 ` [PATCH 7/7] cdev: fix string leaks in devfs links Ahmad Fatoum
  2024-11-29 11:59 ` [PATCH 0/7] add proper strdup_const support Sascha Hauer
  7 siblings, 0 replies; 9+ messages in thread
From: Ahmad Fatoum @ 2024-11-25 15:29 UTC (permalink / raw)
  To: barebox; +Cc: Ahmad Fatoum

Currently, every probed EFI file system involves an unnecessary
allocation; either a string literal is duplicated or a /efiX path is
formatted.

Avoid that extra allocation by just formatting on the stack as the
buffer is not needed later anyway.

Signed-off-by: Ahmad Fatoum <a.fatoum@pengutronix.de>
---
 fs/efi.c | 18 +++++++++++-------
 1 file changed, 11 insertions(+), 7 deletions(-)

diff --git a/fs/efi.c b/fs/efi.c
index cb0eb40da4c2..2125d54ed632 100644
--- a/fs/efi.c
+++ b/fs/efi.c
@@ -451,11 +451,13 @@ static int efifs_init(void)
 
 coredevice_initcall(efifs_init);
 
-static int index;
+static unsigned index;
 
 static int efi_fs_probe(struct efi_device *efidev)
 {
-	char *path, *device;
+	char buf[sizeof("/efi4294967295")];
+	const char *path;
+	char *device;
 	int ret;
 	struct efi_file_io_interface *volume;
 
@@ -463,10 +465,13 @@ static int efi_fs_probe(struct efi_device *efidev)
 		BS->handle_protocol(efi_loaded_image->device_handle,
 				&efi_simple_file_system_protocol_guid, (void*)&volume);
 
-	if (efi_loaded_image && efidev->protocol == volume)
-		path = xstrdup("/boot");
-	else
-		path = basprintf("/efi%d", index);
+	if (efi_loaded_image && efidev->protocol == volume) {
+		path = "/boot";
+	} else {
+		snprintf(buf, sizeof(buf), "/efi%u", index);
+		path = buf;
+	}
+
 	device = basprintf("%s", dev_name(&efidev->dev));
 
 	ret = make_directory(path);
@@ -483,7 +488,6 @@ static int efi_fs_probe(struct efi_device *efidev)
 
 	ret = 0;
 out:
-	free(path);
 	free(device);
 
 	return ret;
-- 
2.39.5




^ permalink raw reply	[flat|nested] 9+ messages in thread

* [PATCH 7/7] cdev: fix string leaks in devfs links
  2024-11-25 15:29 [PATCH 0/7] add proper strdup_const support Ahmad Fatoum
                   ` (5 preceding siblings ...)
  2024-11-25 15:29 ` [PATCH 6/7] fs: efi: replace allocation with local buffer Ahmad Fatoum
@ 2024-11-25 15:29 ` Ahmad Fatoum
  2024-11-29 11:59 ` [PATCH 0/7] add proper strdup_const support Sascha Hauer
  7 siblings, 0 replies; 9+ messages in thread
From: Ahmad Fatoum @ 2024-11-25 15:29 UTC (permalink / raw)
  To: barebox; +Cc: Ahmad Fatoum

The name and part of devfs links are always dynamically allocated, so
make sure to free them once we are done with them.

Signed-off-by: Ahmad Fatoum <a.fatoum@pengutronix.de>
---
 fs/devfs-core.c | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/fs/devfs-core.c b/fs/devfs-core.c
index 0bb363d0a9ff..0651be3d8fc4 100644
--- a/fs/devfs-core.c
+++ b/fs/devfs-core.c
@@ -428,8 +428,11 @@ int devfs_remove(struct cdev *cdev)
 	if (cdev_is_partition(cdev))
 		list_del(&cdev->partition_entry);
 
-	if (cdev->link)
+	if (cdev->link) {
+		free(cdev->name);
+		free(cdev->partname);
 		free(cdev);
+	}
 
 	return 0;
 }
-- 
2.39.5




^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH 0/7] add proper strdup_const support
  2024-11-25 15:29 [PATCH 0/7] add proper strdup_const support Ahmad Fatoum
                   ` (6 preceding siblings ...)
  2024-11-25 15:29 ` [PATCH 7/7] cdev: fix string leaks in devfs links Ahmad Fatoum
@ 2024-11-29 11:59 ` Sascha Hauer
  7 siblings, 0 replies; 9+ messages in thread
From: Sascha Hauer @ 2024-11-29 11:59 UTC (permalink / raw)
  To: barebox, Ahmad Fatoum


On Mon, 25 Nov 2024 16:29:20 +0100, Ahmad Fatoum wrote:
> We currently implement strdup_const as strdup, which is correct, but
> leaves the benefits of a proper implementation on the table:
> Reducing allocations for .rodata strings, which have static storage
> duration anyway.
> 
> This series implements a proper strdup_const that avoids allocations in
> that case.
> 
> [...]

Applied, thanks!

[1/7] sandbox: hostfile: strdup device tree node names
      https://git.pengutronix.de/cgit/barebox/commit/?id=5693aac77e21 (link may not be stable)
[2/7] lds: implement is_barebox_rodata
      https://git.pengutronix.de/cgit/barebox/commit/?id=24ada94d67ae (link may not be stable)
[3/7] string: implement proper strdup_const/free_const
      https://git.pengutronix.de/cgit/barebox/commit/?id=84f699019564 (link may not be stable)
[4/7] treewide: replace basename with kbasename
      https://git.pengutronix.de/cgit/barebox/commit/?id=c71f25b2b5f2 (link may not be stable)
[5/7] treewide: use strdup_const where appropriate
      https://git.pengutronix.de/cgit/barebox/commit/?id=00943daac8d1 (link may not be stable)
[6/7] fs: efi: replace allocation with local buffer
      https://git.pengutronix.de/cgit/barebox/commit/?id=cfbf80529c4c (link may not be stable)
[7/7] cdev: fix string leaks in devfs links
      https://git.pengutronix.de/cgit/barebox/commit/?id=2f8bac45ed59 (link may not be stable)

Best regards,
-- 
Sascha Hauer <s.hauer@pengutronix.de>




^ permalink raw reply	[flat|nested] 9+ messages in thread

end of thread, other threads:[~2024-11-29 12:00 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2024-11-25 15:29 [PATCH 0/7] add proper strdup_const support Ahmad Fatoum
2024-11-25 15:29 ` [PATCH 1/7] sandbox: hostfile: strdup device tree node names Ahmad Fatoum
2024-11-25 15:29 ` [PATCH 2/7] lds: implement is_barebox_rodata Ahmad Fatoum
2024-11-25 15:29 ` [PATCH 3/7] string: implement proper strdup_const/free_const Ahmad Fatoum
2024-11-25 15:29 ` [PATCH 4/7] treewide: replace basename with kbasename Ahmad Fatoum
2024-11-25 15:29 ` [PATCH 5/7] treewide: use strdup_const where appropriate Ahmad Fatoum
2024-11-25 15:29 ` [PATCH 6/7] fs: efi: replace allocation with local buffer Ahmad Fatoum
2024-11-25 15:29 ` [PATCH 7/7] cdev: fix string leaks in devfs links Ahmad Fatoum
2024-11-29 11:59 ` [PATCH 0/7] add proper strdup_const support Sascha Hauer

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox