Rizin
unix-like reverse engineering framework and cli tools
run.c File Reference
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <fcntl.h>
#include <rz_socket.h>
#include <rz_util.h>
#include <rz_lib.h>
#include <rz_cons.h>
#include <sys/stat.h>
#include <sys/types.h>

Go to the source code of this file.

Macros

#define DUP(x)
 

Functions

RZ_API RzRunProfilerz_run_new (const char *str)
 
RZ_API void rz_run_reset (RzRunProfile *p)
 
RZ_API bool rz_run_parse (RzRunProfile *pf, const char *profile)
 
RZ_API void rz_run_free (RzRunProfile *r)
 
static char * getstr (const char *src)
 
static int parseBool (const char *e)
 
static void setASLR (RzRunProfile *r, int enabled)
 
static int handle_redirection_proc (const char *cmd, bool in, bool out, bool err)
 
static int handle_redirection (const char *cmd, bool in, bool out, bool err)
 
RZ_API bool rz_run_parsefile (RzRunProfile *p, const char *b)
 
RZ_API bool rz_run_parseline (RzRunProfile *p, const char *b)
 
RZ_API const char * rz_run_help (void)
 
static int redirect_socket_to_stdio (RzSocket *sock)
 
static int redirect_socket_to_pty (RzSocket *sock)
 
RZ_API int rz_run_config_env (RzRunProfile *p)
 
RZ_API int rz_run_start (RzRunProfile *p)
 
RZ_API char * rz_run_get_environ_profile (char **env)
 

Macro Definition Documentation

◆ DUP

#define DUP (   x)
Value:
{ \
close(x); \
dup2(f, x); \
}
int x
Definition: mipsasm.c:20
#define f(i)
Definition: sha256.c:46

Function Documentation

◆ getstr()

static char* getstr ( const char *  src)
static

Definition at line 152 of file run.c.

152  {
153  int len;
154  char *ret = NULL;
155 
156  switch (*src) {
157  case '\'':
158  ret = strdup(src + 1);
159  if (ret) {
160  len = strlen(ret);
161  if (len > 0) {
162  len--;
163  if (ret[len] == '\'') {
164  ret[len] = 0;
165  return ret;
166  }
167  eprintf("Missing \"\n");
168  }
169  free(ret);
170  }
171  return NULL;
172  case '"':
173  ret = strdup(src + 1);
174  if (ret) {
175  len = strlen(ret);
176  if (len > 0) {
177  len--;
178  if (ret[len] == '"') {
179  ret[len] = 0;
180  rz_str_unescape(ret);
181  return ret;
182  }
183  eprintf("Missing \"\n");
184  }
185  free(ret);
186  }
187  return NULL;
188  case '@': {
189  char *pat = strchr(src + 1, '@');
190  if (pat) {
191  size_t len;
192  long i, rep;
193  *pat++ = 0;
194  rep = strtol(src + 1, NULL, 10);
195  len = strlen(pat);
196  if (rep > 0) {
197  char *buf = malloc(rep);
198  if (buf) {
199  for (i = 0; i < rep; i++) {
200  buf[i] = pat[i % len];
201  }
202  }
203  return buf;
204  }
205  }
206  // slurp file
207  return rz_file_slurp(src + 1, NULL);
208  }
209  case '`': {
210  char *msg = strdup(src + 1);
211  int msg_len = strlen(msg);
212  if (msg_len > 0) {
213  msg[msg_len - 1] = 0;
214  char *ret = rz_sys_cmd_str(msg, NULL, NULL);
215  rz_str_trim_tail(ret);
216  free(msg);
217  return ret;
218  }
219  free(msg);
220  return strdup("");
221  }
222  case '!': {
223  char *a = rz_sys_cmd_str(src + 1, NULL, NULL);
225  return a;
226  }
227  case ':':
228  if (src[1] == '!') {
229  ret = rz_sys_cmd_str(src + 1, NULL, NULL);
230  rz_str_trim_tail(ret); // why no head :?
231  } else {
232  ret = strdup(src);
233  }
234  len = rz_hex_str2bin(src + 1, (ut8 *)ret);
235  if (len > 0) {
236  ret[len] = 0;
237  return ret;
238  }
239  eprintf("Invalid hexpair string\n");
240  free(ret);
241  return NULL;
242  }
243  rz_str_unescape((ret = strdup(src)));
244  return ret;
245 }
size_t len
Definition: 6502dis.c:15
lzma_index ** i
Definition: index.h:629
lzma_index * src
Definition: index.h:567
#define NULL
Definition: cris-opc.c:27
RZ_API void Ht_() free(HtName_(Ht) *ht)
Definition: ht_inc.c:130
voidpf void * buf
Definition: ioapi.h:138
uint8_t ut8
Definition: lh5801.h:11
void * malloc(size_t size)
Definition: malloc.c:123
return strdup("=SP r13\n" "=LR r14\n" "=PC r15\n" "=A0 r0\n" "=A1 r1\n" "=A2 r2\n" "=A3 r3\n" "=ZF zf\n" "=SF nf\n" "=OF vf\n" "=CF cf\n" "=SN or0\n" "gpr lr .32 56 0\n" "gpr pc .32 60 0\n" "gpr cpsr .32 64 0 ____tfiae_________________qvczn\n" "gpr or0 .32 68 0\n" "gpr tf .1 64.5 0 thumb\n" "gpr ef .1 64.9 0 endian\n" "gpr jf .1 64.24 0 java\n" "gpr qf .1 64.27 0 sticky_overflow\n" "gpr vf .1 64.28 0 overflow\n" "gpr cf .1 64.29 0 carry\n" "gpr zf .1 64.30 0 zero\n" "gpr nf .1 64.31 0 negative\n" "gpr itc .4 64.10 0 if_then_count\n" "gpr gef .4 64.16 0 great_or_equal\n" "gpr r0 .32 0 0\n" "gpr r1 .32 4 0\n" "gpr r2 .32 8 0\n" "gpr r3 .32 12 0\n" "gpr r4 .32 16 0\n" "gpr r5 .32 20 0\n" "gpr r6 .32 24 0\n" "gpr r7 .32 28 0\n" "gpr r8 .32 32 0\n" "gpr r9 .32 36 0\n" "gpr r10 .32 40 0\n" "gpr r11 .32 44 0\n" "gpr r12 .32 48 0\n" "gpr r13 .32 52 0\n" "gpr r14 .32 56 0\n" "gpr r15 .32 60 0\n" "gpr r16 .32 64 0\n" "gpr r17 .32 68 0\n")
#define eprintf(x, y...)
Definition: rlcc.c:7
RZ_API RZ_OWN char * rz_file_slurp(const char *str, RZ_NULLABLE size_t *usz)
Definition: file.c:454
RZ_API int rz_hex_str2bin(const char *in, ut8 *out)
Convert an input string in into the binary form in out.
Definition: hex.c:444
RZ_API RZ_BORROW char * rz_str_trim_tail(RZ_NONNULL char *str)
Removes whitespace characters (space, tab, newline etc.) from the end of a string and replaces them w...
Definition: str_trim.c:125
RZ_API int rz_str_unescape(char *buf)
Definition: str.c:1300
RZ_API int RZ_API char * rz_sys_cmd_str(const char *cmd, const char *input, int *len)
Definition: sys.c:669
static struct sockaddr static addrlen static backlog const void msg
Definition: sfsocketcall.h:119
#define a(i)
Definition: sha256.c:41

References a, eprintf, free(), i, len, malloc(), msg, NULL, rz_file_slurp(), rz_hex_str2bin(), rz_str_trim_tail(), rz_str_unescape(), rz_sys_cmd_str(), src, and strdup().

Referenced by rz_run_config_env(), and rz_run_parseline().

◆ handle_redirection()

static int handle_redirection ( const char *  cmd,
bool  in,
bool  out,
bool  err 
)
static

Definition at line 389 of file run.c.

389  {
390 #if __APPLE__
391  // XXX handle this in other layer since things changes a little bit
392  // this seems like a really good place to refactor stuff
393  return 0;
394 #else
395  if (!cmd || !*cmd) {
396  return 0;
397  }
398  if (cmd[0] == '"') {
399 #if __UNIX__
400  if (in) {
401  int pipes[2];
402  if (rz_sys_pipe(pipes, true) != -1) {
403  size_t cmdl = strlen(cmd) - 2;
404  if (write(pipes[1], cmd + 1, cmdl) != cmdl) {
405  eprintf("[ERROR] rz-run: Cannot write to the pipe\n");
406  close(0);
407  return 1;
408  }
409  if (write(pipes[1], "\n", 1) != 1) {
410  eprintf("[ERROR] rz-run: Cannot write to the pipe\n");
411  close(0);
412  return 1;
413  }
414  while ((dup2(pipes[0], STDIN_FILENO) == -1) && (errno == EINTR)) {
415  }
416  rz_sys_pipe_close(pipes[0]);
417  rz_sys_pipe_close(pipes[1]);
418  } else {
419  eprintf("[ERROR] rz-run: Cannot create pipe\n");
420  }
421  }
422 #else
423 #ifdef _MSC_VER
424 #pragma message("string redirection handle not yet done")
425 #else
426 #warning quoted string redirection handle not yet done
427 #endif
428 #endif
429  } else if (cmd[0] == '!') {
430  // redirection to a process
431  return handle_redirection_proc(cmd + 1, in, out, err);
432  } else {
433  // redirection to a file
434  int f, flag = 0, mode = 0;
435  flag |= in ? O_RDONLY : 0;
436  flag |= out ? O_WRONLY | O_CREAT : 0;
437  flag |= err ? O_WRONLY | O_CREAT : 0;
438 #ifdef __WINDOWS__
439  mode = _S_IREAD | _S_IWRITE;
440 #else
441  mode = S_IRUSR | S_IWUSR;
442 #endif
443  f = open(cmd, flag, mode);
444  if (f < 0) {
445  eprintf("[ERROR] rz-run: Cannot open: %s\n", cmd);
446  return 1;
447  }
448 #define DUP(x) \
449  { \
450  close(x); \
451  dup2(f, x); \
452  }
453  if (in) {
454  DUP(0);
455  }
456  if (out) {
457  DUP(1);
458  }
459  if (err) {
460  DUP(2);
461  }
462  close(f);
463  }
464  return 0;
465 #endif
466 }
static bool err
Definition: armass.c:435
const lzma_allocator const uint8_t * in
Definition: block.h:527
const lzma_allocator const uint8_t size_t uint8_t * out
Definition: block.h:528
static static fork write
Definition: sflib.h:33
static static fork const void static count close
Definition: sflib.h:33
static static sync static getppid static getegid const char static filename char static len const char char static bufsiz static mask static vfork const void static prot static getpgrp const char static swapflags cmd
Definition: sflib.h:79
const char int mode
Definition: ioapi.h:137
#define DUP(x)
static int handle_redirection_proc(const char *cmd, bool in, bool out, bool err)
Definition: run.c:303
static static fork const void static count static fd const char static mode const char static pathname const char static path const char static dev const char static group static getpid static getuid void void static data static pause const char static mode static sync const char const char static newpath const char static pathname unsigned long static filedes void static end_data_segment static handler static getegid char static len static pgid const char static path dup2
Definition: sflib.h:94
RZ_API int rz_sys_pipe(int pipefd[2], bool close_on_exec)
Definition: sys.c:1458
RZ_API int rz_sys_pipe_close(int fd)
Definition: sys.c:1462
#define O_WRONLY
Definition: sftypes.h:487
#define O_CREAT
Definition: sftypes.h:489
#define EINTR
Definition: sftypes.h:114
#define O_RDONLY
Definition: sftypes.h:486
#define STDIN_FILENO
Definition: private.h:37

References close, cmd, DUP, dup2, EINTR, eprintf, err, f, handle_redirection_proc(), in, O_CREAT, O_RDONLY, O_WRONLY, out, rz_sys_pipe(), rz_sys_pipe_close(), STDIN_FILENO, and write.

Referenced by rz_run_config_env().

◆ handle_redirection_proc()

static int handle_redirection_proc ( const char *  cmd,
bool  in,
bool  out,
bool  err 
)
static

Definition at line 303 of file run.c.

303  {
304 #if HAVE_OPENPTY && HAVE_FORKPTY && HAVE_LOGIN_TTY
305  if (!dyn_forkpty) {
306  // No forkpty api found, maybe we should fallback to just fork without any pty allocated
307  return -1;
308  }
309  // use PTY to redirect I/O because pipes can be problematic in
310  // case of interactive programs.
311  int saved_stdin = dup(STDIN_FILENO);
312  if (saved_stdin == -1) {
313  return -1;
314  }
315  int saved_stdout = dup(STDOUT_FILENO);
316  if (saved_stdout == -1) {
317  close(saved_stdin);
318  return -1;
319  }
320 
321  int fdm, pid = dyn_forkpty(&fdm, NULL, NULL, NULL);
322  if (pid == -1) {
323  close(saved_stdin);
324  close(saved_stdout);
325  return -1;
326  }
327  const char *tn = ttyname(fdm);
328  if (!tn) {
329  close(saved_stdin);
330  close(saved_stdout);
331  return -1;
332  }
333  int fds = open(tn, O_RDWR);
334  if (fds == -1) {
335  close(saved_stdin);
336  close(saved_stdout);
337  return -1;
338  }
339  if (pid == 0) {
340  close(fdm);
341  // child process
342  if (in) {
343  dup2(fds, STDIN_FILENO);
344  }
345  if (out) {
346  dup2(fds, STDOUT_FILENO);
347  }
348  // child - program to run
349 
350  // necessary because otherwise you can read the same thing you
351  // wrote on fdm.
352  struct termios t;
353  tcgetattr(fds, &t);
354  cfmakeraw(&t);
355  tcsetattr(fds, TCSANOW, &t);
356 
357  int code = rz_sys_system(cmd);
358  restore_saved_fd(saved_stdin, in, STDIN_FILENO);
359  restore_saved_fd(saved_stdout, out, STDOUT_FILENO);
360  exit(code);
361  } else {
362  close(fds);
363  if (in) {
364  dup2(fdm, STDIN_FILENO);
365  }
366  if (out) {
367  dup2(fdm, STDOUT_FILENO);
368  }
369  // parent process
370  int status;
371  waitpid(pid, &status, 0);
372  }
373 
374  // parent
375  close(saved_stdin);
376  close(saved_stdout);
377  return 0;
378 #else
379 #ifdef _MSC_VER
380 #pragma message("TODO: handle_redirection_proc: Not implemented for this platform")
381 #else
382 #warning handle_redirection_proc : unimplemented for this platform
383 #endif
384  return -1;
385 #endif
386 }
static static fork const void static count static fd const char const char static newpath char char char static envp time_t static t const char static mode static whence const char static dir time_t static t unsigned static seconds const char struct utimbuf static buf static inc pid
Definition: sflib.h:64
static static fork const void static count static fd const char const char static newpath char char char static envp time_t static t const char static mode static whence const char static dir time_t static t unsigned static seconds const char struct utimbuf static buf static inc static sig const char static mode dup
Definition: sflib.h:68
static const char struct stat static buf struct stat static buf static vhangup int status
Definition: sflib.h:145
RZ_API int rz_sys_system(const char *command)
Definition: sys.c:1658
#define TCSANOW
Definition: sftypes.h:998
#define O_RDWR
Definition: sftypes.h:488
Definition: inftree9.h:24
#define STDOUT_FILENO
Definition: private.h:41

References close, cmd, dup, dup2, test-lz4-list::exit, in, NULL, O_RDWR, out, pid, rz_sys_system(), status, STDIN_FILENO, STDOUT_FILENO, and TCSANOW.

Referenced by handle_redirection().

◆ parseBool()

static int parseBool ( const char *  e)
static

Definition at line 247 of file run.c.

247  {
248  return (strcmp(e, "yes") ? (strcmp(e, "on") ? (strcmp(e, "true") ? (strcmp(e, "1") ? 0 : 1) : 1) : 1) : 1);
249 }
#define e(frag)

References e.

Referenced by rz_run_parseline().

◆ redirect_socket_to_pty()

static int redirect_socket_to_pty ( RzSocket sock)
static

Definition at line 731 of file run.c.

731  {
732 #if HAVE_OPENPTY && HAVE_FORKPTY && HAVE_LOGIN_TTY
733  // directly duplicating the fds using dup2() creates problems
734  // in case of interactive applications
735  int fdm, fds;
736 
737  if (!dyn_openpty || (dyn_openpty && dyn_openpty(&fdm, &fds, NULL, NULL, NULL) == -1)) {
738  perror("opening pty");
739  return -1;
740  }
741 
742  pid_t child_pid = rz_sys_fork();
743 
744  if (child_pid == -1) {
745  eprintf("cannot fork\n");
746  close(fdm);
747  close(fds);
748  return -1;
749  }
750 
751  if (child_pid == 0) {
752  // child process
753  close(fds);
754 
755  char *buff = NULL;
756  int sockfd = sock->fd;
757  int max_fd = fdm > sockfd ? fdm : sockfd;
758 
759  while (true) {
760  fd_set readfds;
761  FD_ZERO(&readfds);
762  FD_SET(fdm, &readfds);
763  FD_SET(sockfd, &readfds);
764 
765  if (select(max_fd + 1, &readfds, NULL, NULL, NULL) == -1) {
766  perror("select error");
767  break;
768  }
769 
770  if (FD_ISSET(fdm, &readfds)) {
771  if (fd_forward(fdm, sockfd, &buff) != 0) {
772  break;
773  }
774  }
775 
776  if (FD_ISSET(sockfd, &readfds)) {
777  if (fd_forward(sockfd, fdm, &buff) != 0) {
778  break;
779  }
780  }
781  }
782 
783  free(buff);
784  close(fdm);
785  rz_socket_free(sock);
786  exit(0);
787  }
788 
789  // parent
790  rz_socket_close_fd(sock);
791  if (dyn_login_tty) {
792  dyn_login_tty(fds);
793  }
794  close(fdm);
795 
796  // disable the echo on slave stdin
797  struct termios t;
798  tcgetattr(0, &t);
799  cfmakeraw(&t);
800  tcsetattr(0, TCSANOW, &t);
801 
802  return 0;
803 #else
804  // Fallback to socket to I/O redirection
805  return redirect_socket_to_stdio(sock);
806 #endif
807 }
static int redirect_socket_to_stdio(RzSocket *sock)
Definition: run.c:709
static static fork const void static count static fd const char const char static newpath char char char static envp time_t static t const char static mode static whence const char static dir time_t static t unsigned static seconds const char struct utimbuf static buf static inc static sig const char static mode static oldfd struct tms static buf static getgid static geteuid const char static filename static arg static mask struct ustat static ubuf static getppid static setsid static egid sigset_t static set struct timeval struct timezone static tz fd_set readfds
Definition: sflib.h:108
static static fork const void static count static fd const char const char static newpath char char char static envp time_t static t const char static mode static whence const char static dir time_t static t unsigned static seconds const char struct utimbuf static buf static inc static sig const char static mode static oldfd struct tms static buf static getgid static geteuid const char static filename static arg static mask struct ustat static ubuf static getppid static setsid static egid sigset_t static set struct timeval struct timezone static tz select
Definition: sflib.h:108
RZ_API int rz_socket_close_fd(RzSocket *s)
Definition: socket.c:410
RZ_API int rz_socket_free(RzSocket *s)
Definition: socket.c:453
RZ_API int rz_sys_fork(void)
Definition: sys.c:1679
static sockfd
Definition: sfsocketcall.h:114
#define FD_ZERO(set)
Definition: sftypes.h:204
#define FD_ISSET(d, set)
Definition: sftypes.h:214
#define FD_SET(d, set)
Definition: sftypes.h:212
int pid_t
Definition: sftypes.h:38

References close, eprintf, test-lz4-list::exit, rz_socket_t::fd, FD_ISSET, FD_SET, FD_ZERO, free(), NULL, readfds, redirect_socket_to_stdio(), rz_socket_close_fd(), rz_socket_free(), rz_sys_fork(), select, sockfd, and TCSANOW.

Referenced by rz_run_config_env().

◆ redirect_socket_to_stdio()

static int redirect_socket_to_stdio ( RzSocket sock)
static

Definition at line 709 of file run.c.

709  {
710  close(0);
711  close(1);
712  close(2);
713 
714  dup2(sock->fd, 0);
715  dup2(sock->fd, 1);
716  dup2(sock->fd, 2);
717 
718  return 0;
719 }

References close, dup2, and rz_socket_t::fd.

Referenced by redirect_socket_to_pty(), and rz_run_config_env().

◆ rz_run_config_env()

RZ_API int rz_run_config_env ( RzRunProfile p)

Definition at line 809 of file run.c.

809  {
810  int ret;
811 
812 #if HAVE_OPENPTY && HAVE_FORKPTY && HAVE_LOGIN_TTY
813  dyn_init();
814 #endif
815 
816  if (!p->_program && !p->_system && !p->_runlib) {
817  eprintf("No program, system or runlib rule defined\n");
818  return 1;
819  }
820  // when IO is redirected to a process, handle them together
821  if (handle_redirection(p->_stdio, true, true, false) != 0) {
822  return 1;
823  }
824  if (handle_redirection(p->_stdin, true, false, false) != 0) {
825  return 1;
826  }
827  if (handle_redirection(p->_stdout, false, true, false) != 0) {
828  return 1;
829  }
830  if (handle_redirection(p->_stderr, false, false, true) != 0) {
831  return 1;
832  }
833  if (p->_aslr != -1) {
834  setASLR(p, p->_aslr);
835  }
836 #if __UNIX__
837  set_limit(p->_docore, RLIMIT_CORE, RLIM_INFINITY);
838  if (p->_maxfd) {
839  set_limit(p->_maxfd, RLIMIT_NOFILE, p->_maxfd);
840  }
841 #ifdef RLIMIT_NPROC
842  if (p->_maxproc) {
843  set_limit(p->_maxproc, RLIMIT_NPROC, p->_maxproc);
844  }
845 #endif
846  if (p->_maxstack) {
847  set_limit(p->_maxstack, RLIMIT_STACK, p->_maxstack);
848  }
849 #else
850  if (p->_docore || p->_maxfd || p->_maxproc || p->_maxstack)
851  eprintf("Warning: setrlimits not supported for this platform\n");
852 #endif
853  if (p->_connect) {
854  char *q = strchr(p->_connect, ':');
855  if (q) {
856  RzSocket *fd = rz_socket_new(0);
857  *q = 0;
858  if (!rz_socket_connect_tcp(fd, p->_connect, q + 1, 30)) {
859  eprintf("Cannot connect\n");
860  return 1;
861  }
862  if (p->_pty) {
863  if (redirect_socket_to_pty(fd) != 0) {
864  eprintf("socket redirection failed\n");
866  return 1;
867  }
868  } else {
870  }
871  } else {
872  eprintf("Invalid format for connect. missing ':'\n");
873  return 1;
874  }
875  }
876  if (p->_listen) {
877  RzSocket *child, *fd = rz_socket_new(0);
878  bool is_child = false;
879  if (!rz_socket_listen(fd, p->_listen, NULL)) {
880  eprintf("rz-run: cannot listen\n");
882  return 1;
883  }
884  while (true) {
885  child = rz_socket_accept(fd);
886  if (child) {
887  is_child = true;
888 
889  if (p->_dofork && !p->_dodebug) {
890  pid_t child_pid = rz_sys_fork();
891  if (child_pid == -1) {
892  eprintf("rz-run: cannot fork\n");
893  rz_socket_free(child);
895  return 1;
896  } else if (child_pid != 0) {
897  // parent code
898  is_child = false;
899  }
900  }
901 
902  if (is_child) {
904  eprintf("connected\n");
905  if (p->_pty) {
906  if (redirect_socket_to_pty(child) != 0) {
907  eprintf("socket redirection failed\n");
908  rz_socket_free(child);
910  return 1;
911  }
912  } else {
914  }
915  break;
916  } else {
917  rz_socket_close_fd(child);
918  }
919  }
920  }
921  if (!is_child) {
922  rz_socket_free(child);
923  }
925  }
926  if (p->_rzsleep != 0) {
927  rz_sys_sleep(p->_rzsleep);
928  }
929 #if __UNIX__
930  if (p->_chroot) {
931  if (chdir(p->_chroot) == -1) {
932  eprintf("Cannot chdir to chroot in %s\n", p->_chroot);
933  return 1;
934  } else {
935  if (chroot(".") == -1) {
936  eprintf("Cannot chroot to %s\n", p->_chroot);
937  return 1;
938  } else {
939  // Silenting pedantic meson flags...
940  if (chdir("/") == -1) {
941  eprintf("Cannot chdir to /\n");
942  return 1;
943  }
944  if (p->_chgdir) {
945  if (chdir(p->_chgdir) == -1) {
946  eprintf("Cannot chdir after chroot to %s\n", p->_chgdir);
947  return 1;
948  }
949  }
950  }
951  }
952  } else if (p->_chgdir) {
953  if (chdir(p->_chgdir) == -1) {
954  eprintf("Cannot chdir after chroot to %s\n", p->_chgdir);
955  return 1;
956  }
957  }
958 #else
959  if (p->_chgdir) {
960  ret = chdir(p->_chgdir);
961  if (ret < 0) {
962  return 1;
963  }
964  }
965  if (p->_chroot) {
966  ret = chdir(p->_chroot);
967  if (ret < 0) {
968  return 1;
969  }
970  }
971 #endif
972 #if __UNIX__
973  if (p->_setuid) {
974  ret = setgroups(0, NULL);
975  if (ret < 0) {
976  return 1;
977  }
978  ret = setuid(atoi(p->_setuid));
979  if (ret < 0) {
980  return 1;
981  }
982  }
983  if (p->_seteuid) {
984  ret = seteuid(atoi(p->_seteuid));
985  if (ret < 0) {
986  return 1;
987  }
988  }
989  if (p->_setgid) {
990  ret = setgid(atoi(p->_setgid));
991  if (ret < 0) {
992  return 1;
993  }
994  }
995  if (p->_input) {
996  char *inp;
997  int f2[2];
998  if (rz_sys_pipe(f2, true) != -1) {
999  close(0);
1000  dup2(f2[0], 0);
1001  } else {
1002  eprintf("[ERROR] rz-run: Cannot create pipe\n");
1003  return 1;
1004  }
1005  inp = getstr(p->_input);
1006  if (inp) {
1007  size_t inpl = strlen(inp);
1008  if (write(f2[1], inp, inpl) != inpl) {
1009  eprintf("[ERROR] rz-run: Cannot write to the pipe\n");
1010  }
1011  rz_sys_pipe_close(f2[1]);
1012  free(inp);
1013  } else {
1014  eprintf("Invalid input\n");
1015  }
1016  }
1017 #endif
1018  if (p->_rzpreload) {
1019  if (p->_preload) {
1020  eprintf("WARNING: Only one library can be opened at a time\n");
1021  }
1022  char *libdir = rz_path_libdir();
1023  p->_preload = rz_file_path_join(libdir, "librz." RZ_LIB_EXT);
1024  free(libdir);
1025  }
1026  if (p->_libpath) {
1027 #if __WINDOWS__
1028  eprintf("rz-run: libpath unsupported for this platform\n");
1029 #elif __HAIKU__
1030  char *orig = rz_sys_getenv("LIBRARY_PATH");
1031  char *newlib = rz_str_newf("%s:%s", p->_libpath, orig);
1032  rz_sys_setenv("LIBRARY_PATH", newlib);
1033  free(newlib);
1034  free(orig);
1035 #elif __APPLE__
1036  rz_sys_setenv("DYLD_LIBRARY_PATH", p->_libpath);
1037 #else
1038  rz_sys_setenv("LD_LIBRARY_PATH", p->_libpath);
1039 #endif
1040  }
1041  if (p->_preload) {
1042 #if __APPLE__
1043  // 10.6
1044 #ifndef __MAC_10_7
1045  rz_sys_setenv("DYLD_PRELOAD", p->_preload);
1046 #endif
1047  rz_sys_setenv("DYLD_INSERT_LIBRARIES", p->_preload);
1048  // 10.8
1049  rz_sys_setenv("DYLD_FORCE_FLAT_NAMESPACE", "1");
1050 #else
1051  rz_sys_setenv("LD_PRELOAD", p->_preload);
1052 #endif
1053  }
1054  if (p->_timeout) {
1055 #if __UNIX__
1056  int mypid = getpid();
1057  if (!rz_sys_fork()) {
1058  int use_signal = p->_timeout_sig;
1059  if (use_signal < 1) {
1060  use_signal = SIGKILL;
1061  }
1062  sleep(p->_timeout);
1063  if (!kill(mypid, 0)) {
1064  // eprintf ("\nrz_run: Interrupted by timeout\n");
1065  }
1066  kill(mypid, use_signal);
1067  exit(0);
1068  }
1069 #else
1070  if (p->_timeout_sig < 1 || p->_timeout_sig == 9) {
1071  rz_th_new(exit_process, (void *)p->_timeout);
1072  } else {
1073  eprintf("timeout with signal not supported for this platform\n");
1074  }
1075 #endif
1076  }
1077  return 0;
1078 }
#define SIGKILL
static static fork const void static count static fd const char const char static newpath chdir
Definition: sflib.h:33
static static fork const void static count static fd const char const char static newpath const char static path const char static mode static getpid setgid
Definition: sflib.h:41
void * p
Definition: libc.cpp:67
static int redirect_socket_to_pty(RzSocket *sock)
Definition: run.c:731
static int handle_redirection(const char *cmd, bool in, bool out, bool err)
Definition: run.c:389
static char * getstr(const char *src)
Definition: run.c:152
static void setASLR(RzRunProfile *r, int enabled)
Definition: run.c:252
RZ_API RZ_OWN RzThread * rz_th_new(RZ_NONNULL RzThreadFunction function, RZ_NULLABLE void *user)
Creates and starts a new thread.
Definition: thread.c:198
static static fork const void static count static fd const char const char static newpath char char char static envp time_t static t const char static mode static whence const char static dir time_t static t unsigned static seconds const char struct utimbuf static buf static inc kill
Definition: sflib.h:64
static static fork const void static count static fd const char static mode const char static pathname const char static path const char static dev const char static group static getpid static getuid void void static data static pause const char static mode static sync const char const char static newpath const char static pathname unsigned long static filedes void static end_data_segment static handler static getegid char static len static pgid const char static path static newfd static getpgrp static euid const sigset_t static mask const char static len setgroups
Definition: sflib.h:112
static static fork const void static count static fd const char static mode const char static pathname const char static path const char static dev const char static group static getpid static getuid void void static data static pause const char static mode static sync const char const char static newpath const char static pathname unsigned long static filedes void static end_data_segment static handler static getegid char static len static pgid chroot
Definition: sflib.h:92
RZ_API RZ_OWN char * rz_file_path_join(RZ_NONNULL const char *s1, RZ_NULLABLE const char *s2)
Concatenate two paths to create a new one with s1+s2 with the correct path separator.
Definition: file.c:1312
#define RZ_LIB_EXT
Definition: rz_lib.h:31
RZ_API RZ_OWN char * rz_path_libdir(void)
Return the directory where the Rizin libraries are placed.
Definition: path.c:155
RZ_API RzSocket * rz_socket_accept(RzSocket *s)
Definition: socket.c:582
RZ_API bool rz_socket_listen(RzSocket *s, const char *port, const char *certfile)
Definition: socket.c:474
#define rz_socket_connect_tcp(a, b, c, d)
Definition: rz_socket.h:99
RZ_API RzSocket * rz_socket_new(bool is_ssl)
Definition: socket.c:179
RZ_API char * rz_str_newf(const char *fmt,...) RZ_PRINTF_CHECK(1
RZ_API char * rz_sys_getenv(const char *key)
Get the value of an environment variable named key or NULL if none exists.
Definition: sys.c:483
RZ_API int rz_sys_setenv(const char *key, const char *value)
Set an environment variable in the calling process.
Definition: sys.c:405
RZ_API int rz_sys_sleep(int secs)
Sleep for secs seconds.
Definition: sys.c:300
static const z80_opcode fd[]
Definition: z80_tab.h:997

References chdir, chroot, close, dup2, eprintf, test-lz4-list::exit, autogen_x86imm::f2, fd, free(), getstr(), handle_redirection(), kill, NULL, p, redirect_socket_to_pty(), redirect_socket_to_stdio(), rz_file_path_join(), RZ_LIB_EXT, rz_path_libdir(), rz_socket_accept(), rz_socket_close_fd(), rz_socket_connect_tcp, rz_socket_free(), rz_socket_listen(), rz_socket_new(), rz_str_newf(), rz_sys_fork(), rz_sys_getenv(), rz_sys_pipe(), rz_sys_pipe_close(), rz_sys_setenv(), rz_sys_sleep(), rz_th_new(), setASLR(), setgid, setgroups, SIGKILL, and write.

Referenced by rz_main_rz_run().

◆ rz_run_free()

RZ_API void rz_run_free ( RzRunProfile r)

Definition at line 122 of file run.c.

122  {
123  if (r) {
124  free(r->_system);
125  free(r->_program);
126  free(r->_runlib);
127  free(r->_runlib_fcn);
128  free(r->_stdio);
129  free(r->_stdin);
130  free(r->_stdout);
131  free(r->_stderr);
132  free(r->_chgdir);
133  free(r->_chroot);
134  free(r->_libpath);
135  free(r->_preload);
136  free(r);
137  }
138 }
#define r
Definition: crypto_rc6.c:12

References free(), and r.

Referenced by rz_main_rz_run(), and rz_socket_spawn().

◆ rz_run_get_environ_profile()

RZ_API char* rz_run_get_environ_profile ( char **  env)

Definition at line 1329 of file run.c.

1329  {
1330  if (!env) {
1331  return NULL;
1332  }
1334  while (*env) {
1335  char *k = strdup(*env);
1336  char *v = strchr(k, '=');
1337  if (v) {
1338  *v++ = 0;
1339  RzStrEscOptions opt = { 0 };
1340  opt.show_asciidot = false;
1341  opt.esc_bslash = true;
1342  v = rz_str_escape_8bit(v, true, &opt);
1343  if (v) {
1344  rz_strbuf_appendf(sb, "setenv=%s=\"%s\"\n", k, v);
1345  free(v);
1346  }
1347  }
1348  free(k);
1349  env++;
1350  }
1351  return rz_strbuf_drain(sb);
1352 }
static SblHeader sb
Definition: bin_mbn.c:26
const char * k
Definition: dsignal.c:11
const char * v
Definition: dsignal.c:12
RZ_API char * rz_str_escape_8bit(const char *buf, bool colors, RzStrEscOptions *opt)
Definition: str.c:1595
RZ_API RZ_OWN char * rz_strbuf_drain(RzStrBuf *sb)
Definition: strbuf.c:342
RZ_API RzStrBuf * rz_strbuf_new(const char *s)
Definition: strbuf.c:8
RZ_API bool rz_strbuf_appendf(RzStrBuf *sb, const char *fmt,...) RZ_PRINTF_CHECK(2
Group together some common options used by string escaping functions.
Definition: rz_str.h:39
bool esc_bslash
When true, backslashes \ are quoted with \\
Definition: rz_str.h:41
bool show_asciidot
When true, dots . are placed instead of unprintable characters.
Definition: rz_str.h:40
static char ** env
Definition: sys.c:32

References env, RzStrEscOptions::esc_bslash, free(), k, NULL, rz_str_escape_8bit(), rz_strbuf_appendf(), rz_strbuf_drain(), rz_strbuf_new(), sb, RzStrEscOptions::show_asciidot, strdup(), and v.

Referenced by rz_main_rizin().

◆ rz_run_help()

RZ_API const char* rz_run_help ( void  )

Definition at line 630 of file run.c.

630  {
631  return "program=/bin/ls\n"
632  "arg1=/bin\n"
633  "# arg2=hello\n"
634  "# arg3=\"hello\\nworld\"\n"
635  "# arg4=:048490184058104849\n"
636  "# arg5=:!rz-gg -p n50 -d 10:0x8048123\n"
637  "# arg6=@arg.txt\n"
638  "# arg7=@300@ABCD # 300 chars filled with ABCD pattern\n"
639  "# system=rizin -\n"
640  "# daemon=false\n"
641  "# aslr=no\n"
642  "setenv=FOO=BAR\n"
643  "# unsetenv=FOO\n"
644  "# clearenv=true\n"
645  "# envfile=environ.txt\n"
646  "timeout=3\n"
647  "# timeoutsig=SIGTERM # or 15\n"
648  "# connect=localhost:8080\n"
649  "# listen=8080\n"
650  "# pty=false\n"
651  "# fork=true\n"
652  "# bits=32\n"
653  "# pid=0\n"
654  "# pidfile=/tmp/foo.pid\n"
655  "# #sleep=0\n"
656  "# #maxfd=0\n"
657  "# #execve=false\n"
658  "# #maxproc=0\n"
659  "# #maxstack=0\n"
660  "# #core=false\n"
661  "# #stdio=blah.txt\n"
662  "# #stderr=foo.txt\n"
663  "# stdout=foo.txt\n"
664  "# stdin=input.txt # or !program to redirect input from another program\n"
665  "# input=input.txt\n"
666  "# chdir=/\n"
667  "# chroot=/mnt/chroot\n"
668  "# libpath=$PWD:/tmp/lib\n"
669  "# rzpreload=yes\n"
670  "# preload=/lib/libfoo.so\n"
671  "# setuid=2000\n"
672  "# seteuid=2000\n"
673  "# setgid=2001\n"
674  "# setegid=2001\n"
675  "# nice=5\n";
676 }

Referenced by rz_main_rz_run().

◆ rz_run_new()

RZ_API RzRunProfile* rz_run_new ( const char *  str)

Definition at line 86 of file run.c.

86  {
88  if (p) {
89  rz_run_reset(p);
90  if (str) {
92  }
93  }
94  return p;
95 }
RZ_API void rz_run_reset(RzRunProfile *p)
Definition: run.c:97
RZ_API bool rz_run_parsefile(RzRunProfile *p, const char *b)
Definition: run.c:468
#define RZ_NEW0(x)
Definition: rz_types.h:284

References p, RZ_NEW0, rz_run_parsefile(), rz_run_reset(), and cmd_descs_generate::str.

Referenced by rz_main_rz_run(), and rz_socket_spawn().

◆ rz_run_parse()

RZ_API bool rz_run_parse ( RzRunProfile pf,
const char *  profile 
)

Definition at line 103 of file run.c.

103  {
104  rz_return_val_if_fail(pf && profile, false);
105  char *p, *o, *str = strdup(profile);
106  if (!str) {
107  return false;
108  }
109  rz_str_replace_char(str, '\r', 0);
110  p = str;
111  while (p) {
112  if ((o = strchr(p, '\n'))) {
113  *o++ = 0;
114  }
115  rz_run_parseline(pf, p);
116  p = o;
117  }
118  free(str);
119  return true;
120 }
RZ_API bool rz_run_parseline(RzRunProfile *p, const char *b)
Definition: run.c:479
#define rz_return_val_if_fail(expr, val)
Definition: rz_assert.h:108
RZ_API int rz_str_replace_char(char *s, int a, int b)
Definition: str.c:169

References free(), p, rz_return_val_if_fail, rz_run_parseline(), rz_str_replace_char(), cmd_descs_generate::str, and strdup().

Referenced by rz_run_parsefile().

◆ rz_run_parsefile()

RZ_API bool rz_run_parsefile ( RzRunProfile p,
const char *  b 
)

Definition at line 468 of file run.c.

468  {
469  rz_return_val_if_fail(p && b, false);
470  char *s = rz_file_slurp(b, NULL);
471  if (s) {
472  bool ret = rz_run_parse(p, s);
473  free(s);
474  return ret;
475  }
476  return 0;
477 }
RZ_API bool rz_run_parse(RzRunProfile *pf, const char *profile)
Definition: run.c:103
static RzSocket * s
Definition: rtr.c:28
#define b(i)
Definition: sha256.c:42

References b, free(), NULL, p, rz_file_slurp(), rz_return_val_if_fail, rz_run_parse(), and s.

Referenced by rz_run_new().

◆ rz_run_parseline()

RZ_API bool rz_run_parseline ( RzRunProfile p,
const char *  b 
)

Definition at line 479 of file run.c.

479  {
480  int must_free = false;
481  char *e = strchr(b, '=');
482  if (!e || *b == '#') {
483  return 0;
484  }
485  *e++ = 0;
486  if (*e == '$') {
487  must_free = true;
488  e = rz_sys_getenv(e);
489  }
490  if (!e) {
491  return 0;
492  }
493  if (!strcmp(b, "program")) {
494  p->_args[0] = p->_program = strdup(e);
495  } else if (!strcmp(b, "daemon")) {
496  p->_daemon = true;
497  } else if (!strcmp(b, "system")) {
498  p->_system = strdup(e);
499  } else if (!strcmp(b, "runlib")) {
500  p->_runlib = strdup(e);
501  } else if (!strcmp(b, "runlib.fcn")) {
502  p->_runlib_fcn = strdup(e);
503  } else if (!strcmp(b, "aslr")) {
504  p->_aslr = parseBool(e);
505  } else if (!strcmp(b, "pid")) {
506  p->_pid = parseBool(e);
507  } else if (!strcmp(b, "pidfile")) {
508  p->_pidfile = strdup(e);
509  } else if (!strcmp(b, "connect")) {
510  p->_connect = strdup(e);
511  } else if (!strcmp(b, "listen")) {
512  p->_listen = strdup(e);
513  } else if (!strcmp(b, "pty")) {
514  p->_pty = parseBool(e);
515  } else if (!strcmp(b, "stdio")) {
516  if (e[0] == '!') {
517  p->_stdio = strdup(e);
518  } else {
519  p->_stdout = strdup(e);
520  p->_stderr = strdup(e);
521  p->_stdin = strdup(e);
522  }
523  } else if (!strcmp(b, "stdout")) {
524  p->_stdout = strdup(e);
525  } else if (!strcmp(b, "stdin")) {
526  p->_stdin = strdup(e);
527  } else if (!strcmp(b, "stderr")) {
528  p->_stderr = strdup(e);
529  } else if (!strcmp(b, "input")) {
530  p->_input = strdup(e);
531  } else if (!strcmp(b, "chdir")) {
532  p->_chgdir = strdup(e);
533  } else if (!strcmp(b, "core")) {
534  p->_docore = parseBool(e);
535  } else if (!strcmp(b, "fork")) {
536  p->_dofork = parseBool(e);
537  } else if (!strcmp(b, "sleep")) {
538  p->_rzsleep = atoi(e);
539  } else if (!strcmp(b, "maxstack")) {
540  p->_maxstack = atoi(e);
541  } else if (!strcmp(b, "maxproc")) {
542  p->_maxproc = atoi(e);
543  } else if (!strcmp(b, "maxfd")) {
544  p->_maxfd = atoi(e);
545  } else if (!strcmp(b, "bits")) {
546  p->_bits = atoi(e);
547  } else if (!strcmp(b, "chroot")) {
548  p->_chroot = strdup(e);
549  } else if (!strcmp(b, "libpath")) {
550  p->_libpath = strdup(e);
551  } else if (!strcmp(b, "preload")) {
552  p->_preload = strdup(e);
553  } else if (!strcmp(b, "rzpreload")) {
554  p->_rzpreload = parseBool(e);
555  } else if (!strcmp(b, "rzpreweb")) {
556  rz_sys_setenv("RZ_RUN_WEB", "yes");
557  } else if (!strcmp(b, "setuid")) {
558  p->_setuid = strdup(e);
559  } else if (!strcmp(b, "seteuid")) {
560  p->_seteuid = strdup(e);
561  } else if (!strcmp(b, "setgid")) {
562  p->_setgid = strdup(e);
563  } else if (!strcmp(b, "setegid")) {
564  p->_setegid = strdup(e);
565  } else if (!strcmp(b, "nice")) {
566  p->_nice = atoi(e);
567  } else if (!strcmp(b, "timeout")) {
568  p->_timeout = atoi(e);
569  } else if (!strcmp(b, "timeoutsig")) {
570  p->_timeout_sig = rz_signal_from_string(e);
571  } else if (!memcmp(b, "arg", 3)) {
572  int n = atoi(b + 3);
573  if (n >= 0 && n < RZ_RUN_PROFILE_NARGS) {
574  p->_args[n] = getstr(e);
575  p->_argc++;
576  } else {
577  eprintf("Out of bounds args index: %d\n", n);
578  }
579  } else if (!strcmp(b, "envfile")) {
580  char *p, buf[1024];
581  size_t len;
582  FILE *fd = rz_sys_fopen(e, "r");
583  if (!fd) {
584  eprintf("Cannot open '%s'\n", e);
585  if (must_free == true) {
586  free(e);
587  }
588  return false;
589  }
590  for (;;) {
591  if (!fgets(buf, sizeof(buf), fd)) {
592  break;
593  }
594  if (feof(fd)) {
595  break;
596  }
597  p = strchr(buf, '=');
598  if (p) {
599  *p++ = 0;
600  len = strlen(p);
601  if (len > 0 && p[len - 1] == '\n') {
602  p[len - 1] = 0;
603  }
604  if (len > 1 && p[len - 2] == '\r') {
605  p[len - 2] = 0;
606  }
607  rz_sys_setenv(buf, p);
608  }
609  }
610  fclose(fd);
611  } else if (!strcmp(b, "unsetenv")) {
612  rz_sys_setenv(e, NULL);
613  } else if (!strcmp(b, "setenv")) {
614  char *V, *v = strchr(e, '=');
615  if (v) {
616  *v++ = 0;
617  V = getstr(v);
618  rz_sys_setenv(e, V);
619  free(V);
620  }
621  } else if (!strcmp(b, "clearenv")) {
622  rz_sys_clearenv();
623  }
624  if (must_free == true) {
625  free(e);
626  }
627  return true;
628 }
static int parseBool(const char *e)
Definition: run.c:247
int n
Definition: mipsasm.c:19
string FILE
Definition: benchmark.py:21
RZ_API int rz_signal_from_string(const char *str)
Definition: signal.c:52
#define RZ_RUN_PROFILE_NARGS
Definition: rz_socket.h:211
RZ_API int rz_sys_clearenv(void)
Clean all environment variables in the calling process.
Definition: sys.c:346
RZ_API FILE * rz_sys_fopen(const char *path, const char *mode)
Definition: sys.c:1815
#define V(handle, symbol)

References b, e, eprintf, fd, benchmark::FILE, free(), getstr(), len, n, NULL, p, parseBool(), RZ_RUN_PROFILE_NARGS, rz_signal_from_string(), rz_sys_clearenv(), rz_sys_fopen(), rz_sys_getenv(), rz_sys_setenv(), strdup(), v, and V.

Referenced by rz_main_rz_run(), and rz_run_parse().

◆ rz_run_reset()

RZ_API void rz_run_reset ( RzRunProfile p)

Definition at line 97 of file run.c.

97  {
99  memset(p, 0, sizeof(RzRunProfile));
100  p->_aslr = -1;
101 }
return memset(p, 0, total)
#define rz_return_if_fail(expr)
Definition: rz_assert.h:100

References memset(), p, and rz_return_if_fail.

Referenced by rz_run_new().

◆ rz_run_start()

RZ_API int rz_run_start ( RzRunProfile p)

Definition at line 1081 of file run.c.

1081  {
1082 #if HAVE_EXECVE
1083  if (p->_execve) {
1084  exit(rz_sys_execv(p->_program, (char *const *)p->_args));
1085  }
1086 #endif
1087 #if __APPLE__ && HAVE_FORK
1088  posix_spawnattr_t attr = { 0 };
1089  pid_t pid = -1;
1090  int ret;
1091  posix_spawnattr_init(&attr);
1092  if (p->_args[0]) {
1093  char **envp = rz_sys_get_environ();
1094  ut32 spflags = 0; // POSIX_SPAWN_START_SUSPENDED;
1095  spflags |= POSIX_SPAWN_SETEXEC;
1096  if (p->_aslr == 0) {
1097 #define _POSIX_SPAWN_DISABLE_ASLR 0x0100
1098  spflags |= _POSIX_SPAWN_DISABLE_ASLR;
1099  }
1100  (void)posix_spawnattr_setflags(&attr, spflags);
1101  if (p->_bits) {
1102  size_t copied = 1;
1103  cpu_type_t cpu;
1104 #if __i386__ || __x86_64__
1105  cpu = CPU_TYPE_I386;
1106  if (p->_bits == 64) {
1107  cpu |= CPU_ARCH_ABI64;
1108  }
1109 #else
1110  cpu = CPU_TYPE_ANY;
1111 #endif
1112  posix_spawnattr_setbinpref_np(
1113  &attr, 1, &cpu, &copied);
1114  }
1115  ret = posix_spawnp(&pid, p->_args[0],
1116  NULL, &attr, p->_args, envp);
1117  switch (ret) {
1118  case 0:
1119  break;
1120  default:
1121  eprintf("posix_spawnp: %s\n", strerror(ret));
1122  break;
1123  }
1124  exit(ret);
1125  }
1126 #endif
1127  if (p->_system) {
1128  if (p->_pid) {
1129  eprintf("PID: Cannot determine pid with 'system' directive. Use 'program'.\n");
1130  }
1131  if (p->_daemon) {
1132 #if __WINDOWS__
1133  // eprintf ("PID: Cannot determine pid with 'system' directive. Use 'program'.\n");
1134 #else
1135  pid_t child = rz_sys_fork();
1136  if (child == -1) {
1137  perror("fork");
1138  exit(1);
1139  }
1140  if (child) {
1141  if (p->_pidfile) {
1142  char pidstr[32];
1143  snprintf(pidstr, sizeof(pidstr), "%d\n", child);
1144  rz_file_dump(p->_pidfile,
1145  (const ut8 *)pidstr,
1146  strlen(pidstr), 0);
1147  }
1148  exit(0);
1149  }
1150  setsid();
1151  if (p->_timeout) {
1152 #if __UNIX__
1153  int mypid = getpid();
1154  if (!rz_sys_fork()) {
1155  int use_signal = p->_timeout_sig;
1156  if (use_signal < 1) {
1157  use_signal = SIGKILL;
1158  }
1159  sleep(p->_timeout);
1160  if (!kill(mypid, 0)) {
1161  // eprintf ("\nrz_run: Interrupted by timeout\n");
1162  }
1163  kill(mypid, use_signal);
1164  exit(0);
1165  }
1166 #else
1167  eprintf("timeout not supported for this platform\n");
1168 #endif
1169  }
1170 #endif
1171 #if __UNIX__
1172  close(0);
1173  close(1);
1174  char *bin_sh = rz_file_binsh();
1175  int ret = rz_sys_execl(bin_sh, "sh", "-c", p->_system, NULL);
1176  free(bin_sh);
1177  exit(ret);
1178 #else
1179  exit(rz_sys_system(p->_system));
1180 #endif
1181  } else {
1182  if (p->_pidfile) {
1183  eprintf("Warning: pidfile doesnt work with 'system'.\n");
1184  }
1185  exit(rz_sys_system(p->_system));
1186  }
1187  }
1188  if (p->_program) {
1189  if (!rz_file_exists(p->_program)) {
1190  char *progpath = rz_file_path(p->_program);
1191  if (progpath && *progpath) {
1192  free(p->_program);
1193  p->_program = progpath;
1194  } else {
1195  free(progpath);
1196  eprintf("rz-run: %s: file not found\n", p->_program);
1197  return 1;
1198  }
1199  }
1200 #if __UNIX__
1201  // XXX HACK close all non-tty fds
1202  {
1203  int i;
1204  for (i = 3; i < 1024; i++) {
1205  close(i);
1206  }
1207  }
1208  // TODO: use posix_spawn
1209  if (p->_setgid) {
1210  int ret = setgid(atoi(p->_setgid));
1211  if (ret < 0) {
1212  return 1;
1213  }
1214  }
1215  if (p->_pid) {
1216  eprintf("PID: %d\n", getpid());
1217  }
1218  if (p->_pidfile) {
1219  char pidstr[32];
1220  snprintf(pidstr, sizeof(pidstr), "%d\n", getpid());
1221  rz_file_dump(p->_pidfile,
1222  (const ut8 *)pidstr,
1223  strlen(pidstr), 0);
1224  }
1225 #endif
1226 
1227  if (p->_nice) {
1228 #if HAVE_NICE
1229  if (nice(p->_nice) == -1) {
1230  return 1;
1231  }
1232 #else
1233  eprintf("nice not supported for this platform\n");
1234 #endif
1235  }
1236  if (p->_daemon) {
1237 #if __WINDOWS__
1238  eprintf("PID: Cannot determine pid with 'system' directive. Use 'program'.\n");
1239 #else
1240  pid_t child = rz_sys_fork();
1241  if (child == -1) {
1242  perror("fork");
1243  exit(1);
1244  }
1245  if (child) {
1246  if (p->_pidfile) {
1247  char pidstr[32];
1248  snprintf(pidstr, sizeof(pidstr), "%d\n", child);
1249  rz_file_dump(p->_pidfile,
1250  (const ut8 *)pidstr,
1251  strlen(pidstr), 0);
1252  exit(0);
1253  }
1254  }
1255  setsid();
1256 #if HAVE_EXECVE
1257  exit(rz_sys_execv(p->_program, (char *const *)p->_args));
1258 #endif
1259 #endif
1260  }
1261 #if HAVE_EXECVE
1262  exit(rz_sys_execv(p->_program, (char *const *)p->_args));
1263 #endif
1264  }
1265  if (p->_runlib) {
1266  if (!p->_runlib_fcn) {
1267  eprintf("No function specified. Please set runlib.fcn\n");
1268  return 1;
1269  }
1270  void *addr = rz_lib_dl_open(p->_runlib);
1271  if (!addr) {
1272  eprintf("Could not load the library '%s'\n", p->_runlib);
1273  return 1;
1274  }
1275  void (*fcn)(void) = rz_lib_dl_sym(addr, p->_runlib_fcn);
1276  if (!fcn) {
1277  eprintf("Could not find the function '%s'\n", p->_runlib_fcn);
1278  return 1;
1279  }
1280  switch (p->_argc) {
1281  case 0:
1282  fcn();
1283  break;
1284  case 1:
1285  rz_run_call1(fcn, p->_args[1]);
1286  break;
1287  case 2:
1288  rz_run_call2(fcn, p->_args[1], p->_args[2]);
1289  break;
1290  case 3:
1291  rz_run_call3(fcn, p->_args[1], p->_args[2], p->_args[3]);
1292  break;
1293  case 4:
1294  rz_run_call4(fcn, p->_args[1], p->_args[2], p->_args[3], p->_args[4]);
1295  break;
1296  case 5:
1297  rz_run_call5(fcn, p->_args[1], p->_args[2], p->_args[3], p->_args[4],
1298  p->_args[5]);
1299  break;
1300  case 6:
1301  rz_run_call6(fcn, p->_args[1], p->_args[2], p->_args[3], p->_args[4],
1302  p->_args[5], p->_args[6]);
1303  break;
1304  case 7:
1305  rz_run_call7(fcn, p->_args[1], p->_args[2], p->_args[3], p->_args[4],
1306  p->_args[5], p->_args[6], p->_args[7]);
1307  break;
1308  case 8:
1309  rz_run_call8(fcn, p->_args[1], p->_args[2], p->_args[3], p->_args[4],
1310  p->_args[5], p->_args[6], p->_args[7], p->_args[8]);
1311  break;
1312  case 9:
1313  rz_run_call9(fcn, p->_args[1], p->_args[2], p->_args[3], p->_args[4],
1314  p->_args[5], p->_args[6], p->_args[7], p->_args[8], p->_args[9]);
1315  break;
1316  case 10:
1317  rz_run_call10(fcn, p->_args[1], p->_args[2], p->_args[3], p->_args[4],
1318  p->_args[5], p->_args[6], p->_args[7], p->_args[8], p->_args[9], p->_args[10]);
1319  break;
1320  default:
1321  eprintf("Too many arguments.\n");
1322  return 1;
1323  }
1325  }
1326  return 0;
1327 }
static ut32 cpu[32]
Definition: analysis_or1k.c:21
uint32_t ut32
snprintf
Definition: kernel.h:364
static static fork const void static count static fd const char const char static newpath char char char static envp time_t static t const char static mode static whence const char static dir time_t static t unsigned static seconds const char struct utimbuf static buf nice
Definition: sflib.h:61
@ CPU_ARCH_ABI64
@ CPU_TYPE_I386
@ CPU_TYPE_ANY
RZ_API char * rz_file_binsh(void)
Definition: file.c:393
RZ_API bool rz_file_exists(const char *str)
Definition: file.c:192
RZ_API bool rz_file_dump(const char *file, const ut8 *buf, int len, bool append)
Definition: file.c:838
RZ_API char * rz_file_path(const char *bin)
Definition: file.c:354
RZ_API void * rz_lib_dl_sym(void *handler, const char *name)
Definition: lib.c:90
RZ_API void * rz_lib_dl_open(const char *libname)
Definition: lib.c:54
RZ_API int rz_lib_dl_close(void *handler)
Definition: lib.c:104
RZ_API int rz_sys_execv(const char *pathname, char *const argv[])
Definition: sys.c:1483
RZ_API int rz_sys_execl(const char *pathname, const char *arg,...)
Definition: sys.c:1575
RZ_API char ** rz_sys_get_environ(void)
Definition: sys.c:1115
static void rz_run_call8(void *fcn, void *arg1, void *arg2, void *arg3, void *arg4, void *arg5, void *arg6, void *arg7, void *arg8)
Definition: rz_types.h:624
static void rz_run_call9(void *fcn, void *arg1, void *arg2, void *arg3, void *arg4, void *arg5, void *arg6, void *arg7, void *arg8, void *arg9)
Definition: rz_types.h:629
static void rz_run_call1(void *fcn, void *arg1)
Definition: rz_types.h:594
static void rz_run_call6(void *fcn, void *arg1, void *arg2, void *arg3, void *arg4, void *arg5, void *arg6)
Definition: rz_types.h:614
static void rz_run_call3(void *fcn, void *arg1, void *arg2, void *arg3)
Definition: rz_types.h:602
static void rz_run_call4(void *fcn, void *arg1, void *arg2, void *arg3, void *arg4)
Definition: rz_types.h:606
static void rz_run_call5(void *fcn, void *arg1, void *arg2, void *arg3, void *arg4, void *arg5)
Definition: rz_types.h:610
static void rz_run_call10(void *fcn, void *arg1, void *arg2, void *arg3, void *arg4, void *arg5, void *arg6, void *arg7, void *arg8, void *arg9, void *arg10)
Definition: rz_types.h:634
static void rz_run_call7(void *fcn, void *arg1, void *arg2, void *arg3, void *arg4, void *arg5, void *arg6, void *arg7)
Definition: rz_types.h:619
static void rz_run_call2(void *fcn, void *arg1, void *arg2)
Definition: rz_types.h:598
static int addr
Definition: z80asm.c:58

References addr, close, cpu, CPU_ARCH_ABI64, CPU_TYPE_ANY, CPU_TYPE_I386, eprintf, test-lz4-list::exit, free(), i, kill, nice, NULL, p, pid, rz_file_binsh(), rz_file_dump(), rz_file_exists(), rz_file_path(), rz_lib_dl_close(), rz_lib_dl_open(), rz_lib_dl_sym(), rz_run_call1(), rz_run_call10(), rz_run_call2(), rz_run_call3(), rz_run_call4(), rz_run_call5(), rz_run_call6(), rz_run_call7(), rz_run_call8(), rz_run_call9(), rz_sys_execl(), rz_sys_execv(), rz_sys_fork(), rz_sys_get_environ(), rz_sys_system(), setgid, SIGKILL, and snprintf.

Referenced by rz_main_rz_run(), and rz_socket_spawn().

◆ setASLR()

static void setASLR ( RzRunProfile r,
int  enabled 
)
static

Definition at line 252 of file run.c.

252  {
253 #if __linux__
254  rz_sys_aslr(enabled);
255 #if HAVE_DECL_ADDR_NO_RANDOMIZE && !__ANDROID__
256  if (personality(ADDR_NO_RANDOMIZE) == -1) {
257 #endif
258  rz_sys_aslr(0);
259 #if HAVE_DECL_ADDR_NO_RANDOMIZE && !__ANDROID__
260  }
261 #endif
262 #elif __APPLE__
263  // TOO OLD setenv ("DYLD_NO_PIE", "1", 1);
264  // disable this because its
265  const char *argv0 = r->_system ? r->_system
266  : r->_program ? r->_program
267  : r->_args[0] ? r->_args[0]
268  : "/path/to/exec";
269  eprintf("To disable aslr patch mach0.hdr.flags with:\n"
270  "rizin -qwnc 'wx 000000 @ 0x18' %s\n",
271  argv0);
272  // f MH_PIE=0x00200000; wB-MH_PIE @ 24\n");
273  // for osxver>=10.7
274  // "unset the MH_PIE bit in an already linked executable" with --no-pie flag of the script
275  // the right way is to disable the aslr bit in the spawn call
276 #elif __FreeBSD__ || __NetBSD__ || __DragonFly__
277  rz_sys_aslr(enabled);
278 #if HAVE_DECL_PROCCTL_ASLR_CTL
279  int disabled = PROC_ASLR_FORCE_DISABLE;
280  if (procctl(P_PID, getpid(), PROC_ASLR_CTL, &disabled) == -1) {
281  rz_sys_aslr(0);
282  }
283 #endif
284 #else
285  // not supported for this platform
286 #endif
287 }
static const char struct stat static buf struct stat static buf static vhangup int struct rusage static rusage struct sysinfo static info unsigned static __unused struct utsname static buf const char static size const char static name static pid personality
Definition: sflib.h:167
RZ_API bool rz_sys_aslr(int val)
Enable or disable ASLR for the calling process.
Definition: sys.c:546

References eprintf, personality, r, and rz_sys_aslr().

Referenced by rz_run_config_env().