e6fdd7e
Testcase:
e6fdd7e
#define _GNU_SOURCE
e6fdd7e
#include <fcntl.h>
e6fdd7e
#include <unistd.h>
e6fdd7e
e6fdd7e
int
e6fdd7e
main (void)
e6fdd7e
{
e6fdd7e
  int dfd = open ("/tmp", O_RDONLY);
e6fdd7e
  int fd1 = openat (dfd, "abc", O_RDONLY);
e6fdd7e
  int fd2 = openat (0x12345678, "/tmp/abc", O_RDONLY);
e6fdd7e
  int fd3 = openat (AT_FDCWD, "abc", O_RDONLY);
e6fdd7e
  /* This is the only one that should warn.  */
e6fdd7e
  int fd4 = openat (0x12345678, "abc", O_RDONLY);
e6fdd7e
  return 0;
e6fdd7e
}
e6fdd7e
Mark Wielaard c728a33
--- valgrind-3.8.1/coregrind/m_syswrap/syswrap-linux.c.jj	2007-12-11 00:18:43.000000000 +0100
Mark Wielaard c728a33
+++ valgrind-3.8.1/coregrind/m_syswrap/syswrap-linux.c	2008-03-03 11:35:15.000000000 +0100
Mark Wielaard f4ddfbd
@@ -3308,10 +3308,15 @@ PRE(sys_openat)
e6fdd7e
                     int, dfd, const char *, filename, int, flags);
e6fdd7e
    }
e6fdd7e
 
888c615
-   if (ARG1 != VKI_AT_FDCWD && !ML_(fd_allowed)(ARG1, "openat", tid, False))
e6fdd7e
+   PRE_MEM_RASCIIZ( "openat(filename)", ARG2 );
e6fdd7e
+
e6fdd7e
+   /* For absolute filenames, dfd is ignored.  If dfd is AT_FDCWD,
888c615
+      filename is relative to cwd.  */
e6fdd7e
+   if (ML_(safe_to_deref)( (void*)ARG2, 1 )
e6fdd7e
+       && *(Char *)ARG2 != '/'
e6fdd7e
+       && ARG1 != VKI_AT_FDCWD
e6fdd7e
+       && !ML_(fd_allowed)(ARG1, "openat", tid, False))
e6fdd7e
       SET_STATUS_Failure( VKI_EBADF );
e6fdd7e
-   else
e6fdd7e
-      PRE_MEM_RASCIIZ( "openat(filename)", ARG2 );
e6fdd7e
 
e6fdd7e
    /* Handle the case where the open is of /proc/self/cmdline or
e6fdd7e
       /proc/<pid>/cmdline, and just give it a copy of the fd for the