summaryrefslogtreecommitdiffstats
path: root/meta/recipes-devtools/pseudo
diff options
context:
space:
mode:
authorRichard Purdie <richard.purdie@linuxfoundation.org>2020-09-24 00:02:04 +0100
committerRichard Purdie <richard.purdie@linuxfoundation.org>2020-10-07 11:18:38 +0100
commit84d006b9fb9c131fb626a090d9e4a76cc47eaf84 (patch)
tree18f4f1542d6c9f37b9829c79dd2c91d49391dc6f /meta/recipes-devtools/pseudo
parentb5c5d84b8be27c611c1c21d5c13039a90977bbd4 (diff)
downloadpoky-84d006b9fb9c131fb626a090d9e4a76cc47eaf84.tar.gz
pseudo: Add support for ignoring paths from the pseudo DB
Add PSEUDO_IGNORE_PATHS, a comma separated list of path prefixes, where any files underneath are not handled by pseudo. This allows files to be left out of the pseudo datanase where we know we don't need the fake root emulation. This is particularly useful if we know these files can be deleted outside of pseudo context. (From OE-Core rev: 8defb687a2c0ffac232c4d0d63a590871c453a2e) Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
Diffstat (limited to 'meta/recipes-devtools/pseudo')
-rw-r--r--meta/recipes-devtools/pseudo/files/add_ignore_paths.patch298
-rw-r--r--meta/recipes-devtools/pseudo/pseudo_git.bb1
2 files changed, 299 insertions, 0 deletions
diff --git a/meta/recipes-devtools/pseudo/files/add_ignore_paths.patch b/meta/recipes-devtools/pseudo/files/add_ignore_paths.patch
new file mode 100644
index 0000000000..eddfdb8674
--- /dev/null
+++ b/meta/recipes-devtools/pseudo/files/add_ignore_paths.patch
@@ -0,0 +1,298 @@
1Currently, pseudo considers any path accessed whist its running to be
2a valid entry to track in its database. The way OpenEmbedded uses pseudo,
3there are paths we care about accesses to from a pseudo perspective and paths
4which we simply don't care about.
5
6This patch adds a PSEUDO_IGNORE_PATHS environment variable which is a comma
7separated list of path prefixes to ignore accesses to.
8
9To do this, we add some functions which can check a path argument or a file
10descriptor argument and use these in the pseudo wrappers where path or fd
11arguments are present. Where paths are being ignored, we skip straight to
12the underlying real function.
13
14Psuedo needs to keep track of the open fd mappings to files so we still need
15to allow those cases into the pseudo_op function. Specficially this means
16OP_CLOSE, OP_OPEN, OP_DUP and OP_CHDIR.
17
18Apart from OP_OPEN which could call the server, the other operations are client
19side only so passed through. We 'tag' the functions using these operations so
20that the path ignore code isn't triggered. For OP_OPEN we exit early and skip
21the server op. We also have a catch all in client_op to ensure any operatings
22we didn't manage to skip early still get skipped correctly.
23
24OP_CHROOT is a special case. Where ignored path prefixes are used as a chroot,
25for the lifetime of the chroot, the path is effectively dropped from the
26PSEUDO_IGNORE_PATHS list. Whilst slightly counter intuaitive, this turned out
27to be the most effective way to do things due to commands like useradd and
28their use of chroots.
29
30For sqlite3 and appropriate path filtering in OE, this took the database from
3145,000 entries to about 180. For dbus this was 88,000 down to 760. Given the
32number of client to server trips these numbers of paths involves, the win
33is seemingly worthwhile.
34
35Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
36Upstream-Status: Pending
37
38Index: 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;
103Index: 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 },
115Index: 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
128Index: 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)());
176Index: 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;
199Index: 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);
248Index: 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/pseudo_git.bb b/meta/recipes-devtools/pseudo/pseudo_git.bb
index 7eb72f0eab..57c32d0cfc 100644
--- a/meta/recipes-devtools/pseudo/pseudo_git.bb
+++ b/meta/recipes-devtools/pseudo/pseudo_git.bb
@@ -3,6 +3,7 @@ require pseudo.inc
3SRC_URI = "git://git.yoctoproject.org/pseudo;branch=oe-core \ 3SRC_URI = "git://git.yoctoproject.org/pseudo;branch=oe-core \
4 file://0001-configure-Prune-PIE-flags.patch \ 4 file://0001-configure-Prune-PIE-flags.patch \
5 file://delete_mismatches.patch \ 5 file://delete_mismatches.patch \
6 file://add_ignore_paths.patch \
6 file://fallback-passwd \ 7 file://fallback-passwd \
7 file://fallback-group \ 8 file://fallback-group \
8 " 9 "