1
2/*--------------------------------------------------------------------*/
3/*--- File- and socket-related libc stuff.            m_libcfile.c ---*/
4/*--------------------------------------------------------------------*/
5
6/*
7   This file is part of Valgrind, a dynamic binary instrumentation
8   framework.
9
10   Copyright (C) 2000-2013 Julian Seward
11      jseward@acm.org
12
13   This program is free software; you can redistribute it and/or
14   modify it under the terms of the GNU General Public License as
15   published by the Free Software Foundation; either version 2 of the
16   License, or (at your option) any later version.
17
18   This program is distributed in the hope that it will be useful, but
19   WITHOUT ANY WARRANTY; without even the implied warranty of
20   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
21   General Public License for more details.
22
23   You should have received a copy of the GNU General Public License
24   along with this program; if not, write to the Free Software
25   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
26   02111-1307, USA.
27
28   The GNU General Public License is contained in the file COPYING.
29*/
30
31#include "pub_core_basics.h"
32#include "pub_core_vki.h"
33#include "pub_core_vkiscnums.h"
34#include "pub_core_debuglog.h"
35#include "pub_core_libcbase.h"
36#include "pub_core_libcassert.h"
37#include "pub_core_libcfile.h"
38#include "pub_core_libcprint.h"     // VG_(sprintf)
39#include "pub_core_libcproc.h"      // VG_(getpid), VG_(getppid)
40#include "pub_core_xarray.h"
41#include "pub_core_clientstate.h"   // VG_(fd_hard_limit)
42#include "pub_core_syscall.h"
43
44/* IMPORTANT: on Darwin it is essential to use the _nocancel versions
45   of syscalls rather than the vanilla version, if a _nocancel version
46   is available.  See docs/internals/Darwin-notes.txt for the reason
47   why. */
48
49/* ---------------------------------------------------------------------
50   File stuff
51   ------------------------------------------------------------------ */
52
53static inline Bool fd_exists(Int fd)
54{
55   struct vg_stat st;
56   return VG_(fstat)(fd, &st) == 0;
57}
58
59/* Move an fd into the Valgrind-safe range */
60Int VG_(safe_fd)(Int oldfd)
61{
62   Int newfd;
63
64   vg_assert(VG_(fd_hard_limit) != -1);
65
66   newfd = VG_(fcntl)(oldfd, VKI_F_DUPFD, VG_(fd_hard_limit));
67   if (newfd != -1)
68      VG_(close)(oldfd);
69
70   /* Set the close-on-exec flag for this fd. */
71   VG_(fcntl)(newfd, VKI_F_SETFD, VKI_FD_CLOEXEC);
72
73   vg_assert(newfd >= VG_(fd_hard_limit));
74   return newfd;
75}
76
77/* Given a file descriptor, attempt to deduce its filename.  To do
78   this, we use /proc/self/fd/<FD>.  If this doesn't point to a file,
79   or if it doesn't exist, we return False. */
80Bool VG_(resolve_filename) ( Int fd, HChar* buf, Int n_buf )
81{
82#  if defined(VGO_linux)
83   HChar tmp[64];
84   VG_(sprintf)(tmp, "/proc/self/fd/%d", fd);
85   VG_(memset)(buf, 0, n_buf);
86   if (VG_(readlink)(tmp, buf, n_buf) > 0 && buf[0] == '/')
87      return True;
88   else
89      return False;
90
91#  elif defined(VGO_darwin)
92   HChar tmp[VKI_MAXPATHLEN+1];
93   if (0 == VG_(fcntl)(fd, VKI_F_GETPATH, (UWord)tmp)) {
94      if (n_buf > 0) {
95         VG_(strncpy)( buf, tmp, n_buf < sizeof(tmp) ? n_buf : sizeof(tmp) );
96         buf[n_buf-1] = 0;
97      }
98      if (tmp[0] == '/') return True;
99   }
100   return False;
101
102#  else
103#     error Unknown OS
104#  endif
105}
106
107SysRes VG_(mknod) ( const HChar* pathname, Int mode, UWord dev )
108{
109#  if defined(VGP_arm64_linux)
110   /* ARM64 wants to use __NR_mknodat rather than __NR_mknod. */
111   SysRes res = VG_(do_syscall4)(__NR_mknodat,
112                                 VKI_AT_FDCWD, (UWord)pathname, mode, dev);
113#  elif defined(VGO_linux) || defined(VGO_darwin)
114   SysRes res = VG_(do_syscall3)(__NR_mknod,
115                                 (UWord)pathname, mode, dev);
116#  else
117#    error Unknown OS
118#  endif
119   return res;
120}
121
122SysRes VG_(open) ( const HChar* pathname, Int flags, Int mode )
123{
124#  if defined(VGP_arm64_linux)
125   /* ARM64 wants to use __NR_openat rather than __NR_open. */
126   SysRes res = VG_(do_syscall4)(__NR_openat,
127                                 VKI_AT_FDCWD, (UWord)pathname, flags, mode);
128#  elif defined(VGO_linux)
129   SysRes res = VG_(do_syscall3)(__NR_open,
130                                 (UWord)pathname, flags, mode);
131#  elif defined(VGO_darwin)
132   SysRes res = VG_(do_syscall3)(__NR_open_nocancel,
133                                 (UWord)pathname, flags, mode);
134#  else
135#    error Unknown OS
136#  endif
137   return res;
138}
139
140Int VG_(fd_open) (const HChar* pathname, Int flags, Int mode)
141{
142   SysRes sr;
143   sr = VG_(open) (pathname, flags, mode);
144   if (sr_isError (sr))
145      return -1;
146   else
147      return sr_Res (sr);
148}
149
150void VG_(close) ( Int fd )
151{
152   /* Hmm.  Return value is not checked.  That's uncool. */
153#  if defined(VGO_linux)
154   (void)VG_(do_syscall1)(__NR_close, fd);
155#  elif defined(VGO_darwin)
156   (void)VG_(do_syscall1)(__NR_close_nocancel, fd);
157#  else
158#    error Unknown OS
159#  endif
160}
161
162Int VG_(read) ( Int fd, void* buf, Int count)
163{
164   Int    ret;
165#  if defined(VGO_linux)
166   SysRes res = VG_(do_syscall3)(__NR_read, fd, (UWord)buf, count);
167#  elif defined(VGO_darwin)
168   SysRes res = VG_(do_syscall3)(__NR_read_nocancel, fd, (UWord)buf, count);
169#  else
170#    error Unknown OS
171#  endif
172   if (sr_isError(res)) {
173      ret = - (Int)(Word)sr_Err(res);
174      vg_assert(ret < 0);
175   } else {
176      ret = (Int)(Word)sr_Res(res);
177      vg_assert(ret >= 0);
178   }
179   return ret;
180}
181
182Int VG_(write) ( Int fd, const void* buf, Int count)
183{
184   Int    ret;
185#  if defined(VGO_linux)
186   SysRes res = VG_(do_syscall3)(__NR_write, fd, (UWord)buf, count);
187#  elif defined(VGO_darwin)
188   SysRes res = VG_(do_syscall3)(__NR_write_nocancel, fd, (UWord)buf, count);
189#  else
190#    error "Unknown OS"
191#  endif
192   if (sr_isError(res)) {
193      ret = - (Int)(Word)sr_Err(res);
194      vg_assert(ret < 0);
195   } else {
196      ret = (Int)(Word)sr_Res(res);
197      vg_assert(ret >= 0);
198   }
199   return ret;
200}
201
202
203Int VG_(pipe) ( Int fd[2] )
204{
205#  if defined(VGP_mips32_linux) || defined(VGP_mips64_linux)
206   /* __NR_pipe has a strange return convention on mips32-linux. */
207   SysRes res = VG_(do_syscall1)(__NR_pipe, (UWord)fd);
208   if (!sr_isError(res)) {
209      fd[0] = (Int)sr_Res(res);
210      fd[1] = (Int)sr_ResEx(res);
211      return 0;
212   } else {
213      return -1;
214   }
215#  elif defined(VGP_arm64_linux)
216   SysRes res = VG_(do_syscall2)(__NR_pipe2, (UWord)fd, 0);
217   return sr_isError(res) ? -1 : 0;
218#  elif defined(VGO_linux)
219   SysRes res = VG_(do_syscall1)(__NR_pipe, (UWord)fd);
220   return sr_isError(res) ? -1 : 0;
221#  elif defined(VGO_darwin)
222   /* __NR_pipe is UX64, so produces a double-word result */
223   SysRes res = VG_(do_syscall0)(__NR_pipe);
224   if (!sr_isError(res)) {
225      fd[0] = (Int)sr_Res(res);
226      fd[1] = (Int)sr_ResHI(res);
227   }
228   return sr_isError(res) ? -1 : 0;
229#  else
230#    error "Unknown OS"
231#  endif
232}
233
234Off64T VG_(lseek) ( Int fd, Off64T offset, Int whence )
235{
236#  if defined(VGO_linux) || defined(VGP_amd64_darwin)
237#  if defined(__NR__llseek)
238   Off64T result;
239   SysRes res = VG_(do_syscall5)(__NR__llseek, fd,
240                                 offset >> 32, offset & 0xffffffff,
241                                 (UWord)&result, whence);
242   return sr_isError(res) ? (-1) : result;
243#  else
244   SysRes res = VG_(do_syscall3)(__NR_lseek, fd, offset, whence);
245   vg_assert(sizeof(Off64T) == sizeof(Word));
246   return sr_isError(res) ? (-1) : sr_Res(res);
247#  endif
248#  elif defined(VGP_x86_darwin)
249   SysRes res = VG_(do_syscall4)(__NR_lseek, fd,
250                                 offset & 0xffffffff, offset >> 32, whence);
251   return sr_isError(res) ? (-1) : sr_Res(res);
252#  else
253#    error "Unknown plat"
254#  endif
255   /* if you change the error-reporting conventions of this, also
256      change all usage points. */
257}
258
259
260/* stat/fstat support.  It's uggerly.  We have impedance-match into a
261   'struct vg_stat' in order to have a single structure that callers
262   can use consistently on all platforms. */
263
264#define TRANSLATE_TO_vg_stat(_p_vgstat, _p_vkistat) \
265   do { \
266      (_p_vgstat)->dev        = (ULong)( (_p_vkistat)->st_dev ); \
267      (_p_vgstat)->ino        = (ULong)( (_p_vkistat)->st_ino ); \
268      (_p_vgstat)->nlink      = (ULong)( (_p_vkistat)->st_nlink ); \
269      (_p_vgstat)->mode       = (UInt) ( (_p_vkistat)->st_mode ); \
270      (_p_vgstat)->uid        = (UInt) ( (_p_vkistat)->st_uid ); \
271      (_p_vgstat)->gid        = (UInt) ( (_p_vkistat)->st_gid ); \
272      (_p_vgstat)->rdev       = (ULong)( (_p_vkistat)->st_rdev ); \
273      (_p_vgstat)->size       = (Long) ( (_p_vkistat)->st_size ); \
274      (_p_vgstat)->blksize    = (ULong)( (_p_vkistat)->st_blksize ); \
275      (_p_vgstat)->blocks     = (ULong)( (_p_vkistat)->st_blocks ); \
276      (_p_vgstat)->atime      = (ULong)( (_p_vkistat)->st_atime ); \
277      (_p_vgstat)->atime_nsec = (ULong)( (_p_vkistat)->st_atime_nsec ); \
278      (_p_vgstat)->mtime      = (ULong)( (_p_vkistat)->st_mtime ); \
279      (_p_vgstat)->mtime_nsec = (ULong)( (_p_vkistat)->st_mtime_nsec ); \
280      (_p_vgstat)->ctime      = (ULong)( (_p_vkistat)->st_ctime ); \
281      (_p_vgstat)->ctime_nsec = (ULong)( (_p_vkistat)->st_ctime_nsec ); \
282   } while (0)
283
284SysRes VG_(stat) ( const HChar* file_name, struct vg_stat* vgbuf )
285{
286   SysRes res;
287   VG_(memset)(vgbuf, 0, sizeof(*vgbuf));
288
289#  if defined(VGO_linux) || defined(VGO_darwin)
290   /* First try with stat64.  If that doesn't work out, fall back to
291      the vanilla version. */
292#  if defined(__NR_stat64)
293   { struct vki_stat64 buf64;
294     res = VG_(do_syscall2)(__NR_stat64, (UWord)file_name, (UWord)&buf64);
295     if (!(sr_isError(res) && sr_Err(res) == VKI_ENOSYS)) {
296        /* Success, or any failure except ENOSYS */
297        if (!sr_isError(res))
298           TRANSLATE_TO_vg_stat(vgbuf, &buf64);
299        return res;
300     }
301   }
302#  endif /* defined(__NR_stat64) */
303   /* This is the fallback ("vanilla version"). */
304   { struct vki_stat buf;
305#    if defined(VGP_arm64_linux)
306     res = VG_(do_syscall3)(__NR3264_fstatat, VKI_AT_FDCWD,
307                                              (UWord)file_name, (UWord)&buf);
308#    else
309     res = VG_(do_syscall2)(__NR_stat, (UWord)file_name, (UWord)&buf);
310#    endif
311     if (!sr_isError(res))
312        TRANSLATE_TO_vg_stat(vgbuf, &buf);
313     return res;
314   }
315
316#  else
317#    error Unknown OS
318#  endif
319}
320
321Int VG_(fstat) ( Int fd, struct vg_stat* vgbuf )
322{
323   SysRes res;
324   VG_(memset)(vgbuf, 0, sizeof(*vgbuf));
325
326#  if defined(VGO_linux)  ||  defined(VGO_darwin)
327   /* First try with fstat64.  If that doesn't work out, fall back to
328      the vanilla version. */
329#  if defined(__NR_fstat64)
330   { struct vki_stat64 buf64;
331     res = VG_(do_syscall2)(__NR_fstat64, (UWord)fd, (UWord)&buf64);
332     if (!(sr_isError(res) && sr_Err(res) == VKI_ENOSYS)) {
333        /* Success, or any failure except ENOSYS */
334        if (!sr_isError(res))
335           TRANSLATE_TO_vg_stat(vgbuf, &buf64);
336        return sr_isError(res) ? (-1) : 0;
337     }
338   }
339#  endif /* if defined(__NR_fstat64) */
340   { struct vki_stat buf;
341     res = VG_(do_syscall2)(__NR_fstat, (UWord)fd, (UWord)&buf);
342     if (!sr_isError(res))
343        TRANSLATE_TO_vg_stat(vgbuf, &buf);
344     return sr_isError(res) ? (-1) : 0;
345   }
346
347#  else
348#    error Unknown OS
349#  endif
350}
351
352#undef TRANSLATE_TO_vg_stat
353
354
355Long VG_(fsize) ( Int fd )
356{
357   struct vg_stat buf;
358   Int res = VG_(fstat)( fd, &buf );
359   return (res == -1) ? (-1LL) : buf.size;
360}
361
362SysRes VG_(getxattr) ( const HChar* file_name, const HChar* attr_name, Addr attr_value, SizeT attr_value_len )
363{
364   SysRes res;
365#if defined(VGO_linux)
366   res = VG_(do_syscall4)(__NR_getxattr, (UWord)file_name, (UWord)attr_name,
367                          attr_value, attr_value_len);
368#else
369   res = VG_(mk_SysRes_Error)(VKI_ENOSYS);
370#endif
371   return res;
372}
373
374Bool VG_(is_dir) ( const HChar* f )
375{
376   struct vg_stat buf;
377   SysRes res = VG_(stat)(f, &buf);
378   return sr_isError(res) ? False
379                      : VKI_S_ISDIR(buf.mode) ? True : False;
380}
381
382SysRes VG_(dup) ( Int oldfd )
383{
384   return VG_(do_syscall1)(__NR_dup, oldfd);
385}
386
387SysRes VG_(dup2) ( Int oldfd, Int newfd )
388{
389#  if defined(VGO_linux) || defined(VGO_darwin)
390   return VG_(do_syscall2)(__NR_dup2, oldfd, newfd);
391#  else
392#    error Unknown OS
393#  endif
394}
395
396/* Returns -1 on error. */
397Int VG_(fcntl) ( Int fd, Int cmd, Addr arg )
398{
399#  if defined(VGO_linux)
400   SysRes res = VG_(do_syscall3)(__NR_fcntl, fd, cmd, arg);
401#  elif defined(VGO_darwin)
402   SysRes res = VG_(do_syscall3)(__NR_fcntl_nocancel, fd, cmd, arg);
403#  else
404#    error "Unknown OS"
405#  endif
406   return sr_isError(res) ? -1 : sr_Res(res);
407}
408
409Int VG_(rename) ( const HChar* old_name, const HChar* new_name )
410{
411   SysRes res = VG_(do_syscall2)(__NR_rename, (UWord)old_name, (UWord)new_name);
412   return sr_isError(res) ? (-1) : 0;
413}
414
415Int VG_(unlink) ( const HChar* file_name )
416{
417#  if defined(VGP_arm64_linux)
418   SysRes res = VG_(do_syscall2)(__NR_unlinkat, VKI_AT_FDCWD,
419                                                (UWord)file_name);
420#  else
421   SysRes res = VG_(do_syscall1)(__NR_unlink, (UWord)file_name);
422#  endif
423   return sr_isError(res) ? (-1) : 0;
424}
425
426/* The working directory at startup.  AIX doesn't provide an easy
427   system call to do getcwd, but fortunately we don't need arbitrary
428   getcwd support.  All that is really needed is to note the cwd at
429   process startup.  Hence VG_(record_startup_wd) notes it (in a
430   platform dependent way) and VG_(get_startup_wd) produces the noted
431   value.  Hence: */
432static HChar startup_wd[VKI_PATH_MAX];
433static Bool  startup_wd_acquired = False;
434
435/* Record the process' working directory at startup.  Is intended to
436   be called exactly once, at startup, before the working directory
437   changes.  Return True for success, False for failure, so that the
438   caller can bomb out suitably without creating module cycles if
439   there is a problem. */
440Bool VG_(record_startup_wd) ( void )
441{
442   const Int szB = sizeof(startup_wd);
443   vg_assert(!startup_wd_acquired);
444   vg_assert(szB >= 512 && szB <= 16384/*let's say*/); /* stay sane */
445   VG_(memset)(startup_wd, 0, szB);
446#  if defined(VGO_linux)
447   /* Simple: just ask the kernel */
448   { SysRes res
449        = VG_(do_syscall2)(__NR_getcwd, (UWord)startup_wd, szB-1);
450     vg_assert(startup_wd[szB-1] == 0);
451     if (sr_isError(res)) {
452        return False;
453     } else {
454        startup_wd_acquired = True;
455        return True;
456     }
457   }
458#  elif defined(VGO_darwin)
459   /* We can't ask the kernel, so instead rely on launcher-*.c to
460      tell us the startup path.  Note the env var is keyed to the
461      parent's PID, not ours, since our parent is the launcher
462      process. */
463   { HChar  envvar[100];
464     HChar* wd = NULL;
465     VG_(memset)(envvar, 0, sizeof(envvar));
466     VG_(sprintf)(envvar, "VALGRIND_STARTUP_PWD_%d_XYZZY",
467                          (Int)VG_(getppid)());
468     wd = VG_(getenv)( envvar );
469     if (wd == NULL || (1+VG_(strlen)(wd) >= szB))
470        return False;
471     VG_(strncpy_safely)(startup_wd, wd, szB);
472     vg_assert(startup_wd[szB-1] == 0);
473     startup_wd_acquired = True;
474     return True;
475   }
476#  else
477#    error Unknown OS
478#  endif
479}
480
481/* Copy the previously acquired startup_wd into buf[0 .. size-1],
482   or return False if buf isn't big enough. */
483Bool VG_(get_startup_wd) ( HChar* buf, SizeT size )
484{
485   vg_assert(startup_wd_acquired);
486   vg_assert(startup_wd[ sizeof(startup_wd)-1 ] == 0);
487   if (1+VG_(strlen)(startup_wd) >= size)
488      return False;
489   VG_(strncpy_safely)(buf, startup_wd, size);
490   return True;
491}
492
493SysRes VG_(poll) (struct vki_pollfd *fds, Int nfds, Int timeout)
494{
495   SysRes res;
496#  if defined(VGP_arm64_linux)
497   /* ARM64 wants to use __NR_ppoll rather than __NR_poll. */
498   struct vki_timespec timeout_ts;
499   if (timeout >= 0) {
500      timeout_ts.tv_sec = timeout / 1000;
501      timeout_ts.tv_nsec = ((long)timeout % 1000) * 1000000;
502   }
503   res = VG_(do_syscall4)(__NR_ppoll,
504                          (UWord)fds, nfds,
505                          (UWord)(timeout >= 0 ? &timeout_ts : NULL),
506                          (UWord)NULL);
507#  elif defined(VGO_linux)
508   res = VG_(do_syscall3)(__NR_poll, (UWord)fds, nfds, timeout);
509#  elif defined(VGO_darwin)
510   res = VG_(do_syscall3)(__NR_poll_nocancel, (UWord)fds, nfds, timeout);
511#  else
512#    error "Unknown OS"
513#  endif
514   return res;
515}
516
517
518Int VG_(readlink) (const HChar* path, HChar* buf, UInt bufsiz)
519{
520   SysRes res;
521   /* res = readlink( path, buf, bufsiz ); */
522#  if defined(VGP_arm64_linux)
523   res = VG_(do_syscall4)(__NR_readlinkat, VKI_AT_FDCWD,
524                                           (UWord)path, (UWord)buf, bufsiz);
525#  else
526   res = VG_(do_syscall3)(__NR_readlink, (UWord)path, (UWord)buf, bufsiz);
527#  endif
528   return sr_isError(res) ? -1 : sr_Res(res);
529}
530
531Int VG_(getdents) (Int fd, struct vki_dirent *dirp, UInt count)
532{
533#  if defined(VGO_linux)
534   SysRes res;
535   /* res = getdents( fd, dirp, count ); */
536   res = VG_(do_syscall3)(__NR_getdents, fd, (UWord)dirp, count);
537   return sr_isError(res) ? -1 : sr_Res(res);
538#  elif defined(VGO_darwin)
539   I_die_here;
540#  else
541#    error "Unknown OS"
542#  endif
543}
544
545/* Check accessibility of a file.  Returns zero for access granted,
546   nonzero otherwise. */
547Int VG_(access) ( const HChar* path, Bool irusr, Bool iwusr, Bool ixusr )
548{
549#  if defined(VGO_linux)
550   /* Very annoyingly, I cannot find any definition for R_OK et al in
551      the kernel interfaces.  Therefore I reluctantly resort to
552      hardwiring in these magic numbers that I determined by
553      experimentation. */
554#  define VKI_R_OK 4
555#  define VKI_W_OK 2
556#  define VKI_X_OK 1
557#  endif
558
559   UWord w = (irusr ? VKI_R_OK : 0)
560             | (iwusr ? VKI_W_OK : 0)
561             | (ixusr ? VKI_X_OK : 0);
562#  if defined(VGP_arm64_linux)
563   SysRes res = VG_(do_syscall3)(__NR_faccessat, VKI_AT_FDCWD, (UWord)path, w);
564#  else
565   SysRes res = VG_(do_syscall2)(__NR_access, (UWord)path, w);
566#  endif
567   return sr_isError(res) ? 1 : 0;
568
569#  if defined(VGO_linux)
570#  undef VKI_R_OK
571#  undef VKI_W_OK
572#  undef VKI_X_OK
573#  endif
574}
575
576/*
577   Emulate the normal Unix permissions checking algorithm.
578
579   If owner matches, then use the owner permissions, else
580   if group matches, then use the group permissions, else
581   use other permissions.
582
583   Note that we can't deal properly with SUID/SGID.  By default
584   (allow_setuid == False), we refuse to run them (otherwise the
585   executable may misbehave if it doesn't have the permissions it
586   thinks it does).  However, the caller may indicate that setuid
587   executables are allowed, for example if we are going to exec them
588   but not trace into them (iow, client sys_execve when
589   clo_trace_children == False).
590
591   If VKI_EACCES is returned (iow, permission was refused), then
592   *is_setuid is set to True iff permission was refused because the
593   executable is setuid.
594*/
595/* returns: 0 = success, non-0 is failure */
596Int VG_(check_executable)(/*OUT*/Bool* is_setuid,
597                          const HChar* f, Bool allow_setuid)
598{
599   struct vg_stat st;
600   SysRes res = VG_(stat)(f, &st);
601
602   if (is_setuid)
603      *is_setuid = False;
604
605   if (sr_isError(res)) {
606      return sr_Err(res);
607   }
608
609   if ( (st.mode & (VKI_S_ISUID | VKI_S_ISGID)) && !allow_setuid ) {
610      if (is_setuid)
611         *is_setuid = True;
612      return VKI_EACCES;
613   }
614
615   res = VG_(getxattr)(f, "security.capability", (Addr)0, 0);
616   if (!sr_isError(res) && !allow_setuid) {
617      if (is_setuid)
618         *is_setuid = True;
619      return VKI_EACCES;
620   }
621
622   if (VG_(geteuid)() == st.uid) {
623      if (!(st.mode & VKI_S_IXUSR))
624         return VKI_EACCES;
625   } else {
626      Int grpmatch = 0;
627
628      if (VG_(getegid)() == st.gid)
629	 grpmatch = 1;
630      else {
631	 UInt groups[32];
632	 Int ngrp = VG_(getgroups)(32, groups);
633	 Int i;
634         /* ngrp will be -1 if VG_(getgroups) failed. */
635         for (i = 0; i < ngrp; i++) {
636	    if (groups[i] == st.gid) {
637	       grpmatch = 1;
638	       break;
639	    }
640         }
641      }
642
643      if (grpmatch) {
644	 if (!(st.mode & VKI_S_IXGRP)) {
645            return VKI_EACCES;
646         }
647      } else if (!(st.mode & VKI_S_IXOTH)) {
648         return VKI_EACCES;
649      }
650   }
651
652   return 0;
653}
654
655SysRes VG_(pread) ( Int fd, void* buf, Int count, OffT offset )
656{
657   SysRes res;
658   // on 32 bits platforms, we receive a 32 bits OffT but
659   // we must extend it to pass a long long 64 bits.
660#  if defined(VGP_x86_linux)
661   vg_assert(sizeof(OffT) == 4);
662   res = VG_(do_syscall5)(__NR_pread64, fd, (UWord)buf, count,
663                          offset, 0); // Little endian long long
664   return res;
665#  elif defined(VGP_arm_linux)
666   vg_assert(sizeof(OffT) == 4);
667   res = VG_(do_syscall5)(__NR_pread64, fd, (UWord)buf, count,
668                          0, offset); // Big endian long long
669   return res;
670#  elif defined(VGP_ppc32_linux)
671   vg_assert(sizeof(OffT) == 4);
672   res = VG_(do_syscall6)(__NR_pread64, fd, (UWord)buf, count,
673                          0, // Padding needed on PPC32
674                          0, offset); // Big endian long long
675   return res;
676#  elif defined(VGP_mips32_linux) && (VKI_LITTLE_ENDIAN)
677   vg_assert(sizeof(OffT) == 4);
678   res = VG_(do_syscall6)(__NR_pread64, fd, (UWord)buf, count,
679                          0, offset, 0);
680   return res;
681#  elif defined(VGP_mips32_linux) && (VKI_BIG_ENDIAN)
682   vg_assert(sizeof(OffT) == 4);
683   res = VG_(do_syscall6)(__NR_pread64, fd, (UWord)buf, count,
684                          0, 0, offset);
685   return res;
686#  elif defined(VGP_amd64_linux) \
687      || defined(VGP_ppc64_linux) || defined(VGP_s390x_linux) \
688      || defined(VGP_mips64_linux) \
689      || defined(VGP_arm64_linux)
690   res = VG_(do_syscall4)(__NR_pread64, fd, (UWord)buf, count, offset);
691   return res;
692#  elif defined(VGP_amd64_darwin)
693   vg_assert(sizeof(OffT) == 8);
694   res = VG_(do_syscall4)(__NR_pread_nocancel, fd, (UWord)buf, count, offset);
695   return res;
696#  elif defined(VGP_x86_darwin)
697   vg_assert(sizeof(OffT) == 8);
698   res = VG_(do_syscall5)(__NR_pread_nocancel, fd, (UWord)buf, count,
699                          offset & 0xffffffff, offset >> 32);
700   return res;
701#  else
702#    error "Unknown platform"
703#  endif
704}
705
706/* Return the name of a directory for temporary files. */
707const HChar *VG_(tmpdir)(void)
708{
709   const HChar *tmpdir;
710
711   tmpdir = VG_(getenv)("TMPDIR");
712   if (tmpdir == NULL || *tmpdir == '\0') tmpdir = VG_TMPDIR;
713   if (tmpdir == NULL || *tmpdir == '\0') tmpdir = "/tmp";    /* fallback */
714
715   return tmpdir;
716}
717
718static const HChar *mkstemp_format = "%s/valgrind_%s_%08x";
719
720SizeT VG_(mkstemp_fullname_bufsz) ( SizeT part_of_name_len )
721{
722   return VG_(strlen)(mkstemp_format)
723      + VG_(strlen)(VG_(tmpdir)()) - 2 // %s tmpdir
724      + part_of_name_len - 2           // %s part_of_name
725      + 8 - 4                          // %08x
726      + 1;                             // trailing 0
727}
728
729
730/* Create and open (-rw------) a tmp file name incorporating said arg.
731   Returns -1 on failure, else the fd of the file.  If fullname is
732   non-NULL, the file's name is written into it.  The number of bytes
733   written is equal to VG_(mkstemp_fullname_bufsz)(part_of_name). */
734
735Int VG_(mkstemp) ( HChar* part_of_name, /*OUT*/HChar* fullname )
736{
737   HChar  buf[VG_(mkstemp_fullname_bufsz)(VG_(strlen)(part_of_name))];
738   Int    n, tries, fd;
739   UInt   seed;
740   SysRes sres;
741   const HChar *tmpdir;
742
743   vg_assert(part_of_name);
744   n = VG_(strlen)(part_of_name);
745   vg_assert(n > 0 && n < 100);
746
747   seed = (VG_(getpid)() << 9) ^ VG_(getppid)();
748
749   /* Determine sensible location for temporary files */
750   tmpdir = VG_(tmpdir)();
751
752   tries = 0;
753   while (True) {
754      if (tries++ > 10)
755         return -1;
756      VG_(sprintf)( buf, "%s/valgrind_%s_%08x",
757                    tmpdir, part_of_name, VG_(random)( &seed ));
758      if (0)
759         VG_(printf)("VG_(mkstemp): trying: %s\n", buf);
760
761      sres = VG_(open)(buf,
762                       VKI_O_CREAT|VKI_O_RDWR|VKI_O_EXCL|VKI_O_TRUNC,
763                       VKI_S_IRUSR|VKI_S_IWUSR);
764      if (sr_isError(sres)) {
765         VG_(umsg)("VG_(mkstemp): failed to create temp file: %s\n", buf);
766         continue;
767      }
768      /* VG_(safe_fd) doesn't return if it fails. */
769      fd = VG_(safe_fd)( sr_Res(sres) );
770      if (fullname)
771         VG_(strcpy)( fullname, buf );
772      return fd;
773   }
774   /* NOTREACHED */
775}
776
777
778/* ---------------------------------------------------------------------
779   Socket-related stuff.
780   ------------------------------------------------------------------ */
781
782static
783Int parse_inet_addr_and_port ( const HChar* str, UInt* ip_addr, UShort* port );
784
785static
786Int my_connect ( Int sockfd, struct vki_sockaddr_in* serv_addr, Int addrlen );
787
788UInt VG_(htonl) ( UInt x )
789{
790#  if defined(VG_BIGENDIAN)
791   return x;
792#  else
793   return
794      (((x >> 24) & 0xFF) << 0) | (((x >> 16) & 0xFF) << 8)
795      | (((x >> 8) & 0xFF) << 16) | (((x >> 0) & 0xFF) << 24);
796#  endif
797}
798
799UInt VG_(ntohl) ( UInt x )
800{
801#  if defined(VG_BIGENDIAN)
802   return x;
803#  else
804   return
805      (((x >> 24) & 0xFF) << 0) | (((x >> 16) & 0xFF) << 8)
806      | (((x >> 8) & 0xFF) << 16) | (((x >> 0) & 0xFF) << 24);
807#  endif
808}
809
810UShort VG_(htons) ( UShort x )
811{
812#  if defined(VG_BIGENDIAN)
813   return x;
814#  else
815   return
816      (((x >> 8) & 0xFF) << 0) | (((x >> 0) & 0xFF) << 8);
817#  endif
818}
819
820UShort VG_(ntohs) ( UShort x )
821{
822#  if defined(VG_BIGENDIAN)
823   return x;
824#  else
825   return
826      (((x >> 8) & 0xFF) << 0) | (((x >> 0) & 0xFF) << 8);
827#  endif
828}
829
830
831/* The main function.
832
833   Supplied string contains either an ip address "192.168.0.1" or
834   an ip address and port pair, "192.168.0.1:1500".  Parse these,
835   and return:
836     -1 if there is a parse error
837     -2 if no parse error, but specified host:port cannot be opened
838     the relevant file (socket) descriptor, otherwise.
839 is used.
840*/
841Int VG_(connect_via_socket)( const HChar* str )
842{
843#  if defined(VGO_linux) || defined(VGO_darwin)
844   Int sd, res;
845   struct vki_sockaddr_in servAddr;
846   UInt   ip   = 0;
847   UShort port = VG_CLO_DEFAULT_LOGPORT;
848   Bool   ok   = parse_inet_addr_and_port(str, &ip, &port);
849   if (!ok)
850      return -1;
851
852   //if (0)
853   //   VG_(printf)("ip = %d.%d.%d.%d, port %d\n",
854   //               (ip >> 24) & 0xFF, (ip >> 16) & 0xFF,
855   //               (ip >> 8) & 0xFF, ip & 0xFF,
856   //               (UInt)port );
857
858   servAddr.sin_family = VKI_AF_INET;
859   servAddr.sin_addr.s_addr = VG_(htonl)(ip);
860   servAddr.sin_port = VG_(htons)(port);
861
862   /* create socket */
863   sd = VG_(socket)(VKI_AF_INET, VKI_SOCK_STREAM, 0 /* IPPROTO_IP ? */);
864   if (sd < 0) {
865      /* this shouldn't happen ... nevertheless */
866      return -2;
867   }
868
869   /* connect to server */
870   res = my_connect(sd, &servAddr, sizeof(servAddr));
871   if (res < 0) {
872      /* connection failed */
873      return -2;
874   }
875
876   return sd;
877
878#  else
879#    error "Unknown OS"
880#  endif
881}
882
883
884/* Let d = one or more digits.  Accept either:
885   d.d.d.d  or  d.d.d.d:d
886*/
887static Int parse_inet_addr_and_port ( const HChar* str, UInt* ip_addr, UShort* port )
888{
889#  define GET_CH ((*str) ? (*str++) : 0)
890   UInt ipa, i, j, c, any;
891   ipa = 0;
892   for (i = 0; i < 4; i++) {
893      j = 0;
894      any = 0;
895      while (1) {
896         c = GET_CH;
897         if (c < '0' || c > '9') break;
898         j = 10 * j + (int)(c - '0');
899         any = 1;
900      }
901      if (any == 0 || j > 255) goto syntaxerr;
902      ipa = (ipa << 8) + j;
903      if (i <= 2 && c != '.') goto syntaxerr;
904   }
905   if (c == 0 || c == ':')
906      *ip_addr = ipa;
907   if (c == 0) goto ok;
908   if (c != ':') goto syntaxerr;
909   j = 0;
910   any = 0;
911   while (1) {
912      c = GET_CH;
913      if (c < '0' || c > '9') break;
914      j = j * 10 + (int)(c - '0');
915      any = 1;
916      if (j > 65535) goto syntaxerr;
917   }
918   if (any == 0 || c != 0) goto syntaxerr;
919   if (j < 1024) goto syntaxerr;
920   *port = (UShort)j;
921 ok:
922   return 1;
923 syntaxerr:
924   return 0;
925#  undef GET_CH
926}
927
928// GrP fixme safe_fd?
929Int VG_(socket) ( Int domain, Int type, Int protocol )
930{
931#  if defined(VGP_x86_linux) || defined(VGP_ppc32_linux) \
932      || defined(VGP_ppc64_linux) || defined(VGP_s390x_linux)
933   SysRes res;
934   UWord  args[3];
935   args[0] = domain;
936   args[1] = type;
937   args[2] = protocol;
938   res = VG_(do_syscall2)(__NR_socketcall, VKI_SYS_SOCKET, (UWord)&args);
939   return sr_isError(res) ? -1 : sr_Res(res);
940
941#  elif defined(VGP_amd64_linux) || defined(VGP_arm_linux) \
942        || defined(VGP_mips32_linux) || defined(VGP_mips64_linux) \
943        || defined(VGP_arm64_linux)
944   SysRes res;
945   res = VG_(do_syscall3)(__NR_socket, domain, type, protocol );
946   return sr_isError(res) ? -1 : sr_Res(res);
947
948#  elif defined(VGO_darwin)
949   SysRes res;
950   res = VG_(do_syscall3)(__NR_socket, domain, type, protocol);
951   if (!sr_isError(res)) {
952       // Set SO_NOSIGPIPE so write() returns EPIPE instead of raising SIGPIPE
953       Int optval = 1;
954       SysRes res2;
955       res2 = VG_(do_syscall5)(__NR_setsockopt, sr_Res(res), VKI_SOL_SOCKET,
956                               VKI_SO_NOSIGPIPE, (UWord)&optval,
957                               sizeof(optval));
958       // ignore setsockopt() error
959   }
960   return sr_isError(res) ? -1 : sr_Res(res);
961
962#  else
963#    error "Unknown arch"
964#  endif
965}
966
967
968static
969Int my_connect ( Int sockfd, struct vki_sockaddr_in* serv_addr, Int addrlen )
970{
971#  if defined(VGP_x86_linux) || defined(VGP_ppc32_linux) \
972      || defined(VGP_ppc64_linux) || defined(VGP_s390x_linux)
973   SysRes res;
974   UWord  args[3];
975   args[0] = sockfd;
976   args[1] = (UWord)serv_addr;
977   args[2] = addrlen;
978   res = VG_(do_syscall2)(__NR_socketcall, VKI_SYS_CONNECT, (UWord)&args);
979   return sr_isError(res) ? -1 : sr_Res(res);
980
981#  elif defined(VGP_amd64_linux) || defined(VGP_arm_linux) \
982        || defined(VGP_mips32_linux) || defined(VGP_mips64_linux) \
983        || defined(VGP_arm64_linux)
984   SysRes res;
985   res = VG_(do_syscall3)(__NR_connect, sockfd, (UWord)serv_addr, addrlen);
986   return sr_isError(res) ? -1 : sr_Res(res);
987
988#  elif defined(VGO_darwin)
989   SysRes res;
990   res = VG_(do_syscall3)(__NR_connect_nocancel,
991                          sockfd, (UWord)serv_addr, addrlen);
992   return sr_isError(res) ? -1 : sr_Res(res);
993
994#  else
995#    error "Unknown arch"
996#  endif
997}
998
999Int VG_(write_socket)( Int sd, const void *msg, Int count )
1000{
1001   /* This is actually send(). */
1002
1003   /* For Linux, VKI_MSG_NOSIGNAL is a request not to send SIGPIPE on
1004      errors on stream oriented sockets when the other end breaks the
1005      connection. The EPIPE error is still returned.
1006
1007      For Darwin, VG_(socket)() sets SO_NOSIGPIPE to get EPIPE instead of
1008      SIGPIPE */
1009
1010#  if defined(VGP_x86_linux) || defined(VGP_ppc32_linux) \
1011      || defined(VGP_ppc64_linux) || defined(VGP_s390x_linux)
1012   SysRes res;
1013   UWord  args[4];
1014   args[0] = sd;
1015   args[1] = (UWord)msg;
1016   args[2] = count;
1017   args[3] = VKI_MSG_NOSIGNAL;
1018   res = VG_(do_syscall2)(__NR_socketcall, VKI_SYS_SEND, (UWord)&args);
1019   return sr_isError(res) ? -1 : sr_Res(res);
1020
1021#  elif defined(VGP_amd64_linux) || defined(VGP_arm_linux) \
1022        || defined(VGP_mips32_linux) || defined(VGP_mips64_linux) \
1023        || defined(VGP_arm64_linux)
1024   SysRes res;
1025   res = VG_(do_syscall6)(__NR_sendto, sd, (UWord)msg,
1026                                       count, VKI_MSG_NOSIGNAL, 0,0);
1027   return sr_isError(res) ? -1 : sr_Res(res);
1028
1029#  elif defined(VGP_x86_darwin) || defined(VGP_amd64_darwin)
1030   SysRes res;
1031   res = VG_(do_syscall3)(__NR_write_nocancel, sd, (UWord)msg, count);
1032   return sr_isError(res) ? -1 : sr_Res(res);
1033
1034#  else
1035#    error "Unknown platform"
1036#  endif
1037}
1038
1039Int VG_(getsockname) ( Int sd, struct vki_sockaddr *name, Int *namelen)
1040{
1041#  if defined(VGP_x86_linux) || defined(VGP_ppc32_linux) \
1042      || defined(VGP_ppc64_linux) || defined(VGP_s390x_linux) \
1043      || defined(VGP_mips32_linux)
1044   SysRes res;
1045   UWord  args[3];
1046   args[0] = sd;
1047   args[1] = (UWord)name;
1048   args[2] = (UWord)namelen;
1049   res = VG_(do_syscall2)(__NR_socketcall, VKI_SYS_GETSOCKNAME, (UWord)&args);
1050   return sr_isError(res) ? -1 : sr_Res(res);
1051
1052#  elif defined(VGP_amd64_linux) || defined(VGP_arm_linux) \
1053        || defined(VGP_mips64_linux) || defined(VGP_arm64_linux)
1054   SysRes res;
1055   res = VG_(do_syscall3)( __NR_getsockname,
1056                           (UWord)sd, (UWord)name, (UWord)namelen );
1057   return sr_isError(res) ? -1 : sr_Res(res);
1058
1059#  elif defined(VGO_darwin)
1060   SysRes res;
1061   res = VG_(do_syscall3)( __NR_getsockname,
1062                           (UWord)sd, (UWord)name, (UWord)namelen );
1063   return sr_isError(res) ? -1 : sr_Res(res);
1064
1065#  else
1066#    error "Unknown platform"
1067#  endif
1068}
1069
1070Int VG_(getpeername) ( Int sd, struct vki_sockaddr *name, Int *namelen)
1071{
1072#  if defined(VGP_x86_linux) || defined(VGP_ppc32_linux) \
1073      || defined(VGP_ppc64_linux) || defined(VGP_s390x_linux) \
1074      || defined(VGP_mips32_linux)
1075   SysRes res;
1076   UWord  args[3];
1077   args[0] = sd;
1078   args[1] = (UWord)name;
1079   args[2] = (UWord)namelen;
1080   res = VG_(do_syscall2)(__NR_socketcall, VKI_SYS_GETPEERNAME, (UWord)&args);
1081   return sr_isError(res) ? -1 : sr_Res(res);
1082
1083#  elif defined(VGP_amd64_linux) || defined(VGP_arm_linux) \
1084        || defined(VGP_mips64_linux) || defined(VGP_arm64_linux)
1085   SysRes res;
1086   res = VG_(do_syscall3)( __NR_getpeername,
1087                           (UWord)sd, (UWord)name, (UWord)namelen );
1088   return sr_isError(res) ? -1 : sr_Res(res);
1089
1090#  elif defined(VGO_darwin)
1091   SysRes res;
1092   res = VG_(do_syscall3)( __NR_getpeername,
1093                           (UWord)sd, (UWord)name, (UWord)namelen );
1094   return sr_isError(res) ? -1 : sr_Res(res);
1095
1096#  else
1097#    error "Unknown platform"
1098#  endif
1099}
1100
1101Int VG_(getsockopt) ( Int sd, Int level, Int optname, void *optval,
1102                      Int *optlen)
1103{
1104#  if defined(VGP_x86_linux) || defined(VGP_ppc32_linux) \
1105      || defined(VGP_ppc64_linux) || defined(VGP_s390x_linux)
1106   SysRes res;
1107   UWord  args[5];
1108   args[0] = sd;
1109   args[1] = level;
1110   args[2] = optname;
1111   args[3] = (UWord)optval;
1112   args[4] = (UWord)optlen;
1113   res = VG_(do_syscall2)(__NR_socketcall, VKI_SYS_GETSOCKOPT, (UWord)&args);
1114   return sr_isError(res) ? -1 : sr_Res(res);
1115
1116#  elif defined(VGP_amd64_linux) || defined(VGP_arm_linux) \
1117        || defined(VGP_mips32_linux) || defined(VGP_mips64_linux) \
1118        || defined(VGP_arm64_linux)
1119   SysRes res;
1120   res = VG_(do_syscall5)( __NR_getsockopt,
1121                           (UWord)sd, (UWord)level, (UWord)optname,
1122                           (UWord)optval, (UWord)optlen );
1123   return sr_isError(res) ? -1 : sr_Res(res);
1124
1125#  elif defined(VGO_darwin)
1126   SysRes res;
1127   res = VG_(do_syscall5)( __NR_getsockopt,
1128                           (UWord)sd, (UWord)level, (UWord)optname,
1129                           (UWord)optval, (UWord)optlen );
1130   return sr_isError(res) ? -1 : sr_Res(res);
1131
1132#  else
1133#    error "Unknown platform"
1134#  endif
1135}
1136
1137
1138Int VG_(setsockopt) ( Int sd, Int level, Int optname, void *optval,
1139                      Int optlen)
1140{
1141#  if defined(VGP_x86_linux) || defined(VGP_ppc32_linux) \
1142      || defined(VGP_ppc64_linux) || defined(VGP_s390x_linux)
1143   SysRes res;
1144   UWord  args[5];
1145   args[0] = sd;
1146   args[1] = level;
1147   args[2] = optname;
1148   args[3] = (UWord)optval;
1149   args[4] = (UWord)optlen;
1150   res = VG_(do_syscall2)(__NR_socketcall, VKI_SYS_SETSOCKOPT, (UWord)&args);
1151   return sr_isError(res) ? -1 : sr_Res(res);
1152
1153#  elif defined(VGP_amd64_linux) || defined(VGP_arm_linux) \
1154        || defined(VGP_mips32_linux) || defined(VGP_mips64_linux) \
1155        || defined(VGP_arm64_linux)
1156   SysRes res;
1157   res = VG_(do_syscall5)( __NR_setsockopt,
1158                           (UWord)sd, (UWord)level, (UWord)optname,
1159                           (UWord)optval, (UWord)optlen );
1160   return sr_isError(res) ? -1 : sr_Res(res);
1161
1162#  elif defined(VGO_darwin)
1163   SysRes res;
1164   res = VG_(do_syscall5)( __NR_setsockopt,
1165                           (UWord)sd, (UWord)level, (UWord)optname,
1166                           (UWord)optval, (UWord)optlen );
1167   return sr_isError(res) ? -1 : sr_Res(res);
1168
1169#  else
1170#    error "Unknown platform"
1171#  endif
1172}
1173
1174
1175const HChar *VG_(basename)(const HChar *path)
1176{
1177   static HChar buf[VKI_PATH_MAX];
1178
1179   const HChar *p, *end;
1180
1181   if (path == NULL  ||
1182       0 == VG_(strcmp)(path, ""))
1183   {
1184      return ".";
1185   }
1186
1187   p = path + VG_(strlen)(path);
1188   while (p > path  &&  *p == '/') {
1189      // skip all trailing '/'
1190      p--;
1191   }
1192
1193   if (p == path  &&  *p == '/') return "/"; // all slashes
1194
1195   end = p;
1196
1197   while (p > path  &&  *p != '/') {
1198      // now skip non '/'
1199      p--;
1200   }
1201
1202   if (*p == '/') p++;
1203
1204   VG_(strncpy)(buf, p, end-p+1);
1205   buf[end-p+1] = '\0';
1206
1207   return buf;
1208}
1209
1210
1211const HChar *VG_(dirname)(const HChar *path)
1212{
1213   static HChar buf[VKI_PATH_MAX];
1214
1215   const HChar *p;
1216
1217   if (path == NULL  ||
1218       0 == VG_(strcmp)(path, "")  ||
1219       0 == VG_(strcmp)(path, "/"))
1220   {
1221      return ".";
1222   }
1223
1224   p = path + VG_(strlen)(path);
1225   while (p > path  &&  *p == '/') {
1226      // skip all trailing '/'
1227      p--;
1228   }
1229
1230   while (p > path  &&  *p != '/') {
1231      // now skip non '/'
1232      p--;
1233   }
1234
1235   if (p == path) {
1236      if (*p == '/') return "/"; // all slashes
1237      else return "."; // no slashes
1238   }
1239
1240   while (p > path  &&  *p == '/') {
1241      // skip '/' again
1242      p--;
1243   }
1244
1245   VG_(strncpy)(buf, path, p-path+1);
1246   buf[p-path+1] = '\0';
1247
1248   return buf;
1249}
1250
1251
1252/*--------------------------------------------------------------------*/
1253/*--- end                                                          ---*/
1254/*--------------------------------------------------------------------*/
1255