2 * Copyright (C) 2009 Pierre-Marc Fournier
3 * Copyright (C) 2011-2012 Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation; version 2.1 of
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
15 * You should have received a copy of the GNU Lesser General Public
16 * License along with this library; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
21 #include <lttng/ust-dlfcn.h>
30 #include <lttng/ust.h>
32 #include <urcu/uatomic.h>
36 static pid_t (*plibc_func
)(void) = NULL
;
42 func
= uatomic_read(&plibc_func
);
44 func
= dlsym(RTLD_NEXT
, "fork");
46 fprintf(stderr
, "libustfork: unable to find \"fork\" symbol\n");
50 uatomic_set(&plibc_func
, func
);
53 ust_before_fork(&sigset
);
54 /* Do the real fork */
59 ust_after_fork_child(&sigset
);
61 ust_after_fork_parent(&sigset
);
67 int daemon(int nochdir
, int noclose
)
69 static int (*plibc_func
)(int nochdir
, int noclose
) = NULL
;
70 int (*func
)(int nochdir
, int noclose
);
75 func
= uatomic_read(&plibc_func
);
77 func
= dlsym(RTLD_NEXT
, "daemon");
79 fprintf(stderr
, "libustfork: unable to find \"daemon\" symbol\n");
83 uatomic_set(&plibc_func
, func
);
86 ust_before_fork(&sigset
);
87 /* Do the real daemon call */
88 retval
= func(nochdir
, noclose
);
91 /* child, parent called _exit() directly */
92 ust_after_fork_child(&sigset
);
94 /* on error in the parent */
95 ust_after_fork_parent(&sigset
);
101 int setuid(uid_t uid
)
103 static int (*plibc_func
)(uid_t uid
) = NULL
;
104 int (*func
)(uid_t uid
);
108 func
= uatomic_read(&plibc_func
);
110 func
= dlsym(RTLD_NEXT
, "setuid");
112 fprintf(stderr
, "libustfork: unable to find \"setuid\" symbol\n");
116 uatomic_set(&plibc_func
, func
);
119 /* Do the real setuid */
129 int setgid(gid_t gid
)
131 static int (*plibc_func
)(gid_t gid
) = NULL
;
132 int (*func
)(gid_t gid
);
136 func
= uatomic_read(&plibc_func
);
138 func
= dlsym(RTLD_NEXT
, "setgid");
140 fprintf(stderr
, "libustfork: unable to find \"setgid\" symbol\n");
144 uatomic_set(&plibc_func
, func
);
147 /* Do the real setgid */
157 int seteuid(uid_t euid
)
159 static int (*plibc_func
)(uid_t euid
) = NULL
;
160 int (*func
)(uid_t euid
);
164 func
= uatomic_read(&plibc_func
);
166 func
= dlsym(RTLD_NEXT
, "seteuid");
168 fprintf(stderr
, "libustfork: unable to find \"seteuid\" symbol\n");
172 uatomic_set(&plibc_func
, func
);
175 /* Do the real seteuid */
185 int setegid(gid_t egid
)
187 static int (*plibc_func
)(gid_t egid
) = NULL
;
188 int (*func
)(gid_t egid
);
192 func
= uatomic_read(&plibc_func
);
194 func
= dlsym(RTLD_NEXT
, "setegid");
196 fprintf(stderr
, "libustfork: unable to find \"setegid\" symbol\n");
200 uatomic_set(&plibc_func
, func
);
203 /* Do the real setegid */
213 int setreuid(uid_t ruid
, uid_t euid
)
215 static int (*plibc_func
)(uid_t ruid
, uid_t euid
) = NULL
;
216 int (*func
)(uid_t ruid
, uid_t euid
);
220 func
= uatomic_read(&plibc_func
);
222 func
= dlsym(RTLD_NEXT
, "setreuid");
224 fprintf(stderr
, "libustfork: unable to find \"setreuid\" symbol\n");
228 uatomic_set(&plibc_func
, func
);
231 /* Do the real setreuid */
232 retval
= func(ruid
, euid
);
235 ust_after_setreuid();
241 int setregid(gid_t rgid
, gid_t egid
)
243 static int (*plibc_func
)(gid_t rgid
, gid_t egid
) = NULL
;
244 int (*func
)(gid_t rgid
, gid_t egid
);
248 func
= uatomic_read(&plibc_func
);
250 func
= dlsym(RTLD_NEXT
, "setregid");
252 fprintf(stderr
, "libustfork: unable to find \"setregid\" symbol\n");
256 uatomic_set(&plibc_func
, func
);
259 /* Do the real setregid */
260 retval
= func(rgid
, egid
);
263 ust_after_setregid();
273 struct ustfork_clone_info
{
279 static int clone_fn(void *arg
)
281 struct ustfork_clone_info
*info
= (struct ustfork_clone_info
*) arg
;
283 /* clone is now done and we are in child */
284 ust_after_fork_child(&info
->sigset
);
285 return info
->fn(info
->arg
);
288 int clone(int (*fn
)(void *), void *child_stack
, int flags
, void *arg
, ...)
290 static int (*plibc_func
)(int (*fn
)(void *), void *child_stack
,
291 int flags
, void *arg
, pid_t
*ptid
,
292 struct user_desc
*tls
, pid_t
*ctid
) = NULL
;
293 int (*func
)(int (*fn
)(void *), void *child_stack
,
294 int flags
, void *arg
, pid_t
*ptid
,
295 struct user_desc
*tls
, pid_t
*ctid
);
298 struct user_desc
*tls
;
300 /* end of var args */
306 ptid
= va_arg(ap
, pid_t
*);
307 tls
= va_arg(ap
, struct user_desc
*);
308 ctid
= va_arg(ap
, pid_t
*);
311 func
= uatomic_read(&plibc_func
);
313 func
= dlsym(RTLD_NEXT
, "clone");
315 fprintf(stderr
, "libustfork: unable to find \"clone\" symbol.\n");
319 uatomic_set(&plibc_func
, func
);
322 if (flags
& CLONE_VM
) {
324 * Creating a thread, no need to intervene, just pass on
327 retval
= func(fn
, child_stack
, flags
, arg
, ptid
,
331 /* Creating a real process, we need to intervene. */
332 struct ustfork_clone_info info
= { .fn
= fn
, .arg
= arg
};
334 ust_before_fork(&info
.sigset
);
335 retval
= func(clone_fn
, child_stack
, flags
, &info
,
338 /* The child doesn't get here. */
339 ust_after_fork_parent(&info
.sigset
);
345 int setns(int fd
, int nstype
)
347 static int (*plibc_func
)(int fd
, int nstype
) = NULL
;
348 int (*func
)(int fd
, int nstype
);
352 func
= uatomic_read(&plibc_func
);
354 func
= dlsym(RTLD_NEXT
, "setns");
356 fprintf(stderr
, "libustfork: unable to find \"setns\" symbol\n");
360 uatomic_set(&plibc_func
, func
);
363 /* Do the real setns */
364 retval
= func(fd
, nstype
);
373 int unshare(int flags
)
375 static int (*plibc_func
)(int flags
) = NULL
;
376 int (*func
)(int flags
);
380 func
= uatomic_read(&plibc_func
);
382 func
= dlsym(RTLD_NEXT
, "unshare");
384 fprintf(stderr
, "libustfork: unable to find \"unshare\" symbol\n");
388 uatomic_set(&plibc_func
, func
);
391 /* Do the real setns */
392 retval
= func(flags
);
401 int setresuid(uid_t ruid
, uid_t euid
, uid_t suid
)
403 static int (*plibc_func
)(uid_t ruid
, uid_t euid
, uid_t suid
) = NULL
;
404 int (*func
)(uid_t ruid
, uid_t euid
, uid_t suid
);
408 func
= uatomic_read(&plibc_func
);
410 func
= dlsym(RTLD_NEXT
, "setresuid");
412 fprintf(stderr
, "libustfork: unable to find \"setresuid\" symbol\n");
416 uatomic_set(&plibc_func
, func
);
419 /* Do the real setresuid */
420 retval
= func(ruid
, euid
, suid
);
423 ust_after_setresuid();
429 int setresgid(gid_t rgid
, gid_t egid
, gid_t sgid
)
431 static int (*plibc_func
)(gid_t rgid
, gid_t egid
, gid_t sgid
) = NULL
;
432 int (*func
)(gid_t rgid
, gid_t egid
, gid_t sgid
);
436 func
= uatomic_read(&plibc_func
);
438 func
= dlsym(RTLD_NEXT
, "setresgid");
440 fprintf(stderr
, "libustfork: unable to find \"setresgid\" symbol\n");
444 uatomic_set(&plibc_func
, func
);
447 /* Do the real setresgid */
448 retval
= func(rgid
, egid
, sgid
);
451 ust_after_setresgid();
457 #elif defined (__FreeBSD__)
459 pid_t
rfork(int flags
)
461 static pid_t (*plibc_func
)(int flags
) = NULL
;
462 pid_t (*func
)(int flags
);
467 func
= uatomic_read(&plibc_func
);
469 func
= dlsym(RTLD_NEXT
, "rfork");
471 fprintf(stderr
, "libustfork: unable to find \"rfork\" symbol\n");
475 uatomic_set(&plibc_func
, func
);
478 ust_before_fork(&sigset
);
479 /* Do the real rfork */
480 retval
= func(flags
);
484 ust_after_fork_child(&sigset
);
486 ust_after_fork_parent(&sigset
);
493 * On BSD, no need to override vfork, because it runs in the context of
494 * the parent, with parent waiting until execve or exit is executed in
499 #warning "Unknown OS. You might want to ensure that fork/clone/vfork/fork handling is complete."
This page took 0.047418 seconds and 4 git commands to generate.