There is an issue in pseudo where if you open a file, rename the file,
then call fstat on the open fd, pseudo would thrown an abort. This is
because it needs to track the open fd mappings to files and it doesn't
update in the case of a rename.

Add code in pseudo to update the fd mappings in the case of a rename
call. Also add a test case.

Signed-off-by: Richard Purdie <richard.pur...@linuxfoundation.org>
---
 Makefile.in               |  1 +
 pseudo_client.c           | 20 +++++++++++++++++++-
 test/test-rename-fstat.c  | 21 +++++++++++++++++++++
 test/test-rename-fstat.sh |  9 +++++++++
 4 files changed, 50 insertions(+), 1 deletion(-)
 create mode 100644 test/test-rename-fstat.c
 create mode 100755 test/test-rename-fstat.sh

diff --git a/Makefile.in b/Makefile.in
index d1f77d5..6eff522 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -75,6 +75,7 @@ TABLES=table_templates/pseudo_tables.c 
table_templates/pseudo_tables.h
 all: $(LIBPSEUDO) $(PSEUDO) $(PSEUDODB) $(PSEUDOLOG) $(PSEUDO_PROFILE)
 
 test: all | $(BIN) $(LIB) $(LOCALSTATE)
+       $(CC) $(CFLAGS) $(CFLAGS_PSEUDO) -o test/test-rename-fstat 
test/test-rename-fstat.c
        @./run_tests.sh -v
 
 install-lib: $(LIBPSEUDO)
diff --git a/pseudo_client.c b/pseudo_client.c
index f5cab7e..f846d54 100644
--- a/pseudo_client.c
+++ b/pseudo_client.c
@@ -943,6 +943,21 @@ pseudo_client_linked_paths(const char *oldpath, const char 
*newpath) {
        }
 }
 
+static void
+pseudo_client_rename_path(const char *oldpath, const char *newpath) {
+       int fd;
+       for (fd = 3; fd < nfds; ++fd) {
+               if (fd_paths[fd] && !strcmp(oldpath, fd_paths[fd])) {
+                        pseudo_client_path(fd, newpath);
+               }
+       }
+       for (fd = 0; fd < linked_nfds; ++fd) {
+               if (linked_fd_paths[fd] && fd_paths[fd] && !strcmp(oldpath, 
linked_fd_paths[fd])) {
+                       pseudo_client_path_set(fd, newpath, &linked_fd_paths, 
&linked_nfds);
+               }
+       }
+}
+
 static void
 pseudo_client_unlinked_path(const char *path) {
        int fd;
@@ -1939,7 +1954,6 @@ pseudo_client_op(pseudo_op_t op, int access, int fd, int 
dirfd, const char *path
        case OP_FCHOWN:
        case OP_FSTAT:
        case OP_LINK:
-       case OP_RENAME:
        case OP_STAT:
        case OP_CANCEL_UNLINK:
        case OP_MAY_UNLINK:
@@ -1949,6 +1963,10 @@ pseudo_client_op(pseudo_op_t op, int access, int fd, int 
dirfd, const char *path
        case OP_REMOVE_XATTR:
                do_request = 1;
                break;
+       case OP_RENAME:
+               pseudo_client_rename_path(path_extra_1, path);
+               do_request = 1;
+               break;
        default:
                pseudo_diag("error: unknown or unimplemented operator %d (%s)", 
op, pseudo_op_name(op));
                break;
diff --git a/test/test-rename-fstat.c b/test/test-rename-fstat.c
new file mode 100644
index 0000000..ef1daf7
--- /dev/null
+++ b/test/test-rename-fstat.c
@@ -0,0 +1,21 @@
+/*
+ * SPDX-License-Identifier: LGPL-2.1-only
+ *
+ * Test we can rename a file whilst holding an open fd which we fstat after 
renaming
+ */
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <unistd.h>
+
+int main()
+{
+    struct stat buf;
+    int fd = open("test-rename-fstat1", O_RDONLY);
+    rename("test-rename-fstat1", "test-rename-fstat1");
+    fstat(fd, &buf);
+    return 0;
+}
diff --git a/test/test-rename-fstat.sh b/test/test-rename-fstat.sh
new file mode 100755
index 0000000..93b3d8a
--- /dev/null
+++ b/test/test-rename-fstat.sh
@@ -0,0 +1,9 @@
+#!/bin/bash
+#
+# SPDX-License-Identifier: LGPL-2.1-only
+#
+
+rm -f test-rename-fstat1 test-rename-fstat2
+# Will abort if it fails
+./test/test-rename-fstat
+exit $?
-- 
2.27.0

-=-=-=-=-=-=-=-=-=-=-=-
Links: You receive all messages sent to this group.
View/Reply Online (#147410): 
https://lists.openembedded.org/g/openembedded-core/message/147410
Mute This Topic: https://lists.openembedded.org/mt/80194815/21656
Group Owner: openembedded-core+ow...@lists.openembedded.org
Unsubscribe: https://lists.openembedded.org/g/openembedded-core/unsub 
[arch...@mail-archive.com]
-=-=-=-=-=-=-=-=-=-=-=-

Reply via email to