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

Configure Feed

Select the types of activity you want to include in your feed.

Merge tag 'driver-core-3.16-rc4' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/driver-core

Pull driver core fixes from Greg KH:
"Well, one drivercore fix for kernfs to resolve a reported issue with
sysfs files being updated from atomic contexts, and another lz4 bugfix
for testing potential buffer overflows"

* tag 'driver-core-3.16-rc4' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/driver-core:
lz4: add overrun checks to lz4_uncompress_unknownoutputsize()
kernfs: kernfs_notify() must be useable from non-sleepable contexts

+61 -15
+55 -14
fs/kernfs/file.c
··· 39 39 struct list_head files; /* goes through kernfs_open_file.list */ 40 40 }; 41 41 42 + /* 43 + * kernfs_notify() may be called from any context and bounces notifications 44 + * through a work item. To minimize space overhead in kernfs_node, the 45 + * pending queue is implemented as a singly linked list of kernfs_nodes. 46 + * The list is terminated with the self pointer so that whether a 47 + * kernfs_node is on the list or not can be determined by testing the next 48 + * pointer for NULL. 49 + */ 50 + #define KERNFS_NOTIFY_EOL ((void *)&kernfs_notify_list) 51 + 52 + static DEFINE_SPINLOCK(kernfs_notify_lock); 53 + static struct kernfs_node *kernfs_notify_list = KERNFS_NOTIFY_EOL; 54 + 42 55 static struct kernfs_open_file *kernfs_of(struct file *file) 43 56 { 44 57 return ((struct seq_file *)file->private_data)->private; ··· 796 783 return DEFAULT_POLLMASK|POLLERR|POLLPRI; 797 784 } 798 785 799 - /** 800 - * kernfs_notify - notify a kernfs file 801 - * @kn: file to notify 802 - * 803 - * Notify @kn such that poll(2) on @kn wakes up. 804 - */ 805 - void kernfs_notify(struct kernfs_node *kn) 786 + static void kernfs_notify_workfn(struct work_struct *work) 806 787 { 807 - struct kernfs_root *root = kernfs_root(kn); 788 + struct kernfs_node *kn; 808 789 struct kernfs_open_node *on; 809 790 struct kernfs_super_info *info; 810 - unsigned long flags; 811 - 812 - if (WARN_ON(kernfs_type(kn) != KERNFS_FILE)) 791 + repeat: 792 + /* pop one off the notify_list */ 793 + spin_lock_irq(&kernfs_notify_lock); 794 + kn = kernfs_notify_list; 795 + if (kn == KERNFS_NOTIFY_EOL) { 796 + spin_unlock_irq(&kernfs_notify_lock); 813 797 return; 798 + } 799 + kernfs_notify_list = kn->attr.notify_next; 800 + kn->attr.notify_next = NULL; 801 + spin_unlock_irq(&kernfs_notify_lock); 814 802 815 803 /* kick poll */ 816 - spin_lock_irqsave(&kernfs_open_node_lock, flags); 804 + spin_lock_irq(&kernfs_open_node_lock); 817 805 818 806 on = kn->attr.open; 819 807 if (on) { ··· 822 808 wake_up_interruptible(&on->poll); 823 809 } 824 810 825 - spin_unlock_irqrestore(&kernfs_open_node_lock, flags); 811 + spin_unlock_irq(&kernfs_open_node_lock); 826 812 827 813 /* kick fsnotify */ 828 814 mutex_lock(&kernfs_mutex); 829 815 830 - list_for_each_entry(info, &root->supers, node) { 816 + list_for_each_entry(info, &kernfs_root(kn)->supers, node) { 831 817 struct inode *inode; 832 818 struct dentry *dentry; 833 819 ··· 847 833 } 848 834 849 835 mutex_unlock(&kernfs_mutex); 836 + kernfs_put(kn); 837 + goto repeat; 838 + } 839 + 840 + /** 841 + * kernfs_notify - notify a kernfs file 842 + * @kn: file to notify 843 + * 844 + * Notify @kn such that poll(2) on @kn wakes up. Maybe be called from any 845 + * context. 846 + */ 847 + void kernfs_notify(struct kernfs_node *kn) 848 + { 849 + static DECLARE_WORK(kernfs_notify_work, kernfs_notify_workfn); 850 + unsigned long flags; 851 + 852 + if (WARN_ON(kernfs_type(kn) != KERNFS_FILE)) 853 + return; 854 + 855 + spin_lock_irqsave(&kernfs_notify_lock, flags); 856 + if (!kn->attr.notify_next) { 857 + kernfs_get(kn); 858 + kn->attr.notify_next = kernfs_notify_list; 859 + kernfs_notify_list = kn; 860 + schedule_work(&kernfs_notify_work); 861 + } 862 + spin_unlock_irqrestore(&kernfs_notify_lock, flags); 850 863 } 851 864 EXPORT_SYMBOL_GPL(kernfs_notify); 852 865
+1
include/linux/kernfs.h
··· 91 91 const struct kernfs_ops *ops; 92 92 struct kernfs_open_node *open; 93 93 loff_t size; 94 + struct kernfs_node *notify_next; /* for kernfs_notify() */ 94 95 }; 95 96 96 97 /*
+5 -1
lib/lz4/lz4_decompress.c
··· 192 192 int s = 255; 193 193 while ((ip < iend) && (s == 255)) { 194 194 s = *ip++; 195 + if (unlikely(length > (size_t)(length + s))) 196 + goto _output_error; 195 197 length += s; 196 198 } 197 199 } ··· 234 232 if (length == ML_MASK) { 235 233 while (ip < iend) { 236 234 int s = *ip++; 235 + if (unlikely(length > (size_t)(length + s))) 236 + goto _output_error; 237 237 length += s; 238 238 if (s == 255) 239 239 continue; ··· 288 284 289 285 /* write overflow error detected */ 290 286 _output_error: 291 - return (int) (-(((char *) ip) - source)); 287 + return -1; 292 288 } 293 289 294 290 int lz4_decompress(const unsigned char *src, size_t *src_len,