* Converting struct timer_list callback argument to struct timer_list *
@ 2017-08-30 23:39 Kees Cook
2017-08-31 20:13 ` Thomas Gleixner
2017-09-01 10:08 ` Christoph Hellwig
0 siblings, 2 replies; 10+ messages in thread
From: Kees Cook @ 2017-08-30 23:39 UTC (permalink / raw)
To: Thomas Gleixner, Christoph Hellwig; +Cc: LKML
Hi,
I'm working on converting all callbacks of struct timer_list into
taking the struct timer_list * that triggered the callback (instead of
the timer_list.data field), as done for hrtimers, work queues, etc.
Doing this has a number of benefits including actual type checking
(via container_of(), etc) instead of blind type casts, and getting rid
of the .data field which is used in security flaw exploits[1].
I've got the series well on its way, though I think I have something
like 400 users remaining, and they're getting less trivial to convert.
:)
The series goes through several phases of conversion. The series is
here to browse:
https://git.kernel.org/pub/scm/linux/kernel/git/kees/linux.git/log/?h=kspp/timer/20170830
Replace open-coded variants of setup_timer() with actual setup_timer() calls:
coccinelle: Improve setup_timer.cocci matching
Run setup_timer.cocci
timer: Remove init_timer_pinned_deferrable() in favor of
setup_pinned_deferrable_timer()
timer: Remove init_timer_on_stack() in favor of setup_timer_on_stack()
timer: Remove init_timer_pinned() in favor of setup_pinned_timer()
timer: Remove init_timer_deferrable() in favor of setup_deferrable_timer()
Remove little or unused macros, with the goal of removing to ability
to statically define the .data field:
timer: Remove users of TIMER_DEFERRED_INITIALIZER
timer: Remove users of TIMER_INITIALIZER
timer: Remove unused static initializer macros
timer: Remove users of expire and data arguments to DEFINE_TIMER
timer: Remove expires and data arguments from DEFINE_TIMER
timer: Remove expires argument from __TIMER_INITIALIZER()
Fix usages of setup_timer() that Coccinelle can't reason about:
timer: Remove meaningless .data/.function assignments
timer: Collapse cross-function single-assignment .data into setup_timer()
timer: Additional init_timer() -> setup_timer() conversions
Eliminate all open-coded usage of the .data field:
usb/phy-isp1301-omap: Remove .data assignment
media/i2c/tc358743: Initialize timer
scsi/aic7xxx: Clean up timer usage
timer: Fix incorrect casts in callbacks
net/core: Collapse redundant sk_timer callback data assignments
s390/char/sclp: Use separate static data field with with static timer
sparc/led: Use separate static data field with with static timer
mips/sgi-ip32: Use separate static data field with with static timer
mips/sgi-ip22: Use separate static data field with with static timer
net/atm/mpc: Use separate static data field with with static timer
staging/comedi/das16: Make timer initialization unconditional
usb/gadget/snps_udc_core: Move timer initialization earlier
infiniband/rdmavt: Remove redundant timer initialization
scsi/bnx2i: Initialize timer
appletalk: Remove unneeded synchronization
timer: Switch to testing for .function instead of .data
Create temporary casts for function and data arguments so
setup_timer() will take both old and new style function and data
arguments:
timer: Temporarily explicitly cast all callback functions
Convert all DEFINE_TIMER users to taking struct timer_list *:
coccinelle: Add define_timer.cocci
timer: Switch DEFINE_TIMER callbacks to struct timer_list *
Create TIMER_CONTAINER() help for new style callbacks:
timer: Add helper for container_of() usage on callbacks
Convert timer users that Coccinelle can't reason about:
scsi/ipr: Convert timer callbacks to use TIMER_CONATINER
staging/wilc1000: Convert timer callbacks to use TIMER_CONTAINER
amifloppy: Convert timer callbacks to use TIMER_CONTAINER
net/irda: Convert timer callbacks to use TIMER_CONTAINER
led/ledtrig-heartbeat: Convert callback to use TIMER_CONTAINER
kthread: Convert callback to use TIMER_CONTAINER
workqueue: Convert callback to use TIMER_CONTAINER
scsi/pmcraid: Convert callbacks to use TIMER_CONTAINER
net/decnet: Convert callback to use TIMER_CONTAINER
net/lapb: Convert callbacks to use TIMER_CONTAINER
net/mac80211/mesh_plink: Convert callback to use TIMER_CONTAINER
fs/nilfs2: Convert callback to use TIMER_CONTAINER
net/rose: Convert callbacks to use TIMER_CONTAINER
scsi/sas: Convert callback to use TIMER_CONTAINER
media/saa7146: Convert callback to use TIMER_CONTAINER
net/irda-usb: Convert callback to use TIMER_CONTAINER
input: Convert callbacks to use TIMER_CONTAINER
net/irda/bfin_sir: Convert callback to use TIMER_CONTAINER
ALSA: sh: aica: Convert callback to use TIMER_CONTAINER
s390/tape: Convert callback to use TIMER_CONTAINER
net/ti/tlan: Convert callback to use TIMER_CONTAINER
net/wireless/ray_cs: Convert callback to use TIMER_CONTAINER
firewire: Convert callback to use TIMER_CONTAINER
sound/pci/asihpi: Convert callback to use TIMER_CONTAINER
isdn/hisax: Convert callback to use TIMER_CONTAINER
net/hamradio/6pack: Convert callback to use TIMER_CONTAINER
pci/ehp_hpc: Convert callback to use TIMER_CONTAINER
net/usb/usbnet: Convert callback to use TIMER_CONTAINER
tty/sysrq: Convert callback to use TIMER_CONTAINER
scsi/cxgbi: Convert callback to use TIMER_CONTAINER
block/laptop_mode: Convert callback to use TIMER_CONTAINER
libata: Convert callback to use TIMER_CONTAINER
staging: rtl8723bs: Refactor timers to use setup_timer()
staging: rtl8723bs: Convert callback to use TIMER_CONTAINER
staging: rtl8712: Convert callbacks to use TIMER_CONTAINER
staging: rtl8188eu: Convert callbacks to use TIMER_CONTAINER
sound/core: Convert callbacks to use TIMER_CONTAINER
fs/ncpfs: Convert callback to use TIMER_CONTAINER
block/aoe: Convert callbacks to use TIMER_CONTAINER
Rename .data field to .cb_data just to find any remaining .data users
that allmodconfig misses but 0-day can find (the above conversions
could be rearranged to do all .data-using conversions first, then this
patch, then the rest of the conversions):
timer: Rename timer_list.data to timer_list.cb_data
Add Coccinelle script to perform "easy" conversions of timer callbacks:
coccinelle: Add new timer_list handling scripts
timer: Mass-convert timer_list callbacks to use TIMER_CONTAINER
timer: setup_deferrable_timer conversions
timer: setup_pinned_timer conversions
Which gets me to here:
747 files changed, 3363 insertions(+), 3410 deletions(-)
And current builds with the forced casts removed show about 400 more
call sites to fix...
Does this look alright, and should some of this go into -next right
now, just to get some of the clean-ups into the tree? (Basically,
everything before "timer: Temporarily explicitly cast all callback
functions")
Thanks!
-Kees
[1] https://lwn.net/Articles/731082/
--
Kees Cook
Pixel Security
^ permalink raw reply [flat|nested] 10+ messages in thread* Re: Converting struct timer_list callback argument to struct timer_list * 2017-08-30 23:39 Converting struct timer_list callback argument to struct timer_list * Kees Cook @ 2017-08-31 20:13 ` Thomas Gleixner 2017-08-31 23:32 ` Kees Cook 2017-09-01 10:08 ` Christoph Hellwig 1 sibling, 1 reply; 10+ messages in thread From: Thomas Gleixner @ 2017-08-31 20:13 UTC (permalink / raw) To: Kees Cook; +Cc: Christoph Hellwig, LKML On Wed, 30 Aug 2017, Kees Cook wrote: > Which gets me to here: > 747 files changed, 3363 insertions(+), 3410 deletions(-) > > And current builds with the forced casts removed show about 400 more > call sites to fix... That's a herculean task. Chapeau! > Does this look alright, Very well done. I like the temporary typecast trick. > and should some of this go into -next right > now, just to get some of the clean-ups into the tree? (Basically, > everything before "timer: Temporarily explicitly cast all callback > functions") Yes, just get that part in now. Thanks, tglx ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: Converting struct timer_list callback argument to struct timer_list * 2017-08-31 20:13 ` Thomas Gleixner @ 2017-08-31 23:32 ` Kees Cook 0 siblings, 0 replies; 10+ messages in thread From: Kees Cook @ 2017-08-31 23:32 UTC (permalink / raw) To: Thomas Gleixner; +Cc: Christoph Hellwig, LKML On Thu, Aug 31, 2017 at 1:13 PM, Thomas Gleixner <tglx@linutronix.de> wrote: > On Wed, 30 Aug 2017, Kees Cook wrote: >> Which gets me to here: >> 747 files changed, 3363 insertions(+), 3410 deletions(-) >> >> And current builds with the forced casts removed show about 400 more >> call sites to fix... > > That's a herculean task. Chapeau! Coccinelle has helped a lot, but yeah, not a small conversion! :P >> Does this look alright, > > Very well done. I like the temporary typecast trick. Okay, good. Since there's no sensible type checking here already, it didn't seem _worse_. :) >> and should some of this go into -next right >> now, just to get some of the clean-ups into the tree? (Basically, >> everything before "timer: Temporarily explicitly cast all callback >> functions") > > Yes, just get that part in now. Okay, I've sent the first 31 patches your way just now. I'll keep grinding away at the rest... -Kees -- Kees Cook Pixel Security ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: Converting struct timer_list callback argument to struct timer_list * 2017-08-30 23:39 Converting struct timer_list callback argument to struct timer_list * Kees Cook 2017-08-31 20:13 ` Thomas Gleixner @ 2017-09-01 10:08 ` Christoph Hellwig 2017-09-01 10:21 ` Thomas Gleixner 1 sibling, 1 reply; 10+ messages in thread From: Christoph Hellwig @ 2017-09-01 10:08 UTC (permalink / raw) To: Kees Cook; +Cc: Thomas Gleixner, Christoph Hellwig, LKML Good work! I just think that the TIMER_CONTAINER name is revolting. The usual name for such a helper fitting other uses like lists and rbtrees would be timer_entry, and that also reads much better. ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: Converting struct timer_list callback argument to struct timer_list * 2017-09-01 10:08 ` Christoph Hellwig @ 2017-09-01 10:21 ` Thomas Gleixner 2017-09-01 10:44 ` Christoph Hellwig 0 siblings, 1 reply; 10+ messages in thread From: Thomas Gleixner @ 2017-09-01 10:21 UTC (permalink / raw) To: Christoph Hellwig; +Cc: Kees Cook, LKML On Fri, 1 Sep 2017, Christoph Hellwig wrote: > Good work! > > I just think that the TIMER_CONTAINER name is revolting. > > The usual name for such a helper fitting other uses like lists > and rbtrees would be timer_entry, and that also reads much better. I think the plan is to remove that thing afterward, because then the callback function is: void func(struct timer_list *timer) So I don't mind the ugly name as it should be simply removed once the tree is converted over. Thanks, tglx ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: Converting struct timer_list callback argument to struct timer_list * 2017-09-01 10:21 ` Thomas Gleixner @ 2017-09-01 10:44 ` Christoph Hellwig 2017-09-01 16:24 ` Kees Cook 0 siblings, 1 reply; 10+ messages in thread From: Christoph Hellwig @ 2017-09-01 10:44 UTC (permalink / raw) To: Thomas Gleixner; +Cc: Christoph Hellwig, Kees Cook, LKML On Fri, Sep 01, 2017 at 12:21:46PM +0200, Thomas Gleixner wrote: > On Fri, 1 Sep 2017, Christoph Hellwig wrote: > > > Good work! > > > > I just think that the TIMER_CONTAINER name is revolting. > > > > The usual name for such a helper fitting other uses like lists > > and rbtrees would be timer_entry, and that also reads much better. > > I think the plan is to remove that thing afterward, because then the > callback function is: > > void func(struct timer_list *timer) > > So I don't mind the ugly name as it should be simply removed once the tree > is converted over. Well, we can't just remove it, we could just replace it with container_of(). lists and rbtrees just keep their list_entry and rb_entry wrappers for timer_of, so we could save us the additional churn by naming it timer_entry and just keeping it. ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: Converting struct timer_list callback argument to struct timer_list * 2017-09-01 10:44 ` Christoph Hellwig @ 2017-09-01 16:24 ` Kees Cook 2017-09-03 7:37 ` Christoph Hellwig 0 siblings, 1 reply; 10+ messages in thread From: Kees Cook @ 2017-09-01 16:24 UTC (permalink / raw) To: Christoph Hellwig; +Cc: Thomas Gleixner, LKML On Fri, Sep 1, 2017 at 3:44 AM, Christoph Hellwig <hch@infradead.org> wrote: > On Fri, Sep 01, 2017 at 12:21:46PM +0200, Thomas Gleixner wrote: >> On Fri, 1 Sep 2017, Christoph Hellwig wrote: >> >> > Good work! >> > >> > I just think that the TIMER_CONTAINER name is revolting. >> > >> > The usual name for such a helper fitting other uses like lists >> > and rbtrees would be timer_entry, and that also reads much better. >> >> I think the plan is to remove that thing afterward, because then the >> callback function is: >> >> void func(struct timer_list *timer) >> >> So I don't mind the ugly name as it should be simply removed once the tree >> is converted over. The removed casts would be the (TIMER_FUNC_TYPE) and (TIMER_DATA_TYPE) casts. TIMER_CONTAINER is ugly, yes. I can rework that. > Well, we can't just remove it, we could just replace it with > container_of(). lists and rbtrees just keep their list_entry and > rb_entry wrappers for timer_of, so we could save us the additional > churn by naming it timer_entry and just keeping it. These examples are: #define list_entry(ptr, type, member) container_of(ptr, type, member) #define rb_entry(ptr, type, member) container_of(ptr, type, member) The use of a "timer_entry()" at the start of callbacks repeats the struct name, which I find irritating (and it usually results in split lines). For example: #define timer_entry(ptr, type, member) container_of(ptr, type, member) -static void snd_card_asihpi_timer_function(unsigned long data) +static void snd_card_asihpi_timer_function(struct timer_list *t) { - struct snd_card_asihpi_pcm *dpcm = (struct snd_card_asihpi_pcm *)data; + struct snd_card_asihpi_pcm *dpcm = + timer_entry(t, struct snd_card_asihpi_pcm, timer); I prefer to tie this directly to the variable, so how about renaming TIMER_CONTAINER to timer_of(): #define timer_of(var, callback_timer, timer_fieldname) \ container_of(callback_timer, typeof(*var), timer_fieldname) -static void snd_card_asihpi_timer_function(unsigned long data) +static void snd_card_asihpi_timer_function(struct timer_list *t) { - struct snd_card_asihpi_pcm *dpcm = (struct snd_card_asihpi_pcm *)data; + struct snd_card_asihpi_pcm *dpcm = timer_of(dpcm, t, timer); If not, I can just go the timer_entry() way, it just means I have to split a lot of lines. -Kees -- Kees Cook Pixel Security ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: Converting struct timer_list callback argument to struct timer_list * 2017-09-01 16:24 ` Kees Cook @ 2017-09-03 7:37 ` Christoph Hellwig 2017-09-03 20:18 ` Kees Cook 0 siblings, 1 reply; 10+ messages in thread From: Christoph Hellwig @ 2017-09-03 7:37 UTC (permalink / raw) To: Kees Cook; +Cc: Christoph Hellwig, Thomas Gleixner, LKML On Fri, Sep 01, 2017 at 09:24:22AM -0700, Kees Cook wrote: > #define list_entry(ptr, type, member) container_of(ptr, type, member) > #define rb_entry(ptr, type, member) container_of(ptr, type, member) > > The use of a "timer_entry()" at the start of callbacks repeats the > struct name, which I find irritating (and it usually results in split > lines). For example: > > #define timer_entry(ptr, type, member) container_of(ptr, type, member) > > -static void snd_card_asihpi_timer_function(unsigned long data) > +static void snd_card_asihpi_timer_function(struct timer_list *t) > { > - struct snd_card_asihpi_pcm *dpcm = (struct snd_card_asihpi_pcm *)data; > + struct snd_card_asihpi_pcm *dpcm = > + timer_entry(t, struct > snd_card_asihpi_pcm, timer); > > I prefer to tie this directly to the variable, so how about renaming > TIMER_CONTAINER to timer_of(): The TIMER_CONTAINER semantics are more useful indeed, and I which we'd have a general purpose variant of that. But I was complaining about the name anyway. timer_of sounds ok, but timer_entry still sounds a bit more descriptive. As for the split lines: you'll generally get a lot of these, even TIMER_CONTAINER has a quite a few. I generally prefer to move everything right of the = to the next line as that becomes a lot more redable. ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: Converting struct timer_list callback argument to struct timer_list * 2017-09-03 7:37 ` Christoph Hellwig @ 2017-09-03 20:18 ` Kees Cook 2017-09-04 6:07 ` Christoph Hellwig 0 siblings, 1 reply; 10+ messages in thread From: Kees Cook @ 2017-09-03 20:18 UTC (permalink / raw) To: Christoph Hellwig; +Cc: Thomas Gleixner, LKML On Sun, Sep 3, 2017 at 12:37 AM, Christoph Hellwig <hch@infradead.org> wrote: > On Fri, Sep 01, 2017 at 09:24:22AM -0700, Kees Cook wrote: >> #define list_entry(ptr, type, member) container_of(ptr, type, member) >> #define rb_entry(ptr, type, member) container_of(ptr, type, member) >> >> The use of a "timer_entry()" at the start of callbacks repeats the >> struct name, which I find irritating (and it usually results in split >> lines). For example: >> >> #define timer_entry(ptr, type, member) container_of(ptr, type, member) >> >> -static void snd_card_asihpi_timer_function(unsigned long data) >> +static void snd_card_asihpi_timer_function(struct timer_list *t) >> { >> - struct snd_card_asihpi_pcm *dpcm = (struct snd_card_asihpi_pcm *)data; >> + struct snd_card_asihpi_pcm *dpcm = >> + timer_entry(t, struct >> snd_card_asihpi_pcm, timer); >> >> I prefer to tie this directly to the variable, so how about renaming >> TIMER_CONTAINER to timer_of(): > > The TIMER_CONTAINER semantics are more useful indeed, and I which > we'd have a general purpose variant of that. But I was complaining > about the name anyway. timer_of sounds ok, but timer_entry still sounds > a bit more descriptive. As for the split lines: you'll generally > get a lot of these, even TIMER_CONTAINER has a quite a few. I generally > prefer to move everything right of the = to the next line as that > becomes a lot more redable. It feels weird to have different semantics from container_of() too, so I'll probably just switch everything around to be like all the others, in that they are just direct wrappers around container_of()... I'll settle on something and switch everything over. I'm down to about 200 more callsites. :) Found a missed pattern that coccinelle could handle which caught about 1/3rd of my earlier 300ish... -Kees -- Kees Cook Pixel Security ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: Converting struct timer_list callback argument to struct timer_list * 2017-09-03 20:18 ` Kees Cook @ 2017-09-04 6:07 ` Christoph Hellwig 0 siblings, 0 replies; 10+ messages in thread From: Christoph Hellwig @ 2017-09-04 6:07 UTC (permalink / raw) To: Kees Cook; +Cc: Christoph Hellwig, Thomas Gleixner, LKML On Sun, Sep 03, 2017 at 01:18:44PM -0700, Kees Cook wrote: > It feels weird to have different semantics from container_of() too, so > I'll probably just switch everything around to be like all the others, > in that they are just direct wrappers around container_of()... I'll > settle on something and switch everything over. I really like the idea of passing in a variable and not the type, though. Maybe we need to add a new generic helper for that, I just can't think of a good name. ^ permalink raw reply [flat|nested] 10+ messages in thread
end of thread, other threads:[~2017-09-04 6:07 UTC | newest] Thread overview: 10+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2017-08-30 23:39 Converting struct timer_list callback argument to struct timer_list * Kees Cook 2017-08-31 20:13 ` Thomas Gleixner 2017-08-31 23:32 ` Kees Cook 2017-09-01 10:08 ` Christoph Hellwig 2017-09-01 10:21 ` Thomas Gleixner 2017-09-01 10:44 ` Christoph Hellwig 2017-09-01 16:24 ` Kees Cook 2017-09-03 7:37 ` Christoph Hellwig 2017-09-03 20:18 ` Kees Cook 2017-09-04 6:07 ` Christoph Hellwig
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox
Powered by JetHome