9508cc7520eaeb23145814c9976cd24b6501a2a3
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 #include <urcu/uatomic.h>
25 static pid_t (*plibc_func
)(void) = NULL
;
31 func
= uatomic_read(plibc_func
);
33 func
= dlsym(RTLD_NEXT
, "fork");
35 fprintf(stderr
, "libustfork: unable to find \"fork\" symbol\n");
39 uatomic_set(&plibc_func
, func
);
42 lttng_ust_before_fork(&sigset
);
43 /* Do the real fork */
48 lttng_ust_after_fork_child(&sigset
);
50 lttng_ust_after_fork_parent(&sigset
);
56 int daemon(int nochdir
, int noclose
)
58 static int (*plibc_func
)(int nochdir
, int noclose
) = NULL
;
59 int (*func
)(int nochdir
, int noclose
);
64 func
= uatomic_read(plibc_func
);
66 func
= dlsym(RTLD_NEXT
, "daemon");
68 fprintf(stderr
, "libustfork: unable to find \"daemon\" symbol\n");
72 uatomic_set(&plibc_func
, func
);
75 lttng_ust_before_fork(&sigset
);
76 /* Do the real daemon call */
77 retval
= func(nochdir
, noclose
);
80 /* child, parent called _exit() directly */
81 lttng_ust_after_fork_child(&sigset
);
83 /* on error in the parent */
84 lttng_ust_after_fork_parent(&sigset
);
92 static int (*plibc_func
)(uid_t uid
) = NULL
;
93 int (*func
)(uid_t uid
);
97 func
= uatomic_read(plibc_func
);
99 func
= dlsym(RTLD_NEXT
, "setuid");
101 fprintf(stderr
, "libustfork: unable to find \"setuid\" symbol\n");
105 uatomic_set(&plibc_func
, func
);
108 /* Do the real setuid */
112 lttng_ust_after_setuid();
118 int setgid(gid_t gid
)
120 static int (*plibc_func
)(gid_t gid
) = NULL
;
121 int (*func
)(gid_t gid
);
125 func
= uatomic_read(plibc_func
);
127 func
= dlsym(RTLD_NEXT
, "setgid");
129 fprintf(stderr
, "libustfork: unable to find \"setgid\" symbol\n");
133 uatomic_set(&plibc_func
, func
);
136 /* Do the real setgid */
140 lttng_ust_after_setgid();
146 int seteuid(uid_t euid
)
148 static int (*plibc_func
)(uid_t euid
) = NULL
;
149 int (*func
)(uid_t euid
);
153 func
= uatomic_read(plibc_func
);
155 func
= dlsym(RTLD_NEXT
, "seteuid");
157 fprintf(stderr
, "libustfork: unable to find \"seteuid\" symbol\n");
161 uatomic_set(&plibc_func
, func
);
164 /* Do the real seteuid */
168 lttng_ust_after_seteuid();
174 int setegid(gid_t egid
)
176 static int (*plibc_func
)(gid_t egid
) = NULL
;
177 int (*func
)(gid_t egid
);
181 func
= uatomic_read(plibc_func
);
183 func
= dlsym(RTLD_NEXT
, "setegid");
185 fprintf(stderr
, "libustfork: unable to find \"setegid\" symbol\n");
189 uatomic_set(&plibc_func
, func
);
192 /* Do the real setegid */
196 lttng_ust_after_setegid();
202 int setreuid(uid_t ruid
, uid_t euid
)
204 static int (*plibc_func
)(uid_t ruid
, uid_t euid
) = NULL
;
205 int (*func
)(uid_t ruid
, uid_t euid
);
209 func
= uatomic_read(plibc_func
);
211 func
= dlsym(RTLD_NEXT
, "setreuid");
213 fprintf(stderr
, "libustfork: unable to find \"setreuid\" symbol\n");
217 uatomic_set(&plibc_func
, func
);
220 /* Do the real setreuid */
221 retval
= func(ruid
, euid
);
224 lttng_ust_after_setreuid();
230 int setregid(gid_t rgid
, gid_t egid
)
232 static int (*plibc_func
)(gid_t rgid
, gid_t egid
) = NULL
;
233 int (*func
)(gid_t rgid
, gid_t egid
);
237 func
= uatomic_read(plibc_func
);
239 func
= dlsym(RTLD_NEXT
, "setregid");
241 fprintf(stderr
, "libustfork: unable to find \"setregid\" symbol\n");
245 uatomic_set(&plibc_func
, func
);
248 /* Do the real setregid */
249 retval
= func(rgid
, egid
);
252 lttng_ust_after_setregid();
262 struct ustfork_clone_info
{
268 static int clone_fn(void *arg
)
270 struct ustfork_clone_info
*info
= (struct ustfork_clone_info
*) arg
;
272 /* clone is now done and we are in child */
273 lttng_ust_after_fork_child(&info
->sigset
);
274 return info
->fn(info
->arg
);
277 int clone(int (*fn
)(void *), void *child_stack
, int flags
, void *arg
, ...)
279 static int (*plibc_func
)(int (*fn
)(void *), void *child_stack
,
280 int flags
, void *arg
, pid_t
*ptid
,
281 struct user_desc
*tls
, pid_t
*ctid
) = NULL
;
282 int (*func
)(int (*fn
)(void *), void *child_stack
,
283 int flags
, void *arg
, pid_t
*ptid
,
284 struct user_desc
*tls
, pid_t
*ctid
);
287 struct user_desc
*tls
;
289 /* end of var args */
295 ptid
= va_arg(ap
, pid_t
*);
296 tls
= va_arg(ap
, struct user_desc
*);
297 ctid
= va_arg(ap
, pid_t
*);
300 func
= uatomic_read(plibc_func
);
302 func
= dlsym(RTLD_NEXT
, "clone");
304 fprintf(stderr
, "libustfork: unable to find \"clone\" symbol.\n");
308 uatomic_set(&plibc_func
, func
);
311 if (flags
& CLONE_VM
) {
313 * Creating a thread, no need to intervene, just pass on
316 retval
= func(fn
, child_stack
, flags
, arg
, ptid
,
320 /* Creating a real process, we need to intervene. */
321 struct ustfork_clone_info info
= { .fn
= fn
, .arg
= arg
};
323 lttng_ust_before_fork(&info
.sigset
);
324 retval
= func(clone_fn
, child_stack
, flags
, &info
,
327 /* The child doesn't get here. */
328 lttng_ust_after_fork_parent(&info
.sigset
);
334 int setns(int fd
, int nstype
)
336 static int (*plibc_func
)(int fd
, int nstype
) = NULL
;
337 int (*func
)(int fd
, int nstype
);
341 func
= uatomic_read(plibc_func
);
343 func
= dlsym(RTLD_NEXT
, "setns");
345 fprintf(stderr
, "libustfork: unable to find \"setns\" symbol\n");
349 uatomic_set(&plibc_func
, func
);
352 /* Do the real setns */
353 retval
= func(fd
, nstype
);
356 lttng_ust_after_setns();
362 int unshare(int flags
)
364 static int (*plibc_func
)(int flags
) = NULL
;
365 int (*func
)(int flags
);
369 func
= uatomic_read(plibc_func
);
371 func
= dlsym(RTLD_NEXT
, "unshare");
373 fprintf(stderr
, "libustfork: unable to find \"unshare\" symbol\n");
377 uatomic_set(&plibc_func
, func
);
380 /* Do the real setns */
381 retval
= func(flags
);
384 lttng_ust_after_unshare();
390 int setresuid(uid_t ruid
, uid_t euid
, uid_t suid
)
392 static int (*plibc_func
)(uid_t ruid
, uid_t euid
, uid_t suid
) = NULL
;
393 int (*func
)(uid_t ruid
, uid_t euid
, uid_t suid
);
397 func
= uatomic_read(plibc_func
);
399 func
= dlsym(RTLD_NEXT
, "setresuid");
401 fprintf(stderr
, "libustfork: unable to find \"setresuid\" symbol\n");
405 uatomic_set(&plibc_func
, func
);
408 /* Do the real setresuid */
409 retval
= func(ruid
, euid
, suid
);
412 lttng_ust_after_setresuid();
418 int setresgid(gid_t rgid
, gid_t egid
, gid_t sgid
)
420 static int (*plibc_func
)(gid_t rgid
, gid_t egid
, gid_t sgid
) = NULL
;
421 int (*func
)(gid_t rgid
, gid_t egid
, gid_t sgid
);
425 func
= uatomic_read(plibc_func
);
427 func
= dlsym(RTLD_NEXT
, "setresgid");
429 fprintf(stderr
, "libustfork: unable to find \"setresgid\" symbol\n");
433 uatomic_set(&plibc_func
, func
);
436 /* Do the real setresgid */
437 retval
= func(rgid
, egid
, sgid
);
440 lttng_ust_after_setresgid();
446 #elif defined (__FreeBSD__)
448 pid_t
rfork(int flags
)
450 static pid_t (*plibc_func
)(int flags
) = NULL
;
451 pid_t (*func
)(int flags
);
456 func
= uatomic_read(plibc_func
);
458 func
= dlsym(RTLD_NEXT
, "rfork");
460 fprintf(stderr
, "libustfork: unable to find \"rfork\" symbol\n");
464 uatomic_set(&plibc_func
, func
);
467 lttng_ust_before_fork(&sigset
);
468 /* Do the real rfork */
469 retval
= func(flags
);
473 lttng_ust_after_fork_child(&sigset
);
475 lttng_ust_after_fork_parent(&sigset
);
482 * On BSD, no need to override vfork, because it runs in the context of
483 * the parent, with parent waiting until execve or exit is executed in
488 #warning "Unknown OS. You might want to ensure that fork/clone/vfork/fork handling is complete."
This page took 0.040531 seconds and 4 git commands to generate.