diff options
author | Richard Purdie <richard.purdie@linuxfoundation.org> | 2020-10-08 15:08:59 +0100 |
---|---|---|
committer | Richard Purdie <richard.purdie@linuxfoundation.org> | 2020-10-09 12:03:31 +0100 |
commit | 78b2a07710183f267a2b1412429170135764474a (patch) | |
tree | 363cbdd4dfc056186f3152f973fef75c5d55ad84 /meta/recipes-devtools/pseudo/files | |
parent | 49bc76ec33dfe4d7261a430288c5276e195d70a0 (diff) | |
download | poky-78b2a07710183f267a2b1412429170135764474a.tar.gz |
pseudo: Update to account for patches merged on branch
(From OE-Core rev: ea22fb3aa1c5dd3edcd1d8b415a0843a9ee4677c)
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
Diffstat (limited to 'meta/recipes-devtools/pseudo/files')
8 files changed, 0 insertions, 726 deletions
diff --git a/meta/recipes-devtools/pseudo/files/abort_on_mismatch.patch b/meta/recipes-devtools/pseudo/files/abort_on_mismatch.patch deleted file mode 100644 index 1737269ec8..0000000000 --- a/meta/recipes-devtools/pseudo/files/abort_on_mismatch.patch +++ /dev/null | |||
@@ -1,64 +0,0 @@ | |||
1 | Rather than mapping mismatched inode entries to paths, thrown an abort() | ||
2 | instead. Add a new result type to allow the server to pass back | ||
3 | this instruction to the client. | ||
4 | |||
5 | Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org> | ||
6 | Upstream-Status: Pending | ||
7 | |||
8 | Index: git/pseudo.c | ||
9 | =================================================================== | ||
10 | --- git.orig/pseudo.c | ||
11 | +++ git/pseudo.c | ||
12 | @@ -695,17 +695,15 @@ pseudo_op(pseudo_msg_t *msg, const char | ||
13 | msg->path); | ||
14 | pdb_did_unlink_file(path_by_ino, &by_ino, by_ino.deleting); | ||
15 | } else { | ||
16 | - int flags = 0; | ||
17 | - if (msg->nlink > 1) { | ||
18 | - flags = PDBGF_FILE | PDBGF_VERBOSE; | ||
19 | - } | ||
20 | - pseudo_debug(flags, "path mismatch [%d link%s]: ino %llu db '%s' req '%s'.\n", | ||
21 | + pseudo_diag("path mismatch [%d link%s]: ino %llu db '%s' req '%s'.\n", | ||
22 | msg->nlink, | ||
23 | msg->nlink == 1 ? "" : "s", | ||
24 | (unsigned long long) msg_header.ino, | ||
25 | path_by_ino ? path_by_ino : "no path", | ||
26 | msg->path); | ||
27 | found_ino = 0; | ||
28 | + msg->result = RESULT_ABORT; | ||
29 | + goto op_exit; | ||
30 | } | ||
31 | } | ||
32 | } else { | ||
33 | @@ -1025,6 +1023,7 @@ pseudo_op(pseudo_msg_t *msg, const char | ||
34 | break; | ||
35 | } | ||
36 | |||
37 | +op_exit: | ||
38 | /* in the case of an exact match, we just used the pointer | ||
39 | * rather than allocating space. | ||
40 | */ | ||
41 | Index: git/pseudo_client.c | ||
42 | =================================================================== | ||
43 | --- git.orig/pseudo_client.c | ||
44 | +++ git/pseudo_client.c | ||
45 | @@ -1919,6 +1919,10 @@ pseudo_client_op(pseudo_op_t op, int acc | ||
46 | #endif | ||
47 | if (result) { | ||
48 | pseudo_debug(PDBGF_OP, "(%d) %s", getpid(), pseudo_res_name(result->result)); | ||
49 | + if (result->result == RESULT_ABORT) { | ||
50 | + pseudo_diag("abort()ing pseudi client by server request. See https://wiki.yoctoproject.org/wiki/Pseudo_Abort for more details on this.\n"); | ||
51 | + abort(); | ||
52 | + } | ||
53 | if (op == OP_STAT || op == OP_FSTAT) { | ||
54 | pseudo_debug(PDBGF_OP, " mode 0%o uid %d:%d", | ||
55 | (int) result->mode, | ||
56 | Index: git/enums/res.in | ||
57 | =================================================================== | ||
58 | --- git.orig/enums/res.in | ||
59 | +++ git/enums/res.in | ||
60 | @@ -2,3 +2,4 @@ res: RESULT | ||
61 | succeed | ||
62 | fail | ||
63 | error | ||
64 | +abort | ||
diff --git a/meta/recipes-devtools/pseudo/files/add_ignore_paths.patch b/meta/recipes-devtools/pseudo/files/add_ignore_paths.patch deleted file mode 100644 index eddfdb8674..0000000000 --- a/meta/recipes-devtools/pseudo/files/add_ignore_paths.patch +++ /dev/null | |||
@@ -1,298 +0,0 @@ | |||
1 | Currently, pseudo considers any path accessed whist its running to be | ||
2 | a valid entry to track in its database. The way OpenEmbedded uses pseudo, | ||
3 | there are paths we care about accesses to from a pseudo perspective and paths | ||
4 | which we simply don't care about. | ||
5 | |||
6 | This patch adds a PSEUDO_IGNORE_PATHS environment variable which is a comma | ||
7 | separated list of path prefixes to ignore accesses to. | ||
8 | |||
9 | To do this, we add some functions which can check a path argument or a file | ||
10 | descriptor argument and use these in the pseudo wrappers where path or fd | ||
11 | arguments are present. Where paths are being ignored, we skip straight to | ||
12 | the underlying real function. | ||
13 | |||
14 | Psuedo needs to keep track of the open fd mappings to files so we still need | ||
15 | to allow those cases into the pseudo_op function. Specficially this means | ||
16 | OP_CLOSE, OP_OPEN, OP_DUP and OP_CHDIR. | ||
17 | |||
18 | Apart from OP_OPEN which could call the server, the other operations are client | ||
19 | side only so passed through. We 'tag' the functions using these operations so | ||
20 | that the path ignore code isn't triggered. For OP_OPEN we exit early and skip | ||
21 | the server op. We also have a catch all in client_op to ensure any operatings | ||
22 | we didn't manage to skip early still get skipped correctly. | ||
23 | |||
24 | OP_CHROOT is a special case. Where ignored path prefixes are used as a chroot, | ||
25 | for the lifetime of the chroot, the path is effectively dropped from the | ||
26 | PSEUDO_IGNORE_PATHS list. Whilst slightly counter intuaitive, this turned out | ||
27 | to be the most effective way to do things due to commands like useradd and | ||
28 | their use of chroots. | ||
29 | |||
30 | For sqlite3 and appropriate path filtering in OE, this took the database from | ||
31 | 45,000 entries to about 180. For dbus this was 88,000 down to 760. Given the | ||
32 | number of client to server trips these numbers of paths involves, the win | ||
33 | is seemingly worthwhile. | ||
34 | |||
35 | Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org> | ||
36 | Upstream-Status: Pending | ||
37 | |||
38 | Index: git/pseudo_client.c | ||
39 | =================================================================== | ||
40 | --- git.orig/pseudo_client.c | ||
41 | +++ git/pseudo_client.c | ||
42 | @@ -1482,6 +1482,43 @@ base_path(int dirfd, const char *path, i | ||
43 | return newpath; | ||
44 | } | ||
45 | |||
46 | +int pseudo_client_ignore_fd(int fd) { | ||
47 | + if (fd >= 0 && fd <= nfds) | ||
48 | + return pseudo_client_ignore_path(fd_path(fd)); | ||
49 | + return 0; | ||
50 | +} | ||
51 | + | ||
52 | +int pseudo_client_ignore_path_chroot(const char *path, int ignore_chroot) { | ||
53 | + char *env; | ||
54 | + if (path) { | ||
55 | + if (ignore_chroot && pseudo_chroot && strncmp(path, pseudo_chroot, pseudo_chroot_len) == 0) | ||
56 | + return 0; | ||
57 | + env = pseudo_get_value("PSEUDO_IGNORE_PATHS"); | ||
58 | + if (env) { | ||
59 | + char *p = env; | ||
60 | + while (*p) { | ||
61 | + char *next = strchr(p, ','); | ||
62 | + if (!next) | ||
63 | + next = strchr(p, '\0'); | ||
64 | + if ((next - p) && !strncmp(path, p, next - p)) { | ||
65 | + pseudo_debug(PDBGF_PATH | PDBGF_VERBOSE, "ignoring path: '%s'\n", path); | ||
66 | + return 1; | ||
67 | + } | ||
68 | + if (next && *next != '\0') | ||
69 | + p = next+1; | ||
70 | + else | ||
71 | + break; | ||
72 | + } | ||
73 | + free(env); | ||
74 | + } | ||
75 | + } | ||
76 | + return 0; | ||
77 | +} | ||
78 | + | ||
79 | +int pseudo_client_ignore_path(const char *path) { | ||
80 | + return pseudo_client_ignore_path_chroot(path, 1); | ||
81 | +} | ||
82 | + | ||
83 | pseudo_msg_t * | ||
84 | pseudo_client_op(pseudo_op_t op, int access, int fd, int dirfd, const char *path, const PSEUDO_STATBUF *buf, ...) { | ||
85 | pseudo_msg_t *result = 0; | ||
86 | @@ -1522,6 +1559,16 @@ pseudo_client_op(pseudo_op_t op, int acc | ||
87 | } | ||
88 | } | ||
89 | |||
90 | + if (op != OP_CHROOT && op != OP_CHDIR && op != OP_CLOSE && op != OP_DUP | ||
91 | + && pseudo_client_ignore_path_chroot(path, 0)) { | ||
92 | + if (op == OP_OPEN) { | ||
93 | + pseudo_client_path(fd, path); | ||
94 | + } | ||
95 | + /* reenable wrappers */ | ||
96 | + pseudo_magic(); | ||
97 | + return result; | ||
98 | + } | ||
99 | + | ||
100 | #ifdef PSEUDO_XATTRDB | ||
101 | if (buf) { | ||
102 | struct stat64 bufcopy = *buf; | ||
103 | Index: git/pseudo_util.c | ||
104 | =================================================================== | ||
105 | --- git.orig/pseudo_util.c | ||
106 | +++ git/pseudo_util.c | ||
107 | @@ -43,6 +43,7 @@ static struct pseudo_variables pseudo_en | ||
108 | { "PSEUDO_BINDIR", 13, NULL }, | ||
109 | { "PSEUDO_LIBDIR", 13, NULL }, | ||
110 | { "PSEUDO_LOCALSTATEDIR", 20, NULL }, | ||
111 | + { "PSEUDO_IGNORE_PATHS", 19, NULL }, | ||
112 | { "PSEUDO_PASSWD", 13, NULL }, | ||
113 | { "PSEUDO_CHROOT", 13, NULL }, | ||
114 | { "PSEUDO_UIDS", 11, NULL }, | ||
115 | Index: git/pseudo_client.h | ||
116 | =================================================================== | ||
117 | --- git.orig/pseudo_client.h | ||
118 | +++ git/pseudo_client.h | ||
119 | @@ -7,6 +7,8 @@ | ||
120 | * | ||
121 | */ | ||
122 | extern pseudo_msg_t *pseudo_client_op(pseudo_op_t op, int access, int fd, int dirfd, const char *path, const PSEUDO_STATBUF *buf, ...); | ||
123 | +extern int pseudo_client_ignore_path(const char *path); | ||
124 | +extern int pseudo_client_ignore_fd(int fd); | ||
125 | #if PSEUDO_STATBUF_64 | ||
126 | #define base_lstat real_lstat64 | ||
127 | #define base_fstat real_fstat64 | ||
128 | Index: git/ports/linux/wrapfuncs.in | ||
129 | =================================================================== | ||
130 | --- git.orig/ports/linux/wrapfuncs.in | ||
131 | +++ git/ports/linux/wrapfuncs.in | ||
132 | @@ -1,23 +1,23 @@ | ||
133 | -int open(const char *path, int flags, ...{mode_t mode}); /* flags=flags&O_NOFOLLOW */ | ||
134 | +int open(const char *path, int flags, ...{mode_t mode}); /* flags=flags&O_NOFOLLOW, noignore_path=1 */ | ||
135 | char *get_current_dir_name(void); | ||
136 | int __xstat(int ver, const char *path, struct stat *buf); | ||
137 | int __lxstat(int ver, const char *path, struct stat *buf); /* flags=AT_SYMLINK_NOFOLLOW */ | ||
138 | int __fxstat(int ver, int fd, struct stat *buf); | ||
139 | int lchown(const char *path, uid_t owner, gid_t group); /* flags=AT_SYMLINK_NOFOLLOW */ | ||
140 | int __fxstatat(int ver, int dirfd, const char *path, struct stat *buf, int flags); | ||
141 | -int openat(int dirfd, const char *path, int flags, ...{mode_t mode}); /* flags=flags&O_NOFOLLOW */ | ||
142 | -int __openat_2(int dirfd, const char *path, int flags); /* flags=flags&O_NOFOLLOW */ | ||
143 | +int openat(int dirfd, const char *path, int flags, ...{mode_t mode}); /* flags=flags&O_NOFOLLOW, noignore_path=1 */ | ||
144 | +int __openat_2(int dirfd, const char *path, int flags); /* flags=flags&O_NOFOLLOW, noignore_path=1 */ | ||
145 | int mknod(const char *path, mode_t mode, dev_t dev); /* real_func=pseudo_mknod */ | ||
146 | int mknodat(int dirfd, const char *path, mode_t mode, dev_t dev); /* real_func=pseudo_mknodat */ | ||
147 | int __xmknod(int ver, const char *path, mode_t mode, dev_t *dev); /* flags=AT_SYMLINK_NOFOLLOW */ | ||
148 | int __xmknodat(int ver, int dirfd, const char *path, mode_t mode, dev_t *dev); /* flags=AT_SYMLINK_NOFOLLOW */ | ||
149 | -int fcntl(int fd, int cmd, ...{struct flock *lock}); | ||
150 | +int fcntl(int fd, int cmd, ...{struct flock *lock}); /* noignore_path=1 */ | ||
151 | # just so we know the inums of symlinks | ||
152 | char *canonicalize_file_name(const char *filename); | ||
153 | int eaccess(const char *path, int mode); | ||
154 | -int open64(const char *path, int flags, ...{mode_t mode}); /* flags=flags&O_NOFOLLOW */ | ||
155 | -int openat64(int dirfd, const char *path, int flags, ...{mode_t mode}); /* flags=flags&O_NOFOLLOW */ | ||
156 | -int __openat64_2(int dirfd, const char *path, int flags); /* flags=flags&O_NOFOLLOW */ | ||
157 | +int open64(const char *path, int flags, ...{mode_t mode}); /* flags=flags&O_NOFOLLOW, noignore_path=1 */ | ||
158 | +int openat64(int dirfd, const char *path, int flags, ...{mode_t mode}); /* flags=flags&O_NOFOLLOW, noignore_path=1 */ | ||
159 | +int __openat64_2(int dirfd, const char *path, int flags); /* flags=flags&O_NOFOLLOW, noignore_path=1 */ | ||
160 | int creat64(const char *path, mode_t mode); | ||
161 | int stat(const char *path, struct stat *buf); /* real_func=pseudo_stat */ | ||
162 | int lstat(const char *path, struct stat *buf); /* real_func=pseudo_lstat, flags=AT_SYMLINK_NOFOLLOW */ | ||
163 | @@ -29,9 +29,9 @@ int __xstat64(int ver, const char *path, | ||
164 | int __lxstat64(int ver, const char *path, struct stat64 *buf); /* flags=AT_SYMLINK_NOFOLLOW */ | ||
165 | int __fxstat64(int ver, int fd, struct stat64 *buf); | ||
166 | int __fxstatat64(int ver, int dirfd, const char *path, struct stat64 *buf, int flags); | ||
167 | -FILE *fopen64(const char *path, const char *mode); | ||
168 | -int nftw64(const char *path, int (*fn)(const char *, const struct stat64 *, int, struct FTW *), int nopenfd, int flag); | ||
169 | -FILE *freopen64(const char *path, const char *mode, FILE *stream); | ||
170 | +FILE *fopen64(const char *path, const char *mode); /* noignore_path=1 */ | ||
171 | +int nftw64(const char *path, int (*fn)(const char *, const struct stat64 *, int, struct FTW *), int nopenfd, int flag); /* noignore_path=1 */ | ||
172 | +FILE *freopen64(const char *path, const char *mode, FILE *stream); /* noignore_path=1 */ | ||
173 | int ftw64(const char *path, int (*fn)(const char *, const struct stat64 *, int), int nopenfd); | ||
174 | int glob64(const char *pattern, int flags, int (*errfunc)(const char *, int), glob64_t *pglob); | ||
175 | int scandir64(const char *path, struct dirent64 ***namelist, int (*filter)(const struct dirent64 *), int (*compar)()); | ||
176 | Index: git/templates/wrapfuncs.c | ||
177 | =================================================================== | ||
178 | --- git.orig/templates/wrapfuncs.c | ||
179 | +++ git/templates/wrapfuncs.c | ||
180 | @@ -60,9 +60,15 @@ ${maybe_async_skip} | ||
181 | ${rc_assign} (*real_${name})(${call_args}); | ||
182 | } else { | ||
183 | ${fix_paths} | ||
184 | - /* exec*() use this to restore the sig mask */ | ||
185 | - pseudo_saved_sigmask = saved; | ||
186 | - ${rc_assign} wrap_$name(${call_args}); | ||
187 | + if (${ignore_paths}) { | ||
188 | + /* call the real syscall */ | ||
189 | + pseudo_debug(PDBGF_SYSCALL, "${name} ignored path, calling real syscall.\n"); | ||
190 | + ${rc_assign} (*real_${name})(${call_args}); | ||
191 | + } else { | ||
192 | + /* exec*() use this to restore the sig mask */ | ||
193 | + pseudo_saved_sigmask = saved; | ||
194 | + ${rc_assign} wrap_$name(${call_args}); | ||
195 | + } | ||
196 | } | ||
197 | ${variadic_end} | ||
198 | save_errno = errno; | ||
199 | Index: git/ports/unix/wrapfuncs.in | ||
200 | =================================================================== | ||
201 | --- git.orig/ports/unix/wrapfuncs.in | ||
202 | +++ git/ports/unix/wrapfuncs.in | ||
203 | @@ -1,14 +1,14 @@ | ||
204 | int creat(const char *path, mode_t mode); | ||
205 | char *getcwd(char *buf, size_t size); | ||
206 | char *getwd(char *buf); | ||
207 | -int close(int fd); | ||
208 | +int close(int fd); /* noignore_path=1 */ | ||
209 | int fchmod(int fd, mode_t mode); | ||
210 | int fchown(int fd, uid_t owner, gid_t group); | ||
211 | int lchown(const char *path, uid_t owner, gid_t group); /* flags=AT_SYMLINK_NOFOLLOW */ | ||
212 | -int dup2(int oldfd, int newfd); | ||
213 | -int dup(int fd); | ||
214 | -int chdir(const char *path); | ||
215 | -int fchdir(int dirfd); | ||
216 | +int dup2(int oldfd, int newfd); /* noignore_path=1 */ | ||
217 | +int dup(int fd); /* noignore_path=1 */ | ||
218 | +int chdir(const char *path); /* noignore_path=1 */ | ||
219 | +int fchdir(int dirfd); /* noignore_path=1 */ | ||
220 | int access(const char *path, int mode); | ||
221 | FTS *fts_open(char * const *path_argv, int options, int (*compar)(const FTSENT **, const FTSENT **)); /* inode64=1 */ | ||
222 | int ftw(const char *path, int (*fn)(const char *, const struct stat *, int), int nopenfd); | ||
223 | @@ -20,18 +20,18 @@ char *mktemp(char *template); | ||
224 | long pathconf(const char *path, int name); | ||
225 | char *realpath(const char *name, char *resolved_name); /* version="GLIBC_2.3" */ | ||
226 | int remove(const char *path); /* flags=AT_SYMLINK_NOFOLLOW */ | ||
227 | -DIR *opendir(const char *path); | ||
228 | -int closedir(DIR *dirp); | ||
229 | +DIR *opendir(const char *path); /* noignore_path=1 */ | ||
230 | +int closedir(DIR *dirp); /* noignore_path=1 */ | ||
231 | char *tempnam(const char *template, const char *pfx); | ||
232 | char *tmpnam(char *s); | ||
233 | int truncate(const char *path, off_t length); | ||
234 | int utime(const char *path, const struct utimbuf *buf); | ||
235 | int utimes(const char *path, const struct timeval *times); | ||
236 | # needed because libc stdio does horrible things with inline asm syscalls | ||
237 | -FILE *fopen(const char *path, const char *mode); | ||
238 | -int fclose(FILE *fp); | ||
239 | -FILE *freopen(const char *path, const char *mode, FILE *stream); | ||
240 | -int chroot(const char *path); | ||
241 | +FILE *fopen(const char *path, const char *mode); /* noignore_path=1 */ | ||
242 | +int fclose(FILE *fp); /* noignore_path=1 */ | ||
243 | +FILE *freopen(const char *path, const char *mode, FILE *stream); /* noignore_path=1 */ | ||
244 | +int chroot(const char *path); /* noignore_path=1 */ | ||
245 | int acct(const char *path); | ||
246 | int chmod(const char *path, mode_t mode); | ||
247 | int chown(const char *path, uid_t owner, gid_t group); | ||
248 | Index: git/makewrappers | ||
249 | =================================================================== | ||
250 | --- git.orig/makewrappers | ||
251 | +++ git/makewrappers | ||
252 | @@ -228,6 +228,8 @@ class Function: | ||
253 | self.real_func = None | ||
254 | self.paths_to_munge = [] | ||
255 | self.specific_dirfds = {} | ||
256 | + self.fd_arg = False | ||
257 | + self.noignore_path = False | ||
258 | self.hand_wrapped = None | ||
259 | self.async_skip = None | ||
260 | # used for the copyright date when creating stub functions | ||
261 | @@ -267,6 +269,11 @@ class Function: | ||
262 | self.flags = '(flags & AT_SYMLINK_NOFOLLOW)' | ||
263 | elif arg.name.endswith('path'): | ||
264 | self.paths_to_munge.append(arg.name) | ||
265 | + elif arg.name == 'fd': | ||
266 | + self.fd_arg = "fd" | ||
267 | + elif arg.name == 'filedes': | ||
268 | + self.fd_arg = "filedes" | ||
269 | + | ||
270 | |||
271 | # pick default values | ||
272 | if self.type == 'void': | ||
273 | @@ -361,6 +368,25 @@ class Function: | ||
274 | (path, prefix, self.dirfd, path, self.flags)) | ||
275 | return "\n\t\t".join(fix_paths) | ||
276 | |||
277 | + def ignore_paths(self): | ||
278 | + if self.noignore_path: | ||
279 | + return "0" | ||
280 | + | ||
281 | + mainpath = None | ||
282 | + if "oldpath" in self.paths_to_munge: | ||
283 | + mainpath = "oldpath" | ||
284 | + elif "newpath" in self.paths_to_munge: | ||
285 | + mainpath = "newpath" | ||
286 | + elif "path" in self.paths_to_munge: | ||
287 | + mainpath = "path" | ||
288 | + | ||
289 | + if mainpath: | ||
290 | + return "pseudo_client_ignore_path(%s)" % mainpath | ||
291 | + if self.fd_arg: | ||
292 | + return "pseudo_client_ignore_fd(%s)" % self.fd_arg | ||
293 | + | ||
294 | + return "0" | ||
295 | + | ||
296 | def real_predecl(self): | ||
297 | if self.real_func: | ||
298 | return self.decl().replace(self.name, self.real_func, 1) + ";" | ||
diff --git a/meta/recipes-devtools/pseudo/files/delete_mismatches.patch b/meta/recipes-devtools/pseudo/files/delete_mismatches.patch deleted file mode 100644 index 6c78d787c7..0000000000 --- a/meta/recipes-devtools/pseudo/files/delete_mismatches.patch +++ /dev/null | |||
@@ -1,51 +0,0 @@ | |||
1 | When we see cases where the inode no longer matches the file path, pseudo | ||
2 | notices but currently reuses the database entry. This can happen where for | ||
3 | example, a file is deleted and a new file created outside of pseudo where | ||
4 | the inode number is reused. | ||
5 | |||
6 | Change this to ignore the likely stale database entry instead. We're | ||
7 | seeing bugs where inode reuse for deleted files causes permission corruption. | ||
8 | (See bug #14057 for example). We don't want to delete the database entry | ||
9 | as the permissions may need to be applied to that file (and testing shows | ||
10 | we do need the path matching code which handles that). | ||
11 | |||
12 | I appreciate this should never happen under the original design of pseudo | ||
13 | where all file accesses are monitored by pseudo. The reality is to do that, | ||
14 | we'd have to run pseudo: | ||
15 | |||
16 | a) for all tasks | ||
17 | b) as one pseudo database for all of TMPDIR | ||
18 | |||
19 | Neither of these is realistically possible for performance reasons. | ||
20 | |||
21 | I believe pseudo to be much better at catching all accesses than it | ||
22 | might once have been. As such, these "fixups" are in the cases I've | ||
23 | seen in the logs, always incorrect. | ||
24 | |||
25 | It therefore makes more sense to ignore the database data rather than | ||
26 | corrupt the file permissions or worse. Looking at the pseudo logs | ||
27 | in my heavily reused build directories, the number of these | ||
28 | errors is staggering. This issue would explain many weird bugs we've | ||
29 | seen over the years. | ||
30 | |||
31 | There is a risk that we could not map permissions in some case where | ||
32 | we currently would. I have not seen evidence of this in any logs I've | ||
33 | read though. This change, whilst going against the original design, | ||
34 | is in my view the safer option for the project at this point given we | ||
35 | don't use pseudo as originally designed and never will be able to. | ||
36 | |||
37 | Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org> | ||
38 | Upstream-Status: Pending | ||
39 | |||
40 | Index: git/pseudo.c | ||
41 | =================================================================== | ||
42 | --- git.orig/pseudo.c | ||
43 | +++ git/pseudo.c | ||
44 | @@ -699,6 +701,7 @@ pseudo_op(pseudo_msg_t *msg, const char | ||
45 | (unsigned long long) msg_header.ino, | ||
46 | path_by_ino ? path_by_ino : "no path", | ||
47 | msg->path); | ||
48 | + found_ino = 0; | ||
49 | } | ||
50 | } | ||
51 | } else { | ||
diff --git a/meta/recipes-devtools/pseudo/files/mayunlink.patch b/meta/recipes-devtools/pseudo/files/mayunlink.patch deleted file mode 100644 index 9d54e40dd9..0000000000 --- a/meta/recipes-devtools/pseudo/files/mayunlink.patch +++ /dev/null | |||
@@ -1,37 +0,0 @@ | |||
1 | Some operations may call unlink() on an open fd, then call fchown/fchmod/fstat | ||
2 | on that fd. This would currently readd its entry to the database, which | ||
3 | is necessary to preserve its permissions information however since that | ||
4 | file will be lost when it is closed, we don't want the DB entry to persist. | ||
5 | Marking it as may_unlink means the code will know its likely been deleted | ||
6 | and ignore the entry later, giving improved behaviour that simple path | ||
7 | mismatch warnings. We can use an nlink of zero to detect this. | ||
8 | |||
9 | Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org> | ||
10 | Upstream-Status: Pending | ||
11 | |||
12 | Index: git/pseudo.c | ||
13 | =================================================================== | ||
14 | --- git.orig/pseudo.c | ||
15 | +++ git/pseudo.c | ||
16 | @@ -1100,6 +1100,21 @@ pseudo_op(pseudo_msg_t *msg, const char | ||
17 | break; | ||
18 | } | ||
19 | |||
20 | + switch (msg->op) { | ||
21 | + case OP_FCHOWN: /* FALLTHROUGH */ | ||
22 | + case OP_FCHMOD: /* FALLTHROUGH */ | ||
23 | + case OP_FSTAT: | ||
24 | + if (!found_path && !found_ino && (msg->nlink == 0)) { | ||
25 | + /* If nlink is 0 for an fchown/fchmod/fstat, we probably have an fd which is | ||
26 | + * unlinked and we don't want to do inode/path matching against it. Marking it | ||
27 | + * as may unlink gives the right hints in the database to ensure we | ||
28 | + * handle correctly whilst maintaining the permissions whilst the | ||
29 | + * file exists for the fd. */ | ||
30 | + pdb_may_unlink_file(msg, msg->client); | ||
31 | + } | ||
32 | + break; | ||
33 | + } | ||
34 | + | ||
35 | op_exit: | ||
36 | /* in the case of an exact match, we just used the pointer | ||
37 | * rather than allocating space. | ||
diff --git a/meta/recipes-devtools/pseudo/files/pathfix.patch b/meta/recipes-devtools/pseudo/files/pathfix.patch deleted file mode 100644 index b3e63fa28f..0000000000 --- a/meta/recipes-devtools/pseudo/files/pathfix.patch +++ /dev/null | |||
@@ -1,25 +0,0 @@ | |||
1 | We're seeing systems in the wild (e.g. ubuntu 20.04) which call | ||
2 | with a dirfd set to the full filename and path set to "". Since | ||
3 | this seems to be expected to work, handle it accordingly. | ||
4 | |||
5 | Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org> | ||
6 | Upstream-Status: Pending | ||
7 | |||
8 | Index: git/pseudo_client.c | ||
9 | =================================================================== | ||
10 | --- git.orig/pseudo_client.c | ||
11 | +++ git/pseudo_client.c | ||
12 | @@ -1549,8 +1549,12 @@ base_path(int dirfd, const char *path, i | ||
13 | |||
14 | if (!path) | ||
15 | return NULL; | ||
16 | - if (!*path) | ||
17 | + | ||
18 | + if (!*path) { | ||
19 | + if (dirfd != -1 && dirfd != AT_FDCWD) | ||
20 | + return fd_path(dirfd); | ||
21 | return ""; | ||
22 | + } | ||
23 | |||
24 | if (path[0] != '/') { | ||
25 | if (dirfd != -1 && dirfd != AT_FDCWD) { | ||
diff --git a/meta/recipes-devtools/pseudo/files/statxfix.patch b/meta/recipes-devtools/pseudo/files/statxfix.patch deleted file mode 100644 index c47ff27f9f..0000000000 --- a/meta/recipes-devtools/pseudo/files/statxfix.patch +++ /dev/null | |||
@@ -1,56 +0,0 @@ | |||
1 | There is magic in the posts where specific variable names have specific | ||
2 | magic. For that magic to work, "path" needs to be used not "pathname" as | ||
3 | is currently there. Fix this, which fixes path issues on systems using | ||
4 | statx (Ubuntu 20.04 in particular). | ||
5 | |||
6 | Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org> | ||
7 | Upstream-Status: Pending | ||
8 | |||
9 | Index: git/ports/linux/statx/guts/statx.c | ||
10 | =================================================================== | ||
11 | --- git.orig/ports/linux/statx/guts/statx.c | ||
12 | +++ git/ports/linux/statx/guts/statx.c | ||
13 | @@ -5,14 +5,14 @@ | ||
14 | * SPDX-License-Identifier: LGPL-2.1-only | ||
15 | * | ||
16 | * int | ||
17 | - * statx(int dirfd, const char *pathname, int flags, unsigned int mask, struct statx *statxbuf) { | ||
18 | + * statx(int dirfd, const char *path, int flags, unsigned int mask, struct statx *statxbuf) { | ||
19 | * int rc = -1; | ||
20 | */ | ||
21 | pseudo_msg_t *msg; | ||
22 | PSEUDO_STATBUF buf; | ||
23 | int save_errno; | ||
24 | |||
25 | - rc = real_statx(dirfd, pathname, flags, mask, statxbuf); | ||
26 | + rc = real_statx(dirfd, path, flags, mask, statxbuf); | ||
27 | save_errno = errno; | ||
28 | if (rc == -1) { | ||
29 | return rc; | ||
30 | @@ -25,16 +25,16 @@ | ||
31 | buf.st_mode = statxbuf->stx_mode; | ||
32 | buf.st_rdev = makedev(statxbuf->stx_rdev_major, statxbuf->stx_rdev_minor); | ||
33 | buf.st_nlink = statxbuf->stx_nlink; | ||
34 | - msg = pseudo_client_op(OP_STAT, 0, -1, dirfd, pathname, &buf); | ||
35 | + msg = pseudo_client_op(OP_STAT, 0, -1, dirfd, path, &buf); | ||
36 | if (msg && msg->result == RESULT_SUCCEED) { | ||
37 | - pseudo_debug(PDBGF_FILE, "statx(path %s), flags %o, stat rc %d, stat uid %o\n", pathname, flags, rc, statxbuf->stx_uid); | ||
38 | + pseudo_debug(PDBGF_FILE, "statx(path %s), flags %o, stat rc %d, stat uid %o\n", path, flags, rc, statxbuf->stx_uid); | ||
39 | statxbuf->stx_uid = msg->uid; | ||
40 | statxbuf->stx_gid = msg->gid; | ||
41 | statxbuf->stx_mode = msg->mode; | ||
42 | statxbuf->stx_rdev_major = major(msg->rdev); | ||
43 | statxbuf->stx_rdev_minor = minor(msg->rdev); | ||
44 | } else { | ||
45 | - pseudo_debug(PDBGF_FILE, "statx(path %s) failed, flags %o, stat rc %d, stat uid %o\n", pathname, flags, rc, statxbuf->stx_uid); | ||
46 | + pseudo_debug(PDBGF_FILE, "statx(path %s) failed, flags %o, stat rc %d, stat uid %o\n", path, flags, rc, statxbuf->stx_uid); | ||
47 | } | ||
48 | errno = save_errno; | ||
49 | /* return rc; | ||
50 | Index: git/ports/linux/statx/wrapfuncs.in | ||
51 | =================================================================== | ||
52 | --- git.orig/ports/linux/statx/wrapfuncs.in | ||
53 | +++ git/ports/linux/statx/wrapfuncs.in | ||
54 | @@ -1 +1 @@ | ||
55 | -int statx(int dirfd, const char *pathname, int flags, unsigned int mask, struct statx *statxbuf); | ||
56 | +int statx(int dirfd, const char *path, int flags, unsigned int mask, struct statx *statxbuf); | ||
diff --git a/meta/recipes-devtools/pseudo/files/track_link_fds.patch b/meta/recipes-devtools/pseudo/files/track_link_fds.patch deleted file mode 100644 index a3a9eb3f23..0000000000 --- a/meta/recipes-devtools/pseudo/files/track_link_fds.patch +++ /dev/null | |||
@@ -1,155 +0,0 @@ | |||
1 | Consider what happens if a program does: | ||
2 | |||
3 | fd = fopen("A") | ||
4 | link("A", "B") | ||
5 | unlink("A") | ||
6 | fchown(fd) | ||
7 | |||
8 | Assuming we can't use the database, in order to handle this correctly, | ||
9 | we need to change the open fd to point at B when A us unlinked. | ||
10 | |||
11 | Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org> | ||
12 | Upstream-Status: Pending | ||
13 | |||
14 | Index: 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 | |||
26 | Index: 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: | ||
144 | Index: 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/files/xattr_fix.patch b/meta/recipes-devtools/pseudo/files/xattr_fix.patch deleted file mode 100644 index 61d0030b10..0000000000 --- a/meta/recipes-devtools/pseudo/files/xattr_fix.patch +++ /dev/null | |||
@@ -1,40 +0,0 @@ | |||
1 | |||
2 | In the xattr handling functions, if result is NULL, which it can be | ||
3 | with the path ignore code, there is a NULL pointer dereference and | ||
4 | segfault. Everywhere else checks result first, this appears to just | ||
5 | be an omission. | ||
6 | |||
7 | Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org> | ||
8 | Upstream-Status: Pending | ||
9 | |||
10 | Index: git/ports/linux/xattr/pseudo_wrappers.c | ||
11 | =================================================================== | ||
12 | --- git.orig/ports/linux/xattr/pseudo_wrappers.c | ||
13 | +++ git/ports/linux/xattr/pseudo_wrappers.c | ||
14 | @@ -134,7 +134,7 @@ static ssize_t shared_getxattr(const cha | ||
15 | pseudo_debug(PDBGF_XATTR, "getxattr(%s [fd %d], %s)\n", | ||
16 | path ? path : "<no path>", fd, name); | ||
17 | pseudo_msg_t *result = pseudo_client_op(OP_GET_XATTR, 0, fd, -1, path, &buf, name); | ||
18 | - if (result->result != RESULT_SUCCEED) { | ||
19 | + if (!result || result->result != RESULT_SUCCEED) { | ||
20 | errno = ENOATTR; | ||
21 | return -1; | ||
22 | } | ||
23 | @@ -254,7 +254,7 @@ static int shared_setxattr(const char *p | ||
24 | static ssize_t shared_listxattr(const char *path, int fd, char *list, size_t size) { | ||
25 | RC_AND_BUF | ||
26 | pseudo_msg_t *result = pseudo_client_op(OP_LIST_XATTR, 0, fd, -1, path, &buf); | ||
27 | - if (result->result != RESULT_SUCCEED) { | ||
28 | + if (!result || result->result != RESULT_SUCCEED) { | ||
29 | pseudo_debug(PDBGF_XATTR, "listxattr: no success.\n"); | ||
30 | errno = ENOATTR; | ||
31 | return -1; | ||
32 | @@ -276,7 +276,7 @@ static int shared_removexattr(const char | ||
33 | RC_AND_BUF | ||
34 | pseudo_msg_t *result = pseudo_client_op(OP_REMOVE_XATTR, 0, fd, -1, path, &buf, name); | ||
35 | |||
36 | - if (result->result != RESULT_SUCCEED) { | ||
37 | + if (!result || result->result != RESULT_SUCCEED) { | ||
38 | /* docs say ENOATTR, but I don't have one */ | ||
39 | errno = ENOENT; | ||
40 | return -1; | ||