Re: The time(2) man page conflicts with glibc

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Tue, Dec 15, 2015 at 8:58 AM, H.J. Lu <hjl.tools@xxxxxxxxx> wrote:
...
>        time_t time(time_t *t);
...
>        If t is non-NULL, the return value is also stored in the memory pointed
>        to by t.
...
>        On error, ((time_t) -1) is returned, and errno is set appropriately.
...
>        EFAULT t points outside your accessible address space.
...
>    0: b8 c9 00 00 00       mov    $0xc9,%eax
>    5: 0f 05                 syscall
>    7: c3                   retq
>
> I didn't check what kernel returns when memory is invalid.

I did.  The *actual system call* does indeed return -EFAULT when
memory is invalid, which will be observed as 0xfffffffffffffff2 in the
return value.  However, the *vDSO shortcut* (which does not trap into
the kernel) will just segfault the application.  This is an observable
ABI difference between statically and dynamically linked binaries.

Given the extreme obsolescence of the argument to `time`, I would
recommend that the *kernel* be changed to fire an actual SIGSEGV
instead of returning -EFAULT from the syscall version of `time`, and
then that can be the documented behavior, with the historic behavior
relegated to the BUGS section of the manpage.

(Is the vDSO mapped into processes with statically linked executable
images?  If so, we could also consider changing glibc to use it
always.)

Test program and results:

$ cat test.c
#include <time.h>
#include <stdio.h>
#include <errno.h>

int main(void)
{
  time_t a;
  time_t b;
  errno = 0;
  a = time(&b);
  printf("%016llx %016llx %d\n",
         (unsigned long long)a, (unsigned long long)b, errno);

  errno = 0;
  a = time(0);
  printf("%016llx %d\n", (unsigned long long)a, errno);

  errno = 0;
  a = time((time_t *)0x8000FFFF0000FFFF);
  printf("%016llx %d\n", (unsigned long long)a, errno);
  return 0;
}

$ gcc test.c && ./a.out
0000000056701f0d 0000000056701f0d 0
0000000056701f0d 0
Segmentation fault

$ gcc -static test.c && ./a.out
0000000056701f22 0000000056701f22 0
0000000056701f22 0
fffffffffffffff2 0
--
To unsubscribe from this list: send the line "unsubscribe linux-man" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html



[Index of Archives]     [Kernel Documentation]     [Netdev]     [Linux Ethernet Bridging]     [Linux Wireless]     [Kernel Newbies]     [Security]     [Linux for Hams]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux RAID]     [Linux Admin]     [Samba]

  Powered by Linux