Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

isdn: use non-racy method for proc entries creation

Use proc_create()/proc_create_data() to make sure that ->proc_fops and ->data
be setup before gluing PDE to main tree.

Add correct ->owner to proc_fops to fix reading/module unloading race.

Signed-off-by: Denis V. Lunev <den@openvz.org>
Acked-by: Karsten Keil <kkeil@suse.de>
Cc: Alexey Dobriyan <adobriyan@gmail.com>
Cc: "Eric W. Biederman" <ebiederm@xmission.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>

authored by

Denis V. Lunev and committed by
Linus Torvalds
ac41cfd1 a95609cb

+22 -32
+10 -14
drivers/isdn/capi/kcapi_proc.c
··· 114 114 } 115 115 116 116 static const struct file_operations proc_controller_ops = { 117 + .owner = THIS_MODULE, 117 118 .open = seq_controller_open, 118 119 .read = seq_read, 119 120 .llseek = seq_lseek, ··· 122 121 }; 123 122 124 123 static const struct file_operations proc_contrstats_ops = { 124 + .owner = THIS_MODULE, 125 125 .open = seq_contrstats_open, 126 126 .read = seq_read, 127 127 .llseek = seq_lseek, ··· 221 219 } 222 220 223 221 static const struct file_operations proc_applications_ops = { 222 + .owner = THIS_MODULE, 224 223 .open = seq_applications_open, 225 224 .read = seq_read, 226 225 .llseek = seq_lseek, ··· 229 226 }; 230 227 231 228 static const struct file_operations proc_applstats_ops = { 229 + .owner = THIS_MODULE, 232 230 .open = seq_applstats_open, 233 231 .read = seq_read, 234 232 .llseek = seq_lseek, 235 233 .release = seq_release, 236 234 }; 237 - 238 - static void 239 - create_seq_entry(char *name, mode_t mode, const struct file_operations *f) 240 - { 241 - struct proc_dir_entry *entry; 242 - entry = create_proc_entry(name, mode, NULL); 243 - if (entry) 244 - entry->proc_fops = f; 245 - } 246 235 247 236 // --------------------------------------------------------------------------- 248 237 ··· 278 283 } 279 284 280 285 static const struct file_operations proc_driver_ops = { 286 + .owner = THIS_MODULE, 281 287 .open = seq_capi_driver_open, 282 288 .read = seq_read, 283 289 .llseek = seq_lseek, ··· 292 296 { 293 297 proc_mkdir("capi", NULL); 294 298 proc_mkdir("capi/controllers", NULL); 295 - create_seq_entry("capi/controller", 0, &proc_controller_ops); 296 - create_seq_entry("capi/contrstats", 0, &proc_contrstats_ops); 297 - create_seq_entry("capi/applications", 0, &proc_applications_ops); 298 - create_seq_entry("capi/applstats", 0, &proc_applstats_ops); 299 - create_seq_entry("capi/driver", 0, &proc_driver_ops); 299 + proc_create("capi/controller", 0, NULL, &proc_controller_ops); 300 + proc_create("capi/contrstats", 0, NULL, &proc_contrstats_ops); 301 + proc_create("capi/applications", 0, NULL, &proc_applications_ops); 302 + proc_create("capi/applstats", 0, NULL, &proc_applstats_ops); 303 + proc_create("capi/driver", 0, NULL, &proc_driver_ops); 300 304 } 301 305 302 306 void __exit
+2 -3
drivers/isdn/divert/divert_procfs.c
··· 288 288 isdn_proc_entry = proc_mkdir("isdn", init_net.proc_net); 289 289 if (!isdn_proc_entry) 290 290 return (-1); 291 - isdn_divert_entry = create_proc_entry("divert", S_IFREG | S_IRUGO, isdn_proc_entry); 291 + isdn_divert_entry = proc_create("divert", S_IFREG | S_IRUGO, 292 + isdn_proc_entry, &isdn_fops); 292 293 if (!isdn_divert_entry) { 293 294 remove_proc_entry("isdn", init_net.proc_net); 294 295 return (-1); 295 296 } 296 - isdn_divert_entry->proc_fops = &isdn_fops; 297 - isdn_divert_entry->owner = THIS_MODULE; 298 297 #endif /* CONFIG_PROC_FS */ 299 298 300 299 return (0);
+2 -6
drivers/isdn/hardware/eicon/divasproc.c
··· 125 125 126 126 int create_divas_proc(void) 127 127 { 128 - divas_proc_entry = create_proc_entry(divas_proc_name, 129 - S_IFREG | S_IRUGO, 130 - proc_net_eicon); 128 + proc_create(divas_proc_name, S_IFREG | S_IRUGO, proc_net_eicon, 129 + &divas_fops); 131 130 if (!divas_proc_entry) 132 131 return (0); 133 - 134 - divas_proc_entry->proc_fops = &divas_fops; 135 - divas_proc_entry->owner = THIS_MODULE; 136 132 137 133 return (1); 138 134 }
+4 -5
drivers/isdn/hysdn/hysdn_procconf.c
··· 370 370 /******************************************************/ 371 371 static const struct file_operations conf_fops = 372 372 { 373 + .owner = THIS_MODULE, 373 374 .llseek = no_llseek, 374 375 .read = hysdn_conf_read, 375 376 .write = hysdn_conf_write, ··· 403 402 while (card) { 404 403 405 404 sprintf(conf_name, "%s%d", PROC_CONF_BASENAME, card->myid); 406 - if ((card->procconf = (void *) create_proc_entry(conf_name, 407 - S_IFREG | S_IRUGO | S_IWUSR, 408 - hysdn_proc_entry)) != NULL) { 409 - ((struct proc_dir_entry *) card->procconf)->proc_fops = &conf_fops; 410 - ((struct proc_dir_entry *) card->procconf)->owner = THIS_MODULE; 405 + if ((card->procconf = (void *) proc_create(conf_name, 406 + S_IFREG | S_IRUGO | S_IWUSR, 407 + hysdn_proc_entry)) != NULL) { 411 408 hysdn_proclog_init(card); /* init the log file entry */ 412 409 } 413 410 card = card->next; /* next entry */
+4 -4
drivers/isdn/hysdn/hysdn_proclog.c
··· 380 380 /**************************************************/ 381 381 static const struct file_operations log_fops = 382 382 { 383 + .owner = THIS_MODULE, 383 384 .llseek = no_llseek, 384 385 .read = hysdn_log_read, 385 386 .write = hysdn_log_write, ··· 403 402 404 403 if ((pd = kzalloc(sizeof(struct procdata), GFP_KERNEL)) != NULL) { 405 404 sprintf(pd->log_name, "%s%d", PROC_LOG_BASENAME, card->myid); 406 - if ((pd->log = create_proc_entry(pd->log_name, S_IFREG | S_IRUGO | S_IWUSR, hysdn_proc_entry)) != NULL) { 407 - pd->log->proc_fops = &log_fops; 408 - pd->log->owner = THIS_MODULE; 409 - } 405 + pd->log = proc_create(pd->log_name, 406 + S_IFREG | S_IRUGO | S_IWUSR, hysdn_proc_entry, 407 + &log_fops); 410 408 411 409 init_waitqueue_head(&(pd->rd_queue)); 412 410