From: Ahmad Fatoum <a.fatoum@pengutronix.de>
To: barebox@lists.infradead.org
Cc: Ahmad Fatoum <a.fatoum@pengutronix.de>
Subject: [PATCH 3/7] string: implement proper strdup_const/free_const
Date: Mon, 25 Nov 2024 16:29:23 +0100 [thread overview]
Message-ID: <20241125152927.546493-4-a.fatoum@pengutronix.de> (raw)
In-Reply-To: <20241125152927.546493-1-a.fatoum@pengutronix.de>
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
next prev parent reply other threads:[~2024-11-25 15:32 UTC|newest]
Thread overview: 8+ messages / expand[flat|nested] mbox.gz Atom feed top
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 [this message]
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
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20241125152927.546493-4-a.fatoum@pengutronix.de \
--to=a.fatoum@pengutronix.de \
--cc=barebox@lists.infradead.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox