* [PATCH 1/2] posix_timer: separate timer_cleanup from timer_del
@ 2010-05-14 13:28 Andrey Vagin
2010-05-14 13:28 ` [PATCH 2/2] posix_timer: clean up properly if anything fails after *_timer_create Andrey Vagin
` (2 more replies)
0 siblings, 3 replies; 8+ messages in thread
From: Andrey Vagin @ 2010-05-14 13:28 UTC (permalink / raw)
To: Thomas Gleixner, Andrew Morton
Cc: linux-kernel, stable, Oleg Nesterov, Pavel Emelyanov,
Andrey Vagin
Signed-off-by: Andrey Vagin <avagin@openvz.org>
---
include/linux/posix-timers.h | 2 ++
kernel/posix-cpu-timers.c | 13 ++++++++++---
kernel/posix-timers.c | 4 ++++
3 files changed, 16 insertions(+), 3 deletions(-)
diff --git a/include/linux/posix-timers.h b/include/linux/posix-timers.h
index 4f71bf4..613ab27 100644
--- a/include/linux/posix-timers.h
+++ b/include/linux/posix-timers.h
@@ -78,6 +78,7 @@ struct k_clock {
int (*timer_set) (struct k_itimer * timr, int flags,
struct itimerspec * new_setting,
struct itimerspec * old_setting);
+ void (*timer_cleanup) (struct k_itimer * timr);
int (*timer_del) (struct k_itimer * timr);
#define TIMER_RETRY 1
void (*timer_get) (struct k_itimer * timr,
@@ -103,6 +104,7 @@ int posix_cpu_nsleep(const clockid_t which_clock, int flags,
long posix_cpu_nsleep_restart(struct restart_block *restart_block);
int posix_cpu_timer_set(struct k_itimer *timer, int flags,
struct itimerspec *new, struct itimerspec *old);
+void posix_cpu_timer_cleanup(struct k_itimer *timer);
int posix_cpu_timer_del(struct k_itimer *timer);
void posix_cpu_timer_get(struct k_itimer *timer, struct itimerspec *itp);
diff --git a/kernel/posix-cpu-timers.c b/kernel/posix-cpu-timers.c
index bc7704b..7a57833 100644
--- a/kernel/posix-cpu-timers.c
+++ b/kernel/posix-cpu-timers.c
@@ -455,14 +455,21 @@ int posix_cpu_timer_del(struct k_itimer *timer)
spin_unlock(&p->sighand->siglock);
}
read_unlock(&tasklist_lock);
-
- if (!ret)
- put_task_struct(p);
}
+ if (!ret)
+ posix_cpu_timer_cleanup(timer);
+
return ret;
}
+void posix_cpu_timer_cleanup(struct k_itimer *timer)
+{
+ struct task_struct *p = timer->it.cpu.task;
+ if (likely(p != NULL))
+ put_task_struct(p);
+}
+
/*
* Clean out CPU timers still ticking when a thread exited. The task
* pointer is cleared, and the expiry time is replaced with the residual
diff --git a/kernel/posix-timers.c b/kernel/posix-timers.c
index 00d1fda..1195668 100644
--- a/kernel/posix-timers.c
+++ b/kernel/posix-timers.c
@@ -197,6 +197,10 @@ static int common_timer_create(struct k_itimer *new_timer)
return 0;
}
+static inline void common_timer_cleanup(struct k_itimer *timer)
+{
+}
+
static int no_timer_create(struct k_itimer *new_timer)
{
return -EOPNOTSUPP;
--
1.6.6
^ permalink raw reply related [flat|nested] 8+ messages in thread* [PATCH 2/2] posix_timer: clean up properly if anything fails after *_timer_create
2010-05-14 13:28 [PATCH 1/2] posix_timer: separate timer_cleanup from timer_del Andrey Vagin
@ 2010-05-14 13:28 ` Andrey Vagin
2010-05-14 16:03 ` Oleg Nesterov
2010-05-14 16:01 ` [PATCH 1/2] posix_timer: separate timer_cleanup from timer_del Oleg Nesterov
2010-05-24 21:40 ` [stable] " Greg KH
2 siblings, 1 reply; 8+ messages in thread
From: Andrey Vagin @ 2010-05-14 13:28 UTC (permalink / raw)
To: Thomas Gleixner, Andrew Morton
Cc: linux-kernel, stable, Oleg Nesterov, Pavel Emelyanov,
Andrey Vagin
*_timer_create may allocate/get some resources, so need call *_timer_cleanup.
https://bugzilla.sw.ru/show_bug.cgi?id=473702
Signed-off-by: Andrey Vagin <avagin@openvz.org>
---
kernel/posix-timers.c | 8 +++++---
1 files changed, 5 insertions(+), 3 deletions(-)
diff --git a/kernel/posix-timers.c b/kernel/posix-timers.c
index 1195668..8d7cb0e 100644
--- a/kernel/posix-timers.c
+++ b/kernel/posix-timers.c
@@ -574,19 +574,19 @@ SYSCALL_DEFINE3(timer_create, const clockid_t, which_clock,
if (copy_to_user(created_timer_id,
&new_timer_id, sizeof (new_timer_id))) {
error = -EFAULT;
- goto out;
+ goto out_cleanup;
}
if (timer_event_spec) {
if (copy_from_user(&event, timer_event_spec, sizeof (event))) {
error = -EFAULT;
- goto out;
+ goto out_cleanup;
}
rcu_read_lock();
new_timer->it_pid = get_pid(good_sigevent(&event));
rcu_read_unlock();
if (!new_timer->it_pid) {
error = -EINVAL;
- goto out;
+ goto out_cleanup;
}
} else {
event.sigev_notify = SIGEV_SIGNAL;
@@ -613,6 +613,8 @@ SYSCALL_DEFINE3(timer_create, const clockid_t, which_clock,
* and may cease to exist at any time. Don't use or modify
* new_timer after the unlock call.
*/
+out_cleanup:
+ CLOCK_DISPATCH(new_timer->it_clock, timer_cleanup, (new_timer));
out:
release_posix_timer(new_timer, it_id_set);
return error;
--
1.6.6
^ permalink raw reply related [flat|nested] 8+ messages in thread* Re: [PATCH 2/2] posix_timer: clean up properly if anything fails after *_timer_create
2010-05-14 13:28 ` [PATCH 2/2] posix_timer: clean up properly if anything fails after *_timer_create Andrey Vagin
@ 2010-05-14 16:03 ` Oleg Nesterov
2010-05-14 17:18 ` Stanislaw Gruszka
0 siblings, 1 reply; 8+ messages in thread
From: Oleg Nesterov @ 2010-05-14 16:03 UTC (permalink / raw)
To: Andrey Vagin
Cc: Thomas Gleixner, Andrew Morton, linux-kernel, stable,
Pavel Emelyanov, Stanislaw Gruszka
On 05/14, Andrey Vagin wrote:
>
> *_timer_create may allocate/get some resources, so need call *_timer_cleanup.
>
> https://bugzilla.sw.ru/show_bug.cgi?id=473702
Authorization Required
> --- a/kernel/posix-timers.c
> +++ b/kernel/posix-timers.c
> @@ -574,19 +574,19 @@ SYSCALL_DEFINE3(timer_create, const clockid_t, which_clock,
> if (copy_to_user(created_timer_id,
> &new_timer_id, sizeof (new_timer_id))) {
> error = -EFAULT;
> - goto out;
> + goto out_cleanup;
> }
> if (timer_event_spec) {
> if (copy_from_user(&event, timer_event_spec, sizeof (event))) {
> error = -EFAULT;
> - goto out;
> + goto out_cleanup;
> }
> rcu_read_lock();
> new_timer->it_pid = get_pid(good_sigevent(&event));
> rcu_read_unlock();
> if (!new_timer->it_pid) {
> error = -EINVAL;
> - goto out;
> + goto out_cleanup;
> }
> } else {
> event.sigev_notify = SIGEV_SIGNAL;
> @@ -613,6 +613,8 @@ SYSCALL_DEFINE3(timer_create, const clockid_t, which_clock,
> * and may cease to exist at any time. Don't use or modify
> * new_timer after the unlock call.
> */
> +out_cleanup:
> + CLOCK_DISPATCH(new_timer->it_clock, timer_cleanup, (new_timer));
But at first glance you are right, posix_cpu_timer_create() does
get_task_struct(it.cpu.task).
Oleg.
^ permalink raw reply [flat|nested] 8+ messages in thread* Re: [PATCH 2/2] posix_timer: clean up properly if anything fails after *_timer_create
2010-05-14 16:03 ` Oleg Nesterov
@ 2010-05-14 17:18 ` Stanislaw Gruszka
2010-05-14 18:48 ` Oleg Nesterov
0 siblings, 1 reply; 8+ messages in thread
From: Stanislaw Gruszka @ 2010-05-14 17:18 UTC (permalink / raw)
To: Oleg Nesterov, Andrey Vagin
Cc: Thomas Gleixner, Andrew Morton, linux-kernel, stable,
Pavel Emelyanov
On Fri, 14 May 2010 18:03:57 +0200
Oleg Nesterov <oleg@redhat.com> wrote:
> On 05/14, Andrey Vagin wrote:
> >
> > *_timer_create may allocate/get some resources, so need call *_timer_cleanup.
> >
> > https://bugzilla.sw.ru/show_bug.cgi?id=473702
>
> Authorization Required
>
> > --- a/kernel/posix-timers.c
> > +++ b/kernel/posix-timers.c
> > @@ -574,19 +574,19 @@ SYSCALL_DEFINE3(timer_create, const clockid_t, which_clock,
> > if (copy_to_user(created_timer_id,
> > &new_timer_id, sizeof (new_timer_id))) {
> > error = -EFAULT;
> > - goto out;
> > + goto out_cleanup;
> > }
> > if (timer_event_spec) {
> > if (copy_from_user(&event, timer_event_spec, sizeof (event))) {
> > error = -EFAULT;
> > - goto out;
> > + goto out_cleanup;
> > }
> > rcu_read_lock();
> > new_timer->it_pid = get_pid(good_sigevent(&event));
> > rcu_read_unlock();
> > if (!new_timer->it_pid) {
> > error = -EINVAL;
> > - goto out;
> > + goto out_cleanup;
> > }
> > } else {
> > event.sigev_notify = SIGEV_SIGNAL;
> > @@ -613,6 +613,8 @@ SYSCALL_DEFINE3(timer_create, const clockid_t, which_clock,
> > * and may cease to exist at any time. Don't use or modify
> > * new_timer after the unlock call.
> > */
> > +out_cleanup:
> > + CLOCK_DISPATCH(new_timer->it_clock, timer_cleanup, (new_timer));
>
> But at first glance you are right, posix_cpu_timer_create() does
> get_task_struct(it.cpu.task).
If I understand problem correctly, seems to be fine to move
CLOCK_DISPATCH(which_clock, timer_create, (new_timer));
after all possible EFAULT errors and solve leak without creating
new timer_cleanup() callback.
Stanislaw
^ permalink raw reply [flat|nested] 8+ messages in thread* Re: [PATCH 2/2] posix_timer: clean up properly if anything fails after *_timer_create
2010-05-14 17:18 ` Stanislaw Gruszka
@ 2010-05-14 18:48 ` Oleg Nesterov
2010-05-15 14:17 ` Andrew Vagin
0 siblings, 1 reply; 8+ messages in thread
From: Oleg Nesterov @ 2010-05-14 18:48 UTC (permalink / raw)
To: Stanislaw Gruszka
Cc: Andrey Vagin, Thomas Gleixner, Andrew Morton, linux-kernel,
stable, Pavel Emelyanov
On 05/14, Stanislaw Gruszka wrote:
>
> On Fri, 14 May 2010 18:03:57 +0200
> Oleg Nesterov <oleg@redhat.com> wrote:
>
> > On 05/14, Andrey Vagin wrote:
> > >
> > > @@ -613,6 +613,8 @@ SYSCALL_DEFINE3(timer_create, const clockid_t, which_clock,
> > > * and may cease to exist at any time. Don't use or modify
> > > * new_timer after the unlock call.
> > > */
> > > +out_cleanup:
> > > + CLOCK_DISPATCH(new_timer->it_clock, timer_cleanup, (new_timer));
> >
> > But at first glance you are right, posix_cpu_timer_create() does
> > get_task_struct(it.cpu.task).
>
> If I understand problem correctly, seems to be fine to move
> CLOCK_DISPATCH(which_clock, timer_create, (new_timer));
> after all possible EFAULT errors and solve leak without creating
> new timer_cleanup() callback.
I thought about this too, we are doing copy_to_user(created_timer_id)
"in advance" anyway. Probably we can move all this code block
new_timer->it_id = (timer_t) new_timer_id;
new_timer->it_clock = which_clock;
new_timer->it_overrun = -1;
error = CLOCK_DISPATCH(which_clock, timer_create, (new_timer));
if (error)
goto out;
down, right before we take ->siglock.
But I don't understand the change in posix_cpu_timer_del() from 1/2.
Otoh, currently "The next step is hard to back out if there is an error"
comment is not right, release_posix_timer() does put_pid(). We can
move copy_to_user(created_timer_id) down after "if (timer_event_spec)"
block too. (but before CLOCK_DISPATCH(), of course).
Andrey, what do you think?
Oleg.
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH 2/2] posix_timer: clean up properly if anything fails after *_timer_create
2010-05-14 18:48 ` Oleg Nesterov
@ 2010-05-15 14:17 ` Andrew Vagin
0 siblings, 0 replies; 8+ messages in thread
From: Andrew Vagin @ 2010-05-15 14:17 UTC (permalink / raw)
To: Oleg Nesterov
Cc: Stanislaw Gruszka, Andrey Vagin, Thomas Gleixner, Andrew Morton,
linux-kernel, stable, Pavel Emelyanov
On 05/14/2010 10:48 PM, Oleg Nesterov wrote:
> On 05/14, Stanislaw Gruszka wrote:
>
>> On Fri, 14 May 2010 18:03:57 +0200
>> Oleg Nesterov<oleg@redhat.com> wrote:
>>
>>
>>> On 05/14, Andrey Vagin wrote:
>>>
>>>> @@ -613,6 +613,8 @@ SYSCALL_DEFINE3(timer_create, const clockid_t, which_clock,
>>>> * and may cease to exist at any time. Don't use or modify
>>>> * new_timer after the unlock call.
>>>> */
>>>> +out_cleanup:
>>>> + CLOCK_DISPATCH(new_timer->it_clock, timer_cleanup, (new_timer));
>>>>
>>> But at first glance you are right, posix_cpu_timer_create() does
>>> get_task_struct(it.cpu.task).
>>>
>> If I understand problem correctly, seems to be fine to move
>> CLOCK_DISPATCH(which_clock, timer_create, (new_timer));
>> after all possible EFAULT errors and solve leak without creating
>> new timer_cleanup() callback.
>>
> I thought about this too, we are doing copy_to_user(created_timer_id)
> "in advance" anyway. Probably we can move all this code block
>
> new_timer->it_id = (timer_t) new_timer_id;
> new_timer->it_clock = which_clock;
> new_timer->it_overrun = -1;
> error = CLOCK_DISPATCH(which_clock, timer_create, (new_timer));
> if (error)
> goto out;
>
> down, right before we take ->siglock.
>
You are right. I will send a new patch sooner. Thanks for your comments.
> But I don't understand the change in posix_cpu_timer_del() from 1/2.
>
timer_cleanup doesn't do the disarm timer. In case fail in timer_create
it's enough to call timer_cleanup. This changes are not necessary in new
version.
>
> Otoh, currently "The next step is hard to back out if there is an error"
> comment is not right, release_posix_timer() does put_pid(). We can
> move copy_to_user(created_timer_id) down after "if (timer_event_spec)"
> block too. (but before CLOCK_DISPATCH(), of course).
>
> Andrey, what do you think?
>
I've look at code again and think that you are right. At first I created
patches for 2.6.18 kernel, more complex code in this place and the
comment "the next step is ..." induced me to make callback timer_cleanup.
> Oleg.
>
>
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH 1/2] posix_timer: separate timer_cleanup from timer_del
2010-05-14 13:28 [PATCH 1/2] posix_timer: separate timer_cleanup from timer_del Andrey Vagin
2010-05-14 13:28 ` [PATCH 2/2] posix_timer: clean up properly if anything fails after *_timer_create Andrey Vagin
@ 2010-05-14 16:01 ` Oleg Nesterov
2010-05-24 21:40 ` [stable] " Greg KH
2 siblings, 0 replies; 8+ messages in thread
From: Oleg Nesterov @ 2010-05-14 16:01 UTC (permalink / raw)
To: Andrey Vagin
Cc: Thomas Gleixner, Andrew Morton, linux-kernel, stable,
Pavel Emelyanov, Stanislaw Gruszka
(add Stanislaw)
On 05/14, Andrey Vagin wrote:
>
> Signed-off-by: Andrey Vagin <avagin@openvz.org>
You forgot to write the changelog ;)
> --- a/kernel/posix-cpu-timers.c
> +++ b/kernel/posix-cpu-timers.c
> @@ -455,14 +455,21 @@ int posix_cpu_timer_del(struct k_itimer *timer)
> spin_unlock(&p->sighand->siglock);
> }
> read_unlock(&tasklist_lock);
> -
> - if (!ret)
> - put_task_struct(p);
> }
>
> + if (!ret)
> + posix_cpu_timer_cleanup(timer);
> +
> return ret;
> }
Could you please explain this change?
Oleg.
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [stable] [PATCH 1/2] posix_timer: separate timer_cleanup from timer_del
2010-05-14 13:28 [PATCH 1/2] posix_timer: separate timer_cleanup from timer_del Andrey Vagin
2010-05-14 13:28 ` [PATCH 2/2] posix_timer: clean up properly if anything fails after *_timer_create Andrey Vagin
2010-05-14 16:01 ` [PATCH 1/2] posix_timer: separate timer_cleanup from timer_del Oleg Nesterov
@ 2010-05-24 21:40 ` Greg KH
2 siblings, 0 replies; 8+ messages in thread
From: Greg KH @ 2010-05-24 21:40 UTC (permalink / raw)
To: Andrey Vagin
Cc: Thomas Gleixner, Andrew Morton, Pavel Emelyanov, Oleg Nesterov,
linux-kernel, stable
On Fri, May 14, 2010 at 05:28:50PM +0400, Andrey Vagin wrote:
> Signed-off-by: Andrey Vagin <avagin@openvz.org>
> ---
> include/linux/posix-timers.h | 2 ++
> kernel/posix-cpu-timers.c | 13 ++++++++++---
> kernel/posix-timers.c | 4 ++++
I have no idea why this is for the -stable kernels, do you?
Please, just put a:
Cc: stable <stable@kernel.org>
in the signed-off-by area of the patch, so that way I will be notified
when it goes into Linus's tree, not before, which just wastes my time...
thanks,
greg k-h
^ permalink raw reply [flat|nested] 8+ messages in thread
end of thread, other threads:[~2010-05-24 22:02 UTC | newest]
Thread overview: 8+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2010-05-14 13:28 [PATCH 1/2] posix_timer: separate timer_cleanup from timer_del Andrey Vagin
2010-05-14 13:28 ` [PATCH 2/2] posix_timer: clean up properly if anything fails after *_timer_create Andrey Vagin
2010-05-14 16:03 ` Oleg Nesterov
2010-05-14 17:18 ` Stanislaw Gruszka
2010-05-14 18:48 ` Oleg Nesterov
2010-05-15 14:17 ` Andrew Vagin
2010-05-14 16:01 ` [PATCH 1/2] posix_timer: separate timer_cleanup from timer_del Oleg Nesterov
2010-05-24 21:40 ` [stable] " Greg KH
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox