From 2f1db06debc37587c1669d388afd32d8efc6514a Mon Sep 17 00:00:00 2001 From: Emery Hemingway Date: Sat, 27 Jun 2015 15:50:49 -0500 Subject: [PATCH] rump_fs/fuse_fs/lx_fs/ram_fs: symlink fixup Allow symlinks to be passed to the read and write file system utilities. Disallow writes to symlinks with offsets in file system servers, this is to ensure that writing the target of a symlink is an atomic operation. Fixes #1604 --- repos/dde_rump/src/server/rump_fs/symlink.h | 3 ++- repos/libports/src/server/fuse_fs/symlink.h | 3 +++ repos/os/include/file_system/util.h | 8 ++++---- repos/os/src/server/lx_fs/symlink.h | 3 +++ repos/os/src/server/ram_fs/symlink.h | 3 +++ 5 files changed, 15 insertions(+), 5 deletions(-) diff --git a/repos/dde_rump/src/server/rump_fs/symlink.h b/repos/dde_rump/src/server/rump_fs/symlink.h index 4288bb57b9..7045eb7653 100644 --- a/repos/dde_rump/src/server/rump_fs/symlink.h +++ b/repos/dde_rump/src/server/rump_fs/symlink.h @@ -49,7 +49,8 @@ class File_system::Symlink : public Node size_t write(char const *src, size_t len, seek_off_t seek_offset) { - if (!_create) + /* Ideal symlink operations are atomic. */ + if (!_create || seek_offset) return 0; int ret = rump_sys_symlink(src, _path.base()); diff --git a/repos/libports/src/server/fuse_fs/symlink.h b/repos/libports/src/server/fuse_fs/symlink.h index 1901c0d3b7..590f6198e1 100644 --- a/repos/libports/src/server/fuse_fs/symlink.h +++ b/repos/libports/src/server/fuse_fs/symlink.h @@ -70,6 +70,9 @@ class File_system::Symlink : public Node size_t write(char const *src, size_t len, seek_off_t seek_offset) { + /* Ideal symlink operations are atomic. */ + if (seek_offset) return 0; + int res = Fuse::fuse()->op.symlink(src, _path.base()); if (res != 0) return 0; diff --git a/repos/os/include/file_system/util.h b/repos/os/include/file_system/util.h index f16562818a..3bd5c192c2 100644 --- a/repos/os/include/file_system/util.h +++ b/repos/os/include/file_system/util.h @@ -103,7 +103,7 @@ namespace File_system { /** * Read file content */ - static inline size_t read(Session &fs, File_handle const &file_handle, + static inline size_t read(Session &fs, Node_handle const &node_handle, void *dst, size_t count, seek_off_t seek_offset = 0) { bool success = true; @@ -122,7 +122,7 @@ namespace File_system { Packet_descriptor packet(source.alloc_packet(curr_packet_size), 0, - file_handle, + node_handle, File_system::Packet_descriptor::READ, curr_packet_size, seek_offset); @@ -160,7 +160,7 @@ namespace File_system { /** * Write file content */ - static inline size_t write(Session &fs, File_handle const &file_handle, + static inline size_t write(Session &fs, Node_handle const &node_handle, void const *src, size_t count, seek_off_t seek_offset = 0) { bool success = true; @@ -179,7 +179,7 @@ namespace File_system { Packet_descriptor packet(source.alloc_packet(curr_packet_size), 0, - file_handle, + node_handle, File_system::Packet_descriptor::WRITE, curr_packet_size, seek_offset); diff --git a/repos/os/src/server/lx_fs/symlink.h b/repos/os/src/server/lx_fs/symlink.h index 40bc2bf52f..e0c466b730 100644 --- a/repos/os/src/server/lx_fs/symlink.h +++ b/repos/os/src/server/lx_fs/symlink.h @@ -39,6 +39,9 @@ class File_system::Symlink : public Node size_t write(char const *src, size_t len, seek_off_t seek_offset) { + /* Ideal symlink operations are atomic. */ + if (seek_offset) return 0; + size_t count = min(len, sizeof(_link_to) + 1); Genode::strncpy(_link_to, src, count); return count; diff --git a/repos/os/src/server/ram_fs/symlink.h b/repos/os/src/server/ram_fs/symlink.h index c74164e9f7..c632d8521e 100644 --- a/repos/os/src/server/ram_fs/symlink.h +++ b/repos/os/src/server/ram_fs/symlink.h @@ -31,6 +31,9 @@ namespace File_system { size_t write(char const *src, size_t len, seek_off_t seek_offset) { + /* Ideal symlink operations are atomic. */ + if (seek_offset) return 0; + size_t count = min(len, sizeof(_link_to) + 1); Genode::strncpy(_link_to, src, count); return count;