[PATCH 1/3] Export swupdate_remove_directory

6 views
Skip to first unread message

Stefano Babic

unread,
Dec 18, 2025, 10:56:27 AM (3 days ago) Dec 18
to swup...@googlegroups.com, Stefano Babic
Remove #ifndef CONFIG_NOCLEANUP and export unconditionally the function
that can be used on different contexts.

Signed-off-by: Stefano Babic <stefan...@swupdate.org>
---
core/util.c | 2 --
include/util.h | 2 --
2 files changed, 4 deletions(-)

diff --git a/core/util.c b/core/util.c
index 2534da31..62a249e3 100644
--- a/core/util.c
+++ b/core/util.c
@@ -144,7 +144,6 @@ void swupdate_create_directory(const char* path) {
free(dpath);
}

-#ifndef CONFIG_NOCLEANUP
static int _is_mount_point(const char *path, const char *parent_path) {
struct stat path_stat, parent_stat;

@@ -203,7 +202,6 @@ out:
free(dpath);
return ret;
}
-#endif

char **splitargs(char *args, int *argc)
{
diff --git a/include/util.h b/include/util.h
index 52fff11a..d4874f64 100644
--- a/include/util.h
+++ b/include/util.h
@@ -321,9 +321,7 @@ const char* get_tmpdir(void);
const char* get_tmpdirscripts(void);

void swupdate_create_directory(const char* path);
-#ifndef CONFIG_NOCLEANUP
int swupdate_remove_directory(const char* path);
-#endif

int swupdate_mount(const char *device, const char *dir, const char *fstype);
int swupdate_umount(const char *dir);
--
2.43.0

Stefano Babic

unread,
Dec 18, 2025, 10:56:27 AM (3 days ago) Dec 18
to swup...@googlegroups.com, Stefano Babic
There is a privilege escaltion issue in case the temporary directories
(scripts and datadst) are created in advance by an attacker who has set
the sticky bit. To avoid this, SWUpdate will remove and recreate the
directories at each update.

Signed-off-by: Stefano Babic <stefan...@swupdate.org>
Reported-by : Reinhard Kugler <RKu...@sba-research.org>
---
core/stream_interface.c | 4 ++++
core/util.c | 2 ++
2 files changed, 6 insertions(+)

diff --git a/core/stream_interface.c b/core/stream_interface.c
index 85d13fda..a0c73470 100644
--- a/core/stream_interface.c
+++ b/core/stream_interface.c
@@ -619,6 +619,10 @@ void *network_initializer(void *data)
TRACE("Software update started");

/* Create directories for scripts/datadst */
+ if (swupdate_remove_directory(SCRIPTS_DIR_SUFFIX) || swupdate_remove_directory(DATADST_DIR_SUFFIX)) {
+ ERROR("Previous dirs cannot be removed, something wrong, skipping...");
+ continue;
+ }
swupdate_create_directory(SCRIPTS_DIR_SUFFIX);
swupdate_create_directory(DATADST_DIR_SUFFIX);

diff --git a/core/util.c b/core/util.c
index f2997b8b..3f62e070 100644
--- a/core/util.c
+++ b/core/util.c
@@ -149,6 +149,8 @@ static int _is_mount_point(const char *path, const char *parent_path) {
struct stat path_stat, parent_stat;

if (stat(path, &path_stat)) {
+ if (errno == ENOENT)
+ return 0;
ERROR("stat for path %s failed: %s", path, strerror(errno));
return -errno;
}
--
2.43.0

Stefano Babic

unread,
Dec 18, 2025, 10:56:27 AM (3 days ago) Dec 18
to swup...@googlegroups.com, Stefano Babic
If swupdate_remove_directory is called without a directory, a
preesistent file was present and then give up.

Signed-off-by: Stefano Babic <stefan...@swupdate.org>
---
core/util.c | 13 +++++++++++++
1 file changed, 13 insertions(+)

diff --git a/core/util.c b/core/util.c
index 62a249e3..f2997b8b 100644
--- a/core/util.c
+++ b/core/util.c
@@ -7,6 +7,7 @@

#include <stdio.h>
#include <stdlib.h>
+#include <stdbool.h>
#include <stdarg.h>
#include <unistd.h>
#include <string.h>
@@ -176,6 +177,7 @@ static int _remove_directory_cb(const char *fpath, const struct stat *sb,
int swupdate_remove_directory(const char* path)
{
char* dpath;
+ struct stat path_stat;
int ret;
if (asprintf(&dpath, "%s%s", get_tmpdir(), path) ==
ENOMEM_ASPRINTF) {
@@ -183,6 +185,17 @@ int swupdate_remove_directory(const char* path)
return -ENOMEM;
}

+ if (stat(dpath, &path_stat)) {
+ /* not exist, return ok */
+ if (errno == ENOENT)
+ return 0;
+ ERROR("stat for path %s failed: %s", path, strerror(errno));
+ return -errno;
+ }
+ if (!S_ISDIR(path_stat.st_mode)) {
+ ERROR("Tried to remove %s dir, but it is not a dir", path);
+ return -ENODEV;
+ }
ret = _is_mount_point(dpath, get_tmpdir());
if (ret < 0)
goto out;
--
2.43.0

Reply all
Reply to author
Forward
0 new messages