diff mbox series

[v2] util: Ensure swupdate_remove_directory unmounts path

Message ID 20240703192854.1026436-1-james.hilliard1@gmail.com
State Accepted
Headers show
Series [v2] util: Ensure swupdate_remove_directory unmounts path | expand

Commit Message

James Hilliard July 3, 2024, 7:28 p.m. UTC
In the event that the DATADST_DIR is left mounted we should ensure
that it is unmounted prior to deletion, otherwise we may end up
being unable to remove DATADST_DIR and/or accidentially deleting
files inside the mounted filesystem.

Signed-off-by: James Hilliard <james.hilliard1@gmail.com>
---
Changes v1 -> v2:
  - fix stat return value check
---
 core/util.c | 36 ++++++++++++++++++++++++++++++++++++
 1 file changed, 36 insertions(+)
diff mbox series

Patch

diff --git a/core/util.c b/core/util.c
index 70f0d28f..33a9af71 100644
--- a/core/util.c
+++ b/core/util.c
@@ -169,6 +169,26 @@  void swupdate_create_directory(const char* path) {
 }
 
 #ifndef CONFIG_NOCLEANUP
+static int _is_mount_point(const char *path, const char *parent_path) {
+	struct stat path_stat, parent_stat;
+
+	if (stat(path, &path_stat)) {
+		ERROR("stat for path %s failed: %s", path, strerror(errno));
+		return -errno;
+	}
+
+	if (stat(parent_path, &parent_stat)) {
+		ERROR("stat for parent path %s failed: %s", parent_path, strerror(errno));
+		return -errno;
+	}
+
+	if (path_stat.st_dev != parent_stat.st_dev) {
+		return 1;
+	}
+
+	return 0;
+}
+
 static int _remove_directory_cb(const char *fpath, const struct stat *sb,
 								int typeflag, struct FTW *ftwbuf)
 {
@@ -187,7 +207,23 @@  int swupdate_remove_directory(const char* path)
 		ERROR("OOM: Directory %s not removed", path);
 		return -ENOMEM;
 	}
+
+	ret = _is_mount_point(dpath, get_tmpdir());
+	if (ret < 0)
+		goto out;
+
+	if (ret) {
+		WARN("Unexpected mountpoint, unmounting: %s", dpath);
+		ret = swupdate_umount(dpath);
+		if (ret && errno != EINVAL) {
+			ret = -errno;
+			ERROR("Can't unmount path %s: %s", dpath, strerror(errno));
+			goto out;
+		}
+	}
+
 	ret = nftw(dpath, _remove_directory_cb, 64, FTW_DEPTH | FTW_PHYS);
+out:
 	free(dpath);
 	return ret;
 }