OpenVAS Scanner  7.0.1~git
nasl_cmd_exec.c File Reference

This file contains all the "unsafe" functions found in NASL. More...

#include "nasl_cmd_exec.h"
#include "../misc/plugutils.h"
#include "nasl_debug.h"
#include "nasl_func.h"
#include "nasl_global_ctxt.h"
#include "nasl_lex_ctxt.h"
#include "nasl_tree.h"
#include "nasl_var.h"
#include <errno.h>
#include <fcntl.h>
#include <glib.h>
#include <signal.h>
#include <string.h>
#include <sys/param.h>
#include <sys/stat.h>
#include <sys/wait.h>
#include <unistd.h>
Include dependency graph for nasl_cmd_exec.c:

Go to the source code of this file.

Macros

#define MAXPATHLEN   4096
 

Functions

static char * pread_streams (int fdout, int fderr)
 
tree_cellnasl_pread (lex_ctxt *lexic)
 
tree_cellnasl_find_in_path (lex_ctxt *lexic)
 
tree_cellnasl_fread (lex_ctxt *lexic)
 Read file. More...
 
tree_cellnasl_unlink (lex_ctxt *lexic)
 Unlink file. More...
 
tree_cellnasl_fwrite (lex_ctxt *lexic)
 Write file. More...
 
tree_cellnasl_get_tmp_dir (lex_ctxt *lexic)
 
tree_cellnasl_file_stat (lex_ctxt *lexic)
 Stat file. More...
 
tree_cellnasl_file_open (lex_ctxt *lexic)
 Open file. More...
 
tree_cellnasl_file_close (lex_ctxt *lexic)
 Close file. More...
 
tree_cellnasl_file_read (lex_ctxt *lexic)
 Read file. More...
 
tree_cellnasl_file_write (lex_ctxt *lexic)
 Write file. More...
 
tree_cellnasl_file_seek (lex_ctxt *lexic)
 Seek in file. More...
 

Variables

static pid_t pid = 0
 

Detailed Description

This file contains all the "unsafe" functions found in NASL.

Definition in file nasl_cmd_exec.c.

Macro Definition Documentation

◆ MAXPATHLEN

#define MAXPATHLEN   4096

Definition at line 46 of file nasl_cmd_exec.c.

Function Documentation

◆ nasl_file_close()

tree_cell* nasl_file_close ( lex_ctxt lexic)

Close file.

Definition at line 486 of file nasl_cmd_exec.c.

487 {
488  tree_cell *retc;
489  int fd;
490 
491  fd = get_int_var_by_num (lexic, 0, -1);
492  if (fd < 0)
493  {
494  nasl_perror (lexic, "file_close: need file pointer argument\n");
495  return NULL;
496  }
497 
498  if (close (fd) < 0)
499  {
500  nasl_perror (lexic, "file_close: %s\n", strerror (errno));
501  return NULL;
502  }
503 
504  retc = alloc_typed_cell (CONST_INT);
505  retc->x.i_val = 0;
506  return retc;
507 }

References alloc_typed_cell(), CONST_INT, get_int_var_by_num(), TC::i_val, nasl_perror(), and TC::x.

Here is the call graph for this function:

◆ nasl_file_open()

tree_cell* nasl_file_open ( lex_ctxt lexic)

Open file.

Definition at line 400 of file nasl_cmd_exec.c.

401 {
402  tree_cell *retc;
403  char *fname, *mode;
404  struct stat lstat_info, fstat_info;
405  int fd;
406  int imode = O_RDONLY;
407 
408  fname = get_str_var_by_name (lexic, "name");
409  if (fname == NULL)
410  {
411  nasl_perror (lexic, "file_open: need file name argument\n");
412  return NULL;
413  }
414 
415  mode = get_str_var_by_name (lexic, "mode");
416  if (mode == NULL)
417  {
418  nasl_perror (lexic, "file_open: need file mode argument\n");
419  return NULL;
420  }
421 
422  if (strcmp (mode, "r") == 0)
423  imode = O_RDONLY;
424  else if (strcmp (mode, "w") == 0)
425  imode = O_WRONLY | O_CREAT;
426  else if (strcmp (mode, "w+") == 0)
427  imode = O_WRONLY | O_TRUNC | O_CREAT;
428  else if (strcmp (mode, "a") == 0)
429  imode = O_WRONLY | O_APPEND | O_CREAT;
430  else if (strcmp (mode, "a+") == 0)
431  imode = O_RDWR | O_APPEND | O_CREAT;
432 
433  if (lstat (fname, &lstat_info) == -1)
434  {
435  if (errno != ENOENT)
436  {
437  nasl_perror (lexic, "file_open: %s: %s\n", fname, strerror (errno));
438  return NULL;
439  }
440  fd = open (fname, imode, 0600);
441  if (fd < 0)
442  {
443  nasl_perror (lexic, "file_open: %s: %s\n", fname, strerror (errno));
444  return NULL;
445  }
446  }
447  else
448  {
449  fd = open (fname, imode, 0600);
450  if (fd < 0)
451  {
452  nasl_perror (lexic, "file_open: %s: possible symlink attack!?! %s\n",
453  fname, strerror (errno));
454  return NULL;
455  }
456  if (fstat (fd, &fstat_info) == -1)
457  {
458  close (fd);
459  nasl_perror (lexic, "fread: %s: possible symlink attack!?! %s\n",
460  fname, strerror (errno));
461  return NULL;
462  }
463  else
464  {
465  if (lstat_info.st_mode != fstat_info.st_mode
466  || lstat_info.st_ino != fstat_info.st_ino
467  || lstat_info.st_dev != fstat_info.st_dev)
468  {
469  close (fd);
470  nasl_perror (lexic, "fread: %s: possible symlink attack!?!\n",
471  fname);
472  return NULL;
473  }
474  }
475  }
476 
477  retc = alloc_typed_cell (CONST_INT);
478  retc->x.i_val = fd;
479  return retc;
480 }

References alloc_typed_cell(), CONST_INT, get_str_var_by_name(), TC::i_val, nasl_perror(), and TC::x.

Here is the call graph for this function:

◆ nasl_file_read()

tree_cell* nasl_file_read ( lex_ctxt lexic)

Read file.

Definition at line 513 of file nasl_cmd_exec.c.

514 {
515  tree_cell *retc;
516  char *buf;
517  int fd;
518  int flength;
519  int n;
520 
521  fd = get_int_var_by_name (lexic, "fp", -1);
522  if (fd < 0)
523  {
524  nasl_perror (lexic, "file_read: need file pointer argument\n");
525  return NULL;
526  }
527 
528  flength = get_int_var_by_name (lexic, "length", 0);
529 
530  buf = g_malloc0 (flength + 1);
531 
532  for (n = 0; n < flength;)
533  {
534  int e;
535  errno = 0;
536  e = read (fd, buf + n, flength - n);
537  if (e < 0 && errno == EINTR)
538  continue;
539  else if (e <= 0)
540  break;
541  else
542  n += e;
543  }
544 
545  retc = alloc_typed_cell (CONST_DATA);
546  retc->size = n;
547  retc->x.str_val = buf;
548  return retc;
549 }

References alloc_typed_cell(), CONST_DATA, get_int_var_by_name(), nasl_perror(), TC::size, TC::str_val, and TC::x.

Here is the call graph for this function:

◆ nasl_file_seek()

tree_cell* nasl_file_seek ( lex_ctxt lexic)

Seek in file.

Definition at line 598 of file nasl_cmd_exec.c.

599 {
600  tree_cell *retc;
601  int fd;
602  int foffset;
603 
604  foffset = get_int_var_by_name (lexic, "offset", 0);
605  fd = get_int_var_by_name (lexic, "fp", -1);
606  if (fd < 0)
607  {
608  nasl_perror (lexic, "file_seek: need one arguments 'fp'\n");
609  return NULL;
610  }
611 
612  if (lseek (fd, foffset, SEEK_SET) < 0)
613  {
614  nasl_perror (lexic, "fseek: %s\n", strerror (errno));
615  return NULL;
616  }
617 
618  retc = alloc_typed_cell (CONST_INT);
619  retc->x.i_val = 0;
620  return retc;
621 }

References alloc_typed_cell(), CONST_INT, get_int_var_by_name(), TC::i_val, nasl_perror(), and TC::x.

Here is the call graph for this function:

◆ nasl_file_stat()

tree_cell* nasl_file_stat ( lex_ctxt lexic)

Stat file.

Definition at line 375 of file nasl_cmd_exec.c.

376 {
377  tree_cell *retc;
378  char *fname;
379  struct stat st;
380 
381  fname = get_str_var_by_num (lexic, 0);
382  if (fname == NULL)
383  {
384  nasl_perror (lexic, "file_stat: need one argument (file name)\n");
385  return NULL;
386  }
387 
388  if (stat (fname, &st) < 0)
389  return NULL;
390 
391  retc = alloc_typed_cell (CONST_INT);
392  retc->x.i_val = (int) st.st_size;
393  return retc;
394 }

References alloc_typed_cell(), CONST_INT, get_str_var_by_num(), TC::i_val, nasl_perror(), and TC::x.

Here is the call graph for this function:

◆ nasl_file_write()

tree_cell* nasl_file_write ( lex_ctxt lexic)

Write file.

Definition at line 555 of file nasl_cmd_exec.c.

556 {
557  tree_cell *retc;
558  char *content;
559  int len;
560  int fd;
561  int n;
562 
563  content = get_str_var_by_name (lexic, "data");
564  fd = get_int_var_by_name (lexic, "fp", -1);
565  if (content == NULL || fd < 0)
566  {
567  nasl_perror (lexic, "file_write: need two arguments 'fp' and 'data'\n");
568  return NULL;
569  }
570  len = get_var_size_by_name (lexic, "data");
571 
572  for (n = 0; n < len;)
573  {
574  int e;
575  errno = 0;
576  e = write (fd, content + n, len - n);
577  if (e < 0 && errno == EINTR)
578  continue;
579  else if (e <= 0)
580  {
581  nasl_perror (lexic, "file_write: write() failed - %s\n",
582  strerror (errno));
583  break;
584  }
585  else
586  n += e;
587  }
588 
589  retc = alloc_typed_cell (CONST_INT);
590  retc->x.i_val = n;
591  return retc;
592 }

References alloc_typed_cell(), CONST_INT, get_int_var_by_name(), get_str_var_by_name(), get_var_size_by_name(), TC::i_val, nasl_perror(), and TC::x.

Here is the call graph for this function:

◆ nasl_find_in_path()

tree_cell* nasl_find_in_path ( lex_ctxt lexic)

Definition at line 227 of file nasl_cmd_exec.c.

228 {
229  tree_cell *retc;
230  char *cmd, *result;
231 
232  cmd = get_str_var_by_num (lexic, 0);
233  if (cmd == NULL)
234  {
235  nasl_perror (lexic, "find_in_path() usage: cmd\n");
236  return NULL;
237  }
238 
239  retc = alloc_typed_cell (CONST_INT);
240  result = g_find_program_in_path (cmd);
241  retc->x.i_val = !!result;
242  g_free (result);
243  return retc;
244 }

References alloc_typed_cell(), CONST_INT, get_str_var_by_num(), TC::i_val, nasl_perror(), and TC::x.

Here is the call graph for this function:

◆ nasl_fread()

tree_cell* nasl_fread ( lex_ctxt lexic)

Read file.

Definition at line 254 of file nasl_cmd_exec.c.

255 {
256  tree_cell *retc;
257  char *fname, *fcontent;
258  size_t flen;
259  GError *ferror = NULL;
260 
261  fname = get_str_var_by_num (lexic, 0);
262  if (fname == NULL)
263  {
264  nasl_perror (lexic, "fread: need one argument (file name)\n");
265  return NULL;
266  }
267 
268  if (!g_file_get_contents (fname, &fcontent, &flen, &ferror))
269  {
270  nasl_perror (lexic, "fread: %s", ferror ? ferror->message : "Error");
271  if (ferror)
272  g_error_free (ferror);
273  return NULL;
274  }
275 
276  retc = alloc_typed_cell (CONST_DATA);
277  retc->size = flen;
278  retc->x.str_val = fcontent;
279  return retc;
280 }

References alloc_typed_cell(), CONST_DATA, get_str_var_by_num(), nasl_perror(), TC::size, TC::str_val, and TC::x.

Here is the call graph for this function:

◆ nasl_fwrite()

tree_cell* nasl_fwrite ( lex_ctxt lexic)

Write file.

Definition at line 315 of file nasl_cmd_exec.c.

316 {
317  tree_cell *retc;
318  char *fcontent, *fname;
319  size_t flen;
320  GError *ferror = NULL;
321 
322  fcontent = get_str_var_by_name (lexic, "data");
323  fname = get_str_var_by_name (lexic, "file");
324  if (!fcontent || !fname)
325  {
326  nasl_perror (lexic, "fwrite: need two arguments 'data' and 'file'\n");
327  return NULL;
328  }
329  flen = get_var_size_by_name (lexic, "data");
330 
331  if (!g_file_set_contents (fname, fcontent, flen, &ferror))
332  {
333  nasl_perror (lexic, "fwrite: %s", ferror ? ferror->message : "Error");
334  if (ferror)
335  g_error_free (ferror);
336  return NULL;
337  }
338  retc = alloc_typed_cell (CONST_INT);
339  retc->x.i_val = flen;
340  return retc;
341 }

References alloc_typed_cell(), CONST_INT, get_str_var_by_name(), get_var_size_by_name(), TC::i_val, nasl_perror(), and TC::x.

Here is the call graph for this function:

◆ nasl_get_tmp_dir()

tree_cell* nasl_get_tmp_dir ( lex_ctxt lexic)

Definition at line 344 of file nasl_cmd_exec.c.

345 {
346  tree_cell *retc;
347  char path[MAXPATHLEN];
348 
349  snprintf (path, sizeof (path), "%s/", g_get_tmp_dir ());
350  if (access (path, R_OK | W_OK | X_OK) < 0)
351  {
352  nasl_perror (
353  lexic,
354  "get_tmp_dir(): %s not available - check your OpenVAS installation\n",
355  path);
356  return NULL;
357  }
358 
359  retc = alloc_typed_cell (CONST_DATA);
360  retc->x.str_val = strdup (path);
361  retc->size = strlen (retc->x.str_val);
362 
363  return retc;
364 }

References alloc_typed_cell(), CONST_DATA, MAXPATHLEN, nasl_perror(), TC::size, TC::str_val, and TC::x.

Here is the call graph for this function:

◆ nasl_pread()

tree_cell* nasl_pread ( lex_ctxt lexic)
Todo:
Supspects to glib replacements, all path related stuff.

Definition at line 98 of file nasl_cmd_exec.c.

99 {
100  tree_cell *retc = NULL, *a;
101  anon_nasl_var *v;
102  nasl_array *av;
103  int i, j, n, cd, fdout = 0, fderr = 0;
104  char **args = NULL, *cmd, *str;
105  char cwd[MAXPATHLEN], newdir[MAXPATHLEN];
106  GError *error = NULL;
107 
108  if (pid != 0)
109  {
110  nasl_perror (lexic, "nasl_pread is not reentrant!\n");
111  return NULL;
112  }
113 
114  a = get_variable_by_name (lexic, "argv");
115  cmd = get_str_var_by_name (lexic, "cmd");
116  if (cmd == NULL || a == NULL || (v = a->x.ref_val) == NULL)
117  {
118  deref_cell (a);
119  nasl_perror (lexic, "pread() usage: cmd:..., argv:...\n");
120  return NULL;
121  }
122  deref_cell (a);
123 
124  if (v->var_type == VAR2_ARRAY)
125  av = &v->v.v_arr;
126  else
127  {
128  nasl_perror (lexic, "pread: argv element must be an array (0x%x)\n",
129  v->var_type);
130  return NULL;
131  }
132 
133  cd = get_int_var_by_name (lexic, "cd", 0);
134 
135  cwd[0] = '\0';
136  if (cd)
137  {
138  char *p;
139 
140  memset (newdir, '\0', sizeof (newdir));
141  if (cmd[0] == '/')
142  strncpy (newdir, cmd, sizeof (newdir) - 1);
143  else
144  {
145  p = g_find_program_in_path (cmd);
146  if (p != NULL)
147  strncpy (newdir, p, sizeof (newdir) - 1);
148  else
149  {
150  nasl_perror (lexic, "pread: '%s' not found in $PATH\n", cmd);
151  return NULL;
152  }
153  g_free (p);
154  }
155  p = strrchr (newdir, '/');
156  if (p && p != newdir)
157  *p = '\0';
158  if (getcwd (cwd, sizeof (cwd)) == NULL)
159  {
160  nasl_perror (lexic, "pread(): getcwd: %s\n", strerror (errno));
161  *cwd = '\0';
162  }
163 
164  if (chdir (newdir) < 0)
165  {
166  nasl_perror (lexic, "pread: could not chdir to %s\n", newdir);
167  return NULL;
168  }
169  if (cmd[0] != '/' && strlen (newdir) + strlen (cmd) + 1 < sizeof (newdir))
170  {
171  strcat (newdir, "/");
172  strcat (newdir, cmd);
173  }
174  }
175 
176  if (av->hash_elt != NULL)
177  nasl_perror (lexic, "pread: named elements in 'cmd' are ignored!\n");
178  n = av->max_idx;
179  args = g_malloc0 (sizeof (char *) * (n + 2)); /* Last arg is NULL */
180  for (j = 0, i = 0; i < n; i++)
181  {
182  str = (char *) var2str (av->num_elt[i]);
183  if (str != NULL)
184  args[j++] = g_strdup (str);
185  }
186  args[j] = NULL;
187 
188  if (g_spawn_async_with_pipes (NULL, args, NULL, G_SPAWN_SEARCH_PATH, NULL,
189  NULL, &pid, NULL, &fdout, &fderr, &error)
190  == FALSE)
191  {
192  if (error)
193  {
194  g_warning ("%s: %s", __FUNCTION__, error->message);
195  g_error_free (error);
196  }
197  goto finish_pread;
198  }
199 
200  str = pread_streams (fdout, fderr);
201  if (str)
202  {
203  retc = alloc_typed_cell (CONST_DATA);
204  retc->x.str_val = str;
205  retc->size = strlen (str);
206  }
207  else if (errno && errno != EINTR)
208  nasl_perror (lexic, "nasl_pread: fread(): %s\n", strerror (errno));
209  close (fdout);
210  close (fderr);
211  if (*cwd != '\0')
212  if (chdir (cwd) < 0)
213  nasl_perror (lexic, "pread(): chdir(%s): %s\n", cwd, strerror (errno));
214 
215 finish_pread:
216  for (i = 0; i < n; i++)
217  g_free (args[i]);
218  g_free (args);
219 
220  g_spawn_close_pid (pid);
221  pid = 0;
222 
223  return retc;
224 }

References alloc_typed_cell(), CONST_DATA, deref_cell(), get_int_var_by_name(), get_str_var_by_name(), get_variable_by_name(), st_nasl_array::hash_elt, st_nasl_array::max_idx, MAXPATHLEN, nasl_perror(), st_nasl_array::num_elt, pid, pread_streams(), TC::size, TC::str_val, st_a_nasl_var::v, st_a_nasl_var::v_arr, VAR2_ARRAY, var2str(), st_a_nasl_var::var_type, and TC::x.

Here is the call graph for this function:

◆ nasl_unlink()

tree_cell* nasl_unlink ( lex_ctxt lexic)

Unlink file.

Definition at line 290 of file nasl_cmd_exec.c.

291 {
292  char *fname;
293 
294  fname = get_str_var_by_num (lexic, 0);
295  if (fname == NULL)
296  {
297  nasl_perror (lexic, "unlink: need one argument (file name)\n");
298  return NULL;
299  }
300 
301  if (unlink (fname) < 0)
302  {
303  nasl_perror (lexic, "unlink(%s): %s\n", fname, strerror (errno));
304  return NULL;
305  }
306  /* No need to return a value */
307  return FAKE_CELL;
308 }

References FAKE_CELL, get_str_var_by_num(), and nasl_perror().

Here is the call graph for this function:

◆ pread_streams()

static char* pread_streams ( int  fdout,
int  fderr 
)
static

Definition at line 52 of file nasl_cmd_exec.c.

53 {
54  GString *str;
55 
56  str = g_string_new ("");
57  errno = 0;
58  for (;;)
59  {
60  fd_set fds;
61  char buf[8192];
62  int ret, ret_out = 0, ret_err = 0;
63  int maxfd = fdout > fderr ? fdout : fderr;
64 
65  FD_ZERO (&fds);
66  FD_SET (fdout, &fds);
67  FD_SET (fderr, &fds);
68 
69  ret = select (maxfd + 1, &fds, NULL, NULL, NULL);
70  if (ret == -1)
71  {
72  if (errno == EINTR)
73  continue;
74  return NULL;
75  }
76  bzero (buf, sizeof (buf));
77  if (FD_ISSET (fdout, &fds))
78  {
79  ret_out = read (fdout, buf, sizeof (buf));
80  if (ret_out > 0)
81  g_string_append (str, buf);
82  }
83  if (FD_ISSET (fderr, &fds))
84  {
85  ret_err = read (fderr, buf, sizeof (buf));
86  if (ret_err > 0)
87  g_string_append (str, buf);
88  }
89  if (ret_out <= 0 && ret_err <= 0)
90  break;
91  }
92 
93  return g_string_free (str, FALSE);
94 }

Referenced by nasl_pread().

Here is the caller graph for this function:

Variable Documentation

◆ pid

pid_t pid = 0
static

Definition at line 49 of file nasl_cmd_exec.c.

Referenced by nasl_pread().

st_a_nasl_var
Definition: nasl_var.h:50
VAR2_ARRAY
@ VAR2_ARRAY
Definition: nasl_var.h:30
CONST_DATA
@ CONST_DATA
Definition: nasl_tree.h:93
get_var_size_by_name
int get_var_size_by_name(lex_ctxt *, const char *)
Definition: nasl_var.c:1147
TC::str_val
char * str_val
Definition: nasl_tree.h:112
var2str
const char * var2str(anon_nasl_var *v)
Definition: nasl_var.c:1076
st_nasl_array::max_idx
int max_idx
Definition: nasl_var.h:45
st_a_nasl_var::v_arr
nasl_array v_arr
Definition: nasl_var.h:60
st_nasl_array::hash_elt
struct st_n_nasl_var ** hash_elt
Definition: nasl_var.h:47
FAKE_CELL
#define FAKE_CELL
Definition: nasl_tree.h:119
TC::x
union TC::@2 x
get_str_var_by_name
char * get_str_var_by_name(lex_ctxt *, const char *)
Definition: nasl_var.c:1127
st_nasl_array
Definition: nasl_var.h:43
pread_streams
static char * pread_streams(int fdout, int fderr)
Definition: nasl_cmd_exec.c:52
nasl_perror
void nasl_perror(lex_ctxt *lexic, char *msg,...)
Definition: nasl_debug.c:120
pid
static pid_t pid
Definition: nasl_cmd_exec.c:49
TC::size
int size
Definition: nasl_tree.h:109
get_int_var_by_name
long int get_int_var_by_name(lex_ctxt *, const char *, int)
Definition: nasl_var.c:1113
get_int_var_by_num
long int get_int_var_by_num(lex_ctxt *, int, int)
Definition: nasl_var.c:1106
get_str_var_by_num
char * get_str_var_by_num(lex_ctxt *, int)
Definition: nasl_var.c:1120
st_a_nasl_var::var_type
int var_type
Definition: nasl_var.h:52
TC
Definition: nasl_tree.h:104
CONST_INT
@ CONST_INT
Definition: nasl_tree.h:90
st_a_nasl_var::v
union st_a_nasl_var::@4 v
MAXPATHLEN
#define MAXPATHLEN
Definition: nasl_cmd_exec.c:46
deref_cell
void deref_cell(tree_cell *c)
Definition: nasl_tree.c:192
alloc_typed_cell
tree_cell * alloc_typed_cell(int typ)
Definition: nasl_tree.c:40
get_variable_by_name
tree_cell * get_variable_by_name(lex_ctxt *, const char *)
Definition: nasl_var.c:191
TC::i_val
long int i_val
Definition: nasl_tree.h:113
st_nasl_array::num_elt
struct st_a_nasl_var ** num_elt
Definition: nasl_var.h:46