diff options
-rw-r--r-- | meta/recipes-devtools/pseudo/files/add_ignore_paths.patch | 298 | ||||
-rw-r--r-- | meta/recipes-devtools/pseudo/pseudo_git.bb | 1 |
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 @@ | |||
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/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 | |||
3 | SRC_URI = "git://git.yoctoproject.org/pseudo;branch=oe-core \ | 3 | SRC_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 | " |