summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRichard Purdie <richard.purdie@linuxfoundation.org>2020-09-30 14:36:20 +0100
committerRichard Purdie <richard.purdie@linuxfoundation.org>2020-10-07 11:18:38 +0100
commit842de9dbba53d04644e1c491fc0d4681d66680fd (patch)
treef3da48774e19f5a5887c99a66d872c5b9367461f
parent84e0642ed6aba422583871fc153bbd94380074de (diff)
downloadpoky-842de9dbba53d04644e1c491fc0d4681d66680fd.tar.gz
psuedo: Add tracking of linked files for fds
Where files are link()'d and one is unlink()'d, pseudo's fd mappings can become confused. Add a patch to try and improve this for the common usecases we see. (From OE-Core rev: 9ce621fa2099608ca0ccbb8420b31d71cdd7b00e) Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
-rw-r--r--meta/recipes-devtools/pseudo/files/track_link_fds.patch155
-rw-r--r--meta/recipes-devtools/pseudo/pseudo_git.bb1
2 files changed, 156 insertions, 0 deletions
diff --git a/meta/recipes-devtools/pseudo/files/track_link_fds.patch b/meta/recipes-devtools/pseudo/files/track_link_fds.patch
new file mode 100644
index 0000000000..a3a9eb3f23
--- /dev/null
+++ b/meta/recipes-devtools/pseudo/files/track_link_fds.patch
@@ -0,0 +1,155 @@
1Consider what happens if a program does:
2
3fd = fopen("A")
4link("A", "B")
5unlink("A")
6fchown(fd)
7
8Assuming we can't use the database, in order to handle this correctly,
9we need to change the open fd to point at B when A us unlinked.
10
11Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
12Upstream-Status: Pending
13
14Index: git/ports/unix/guts/linkat.c
15===================================================================
16--- git.orig/ports/unix/guts/linkat.c
17+++ git/ports/unix/guts/linkat.c
18@@ -116,6 +116,7 @@
19 * if the thing linked is a symlink.
20 */
21 pseudo_client_op(OP_LINK, 0, -1, -1, newpath, &buf);
22+ pseudo_client_linked_paths(oldpath, newpath);
23
24 errno = save_errno;
25
26Index: git/pseudo_client.c
27===================================================================
28--- git.orig/pseudo_client.c
29+++ git/pseudo_client.c
30@@ -70,6 +70,8 @@ int pseudo_umask = 022;
31
32 static char **fd_paths = NULL;
33 static int nfds = 0;
34+static char **linked_fd_paths = NULL;
35+static int linked_nfds = 0;
36 static const char **passwd_paths = NULL;
37 static int npasswd_paths = 0;
38 #ifdef PSEUDO_PROFILING
39@@ -889,39 +891,70 @@ fd_path(int fd) {
40 }
41
42 static void
43-pseudo_client_path(int fd, const char *path) {
44+pseudo_client_path_set(int fd, const char *path, char ***patharray, int *len) {
45 if (fd < 0)
46 return;
47
48- if (fd >= nfds) {
49+ if (fd >= *len) {
50 int i;
51 pseudo_debug(PDBGF_CLIENT, "expanding fds from %d to %d\n",
52- nfds, fd + 1);
53- fd_paths = realloc(fd_paths, (fd + 1) * sizeof(char *));
54- for (i = nfds; i < fd + 1; ++i)
55- fd_paths[i] = 0;
56- nfds = fd + 1;
57+ *len, fd + 1);
58+ (*patharray) = realloc((*patharray), (fd + 1) * sizeof(char *));
59+ for (i = *len; i < fd + 1; ++i)
60+ (*patharray)[i] = 0;
61+ *len = fd + 1;
62 } else {
63- if (fd_paths[fd]) {
64+ if ((*patharray)[fd]) {
65 pseudo_debug(PDBGF_CLIENT, "reopening fd %d [%s] -- didn't see close\n",
66- fd, fd_paths[fd]);
67+ fd, (*patharray)[fd]);
68 }
69 /* yes, it is safe to free null pointers. yay for C89 */
70- free(fd_paths[fd]);
71- fd_paths[fd] = 0;
72+ free((*patharray)[fd]);
73+ (*patharray)[fd] = 0;
74 }
75 if (path) {
76- fd_paths[fd] = strdup(path);
77+ (*patharray)[fd] = strdup(path);
78+ }
79+}
80+
81+static void
82+pseudo_client_path(int fd, const char *path) {
83+ pseudo_client_path_set(fd, path, &fd_paths, &nfds);
84+}
85+
86+void
87+pseudo_client_linked_paths(const char *oldpath, const char *newpath) {
88+ int fd;
89+ for (fd = 3; fd < nfds; ++fd) {
90+ if (fd_paths[fd] && !strcmp(oldpath, fd_paths[fd])) {
91+ pseudo_client_path_set(fd, newpath, &linked_fd_paths, &linked_nfds);
92+ }
93 }
94 }
95
96 static void
97+pseudo_client_unlinked_path(const char *path) {
98+ int fd;
99+ for (fd = 0; fd < linked_nfds; ++fd) {
100+ if (linked_fd_paths[fd] && fd_paths[fd] && !strcmp(path, fd_paths[fd])) {
101+ pseudo_client_path(fd, linked_fd_paths[fd]);
102+ }
103+ }
104+}
105+
106+
107+static void
108 pseudo_client_close(int fd) {
109 if (fd < 0 || fd >= nfds)
110 return;
111
112 free(fd_paths[fd]);
113 fd_paths[fd] = 0;
114+
115+ if (fd < linked_nfds) {
116+ free(linked_fd_paths[fd]);
117+ linked_fd_paths[fd] = 0;
118+ }
119 }
120
121 /* spawn server */
122@@ -1860,6 +1893,12 @@ pseudo_client_op(pseudo_op_t op, int acc
123 dirfd);
124 pseudo_client_path(dirfd, fd_path(fd));
125 break;
126+ case OP_UNLINK:
127+ case OP_DID_UNLINK:
128+ if (path)
129+ pseudo_client_unlinked_path(path);
130+ do_request = 1;
131+ break;
132 /* operations for which we should use the magic uid/gid */
133 case OP_CHMOD:
134 case OP_CREAT:
135@@ -1882,8 +1921,6 @@ pseudo_client_op(pseudo_op_t op, int acc
136 case OP_LINK:
137 case OP_RENAME:
138 case OP_STAT:
139- case OP_UNLINK:
140- case OP_DID_UNLINK:
141 case OP_CANCEL_UNLINK:
142 case OP_MAY_UNLINK:
143 case OP_GET_XATTR:
144Index: git/pseudo_client.h
145===================================================================
146--- git.orig/pseudo_client.h
147+++ git/pseudo_client.h
148@@ -9,6 +9,7 @@
149 extern pseudo_msg_t *pseudo_client_op(pseudo_op_t op, int access, int fd, int dirfd, const char *path, const PSEUDO_STATBUF *buf, ...);
150 extern int pseudo_client_ignore_path(const char *path);
151 extern int pseudo_client_ignore_fd(int fd);
152+extern void pseudo_client_linked_paths(const char *oldpath, const char *newpath);
153 #if PSEUDO_STATBUF_64
154 #define base_lstat real_lstat64
155 #define base_fstat real_fstat64
diff --git a/meta/recipes-devtools/pseudo/pseudo_git.bb b/meta/recipes-devtools/pseudo/pseudo_git.bb
index 56c9b4e232..a5e79ec9a5 100644
--- a/meta/recipes-devtools/pseudo/pseudo_git.bb
+++ b/meta/recipes-devtools/pseudo/pseudo_git.bb
@@ -5,6 +5,7 @@ SRC_URI = "git://git.yoctoproject.org/pseudo;branch=oe-core \
5 file://delete_mismatches.patch \ 5 file://delete_mismatches.patch \
6 file://add_ignore_paths.patch \ 6 file://add_ignore_paths.patch \
7 file://abort_on_mismatch.patch \ 7 file://abort_on_mismatch.patch \
8 file://track_link_fds.patch \
8 file://fallback-passwd \ 9 file://fallback-passwd \
9 file://fallback-group \ 10 file://fallback-group \
10 " 11 "