b3b182dd74ee240db741805adb2dca84c53fa671
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>
19 #include <lttng/ust-fork.h>
21 #if !defined(LTTNG_UST_CUSTOM_UPGRADE_CONFLICTING_SYMBOLS)
22 static int (*__ust_before_fork
)(sigset_t
*save_sigset
) = NULL
;
23 static int (*__ust_after_fork_child
)(sigset_t
*restore_sigset
) = NULL
;
24 static int (*__ust_after_fork_parent
)(sigset_t
*restore_sigset
) = NULL
;
26 static void (*__ust_after_setns
)(void) = NULL
;
27 static void (*__ust_after_unshare
)(void) = NULL
;
28 static void (*__ust_after_setuid
)(void) = NULL
;
29 static void (*__ust_after_setgid
)(void) = NULL
;
30 static void (*__ust_after_seteuid
)(void) = NULL
;
31 static void (*__ust_after_setegid
)(void) = NULL
;
32 static void (*__ust_after_setreuid
)(void) = NULL
;
33 static void (*__ust_after_setregid
)(void) = NULL
;
34 static void (*__ust_after_setresuid
)(void) = NULL
;
35 static void (*__ust_after_setresgid
)(void) = NULL
;
38 void *_init_ust_before_fork(void)
40 if (__ust_before_fork
== NULL
) {
41 __ust_before_fork
= dlsym(RTLD_DEFAULT
, "ust_before_fork");
43 if (__ust_before_fork
== NULL
) {
44 fprintf(stderr
, "%s\n", dlerror());
48 return __ust_before_fork
;
52 void *_init_ust_after_fork_child(void)
54 if (__ust_after_fork_child
== NULL
) {
55 __ust_after_fork_child
= dlsym(RTLD_DEFAULT
, "ust_after_fork_child");
57 if (__ust_after_fork_child
== NULL
) {
58 fprintf(stderr
, "%s\n", dlerror());
62 return __ust_after_fork_child
;
66 void *_init_ust_after_fork_parent(void)
68 if (__ust_after_fork_parent
== NULL
) {
69 __ust_after_fork_parent
= dlsym(RTLD_DEFAULT
, "ust_after_fork_parent");
71 if (__ust_after_fork_parent
== NULL
) {
72 fprintf(stderr
, "%s\n", dlerror());
76 return __ust_after_fork_parent
;
80 void *_init_ust_after_setns(void)
82 if (__ust_after_setns
== NULL
) {
83 __ust_after_setns
= dlsym(RTLD_DEFAULT
, "ust_after_setns");
85 if (__ust_after_setns
== NULL
) {
86 fprintf(stderr
, "%s\n", dlerror());
90 return __ust_after_setns
;
94 void *_init_ust_after_unshare(void)
96 if (__ust_after_unshare
== NULL
) {
97 __ust_after_unshare
= dlsym(RTLD_DEFAULT
, "ust_after_unshare");
99 if (__ust_after_unshare
== NULL
) {
100 fprintf(stderr
, "%s\n", dlerror());
104 return __ust_after_unshare
;
108 void *_init_ust_after_setuid(void)
110 if (__ust_after_setuid
== NULL
) {
111 __ust_after_setuid
= dlsym(RTLD_DEFAULT
, "ust_after_setuid");
113 if (__ust_after_setuid
== NULL
) {
114 fprintf(stderr
, "%s\n", dlerror());
118 return __ust_after_setuid
;
122 void *_init_ust_after_setgid(void)
124 if (__ust_after_setgid
== NULL
) {
125 __ust_after_setgid
= dlsym(RTLD_DEFAULT
, "ust_after_setgid");
127 if (__ust_after_setgid
== NULL
) {
128 fprintf(stderr
, "%s\n", dlerror());
132 return __ust_after_setgid
;
136 void *_init_ust_after_seteuid(void)
138 if (__ust_after_seteuid
== NULL
) {
139 __ust_after_seteuid
= dlsym(RTLD_DEFAULT
, "ust_after_seteuid");
141 if (__ust_after_seteuid
== NULL
) {
142 fprintf(stderr
, "%s\n", dlerror());
146 return __ust_after_seteuid
;
150 void *_init_ust_after_setegid(void)
152 if (__ust_after_setegid
== NULL
) {
153 __ust_after_setegid
= dlsym(RTLD_DEFAULT
, "ust_after_setegid");
155 if (__ust_after_setegid
== NULL
) {
156 fprintf(stderr
, "%s\n", dlerror());
160 return __ust_after_setegid
;
164 void *_init_ust_after_setreuid(void)
166 if (__ust_after_setreuid
== NULL
) {
167 __ust_after_setreuid
= dlsym(RTLD_DEFAULT
, "ust_after_setreuid");
169 if (__ust_after_setreuid
== NULL
) {
170 fprintf(stderr
, "%s\n", dlerror());
174 return __ust_after_setreuid
;
178 void *_init_ust_after_setregid(void)
180 if (__ust_after_setregid
== NULL
) {
181 __ust_after_setregid
= dlsym(RTLD_DEFAULT
, "ust_after_setregid");
183 if (__ust_after_setregid
== NULL
) {
184 fprintf(stderr
, "%s\n", dlerror());
188 return __ust_after_setregid
;
192 void *_init_ust_after_setresuid(void)
194 if (__ust_after_setresuid
== NULL
) {
195 __ust_after_setresuid
= dlsym(RTLD_DEFAULT
, "ust_after_setresuid");
197 if (__ust_after_setresuid
== NULL
) {
198 fprintf(stderr
, "%s\n", dlerror());
202 return __ust_after_setresuid
;
206 void *_init_ust_after_setresgid(void)
208 if (__ust_after_setresgid
== NULL
) {
209 __ust_after_setresgid
= dlsym(RTLD_DEFAULT
, "ust_after_setresgid");
211 if (__ust_after_setresgid
== NULL
) {
212 fprintf(stderr
, "%s\n", dlerror());
216 return __ust_after_setresgid
;
220 void _lttng_ust_fork_ctor(void)
221 __attribute__((constructor
));
223 void _lttng_ust_fork_ctor(void)
228 * Load ust-2.12 in the global symbol namespace.
230 handle
= dlopen("liblttng-ust.so.0", RTLD_GLOBAL
| RTLD_NOW
);
232 fprintf(stderr
, "liblttng-ust-fork.so.1: Failed to dlopen liblttng-ust.so.0: %s\n", dlerror());
240 static pid_t (*plibc_func
)(void) = NULL
;
245 if (plibc_func
== NULL
) {
246 plibc_func
= dlsym(RTLD_NEXT
, "fork");
247 if (plibc_func
== NULL
) {
248 fprintf(stderr
, "libustfork: unable to find \"fork\" symbol\n");
254 lttng_ust_before_fork(&sigset
);
255 #if !defined(LTTNG_UST_CUSTOM_UPGRADE_CONFLICTING_SYMBOLS)
256 if (_init_ust_before_fork()) {
257 __ust_before_fork(&sigset
);
261 /* Do the real fork */
262 retval
= plibc_func();
266 #if !defined(LTTNG_UST_CUSTOM_UPGRADE_CONFLICTING_SYMBOLS)
267 if (_init_ust_after_fork_child()) {
268 __ust_after_fork_child(&sigset
);
271 lttng_ust_after_fork_child(&sigset
);
273 #if !defined(LTTNG_UST_CUSTOM_UPGRADE_CONFLICTING_SYMBOLS)
274 if (_init_ust_after_fork_parent()) {
275 __ust_after_fork_parent(&sigset
);
278 lttng_ust_after_fork_parent(&sigset
);
284 int daemon(int nochdir
, int noclose
)
286 static int (*plibc_func
)(int nochdir
, int noclose
) = NULL
;
291 if (plibc_func
== NULL
) {
292 plibc_func
= dlsym(RTLD_NEXT
, "daemon");
293 if (plibc_func
== NULL
) {
294 fprintf(stderr
, "libustfork: unable to find \"daemon\" symbol\n");
300 lttng_ust_before_fork(&sigset
);
301 #if !defined(LTTNG_UST_CUSTOM_UPGRADE_CONFLICTING_SYMBOLS)
302 if (_init_ust_before_fork()) {
303 __ust_before_fork(&sigset
);
307 /* Do the real daemon call */
308 retval
= plibc_func(nochdir
, noclose
);
311 /* child, parent called _exit() directly */
312 #if !defined(LTTNG_UST_CUSTOM_UPGRADE_CONFLICTING_SYMBOLS)
313 if (_init_ust_after_fork_child()) {
314 __ust_after_fork_child(&sigset
);
317 lttng_ust_after_fork_child(&sigset
);
319 /* on error in the parent */
320 #if !defined(LTTNG_UST_CUSTOM_UPGRADE_CONFLICTING_SYMBOLS)
321 if (_init_ust_after_fork_parent()) {
322 __ust_after_fork_parent(&sigset
);
325 lttng_ust_after_fork_parent(&sigset
);
331 int setuid(uid_t uid
)
333 static int (*plibc_func
)(uid_t uid
) = NULL
;
337 if (plibc_func
== NULL
) {
338 plibc_func
= dlsym(RTLD_NEXT
, "setuid");
339 if (plibc_func
== NULL
) {
340 fprintf(stderr
, "libustfork: unable to find \"setuid\" symbol\n");
346 /* Do the real setuid */
347 retval
= plibc_func(uid
);
350 #if !defined(LTTNG_UST_CUSTOM_UPGRADE_CONFLICTING_SYMBOLS)
351 if (_init_ust_after_setuid()) {
352 __ust_after_setuid();
355 lttng_ust_after_setuid();
361 int setgid(gid_t gid
)
363 static int (*plibc_func
)(gid_t gid
) = NULL
;
367 if (plibc_func
== NULL
) {
368 plibc_func
= dlsym(RTLD_NEXT
, "setgid");
369 if (plibc_func
== NULL
) {
370 fprintf(stderr
, "libustfork: unable to find \"setgid\" symbol\n");
376 /* Do the real setgid */
377 retval
= plibc_func(gid
);
380 #if !defined(LTTNG_UST_CUSTOM_UPGRADE_CONFLICTING_SYMBOLS)
381 if (_init_ust_after_setgid()) {
382 __ust_after_setgid();
385 lttng_ust_after_setgid();
391 int seteuid(uid_t euid
)
393 static int (*plibc_func
)(uid_t euid
) = NULL
;
397 if (plibc_func
== NULL
) {
398 plibc_func
= dlsym(RTLD_NEXT
, "seteuid");
399 if (plibc_func
== NULL
) {
400 fprintf(stderr
, "libustfork: unable to find \"seteuid\" symbol\n");
406 /* Do the real seteuid */
407 retval
= plibc_func(euid
);
410 #if !defined(LTTNG_UST_CUSTOM_UPGRADE_CONFLICTING_SYMBOLS)
411 if (_init_ust_after_seteuid()) {
412 __ust_after_seteuid();
415 lttng_ust_after_seteuid();
421 int setegid(gid_t egid
)
423 static int (*plibc_func
)(gid_t egid
) = NULL
;
427 if (plibc_func
== NULL
) {
428 plibc_func
= dlsym(RTLD_NEXT
, "setegid");
429 if (plibc_func
== NULL
) {
430 fprintf(stderr
, "libustfork: unable to find \"setegid\" symbol\n");
436 /* Do the real setegid */
437 retval
= plibc_func(egid
);
440 #if !defined(LTTNG_UST_CUSTOM_UPGRADE_CONFLICTING_SYMBOLS)
441 if (_init_ust_after_setegid()) {
442 __ust_after_setegid();
445 lttng_ust_after_setegid();
451 int setreuid(uid_t ruid
, uid_t euid
)
453 static int (*plibc_func
)(uid_t ruid
, uid_t euid
) = NULL
;
457 if (plibc_func
== NULL
) {
458 plibc_func
= dlsym(RTLD_NEXT
, "setreuid");
459 if (plibc_func
== NULL
) {
460 fprintf(stderr
, "libustfork: unable to find \"setreuid\" symbol\n");
466 /* Do the real setreuid */
467 retval
= plibc_func(ruid
, euid
);
470 #if !defined(LTTNG_UST_CUSTOM_UPGRADE_CONFLICTING_SYMBOLS)
471 if (_init_ust_after_setreuid()) {
472 __ust_after_setreuid();
475 lttng_ust_after_setreuid();
481 int setregid(gid_t rgid
, gid_t egid
)
483 static int (*plibc_func
)(gid_t rgid
, gid_t egid
) = NULL
;
487 if (plibc_func
== NULL
) {
488 plibc_func
= dlsym(RTLD_NEXT
, "setregid");
489 if (plibc_func
== NULL
) {
490 fprintf(stderr
, "libustfork: unable to find \"setregid\" symbol\n");
496 /* Do the real setregid */
497 retval
= plibc_func(rgid
, egid
);
500 #if !defined(LTTNG_UST_CUSTOM_UPGRADE_CONFLICTING_SYMBOLS)
501 if (_init_ust_after_setregid()) {
502 __ust_after_setregid();
505 lttng_ust_after_setregid();
515 struct ustfork_clone_info
{
521 static int clone_fn(void *arg
)
523 struct ustfork_clone_info
*info
= (struct ustfork_clone_info
*) arg
;
525 /* clone is now done and we are in child */
526 #if !defined(LTTNG_UST_CUSTOM_UPGRADE_CONFLICTING_SYMBOLS)
527 if (_init_ust_after_fork_child()) {
528 __ust_after_fork_child(&info
->sigset
);
531 lttng_ust_after_fork_child(&info
->sigset
);
532 return info
->fn(info
->arg
);
535 int clone(int (*fn
)(void *), void *child_stack
, int flags
, void *arg
, ...)
537 static int (*plibc_func
)(int (*fn
)(void *), void *child_stack
,
538 int flags
, void *arg
, pid_t
*ptid
,
539 struct user_desc
*tls
, pid_t
*ctid
) = NULL
;
542 struct user_desc
*tls
;
544 /* end of var args */
550 ptid
= va_arg(ap
, pid_t
*);
551 tls
= va_arg(ap
, struct user_desc
*);
552 ctid
= va_arg(ap
, pid_t
*);
555 if (plibc_func
== NULL
) {
556 plibc_func
= dlsym(RTLD_NEXT
, "clone");
557 if (plibc_func
== NULL
) {
558 fprintf(stderr
, "libustfork: unable to find \"clone\" symbol.\n");
564 if (flags
& CLONE_VM
) {
566 * Creating a thread, no need to intervene, just pass on
569 retval
= plibc_func(fn
, child_stack
, flags
, arg
, ptid
,
573 /* Creating a real process, we need to intervene. */
574 struct ustfork_clone_info info
= { .fn
= fn
, .arg
= arg
};
576 lttng_ust_before_fork(&info
.sigset
);
577 #if !defined(LTTNG_UST_CUSTOM_UPGRADE_CONFLICTING_SYMBOLS)
578 if (_init_ust_before_fork()) {
579 __ust_before_fork(&info
.sigset
);
582 retval
= plibc_func(clone_fn
, child_stack
, flags
, &info
,
585 /* The child doesn't get here. */
586 #if !defined(LTTNG_UST_CUSTOM_UPGRADE_CONFLICTING_SYMBOLS)
587 if (_init_ust_after_fork_parent()) {
588 __ust_after_fork_parent(&info
.sigset
);
591 lttng_ust_after_fork_parent(&info
.sigset
);
597 int setns(int fd
, int nstype
)
599 static int (*plibc_func
)(int fd
, int nstype
) = NULL
;
603 if (plibc_func
== NULL
) {
604 plibc_func
= dlsym(RTLD_NEXT
, "setns");
605 if (plibc_func
== NULL
) {
606 fprintf(stderr
, "libustfork: unable to find \"setns\" symbol\n");
612 /* Do the real setns */
613 retval
= plibc_func(fd
, nstype
);
616 #if !defined(LTTNG_UST_CUSTOM_UPGRADE_CONFLICTING_SYMBOLS)
617 if (_init_ust_after_setns()) {
621 lttng_ust_after_setns();
627 int unshare(int flags
)
629 static int (*plibc_func
)(int flags
) = NULL
;
633 if (plibc_func
== NULL
) {
634 plibc_func
= dlsym(RTLD_NEXT
, "unshare");
635 if (plibc_func
== NULL
) {
636 fprintf(stderr
, "libustfork: unable to find \"unshare\" symbol\n");
642 /* Do the real setns */
643 retval
= plibc_func(flags
);
646 #if !defined(LTTNG_UST_CUSTOM_UPGRADE_CONFLICTING_SYMBOLS)
647 if (_init_ust_after_unshare()) {
648 __ust_after_unshare();
651 lttng_ust_after_unshare();
657 int setresuid(uid_t ruid
, uid_t euid
, uid_t suid
)
659 static int (*plibc_func
)(uid_t ruid
, uid_t euid
, uid_t suid
) = NULL
;
663 if (plibc_func
== NULL
) {
664 plibc_func
= dlsym(RTLD_NEXT
, "setresuid");
665 if (plibc_func
== NULL
) {
666 fprintf(stderr
, "libustfork: unable to find \"setresuid\" symbol\n");
672 /* Do the real setresuid */
673 retval
= plibc_func(ruid
, euid
, suid
);
676 #if !defined(LTTNG_UST_CUSTOM_UPGRADE_CONFLICTING_SYMBOLS)
677 if (_init_ust_after_setresuid()) {
678 __ust_after_setresuid();
681 lttng_ust_after_setresuid();
687 int setresgid(gid_t rgid
, gid_t egid
, gid_t sgid
)
689 static int (*plibc_func
)(gid_t rgid
, gid_t egid
, gid_t sgid
) = NULL
;
693 if (plibc_func
== NULL
) {
694 plibc_func
= dlsym(RTLD_NEXT
, "setresgid");
695 if (plibc_func
== NULL
) {
696 fprintf(stderr
, "libustfork: unable to find \"setresgid\" symbol\n");
702 /* Do the real setresgid */
703 retval
= plibc_func(rgid
, egid
, sgid
);
706 #if !defined(LTTNG_UST_CUSTOM_UPGRADE_CONFLICTING_SYMBOLS)
707 if (_init_ust_after_setresgid()) {
708 __ust_after_setresgid();
711 lttng_ust_after_setresgid();
717 #elif defined (__FreeBSD__)
719 pid_t
rfork(int flags
)
721 static pid_t (*plibc_func
)(int flags
) = NULL
;
726 if (plibc_func
== NULL
) {
727 plibc_func
= dlsym(RTLD_NEXT
, "rfork");
728 if (plibc_func
== NULL
) {
729 fprintf(stderr
, "libustfork: unable to find \"rfork\" symbol\n");
735 lttng_ust_before_fork(&sigset
);
736 /* Do the real rfork */
737 retval
= plibc_func(flags
);
741 lttng_ust_after_fork_child(&sigset
);
743 lttng_ust_after_fork_parent(&sigset
);
750 * On BSD, no need to override vfork, because it runs in the context of
751 * the parent, with parent waiting until execve or exit is executed in
756 #warning "Unknown OS. You might want to ensure that fork/clone/vfork/fork handling is complete."
This page took 0.04723 seconds and 5 git commands to generate.