~lattis/muon

null-terminate readlink buffer v1 APPLIED

illiliti: 3
 null-terminate readlink buffer
 use proper return type for readlink
 refactor fs_copy_link

 3 files changed, 19 insertions(+), 8 deletions(-)
Export patchset (mbox)
How do I use this?

Copy & paste the following snippet into your terminal to import this patchset into git:

curl -s https://lists.sr.ht/~lattis/muon/patches/35430/mbox | git am -3
Learn more about email & git

[PATCH 1/3] null-terminate readlink buffer Export this patch

readlink does not null-terminate the buffer. do it manually to avoid
creating corrupted symlinks.
---
 src/platform/filesystem.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/platform/filesystem.c b/src/platform/filesystem.c
index ba878912..8b9f6330 100644
--- a/src/platform/filesystem.c
+++ b/src/platform/filesystem.c
@@ -548,7 +548,7 @@ fs_copy_link(const char *src, const char *dest)
		goto ret;
	}


	buf.buf[n] = '\0';
	res = fs_make_symlink(buf.buf, dest, true);
ret:
	sbuf_destroy(&buf);
-- 
2.35.1
Looks good to me.  I didn't realize readlink doesn't append a
terminating null byte.

Stone

[PATCH 2/3] use proper return type for readlink Export this patch

---
 src/platform/filesystem.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/platform/filesystem.c b/src/platform/filesystem.c
index 8b9f6330..b52ff1dc 100644
--- a/src/platform/filesystem.c
+++ b/src/platform/filesystem.c
@@ -538,7 +538,7 @@ fs_copy_link(const char *src, const char *dest)
{
	bool res = false;
	SBUF_manual(buf);
	int n;
	ssize_t n;
	while ((n = readlink(src, buf.buf, buf.cap)) != -1 && (uint32_t)n >= buf.cap) {
		sbuf_grow(NULL, &buf, buf.cap);
	}
-- 
2.35.1

[PATCH 3/3] refactor fs_copy_link Export this patch

use fstat to get buffer size instead of busy looping readlink
---
 src/platform/filesystem.c | 23 +++++++++++++++++------
 1 file changed, 17 insertions(+), 6 deletions(-)

diff --git a/src/platform/filesystem.c b/src/platform/filesystem.c
index b52ff1dc..372af0c3 100644
--- a/src/platform/filesystem.c
+++ b/src/platform/filesystem.c
@@ -537,21 +537,32 @@ static bool
fs_copy_link(const char *src, const char *dest)
{
	bool res = false;
	SBUF_manual(buf);
	ssize_t n;
	while ((n = readlink(src, buf.buf, buf.cap)) != -1 && (uint32_t)n >= buf.cap) {
		sbuf_grow(NULL, &buf, buf.cap);
	char *buf;

	struct stat st;
	if (!fs_lstat(src, &st)) {
		return false;
	}

	if (!S_ISLNK(st.st_mode)) {
		return false;
	}

	// TODO: allow pseudo-files?
	assert(st.st_size > 0);

	buf = z_malloc(st.st_size + 1);
	n = readlink(src, buf, st.st_size);
	if (n == -1) {
		LOG_E("readlink('%s') failed: %s", src, strerror(errno));
		goto ret;
	}

	buf.buf[n] = '\0';
	res = fs_make_symlink(buf.buf, dest, true);
	buf[n] = '\0';
	res = fs_make_symlink(buf, dest, true);
ret:
	sbuf_destroy(&buf);
	z_free(buf);
	return res;
}

-- 
2.35.1