diff options
author | Mike Frysinger <vapier@gentoo.org> | 2007-02-09 22:23:35 +0000 |
---|---|---|
committer | Mike Frysinger <vapier@gentoo.org> | 2007-02-09 22:23:35 +0000 |
commit | 59dc2f86bf4be0702ab71ed7ec0c2e45f6d7f684 (patch) | |
tree | 1230d0e6b4ec0c151e9dce16ef9753f8ef30c801 /librt | |
parent | 87ad91cafbef5c328ed83c7c5bf56df6a15cadcf (diff) |
Kay McCormick reports: when evp is NULL, it is reset too late and so can cause a crash when it is dereferenced
Diffstat (limited to 'librt')
-rw-r--r-- | librt/timer_create.c | 29 |
1 files changed, 14 insertions, 15 deletions
diff --git a/librt/timer_create.c b/librt/timer_create.c index 7e77c0624..6aca5fffb 100644 --- a/librt/timer_create.c +++ b/librt/timer_create.c @@ -26,9 +26,19 @@ int timer_create(clockid_t clock_id, struct sigevent *evp, timer_t * timerid) { int retval; kernel_timer_t ktimerid; - struct sigevent local_evp; + struct sigevent default_evp; struct timer *newp; + if (evp == NULL) { + /* + * The kernel has to pass up the timer ID which is a userlevel object. + * Therefore we cannot leave it up to the kernel to determine it. + */ + default_evp.sigev_notify = SIGEV_SIGNAL; + default_evp.sigev_signo = SIGALRM; + evp = &default_evp; + } + /* Notification via a thread is not supported yet */ if (__builtin_expect(evp->sigev_notify == SIGEV_THREAD, 1)) return -1; @@ -38,25 +48,14 @@ int timer_create(clockid_t clock_id, struct sigevent *evp, timer_t * timerid) * struct timer as a derived class with the first two elements * being in the superclass. We only need these two elements here. */ - newp = (struct timer *)malloc(offsetof(struct timer, thrfunc)); + newp = malloc(offsetof(struct timer, thrfunc)); if (newp == NULL) return -1; /* No memory */ - - if (evp == NULL) { - /* - * The kernel has to pass up the timer ID which is a userlevel object. - * Therefore we cannot leave it up to the kernel to determine it. - */ - local_evp.sigev_notify = SIGEV_SIGNAL; - local_evp.sigev_signo = SIGALRM; - local_evp.sigev_value.sival_ptr = newp; - - evp = &local_evp; - } + default_evp.sigev_value.sival_ptr = newp; retval = __syscall_timer_create(clock_id, evp, &ktimerid); if (retval != -1) { - newp->sigev_notify = (evp != NULL ? evp->sigev_notify : SIGEV_SIGNAL); + newp->sigev_notify = evp->sigev_notify; newp->ktimerid = ktimerid; *timerid = (timer_t) newp; |