diff options
author | Petr Baudis <pasky@ucw.cz> | 2013-03-14 01:16:53 +0100 |
---|---|---|
committer | Petr Baudis <pasky@ucw.cz> | 2013-03-14 01:16:53 +0100 |
commit | 58a1335e76a553e1cf4edeebc27f16fc9b53d6e6 (patch) | |
tree | 9fd5fa6a35ac6cae08023fae5fc0037e29c8e09b /sysdeps/unix/sysv/linux/times.c | |
parent | bb48a26acf98a377a0ec235d127311ae4fbfb623 (diff) | |
download | glibc-58a1335e76a553e1cf4edeebc27f16fc9b53d6e6.tar.gz glibc-58a1335e76a553e1cf4edeebc27f16fc9b53d6e6.tar.xz glibc-58a1335e76a553e1cf4edeebc27f16fc9b53d6e6.zip |
Fix __times() handling of EFAULT when buf is NULL
Diffstat (limited to 'sysdeps/unix/sysv/linux/times.c')
-rw-r--r-- | sysdeps/unix/sysv/linux/times.c | 10 |
1 files changed, 6 insertions, 4 deletions
diff --git a/sysdeps/unix/sysv/linux/times.c b/sysdeps/unix/sysv/linux/times.c index f3b5f014e2..e59bb4ed6d 100644 --- a/sysdeps/unix/sysv/linux/times.c +++ b/sysdeps/unix/sysv/linux/times.c @@ -26,13 +26,14 @@ __times (struct tms *buf) INTERNAL_SYSCALL_DECL (err); clock_t ret = INTERNAL_SYSCALL (times, err, 1, buf); if (INTERNAL_SYSCALL_ERROR_P (ret, err) - && __builtin_expect (INTERNAL_SYSCALL_ERRNO (ret, err) == EFAULT, 0)) + && __builtin_expect (INTERNAL_SYSCALL_ERRNO (ret, err) == EFAULT, 0) + && buf) { /* This might be an error or not. For architectures which have no separate return value and error indicators we cannot distinguish a return value of -1 from an error. Do it the - hard way. We crash applications which pass in an invalid BUF - pointer. */ + hard way. We crash applications which pass in an invalid + non-NULL BUF pointer. Linux allows BUF to be NULL. */ #define touch(v) \ do { \ clock_t temp = v; \ @@ -44,7 +45,8 @@ __times (struct tms *buf) touch (buf->tms_cutime); touch (buf->tms_cstime); - /* If we come here the memory is valid and the kernel did not + /* If we come here the memory is valid (or BUF is NULL, which is + * a valid condition for the kernel syscall) and the kernel did not return an EFAULT error. Return the value given by the kernel. */ } |