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>
16 #include <lttng/ust-fork.h>
20 static pid_t (*plibc_func
)(void) = NULL
;
25 if (plibc_func
== NULL
) {
26 plibc_func
= dlsym(RTLD_NEXT
, "fork");
27 if (plibc_func
== NULL
) {
28 fprintf(stderr
, "libustfork: unable to find \"fork\" symbol\n");
34 lttng_ust_before_fork(&sigset
);
35 /* Do the real fork */
36 retval
= plibc_func();
40 lttng_ust_after_fork_child(&sigset
);
42 lttng_ust_after_fork_parent(&sigset
);
48 int daemon(int nochdir
, int noclose
)
50 static int (*plibc_func
)(int nochdir
, int noclose
) = NULL
;
55 if (plibc_func
== NULL
) {
56 plibc_func
= dlsym(RTLD_NEXT
, "daemon");
57 if (plibc_func
== NULL
) {
58 fprintf(stderr
, "libustfork: unable to find \"daemon\" symbol\n");
64 lttng_ust_before_fork(&sigset
);
65 /* Do the real daemon call */
66 retval
= plibc_func(nochdir
, noclose
);
69 /* child, parent called _exit() directly */
70 lttng_ust_after_fork_child(&sigset
);
72 /* on error in the parent */
73 lttng_ust_after_fork_parent(&sigset
);
81 static int (*plibc_func
)(uid_t uid
) = NULL
;
85 if (plibc_func
== NULL
) {
86 plibc_func
= dlsym(RTLD_NEXT
, "setuid");
87 if (plibc_func
== NULL
) {
88 fprintf(stderr
, "libustfork: unable to find \"setuid\" symbol\n");
94 /* Do the real setuid */
95 retval
= plibc_func(uid
);
98 lttng_ust_after_setuid();
104 int setgid(gid_t gid
)
106 static int (*plibc_func
)(gid_t gid
) = NULL
;
110 if (plibc_func
== NULL
) {
111 plibc_func
= dlsym(RTLD_NEXT
, "setgid");
112 if (plibc_func
== NULL
) {
113 fprintf(stderr
, "libustfork: unable to find \"setgid\" symbol\n");
119 /* Do the real setgid */
120 retval
= plibc_func(gid
);
123 lttng_ust_after_setgid();
129 int seteuid(uid_t euid
)
131 static int (*plibc_func
)(uid_t euid
) = NULL
;
135 if (plibc_func
== NULL
) {
136 plibc_func
= dlsym(RTLD_NEXT
, "seteuid");
137 if (plibc_func
== NULL
) {
138 fprintf(stderr
, "libustfork: unable to find \"seteuid\" symbol\n");
144 /* Do the real seteuid */
145 retval
= plibc_func(euid
);
148 lttng_ust_after_seteuid();
154 int setegid(gid_t egid
)
156 static int (*plibc_func
)(gid_t egid
) = NULL
;
160 if (plibc_func
== NULL
) {
161 plibc_func
= dlsym(RTLD_NEXT
, "setegid");
162 if (plibc_func
== NULL
) {
163 fprintf(stderr
, "libustfork: unable to find \"setegid\" symbol\n");
169 /* Do the real setegid */
170 retval
= plibc_func(egid
);
173 lttng_ust_after_setegid();
179 int setreuid(uid_t ruid
, uid_t euid
)
181 static int (*plibc_func
)(uid_t ruid
, uid_t euid
) = NULL
;
185 if (plibc_func
== NULL
) {
186 plibc_func
= dlsym(RTLD_NEXT
, "setreuid");
187 if (plibc_func
== NULL
) {
188 fprintf(stderr
, "libustfork: unable to find \"setreuid\" symbol\n");
194 /* Do the real setreuid */
195 retval
= plibc_func(ruid
, euid
);
198 lttng_ust_after_setreuid();
204 int setregid(gid_t rgid
, gid_t egid
)
206 static int (*plibc_func
)(gid_t rgid
, gid_t egid
) = NULL
;
210 if (plibc_func
== NULL
) {
211 plibc_func
= dlsym(RTLD_NEXT
, "setregid");
212 if (plibc_func
== NULL
) {
213 fprintf(stderr
, "libustfork: unable to find \"setregid\" symbol\n");
219 /* Do the real setregid */
220 retval
= plibc_func(rgid
, egid
);
223 lttng_ust_after_setregid();
233 struct ustfork_clone_info
{
239 static int clone_fn(void *arg
)
241 struct ustfork_clone_info
*info
= (struct ustfork_clone_info
*) arg
;
243 /* clone is now done and we are in child */
244 lttng_ust_after_fork_child(&info
->sigset
);
245 return info
->fn(info
->arg
);
248 int clone(int (*fn
)(void *), void *child_stack
, int flags
, void *arg
, ...)
250 static int (*plibc_func
)(int (*fn
)(void *), void *child_stack
,
251 int flags
, void *arg
, pid_t
*ptid
,
252 struct user_desc
*tls
, pid_t
*ctid
) = NULL
;
255 struct user_desc
*tls
;
257 /* end of var args */
263 ptid
= va_arg(ap
, pid_t
*);
264 tls
= va_arg(ap
, struct user_desc
*);
265 ctid
= va_arg(ap
, pid_t
*);
268 if (plibc_func
== NULL
) {
269 plibc_func
= dlsym(RTLD_NEXT
, "clone");
270 if (plibc_func
== NULL
) {
271 fprintf(stderr
, "libustfork: unable to find \"clone\" symbol.\n");
277 if (flags
& CLONE_VM
) {
279 * Creating a thread, no need to intervene, just pass on
282 retval
= plibc_func(fn
, child_stack
, flags
, arg
, ptid
,
286 /* Creating a real process, we need to intervene. */
287 struct ustfork_clone_info info
= { .fn
= fn
, .arg
= arg
};
289 lttng_ust_before_fork(&info
.sigset
);
290 retval
= plibc_func(clone_fn
, child_stack
, flags
, &info
,
293 /* The child doesn't get here. */
294 lttng_ust_after_fork_parent(&info
.sigset
);
300 int setns(int fd
, int nstype
)
302 static int (*plibc_func
)(int fd
, int nstype
) = NULL
;
306 if (plibc_func
== NULL
) {
307 plibc_func
= dlsym(RTLD_NEXT
, "setns");
308 if (plibc_func
== NULL
) {
309 fprintf(stderr
, "libustfork: unable to find \"setns\" symbol\n");
315 /* Do the real setns */
316 retval
= plibc_func(fd
, nstype
);
319 lttng_ust_after_setns();
325 int unshare(int flags
)
327 static int (*plibc_func
)(int flags
) = NULL
;
331 if (plibc_func
== NULL
) {
332 plibc_func
= dlsym(RTLD_NEXT
, "unshare");
333 if (plibc_func
== NULL
) {
334 fprintf(stderr
, "libustfork: unable to find \"unshare\" symbol\n");
340 /* Do the real setns */
341 retval
= plibc_func(flags
);
344 lttng_ust_after_unshare();
350 int setresuid(uid_t ruid
, uid_t euid
, uid_t suid
)
352 static int (*plibc_func
)(uid_t ruid
, uid_t euid
, uid_t suid
) = NULL
;
356 if (plibc_func
== NULL
) {
357 plibc_func
= dlsym(RTLD_NEXT
, "setresuid");
358 if (plibc_func
== NULL
) {
359 fprintf(stderr
, "libustfork: unable to find \"setresuid\" symbol\n");
365 /* Do the real setresuid */
366 retval
= plibc_func(ruid
, euid
, suid
);
369 lttng_ust_after_setresuid();
375 int setresgid(gid_t rgid
, gid_t egid
, gid_t sgid
)
377 static int (*plibc_func
)(gid_t rgid
, gid_t egid
, gid_t sgid
) = NULL
;
381 if (plibc_func
== NULL
) {
382 plibc_func
= dlsym(RTLD_NEXT
, "setresgid");
383 if (plibc_func
== NULL
) {
384 fprintf(stderr
, "libustfork: unable to find \"setresgid\" symbol\n");
390 /* Do the real setresgid */
391 retval
= plibc_func(rgid
, egid
, sgid
);
394 lttng_ust_after_setresgid();
400 #elif defined (__FreeBSD__)
402 pid_t
rfork(int flags
)
404 static pid_t (*plibc_func
)(void) = NULL
;
409 if (plibc_func
== NULL
) {
410 plibc_func
= dlsym(RTLD_NEXT
, "rfork");
411 if (plibc_func
== NULL
) {
412 fprintf(stderr
, "libustfork: unable to find \"rfork\" symbol\n");
418 lttng_ust_before_fork(&sigset
);
419 /* Do the real rfork */
420 retval
= plibc_func();
424 lttng_ust_after_fork_child(&sigset
);
426 lttng_ust_after_fork_parent(&sigset
);
433 * On BSD, no need to override vfork, because it runs in the context of
434 * the parent, with parent waiting until execve or exit is executed in
439 #warning "Unknown OS. You might want to ensure that fork/clone/vfork/fork handling is complete."
This page took 0.040331 seconds and 4 git commands to generate.