diff options
author | Alexey Dobriyan <adobriyan@gmail.com> | 2009-03-25 15:48:06 -0400 |
---|---|---|
committer | Alexey Dobriyan <adobriyan@gmail.com> | 2009-03-30 17:14:44 -0400 |
commit | 99b76233803beab302123d243eea9e41149804f3 (patch) | |
tree | 398178210fe66845ccd6fa4258ba762a87e023ad /sound/core/info.c | |
parent | 3dec7f59c370c7b58184d63293c3dc984d475840 (diff) |
proc 2/2: remove struct proc_dir_entry::owner
Setting ->owner as done currently (pde->owner = THIS_MODULE) is racy
as correctly noted at bug #12454. Someone can lookup entry with NULL
->owner, thus not pinning enything, and release it later resulting
in module refcount underflow.
We can keep ->owner and supply it at registration time like ->proc_fops
and ->data.
But this leaves ->owner as easy-manipulative field (just one C assignment)
and somebody will forget to unpin previous/pin current module when
switching ->owner. ->proc_fops is declared as "const" which should give
some thoughts.
->read_proc/->write_proc were just fixed to not require ->owner for
protection.
rmmod'ed directories will be empty and return "." and ".." -- no harm.
And directories with tricky enough readdir and lookup shouldn't be modular.
We definitely don't want such modular code.
Removing ->owner will also make PDE smaller.
So, let's nuke it.
Kudos to Jeff Layton for reminding about this, let's say, oversight.
http://bugzilla.kernel.org/show_bug.cgi?id=12454
Signed-off-by: Alexey Dobriyan <adobriyan@gmail.com>
Diffstat (limited to 'sound/core/info.c')
-rw-r--r-- | sound/core/info.c | 31 |
1 files changed, 2 insertions, 29 deletions
diff --git a/sound/core/info.c b/sound/core/info.c index 70fa87189f36..35df614f6c55 100644 --- a/sound/core/info.c +++ b/sound/core/info.c | |||
@@ -154,11 +154,6 @@ EXPORT_SYMBOL(snd_seq_root); | |||
154 | struct snd_info_entry *snd_oss_root; | 154 | struct snd_info_entry *snd_oss_root; |
155 | #endif | 155 | #endif |
156 | 156 | ||
157 | static inline void snd_info_entry_prepare(struct proc_dir_entry *de) | ||
158 | { | ||
159 | de->owner = THIS_MODULE; | ||
160 | } | ||
161 | |||
162 | static void snd_remove_proc_entry(struct proc_dir_entry *parent, | 157 | static void snd_remove_proc_entry(struct proc_dir_entry *parent, |
163 | struct proc_dir_entry *de) | 158 | struct proc_dir_entry *de) |
164 | { | 159 | { |
@@ -522,32 +517,11 @@ static const struct file_operations snd_info_entry_operations = | |||
522 | .release = snd_info_entry_release, | 517 | .release = snd_info_entry_release, |
523 | }; | 518 | }; |
524 | 519 | ||
525 | /** | ||
526 | * snd_create_proc_entry - create a procfs entry | ||
527 | * @name: the name of the proc file | ||
528 | * @mode: the file permission bits, S_Ixxx | ||
529 | * @parent: the parent proc-directory entry | ||
530 | * | ||
531 | * Creates a new proc file entry with the given name and permission | ||
532 | * on the given directory. | ||
533 | * | ||
534 | * Returns the pointer of new instance or NULL on failure. | ||
535 | */ | ||
536 | static struct proc_dir_entry *snd_create_proc_entry(const char *name, mode_t mode, | ||
537 | struct proc_dir_entry *parent) | ||
538 | { | ||
539 | struct proc_dir_entry *p; | ||
540 | p = create_proc_entry(name, mode, parent); | ||
541 | if (p) | ||
542 | snd_info_entry_prepare(p); | ||
543 | return p; | ||
544 | } | ||
545 | |||
546 | int __init snd_info_init(void) | 520 | int __init snd_info_init(void) |
547 | { | 521 | { |
548 | struct proc_dir_entry *p; | 522 | struct proc_dir_entry *p; |
549 | 523 | ||
550 | p = snd_create_proc_entry("asound", S_IFDIR | S_IRUGO | S_IXUGO, NULL); | 524 | p = create_proc_entry("asound", S_IFDIR | S_IRUGO | S_IXUGO, NULL); |
551 | if (p == NULL) | 525 | if (p == NULL) |
552 | return -ENOMEM; | 526 | return -ENOMEM; |
553 | snd_proc_root = p; | 527 | snd_proc_root = p; |
@@ -974,12 +948,11 @@ int snd_info_register(struct snd_info_entry * entry) | |||
974 | return -ENXIO; | 948 | return -ENXIO; |
975 | root = entry->parent == NULL ? snd_proc_root : entry->parent->p; | 949 | root = entry->parent == NULL ? snd_proc_root : entry->parent->p; |
976 | mutex_lock(&info_mutex); | 950 | mutex_lock(&info_mutex); |
977 | p = snd_create_proc_entry(entry->name, entry->mode, root); | 951 | p = create_proc_entry(entry->name, entry->mode, root); |
978 | if (!p) { | 952 | if (!p) { |
979 | mutex_unlock(&info_mutex); | 953 | mutex_unlock(&info_mutex); |
980 | return -ENOMEM; | 954 | return -ENOMEM; |
981 | } | 955 | } |
982 | p->owner = entry->module; | ||
983 | if (!S_ISDIR(entry->mode)) | 956 | if (!S_ISDIR(entry->mode)) |
984 | p->proc_fops = &snd_info_entry_operations; | 957 | p->proc_fops = &snd_info_entry_operations; |
985 | p->size = entry->size; | 958 | p->size = entry->size; |