2 * SPDX-License-Identifier: LGPL-2.1-only
4 * Copyright (C) 2009 Pierre-Marc Fournier
5 * Copyright (C) 2011-2012 Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
8 /* Has to be included first to override dlfcn.h */
9 #include <common/compat/dlfcn.h>
18 #include <lttng/ust-fork.h>
22 static pid_t (*plibc_func
)(void) = NULL
;
27 if (plibc_func
== NULL
) {
28 plibc_func
= dlsym(RTLD_NEXT
, "fork");
29 if (plibc_func
== NULL
) {
30 fprintf(stderr
, "libustfork: unable to find \"fork\" symbol\n");
36 lttng_ust_before_fork(&sigset
);
37 /* Do the real fork */
38 retval
= plibc_func();
42 lttng_ust_after_fork_child(&sigset
);
44 lttng_ust_after_fork_parent(&sigset
);
50 int daemon(int nochdir
, int noclose
)
52 static int (*plibc_func
)(int nochdir
, int noclose
) = NULL
;
57 if (plibc_func
== NULL
) {
58 plibc_func
= dlsym(RTLD_NEXT
, "daemon");
59 if (plibc_func
== NULL
) {
60 fprintf(stderr
, "libustfork: unable to find \"daemon\" symbol\n");
66 lttng_ust_before_fork(&sigset
);
67 /* Do the real daemon call */
68 retval
= plibc_func(nochdir
, noclose
);
71 /* child, parent called _exit() directly */
72 lttng_ust_after_fork_child(&sigset
);
74 /* on error in the parent */
75 lttng_ust_after_fork_parent(&sigset
);
83 static int (*plibc_func
)(uid_t uid
) = NULL
;
87 if (plibc_func
== NULL
) {
88 plibc_func
= dlsym(RTLD_NEXT
, "setuid");
89 if (plibc_func
== NULL
) {
90 fprintf(stderr
, "libustfork: unable to find \"setuid\" symbol\n");
96 /* Do the real setuid */
97 retval
= plibc_func(uid
);
100 lttng_ust_after_setuid();
106 int setgid(gid_t gid
)
108 static int (*plibc_func
)(gid_t gid
) = NULL
;
112 if (plibc_func
== NULL
) {
113 plibc_func
= dlsym(RTLD_NEXT
, "setgid");
114 if (plibc_func
== NULL
) {
115 fprintf(stderr
, "libustfork: unable to find \"setgid\" symbol\n");
121 /* Do the real setgid */
122 retval
= plibc_func(gid
);
125 lttng_ust_after_setgid();
131 int seteuid(uid_t euid
)
133 static int (*plibc_func
)(uid_t euid
) = NULL
;
137 if (plibc_func
== NULL
) {
138 plibc_func
= dlsym(RTLD_NEXT
, "seteuid");
139 if (plibc_func
== NULL
) {
140 fprintf(stderr
, "libustfork: unable to find \"seteuid\" symbol\n");
146 /* Do the real seteuid */
147 retval
= plibc_func(euid
);
150 lttng_ust_after_seteuid();
156 int setegid(gid_t egid
)
158 static int (*plibc_func
)(gid_t egid
) = NULL
;
162 if (plibc_func
== NULL
) {
163 plibc_func
= dlsym(RTLD_NEXT
, "setegid");
164 if (plibc_func
== NULL
) {
165 fprintf(stderr
, "libustfork: unable to find \"setegid\" symbol\n");
171 /* Do the real setegid */
172 retval
= plibc_func(egid
);
175 lttng_ust_after_setegid();
181 int setreuid(uid_t ruid
, uid_t euid
)
183 static int (*plibc_func
)(uid_t ruid
, uid_t euid
) = NULL
;
187 if (plibc_func
== NULL
) {
188 plibc_func
= dlsym(RTLD_NEXT
, "setreuid");
189 if (plibc_func
== NULL
) {
190 fprintf(stderr
, "libustfork: unable to find \"setreuid\" symbol\n");
196 /* Do the real setreuid */
197 retval
= plibc_func(ruid
, euid
);
200 lttng_ust_after_setreuid();
206 int setregid(gid_t rgid
, gid_t egid
)
208 static int (*plibc_func
)(gid_t rgid
, gid_t egid
) = NULL
;
212 if (plibc_func
== NULL
) {
213 plibc_func
= dlsym(RTLD_NEXT
, "setregid");
214 if (plibc_func
== NULL
) {
215 fprintf(stderr
, "libustfork: unable to find \"setregid\" symbol\n");
221 /* Do the real setregid */
222 retval
= plibc_func(rgid
, egid
);
225 lttng_ust_after_setregid();
235 struct ustfork_clone_info
{
241 static int clone_fn(void *arg
)
243 struct ustfork_clone_info
*info
= (struct ustfork_clone_info
*) arg
;
245 /* clone is now done and we are in child */
246 lttng_ust_after_fork_child(&info
->sigset
);
247 return info
->fn(info
->arg
);
250 int clone(int (*fn
)(void *), void *child_stack
, int flags
, void *arg
, ...)
252 static int (*plibc_func
)(int (*fn
)(void *), void *child_stack
,
253 int flags
, void *arg
, pid_t
*ptid
,
254 struct user_desc
*tls
, pid_t
*ctid
) = NULL
;
257 struct user_desc
*tls
;
259 /* end of var args */
265 ptid
= va_arg(ap
, pid_t
*);
266 tls
= va_arg(ap
, struct user_desc
*);
267 ctid
= va_arg(ap
, pid_t
*);
270 if (plibc_func
== NULL
) {
271 plibc_func
= dlsym(RTLD_NEXT
, "clone");
272 if (plibc_func
== NULL
) {
273 fprintf(stderr
, "libustfork: unable to find \"clone\" symbol.\n");
279 if (flags
& CLONE_VM
) {
281 * Creating a thread, no need to intervene, just pass on
284 retval
= plibc_func(fn
, child_stack
, flags
, arg
, ptid
,
288 /* Creating a real process, we need to intervene. */
289 struct ustfork_clone_info info
= { .fn
= fn
, .arg
= arg
};
291 lttng_ust_before_fork(&info
.sigset
);
292 retval
= plibc_func(clone_fn
, child_stack
, flags
, &info
,
295 /* The child doesn't get here. */
296 lttng_ust_after_fork_parent(&info
.sigset
);
302 int setns(int fd
, int nstype
)
304 static int (*plibc_func
)(int fd
, int nstype
) = NULL
;
308 if (plibc_func
== NULL
) {
309 plibc_func
= dlsym(RTLD_NEXT
, "setns");
310 if (plibc_func
== NULL
) {
311 fprintf(stderr
, "libustfork: unable to find \"setns\" symbol\n");
317 /* Do the real setns */
318 retval
= plibc_func(fd
, nstype
);
321 lttng_ust_after_setns();
327 int unshare(int flags
)
329 static int (*plibc_func
)(int flags
) = NULL
;
333 if (plibc_func
== NULL
) {
334 plibc_func
= dlsym(RTLD_NEXT
, "unshare");
335 if (plibc_func
== NULL
) {
336 fprintf(stderr
, "libustfork: unable to find \"unshare\" symbol\n");
342 /* Do the real setns */
343 retval
= plibc_func(flags
);
346 lttng_ust_after_unshare();
352 int setresuid(uid_t ruid
, uid_t euid
, uid_t suid
)
354 static int (*plibc_func
)(uid_t ruid
, uid_t euid
, uid_t suid
) = NULL
;
358 if (plibc_func
== NULL
) {
359 plibc_func
= dlsym(RTLD_NEXT
, "setresuid");
360 if (plibc_func
== NULL
) {
361 fprintf(stderr
, "libustfork: unable to find \"setresuid\" symbol\n");
367 /* Do the real setresuid */
368 retval
= plibc_func(ruid
, euid
, suid
);
371 lttng_ust_after_setresuid();
377 int setresgid(gid_t rgid
, gid_t egid
, gid_t sgid
)
379 static int (*plibc_func
)(gid_t rgid
, gid_t egid
, gid_t sgid
) = NULL
;
383 if (plibc_func
== NULL
) {
384 plibc_func
= dlsym(RTLD_NEXT
, "setresgid");
385 if (plibc_func
== NULL
) {
386 fprintf(stderr
, "libustfork: unable to find \"setresgid\" symbol\n");
392 /* Do the real setresgid */
393 retval
= plibc_func(rgid
, egid
, sgid
);
396 lttng_ust_after_setresgid();
402 #elif defined (__FreeBSD__)
404 pid_t
rfork(int flags
)
406 static pid_t (*plibc_func
)(void) = NULL
;
411 if (plibc_func
== NULL
) {
412 plibc_func
= dlsym(RTLD_NEXT
, "rfork");
413 if (plibc_func
== NULL
) {
414 fprintf(stderr
, "libustfork: unable to find \"rfork\" symbol\n");
420 lttng_ust_before_fork(&sigset
);
421 /* Do the real rfork */
422 retval
= plibc_func();
426 lttng_ust_after_fork_child(&sigset
);
428 lttng_ust_after_fork_parent(&sigset
);
435 * On BSD, no need to override vfork, because it runs in the context of
436 * the parent, with parent waiting until execve or exit is executed in
441 #warning "Unknown OS. You might want to ensure that fork/clone/vfork/fork handling is complete."
This page took 0.03897 seconds and 4 git commands to generate.