From: Roman Zippel <zippel@linux-m68k.org>
To: Al Viro <viro@ftp.linux.org.uk>
Cc: Linus Torvalds <torvalds@osdl.org>, Andrew Morton <akpm@osdl.org>,
Eric Sandeen <sandeen@redhat.com>,
Linux Kernel Mailing List <linux-kernel@vger.kernel.org>,
Al Viro <viro@zeniv.linux.org.uk>
Subject: Re: [UPDATED PATCH] fix memory corruption from misinterpreted bad_inode_ops return values
Date: Sun, 7 Jan 2007 03:14:40 +0100 (CET) [thread overview]
Message-ID: <Pine.LNX.4.64.0701070311450.5666@localhost.localdomain> (raw)
In-Reply-To: <20070104192223.GX17561@ftp.linux.org.uk>
Hi,
On Thu, 4 Jan 2007, Al Viro wrote:
> PS: what would be the sane strategy for timer series merge, BTW?
PPS: I still don't like it. It fixes a rather theoretical problem with
absolutely no practical relevance.
PPPS: type safety is also possible with container_of(), the prototype
patch below demonstrates how to check that the signature matches and
additionally it doesn't require to convert everything at once. More
sophisticated checks can be done by putting this information into a
separate section, from where it can be extracted at compile/run time.
bye, Roman
---
include/linux/timer.h | 24 ++++++++++++++++++++++++
kernel/timer.c | 18 +++++++++++++++++-
kernel/workqueue.c | 24 ++++++++++--------------
3 files changed, 51 insertions(+), 15 deletions(-)
Index: linux-2.6-git/include/linux/timer.h
===================================================================
--- linux-2.6-git.orig/include/linux/timer.h 2007-01-06 20:45:02.000000000 +0100
+++ linux-2.6-git/include/linux/timer.h 2007-01-06 21:00:07.000000000 +0100
@@ -13,16 +13,40 @@ struct timer_list {
void (*function)(unsigned long);
unsigned long data;
+ unsigned long _sig;
struct tvec_t_base_s *base;
};
+#define __timer_sig(type, member) ((offsetof(type, member) << 16) | sizeof(type))
+
+#define __TIMER_OLD_SIG (0xa5005a)
+
+typedef void timer_cb_t(struct timer_list *);
+
+extern void __timer_init(struct timer_list *t, timer_cb_t *func, long sig);
+
+#define timer_init(ptr, member, func) \
+ __timer_init(&(ptr)->member, func, \
+ __timer_sig(typeof(*ptr), member))
+
+#define timer_of(ptr, type, member) ({ \
+ const struct timer_list *_t = (ptr); \
+ if (_t->_sig != __timer_sig(type, member)) { \
+ WARN_ON(_t->_sig != -__timer_sig(type, member));\
+ return; \
+ } \
+ container_of(ptr, type, member); \
+})
+
+
extern struct tvec_t_base_s boot_tvec_bases;
#define TIMER_INITIALIZER(_function, _expires, _data) { \
.function = (_function), \
.expires = (_expires), \
.data = (_data), \
+ ._sig = __TIMER_OLD_SIG, \
.base = &boot_tvec_bases, \
}
Index: linux-2.6-git/kernel/timer.c
===================================================================
--- linux-2.6-git.orig/kernel/timer.c 2007-01-06 20:45:02.000000000 +0100
+++ linux-2.6-git/kernel/timer.c 2007-01-06 21:00:07.000000000 +0100
@@ -226,6 +226,11 @@ static void internal_add_timer(tvec_base
unsigned long idx = expires - base->timer_jiffies;
struct list_head *vec;
+ if (!timer->_sig) {
+ WARN_ON(1);
+ timer->_sig = __TIMER_OLD_SIG;
+ }
+
if (idx < TVR_SIZE) {
int i = expires & TVR_MASK;
vec = base->tv1.vec + i;
@@ -271,11 +276,22 @@ static void internal_add_timer(tvec_base
*/
void fastcall init_timer(struct timer_list *timer)
{
+ timer->_sig = __TIMER_OLD_SIG;
timer->entry.next = NULL;
timer->base = __raw_get_cpu_var(tvec_bases);
}
EXPORT_SYMBOL(init_timer);
+extern void __timer_init(struct timer_list *t, timer_cb_t *func, long sig)
+{
+ t->function = (void *)func;
+ t->_sig = -sig;
+ func(t);
+ t->_sig = sig;
+ t->entry.next = NULL;
+ t->base = __raw_get_cpu_var(tvec_bases);
+}
+
static inline void detach_timer(struct timer_list *timer,
int clear_pending)
{
@@ -567,7 +583,7 @@ static inline void __run_timers(tvec_bas
timer = list_entry(head->next,struct timer_list,entry);
fn = timer->function;
- data = timer->data;
+ data = timer->_sig == __TIMER_OLD_SIG ? timer->data : (unsigned long)timer;
set_running_timer(base, timer);
detach_timer(timer, 1);
Index: linux-2.6-git/kernel/workqueue.c
===================================================================
--- linux-2.6-git.orig/kernel/workqueue.c 2007-01-06 19:51:40.000000000 +0100
+++ linux-2.6-git/kernel/workqueue.c 2007-01-06 21:02:59.000000000 +0100
@@ -218,9 +218,9 @@ int fastcall queue_work(struct workqueue
}
EXPORT_SYMBOL_GPL(queue_work);
-static void delayed_work_timer_fn(unsigned long __data)
+static void delayed_work_timer_fn(struct timer_list *timer)
{
- struct delayed_work *dwork = (struct delayed_work *)__data;
+ struct delayed_work *dwork = timer_of(timer, struct delayed_work, timer);
struct workqueue_struct *wq = get_wq_data(&dwork->work);
int cpu = smp_processor_id();
@@ -242,22 +242,20 @@ int fastcall queue_delayed_work(struct w
struct delayed_work *dwork, unsigned long delay)
{
int ret = 0;
- struct timer_list *timer = &dwork->timer;
struct work_struct *work = &dwork->work;
if (delay == 0)
return queue_work(wq, work);
if (!test_and_set_bit(WORK_STRUCT_PENDING, work_data_bits(work))) {
- BUG_ON(timer_pending(timer));
+ BUG_ON(timer_pending(&dwork->timer));
BUG_ON(!list_empty(&work->entry));
/* This stores wq for the moment, for the timer_fn */
set_wq_data(work, wq);
- timer->expires = jiffies + delay;
- timer->data = (unsigned long)dwork;
- timer->function = delayed_work_timer_fn;
- add_timer(timer);
+ timer_init(dwork, timer, delayed_work_timer_fn);
+ dwork->timer.expires = jiffies + delay;
+ add_timer(&dwork->timer);
ret = 1;
}
return ret;
@@ -277,19 +275,17 @@ int queue_delayed_work_on(int cpu, struc
struct delayed_work *dwork, unsigned long delay)
{
int ret = 0;
- struct timer_list *timer = &dwork->timer;
struct work_struct *work = &dwork->work;
if (!test_and_set_bit(WORK_STRUCT_PENDING, work_data_bits(work))) {
- BUG_ON(timer_pending(timer));
+ BUG_ON(timer_pending(&dwork->timer));
BUG_ON(!list_empty(&work->entry));
/* This stores wq for the moment, for the timer_fn */
set_wq_data(work, wq);
- timer->expires = jiffies + delay;
- timer->data = (unsigned long)dwork;
- timer->function = delayed_work_timer_fn;
- add_timer_on(timer, cpu);
+ timer_init(dwork, timer, delayed_work_timer_fn);
+ dwork->timer.expires = jiffies + delay;
+ add_timer_on(&dwork->timer, cpu);
ret = 1;
}
return ret;
next prev parent reply other threads:[~2007-01-07 2:15 UTC|newest]
Thread overview: 32+ messages / expand[flat|nested] mbox.gz Atom feed top
2007-01-03 23:46 Eric Sandeen
2007-01-04 0:26 ` Andrew Morton
2007-01-04 17:51 ` Eric Sandeen
2007-01-04 18:26 ` Andrew Morton
2007-01-04 18:33 ` Eric Sandeen
2007-01-04 18:54 ` Andrew Morton
2007-01-04 19:09 ` Linus Torvalds
2007-01-04 19:14 ` Al Viro
2007-01-04 19:22 ` Al Viro
2007-01-04 19:32 ` Linus Torvalds
2007-01-07 2:14 ` Roman Zippel [this message]
2007-01-04 19:30 ` Linus Torvalds
2007-01-04 20:24 ` Al Viro
2007-01-04 21:00 ` Andrew Morton
2007-01-04 21:04 ` Eric Sandeen
2007-01-04 21:10 ` Andrew Morton
2007-01-04 21:18 ` Eric Sandeen
2007-01-04 21:30 ` Linus Torvalds
2007-01-04 21:50 ` Eric Sandeen
2007-01-04 21:52 ` Al Viro
2007-01-04 22:38 ` Mitchell Blank Jr
2007-01-04 22:35 ` Linus Torvalds
2007-01-04 22:48 ` Eric Sandeen
2007-01-04 23:06 ` Andrew Morton
2007-01-04 23:17 ` Linus Torvalds
2007-01-04 23:28 ` Eric Sandeen
2007-01-04 23:21 ` Mitchell Blank Jr
2007-01-04 23:52 ` Al Viro
2007-01-05 5:59 ` Duplicated functions (was: fix memory corruption from misinterpreted bad_inode_ops return values) Mitchell Blank Jr
2007-01-05 15:40 ` [UPDATED PATCH] fix memory corruption from misinterpreted bad_inode_ops return values Arjan van de Ven
2007-01-04 19:23 Mikael Pettersson
[not found] <7zo1U-ht-9@gated-at.bofh.it>
[not found] ` <7zoEG-1kW-19@gated-at.bofh.it>
[not found] ` <7zF2R-1wJ-33@gated-at.bofh.it>
[not found] ` <7zFvU-2p5-21@gated-at.bofh.it>
[not found] ` <7zFFr-2AP-1@gated-at.bofh.it>
[not found] ` <7zFYY-31i-19@gated-at.bofh.it>
[not found] ` <7zGie-3Ji-17@gated-at.bofh.it>
[not found] ` <7zGif-3Ji-21@gated-at.bofh.it>
[not found] ` <7zGBC-49g-39@gated-at.bofh.it>
[not found] ` <7zHnX-5rJ-25@gated-at.bofh.it>
[not found] ` <7zI0B-6x2-5@gated-at.bofh.it>
[not found] ` <7zI0B-6x2-3@gated-at.bofh.it>
[not found] ` <7zIak-6JF-15@gated-at.bofh.it>
[not found] ` <7zIak-6JF-13@gated-at.bofh.it>
2007-01-05 16:33 ` Bodo Eggert
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=Pine.LNX.4.64.0701070311450.5666@localhost.localdomain \
--to=zippel@linux-m68k.org \
--cc=akpm@osdl.org \
--cc=linux-kernel@vger.kernel.org \
--cc=sandeen@redhat.com \
--cc=torvalds@osdl.org \
--cc=viro@ftp.linux.org.uk \
--cc=viro@zeniv.linux.org.uk \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®