https://bugs.kde.org/show_bug.cgi?id=516748

            Bug ID: 516748
           Summary: Incorrect use of SET_STATUS_Failure for syscall
                    wrappers that return error codes rather than -1 on
                    error
    Classification: Developer tools
           Product: valgrind
      Version First 3.27 GIT
       Reported In:
          Platform: Other
                OS: Other
            Status: REPORTED
          Severity: normal
          Priority: NOR
         Component: general
          Assignee: [email protected]
          Reporter: [email protected]
  Target Milestone: ---

I don't think that this affects Linux at all. It certainly affects FreeBSD and
most likely also Solaris and Darwin.

On FreeBSD Darwin and Solaris the carry flag is usually used to indicate an
error. In that case the return from the syscall gets put into errno and the
wrapper returns -1.

However there are some system calls that don't follow this convention. Instead
they usually return 0 for success or otherwise an error code (like errno, but
they don't set errno). For this class of syscalls the kernel does not set the
carry flag on return.  The wrapper simply returns the value returned from the
kernel.

That means that code like this is wrong

// SYS_posix_fallocate 530
// int posix_fallocate(int fd, off_t offset, off_t len);
PRE(sys_posix_fallocate)
{
   PRINT("sys_posix_fallocate ( %" FMT_REGWORD "d, %" FMT_REGWORD "u, %"
FMT_REGWORD "u )",
         SARG1, ARG2, ARG3);
   PRE_REG_READ3(long, "posix_fallocate",
                 int, fd, vki_off_t, offset,
                 vki_off_t, len);
   if (!ML_(fd_allowed)(ARG1, "posix_fallocate", tid, False))
      SET_STATUS_Failure(VKI_EBADF);
}

If ML_(fd_allowed) fails SET_STATUS_Failure will cause the carry flag to get
set. That will cause the syscall wrapper to return -1 and set errno rather than
returning EBADF.

The above code should use SET_STATUS_Success. That doesn't look good for
legibility so I'll probably create a macro alias, something like

/* for syscalls that just return an error code without using the error flag */
#define SET_STATUS_FailureCode SET_STATUS_Success

so that I can write

   if (!ML_(fd_allowed)(ARG1, "posix_fallocate", tid, False))
      SET_STATUS_FaulureCode(VKI_EBADF);

I need to go though all of the FreeBSD Darwin and Solaris syscall wrappers to
check which ones are affected.

-- 
You are receiving this mail because:
You are watching all bug changes.

Reply via email to