• Alexey Dobriyan's avatar
    Fix rmmod/read/write races in /proc entries · 786d7e16
    Alexey Dobriyan authored
    Fix following races:
    ===========================================
    1. Write via ->write_proc sleeps in copy_from_user(). Module disappears
       meanwhile. Or, more generically, system call done on /proc file, method
       supplied by module is called, module dissapeares meanwhile.
    
       pde = create_proc_entry()
       if (!pde)
    	return -ENOMEM;
       pde->write_proc = ...
    				open
    				write
    				copy_from_user
       pde = create_proc_entry();
       if (!pde) {
    	remove_proc_entry();
    	return -ENOMEM;
    	/* module unloaded */
       }
    				*boom*
    ==========================================
    2. bogo-revoke aka proc_kill_inodes()
    
      remove_proc_entry		vfs_read
      proc_kill_inodes		[check ->f_op validness]
    				[check ->f_op->read validness]
    				[verify_area, security permissions checks]
    	->f_op = NULL;
    				if (file->f_op->read)
    					/* ->f_op dereference, boom */
    
    NOTE, NOTE, NOTE: file_operations are proxied for regular files only. Let's
    see how this scheme behaves, then extend if needed for directories.
    Directories creators in /proc only set ->owner for them, so proxying for
    directories may be unneeded.
    
    NOTE, NOTE, NOTE: methods being proxied are ->llseek, ->read, ->write,
    ->poll, ->unlocked_ioctl, ->ioctl, ->compat_ioctl, ->open, ->release.
    If your in-tree module uses something else, yell on me. Full audit pending.
    
    [akpm@linux-foundation.org: build fix]
    Signed-off-by: default avatarAlexey Dobriyan <adobriyan@sw.ru>
    Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
    Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
    786d7e16
inode.c 10.2 KB