execute_program.c revision ab3b72cc5d2d3efb3542192f0d72ff2ea4b082f9
1#include "config.h" 2 3#if defined(HAVE_LIBUNWIND) 4#include <libunwind-ptrace.h> 5#endif /* defined(HAVE_LIBUNWIND) */ 6 7#include <stdio.h> 8#include <stdlib.h> 9#include <sys/types.h> 10#include <sys/stat.h> 11#include <unistd.h> 12#include <errno.h> 13#include <string.h> 14#include <pwd.h> 15#include <grp.h> 16 17#include "common.h" 18 19static void 20change_uid(Process *proc) { 21 uid_t run_uid, run_euid; 22 gid_t run_gid, run_egid; 23 24 if (options.user) { 25 struct passwd *pent; 26 27 if (getuid() != 0 || geteuid() != 0) { 28 fprintf(stderr, 29 "you must be root to use the -u option\n"); 30 exit(1); 31 } 32 if ((pent = getpwnam(options.user)) == NULL) { 33 fprintf(stderr, "cannot find user `%s'\n", options.user); 34 exit(1); 35 } 36 run_uid = pent->pw_uid; 37 run_gid = pent->pw_gid; 38 39 if (initgroups(options.user, run_gid) < 0) { 40 perror("ltrace: initgroups"); 41 exit(1); 42 } 43 } else { 44 run_uid = getuid(); 45 run_gid = getgid(); 46 } 47 if (options.user || !geteuid()) { 48 struct stat statbuf; 49 run_euid = run_uid; 50 run_egid = run_gid; 51 52 if (!stat(proc->filename, &statbuf)) { 53 if (statbuf.st_mode & S_ISUID) { 54 run_euid = statbuf.st_uid; 55 } 56 if (statbuf.st_mode & S_ISGID) { 57 run_egid = statbuf.st_gid; 58 } 59 } 60 if (setregid(run_gid, run_egid) < 0) { 61 perror("ltrace: setregid"); 62 exit(1); 63 } 64 if (setreuid(run_uid, run_euid) < 0) { 65 perror("ltrace: setreuid"); 66 exit(1); 67 } 68 } 69} 70 71void 72execute_program(Process *sp, char **argv) { 73 pid_t pid; 74 75 debug(1, "Executing `%s'...", sp->filename); 76 77 pid = fork(); 78 if (pid < 0) { 79 perror("ltrace: fork"); 80 exit(1); 81 } else if (!pid) { /* child */ 82 change_uid(sp); 83 trace_me(); 84 execvp(sp->filename, argv); 85 fprintf(stderr, "Can't execute `%s': %s\n", sp->filename, 86 strerror(errno)); 87 _exit(1); 88 } 89 90 debug(1, "PID=%d", pid); 91 92 sp->pid = pid; 93 94#if defined(HAVE_LIBUNWIND) 95 sp->unwind_priv = _UPT_create(pid); 96#endif /* defined(HAVE_LIBUNWIND) */ 97 98 return; 99} 100