This is the mail archive of the
libc-alpha@sourceware.org
mailing list for the glibc project.
[PATCH]: NULL pointer check in timer_* functions
- From: Khem Raj <kraj at mvista dot com>
- To: libc-alpha at sources dot redhat dot com
- Date: Thu, 11 Aug 2005 17:31:51 -0700
- Subject: [PATCH]: NULL pointer check in timer_* functions
- Reply-to: kraj at mvista dot com
Hi
I came across this problem while running a small test where a timer is
created and deleted after that a call to timer_settime is made. This
caused a segmentation fault
on x86_64 target because the old_timer_delete function the timerid was
nullified. So when the call was made for timer_settime it passed 0
timerid and caused the segmentation fault.
This only happens if we are running a binary which was linked against
older glibc (e.g.) 2.2.5 because then only it is calling the
compatibility code.
I tracked it down to a problem inside timer_* functions. Currently we do
not check for timerid for NULL value inside timer_delete()
timer_settime() and timer_gettime() timer_getoverrun() functions.
This patch adds the checks to these functions.
Other way to fix this was do not nullify timerid in compatibility code
when timer is deleted instead of having an array to hold just the
timerid's expand this to hold additional element which will denote if
timer is deleted or is in use. In this approach the size of array will
double and also the checking code has to be added.
Is this OK or is it that we don't need this kind of checks at all.
Thanks
-Khem
nptl/Changelog
2005-08-11 Khem Raj <kraj@mvista.com>
* sysdeps/unix/sysv/linux/timer_delete.c (timer_delete): Check for
NULL timerid.
* sysdeps/unix/sysv/linux/timer_delete.c (timer_delete): Likewise.
* sysdeps/unix/sysv/linux/timer_delete.c (timer_delete): Likewise.
* sysdeps/unix/sysv/linux/timer_delete.c (timer_delete): Likewise.
? diff
Index: timer_delete.c
===================================================================
RCS file: /cvs/glibc/libc/nptl/sysdeps/unix/sysv/linux/timer_delete.c,v
retrieving revision 1.4
diff -u -r1.4 timer_delete.c
--- timer_delete.c 18 Jun 2003 18:39:11 -0000 1.4
+++ timer_delete.c 11 Aug 2005 23:24:44 -0000
@@ -48,7 +48,11 @@
# endif
{
struct timer *kt = (struct timer *) timerid;
-
+ if (kt == NULL) {
+ __set_errno (EINVAL);
+ return -1;
+ }
+
/* Delete the kernel timer object. */
int res = INLINE_SYSCALL (timer_delete, 1, kt->ktimerid);
Index: timer_getoverr.c
===================================================================
RCS file: /cvs/glibc/libc/nptl/sysdeps/unix/sysv/linux/timer_getoverr.c,v
retrieving revision 1.4
diff -u -r1.4 timer_getoverr.c
--- timer_getoverr.c 18 Jun 2003 18:40:05 -0000 1.4
+++ timer_getoverr.c 11 Aug 2005 23:24:44 -0000
@@ -47,6 +47,10 @@
# endif
{
struct timer *kt = (struct timer *) timerid;
+ if (kt == NULL) {
+ __set_errno (EINVAL);
+ return -1;
+ }
/* Get the information from the kernel. */
int res = INLINE_SYSCALL (timer_getoverrun, 1, kt->ktimerid);
Index: timer_gettime.c
===================================================================
RCS file: /cvs/glibc/libc/nptl/sysdeps/unix/sysv/linux/timer_gettime.c,v
retrieving revision 1.3
diff -u -r1.3 timer_gettime.c
--- timer_gettime.c 18 Jun 2003 18:41:08 -0000 1.3
+++ timer_gettime.c 11 Aug 2005 23:24:44 -0000
@@ -49,8 +49,12 @@
# endif
{
struct timer *kt = (struct timer *) timerid;
+ if (kt == NULL) {
+ __set_errno (EINVAL);
+ return -1;
+ }
- /* Delete the kernel timer object. */
+ /* Get time from the kernel timer.*/
int res = INLINE_SYSCALL (timer_gettime, 2, kt->ktimerid, value);
# ifndef __ASSUME_POSIX_TIMERS
Index: timer_settime.c
===================================================================
RCS file: /cvs/glibc/libc/nptl/sysdeps/unix/sysv/linux/timer_settime.c,v
retrieving revision 1.4
diff -u -r1.4 timer_settime.c
--- timer_settime.c 18 Jun 2003 18:42:00 -0000 1.4
+++ timer_settime.c 11 Aug 2005 23:24:44 -0000
@@ -53,8 +53,12 @@
# endif
{
struct timer *kt = (struct timer *) timerid;
-
- /* Delete the kernel timer object. */
+ if (kt == NULL) {
+ __set_errno (EINVAL);
+ return -1;
+ }
+
+ /* Set time in kernel timer.*/
int res = INLINE_SYSCALL (timer_settime, 4, kt->ktimerid, flags,
value, ovalue);