diff options
| author | Linus Torvalds <torvalds@linux-foundation.org> | 2018-10-26 11:42:25 -0400 |
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2018-10-26 11:42:25 -0400 |
| commit | 26873acacbdbb4e4b444f5dd28dcc4853f0e8ba2 (patch) | |
| tree | e52dc2be053540bc67abe3faa1c4570f6a61b306 | |
| parent | 9703fc8caf36ac65dca1538b23dd137de0b53233 (diff) | |
| parent | 09d1ea1c7309c8ca91151778bb3efe514f2e03ed (diff) | |
Merge tag 'driver-core-4.20-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/driver-core
Pull driver core updates from Greg KH:
"Here is a small number of driver core patches for 4.20-rc1.
Not much happened here this merge window, only a very tiny number of
patches that do:
- add BUS_ATTR_WO() for use by drivers
- component error path fixes
- kernfs range check fix
- other tiny error path fixes and const changes
All of these have been in linux-next with no reported issues for a
while"
* tag 'driver-core-4.20-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/driver-core:
devres: provide devm_kstrdup_const()
mm: move is_kernel_rodata() to asm-generic/sections.h
devres: constify p in devm_kfree()
driver core: add BUS_ATTR_WO() macro
kernfs: Fix range checks in kernfs_get_target_path
component: fix loop condition to call unbind() if bind() fails
drivers/base/devtmpfs.c: don't pretend path is const in delete_path
kernfs: update comment about kernfs_path() return value
| -rw-r--r-- | drivers/base/component.c | 6 | ||||
| -rw-r--r-- | drivers/base/devres.c | 36 | ||||
| -rw-r--r-- | drivers/base/devtmpfs.c | 2 | ||||
| -rw-r--r-- | fs/kernfs/symlink.c | 5 | ||||
| -rw-r--r-- | include/asm-generic/sections.h | 14 | ||||
| -rw-r--r-- | include/linux/device.h | 6 | ||||
| -rw-r--r-- | include/linux/kernfs.h | 9 | ||||
| -rw-r--r-- | mm/util.c | 7 |
8 files changed, 66 insertions, 19 deletions
diff --git a/drivers/base/component.c b/drivers/base/component.c index 8946dfee4768..e8d676fad0c9 100644 --- a/drivers/base/component.c +++ b/drivers/base/component.c | |||
| @@ -536,9 +536,9 @@ int component_bind_all(struct device *master_dev, void *data) | |||
| 536 | } | 536 | } |
| 537 | 537 | ||
| 538 | if (ret != 0) { | 538 | if (ret != 0) { |
| 539 | for (; i--; ) | 539 | for (; i > 0; i--) |
| 540 | if (!master->match->compare[i].duplicate) { | 540 | if (!master->match->compare[i - 1].duplicate) { |
| 541 | c = master->match->compare[i].component; | 541 | c = master->match->compare[i - 1].component; |
| 542 | component_unbind(c, master, data); | 542 | component_unbind(c, master, data); |
| 543 | } | 543 | } |
| 544 | } | 544 | } |
diff --git a/drivers/base/devres.c b/drivers/base/devres.c index f98a097e73f2..4aaf00d2098b 100644 --- a/drivers/base/devres.c +++ b/drivers/base/devres.c | |||
| @@ -11,6 +11,8 @@ | |||
| 11 | #include <linux/slab.h> | 11 | #include <linux/slab.h> |
| 12 | #include <linux/percpu.h> | 12 | #include <linux/percpu.h> |
| 13 | 13 | ||
| 14 | #include <asm/sections.h> | ||
| 15 | |||
| 14 | #include "base.h" | 16 | #include "base.h" |
| 15 | 17 | ||
| 16 | struct devres_node { | 18 | struct devres_node { |
| @@ -823,6 +825,28 @@ char *devm_kstrdup(struct device *dev, const char *s, gfp_t gfp) | |||
| 823 | EXPORT_SYMBOL_GPL(devm_kstrdup); | 825 | EXPORT_SYMBOL_GPL(devm_kstrdup); |
| 824 | 826 | ||
| 825 | /** | 827 | /** |
| 828 | * devm_kstrdup_const - resource managed conditional string duplication | ||
| 829 | * @dev: device for which to duplicate the string | ||
| 830 | * @s: the string to duplicate | ||
| 831 | * @gfp: the GFP mask used in the kmalloc() call when allocating memory | ||
| 832 | * | ||
| 833 | * Strings allocated by devm_kstrdup_const will be automatically freed when | ||
| 834 | * the associated device is detached. | ||
| 835 | * | ||
| 836 | * RETURNS: | ||
| 837 | * Source string if it is in .rodata section otherwise it falls back to | ||
| 838 | * devm_kstrdup. | ||
| 839 | */ | ||
| 840 | const char *devm_kstrdup_const(struct device *dev, const char *s, gfp_t gfp) | ||
| 841 | { | ||
| 842 | if (is_kernel_rodata((unsigned long)s)) | ||
| 843 | return s; | ||
| 844 | |||
| 845 | return devm_kstrdup(dev, s, gfp); | ||
| 846 | } | ||
| 847 | EXPORT_SYMBOL_GPL(devm_kstrdup_const); | ||
| 848 | |||
| 849 | /** | ||
| 826 | * devm_kvasprintf - Allocate resource managed space and format a string | 850 | * devm_kvasprintf - Allocate resource managed space and format a string |
| 827 | * into that. | 851 | * into that. |
| 828 | * @dev: Device to allocate memory for | 852 | * @dev: Device to allocate memory for |
| @@ -885,11 +909,19 @@ EXPORT_SYMBOL_GPL(devm_kasprintf); | |||
| 885 | * | 909 | * |
| 886 | * Free memory allocated with devm_kmalloc(). | 910 | * Free memory allocated with devm_kmalloc(). |
| 887 | */ | 911 | */ |
| 888 | void devm_kfree(struct device *dev, void *p) | 912 | void devm_kfree(struct device *dev, const void *p) |
| 889 | { | 913 | { |
| 890 | int rc; | 914 | int rc; |
| 891 | 915 | ||
| 892 | rc = devres_destroy(dev, devm_kmalloc_release, devm_kmalloc_match, p); | 916 | /* |
| 917 | * Special case: pointer to a string in .rodata returned by | ||
| 918 | * devm_kstrdup_const(). | ||
| 919 | */ | ||
| 920 | if (unlikely(is_kernel_rodata((unsigned long)p))) | ||
| 921 | return; | ||
| 922 | |||
| 923 | rc = devres_destroy(dev, devm_kmalloc_release, | ||
| 924 | devm_kmalloc_match, (void *)p); | ||
| 893 | WARN_ON(rc); | 925 | WARN_ON(rc); |
| 894 | } | 926 | } |
| 895 | EXPORT_SYMBOL_GPL(devm_kfree); | 927 | EXPORT_SYMBOL_GPL(devm_kfree); |
diff --git a/drivers/base/devtmpfs.c b/drivers/base/devtmpfs.c index f7768077e817..b93fc862d365 100644 --- a/drivers/base/devtmpfs.c +++ b/drivers/base/devtmpfs.c | |||
| @@ -252,7 +252,7 @@ static int dev_rmdir(const char *name) | |||
| 252 | 252 | ||
| 253 | static int delete_path(const char *nodepath) | 253 | static int delete_path(const char *nodepath) |
| 254 | { | 254 | { |
| 255 | const char *path; | 255 | char *path; |
| 256 | int err = 0; | 256 | int err = 0; |
| 257 | 257 | ||
| 258 | path = kstrdup(nodepath, GFP_KERNEL); | 258 | path = kstrdup(nodepath, GFP_KERNEL); |
diff --git a/fs/kernfs/symlink.c b/fs/kernfs/symlink.c index 305b220af45d..162f43b80c84 100644 --- a/fs/kernfs/symlink.c +++ b/fs/kernfs/symlink.c | |||
| @@ -72,6 +72,9 @@ static int kernfs_get_target_path(struct kernfs_node *parent, | |||
| 72 | if (base == kn) | 72 | if (base == kn) |
| 73 | break; | 73 | break; |
| 74 | 74 | ||
| 75 | if ((s - path) + 3 >= PATH_MAX) | ||
| 76 | return -ENAMETOOLONG; | ||
| 77 | |||
| 75 | strcpy(s, "../"); | 78 | strcpy(s, "../"); |
| 76 | s += 3; | 79 | s += 3; |
| 77 | base = base->parent; | 80 | base = base->parent; |
| @@ -88,7 +91,7 @@ static int kernfs_get_target_path(struct kernfs_node *parent, | |||
| 88 | if (len < 2) | 91 | if (len < 2) |
| 89 | return -EINVAL; | 92 | return -EINVAL; |
| 90 | len--; | 93 | len--; |
| 91 | if ((s - path) + len > PATH_MAX) | 94 | if ((s - path) + len >= PATH_MAX) |
| 92 | return -ENAMETOOLONG; | 95 | return -ENAMETOOLONG; |
| 93 | 96 | ||
| 94 | /* reverse fillup of target string from target to base */ | 97 | /* reverse fillup of target string from target to base */ |
diff --git a/include/asm-generic/sections.h b/include/asm-generic/sections.h index 849cd8eb5ca0..d79abca81a52 100644 --- a/include/asm-generic/sections.h +++ b/include/asm-generic/sections.h | |||
| @@ -141,4 +141,18 @@ static inline bool init_section_intersects(void *virt, size_t size) | |||
| 141 | return memory_intersects(__init_begin, __init_end, virt, size); | 141 | return memory_intersects(__init_begin, __init_end, virt, size); |
| 142 | } | 142 | } |
| 143 | 143 | ||
| 144 | /** | ||
| 145 | * is_kernel_rodata - checks if the pointer address is located in the | ||
| 146 | * .rodata section | ||
| 147 | * | ||
| 148 | * @addr: address to check | ||
| 149 | * | ||
| 150 | * Returns: true if the address is located in .rodata, false otherwise. | ||
| 151 | */ | ||
| 152 | static inline bool is_kernel_rodata(unsigned long addr) | ||
| 153 | { | ||
| 154 | return addr >= (unsigned long)__start_rodata && | ||
| 155 | addr < (unsigned long)__end_rodata; | ||
| 156 | } | ||
| 157 | |||
| 144 | #endif /* _ASM_GENERIC_SECTIONS_H_ */ | 158 | #endif /* _ASM_GENERIC_SECTIONS_H_ */ |
diff --git a/include/linux/device.h b/include/linux/device.h index 90224e75ade4..1b25c7a43f4c 100644 --- a/include/linux/device.h +++ b/include/linux/device.h | |||
| @@ -55,6 +55,8 @@ struct bus_attribute { | |||
| 55 | struct bus_attribute bus_attr_##_name = __ATTR_RW(_name) | 55 | struct bus_attribute bus_attr_##_name = __ATTR_RW(_name) |
| 56 | #define BUS_ATTR_RO(_name) \ | 56 | #define BUS_ATTR_RO(_name) \ |
| 57 | struct bus_attribute bus_attr_##_name = __ATTR_RO(_name) | 57 | struct bus_attribute bus_attr_##_name = __ATTR_RO(_name) |
| 58 | #define BUS_ATTR_WO(_name) \ | ||
| 59 | struct bus_attribute bus_attr_##_name = __ATTR_WO(_name) | ||
| 58 | 60 | ||
| 59 | extern int __must_check bus_create_file(struct bus_type *, | 61 | extern int __must_check bus_create_file(struct bus_type *, |
| 60 | struct bus_attribute *); | 62 | struct bus_attribute *); |
| @@ -692,8 +694,10 @@ static inline void *devm_kcalloc(struct device *dev, | |||
| 692 | { | 694 | { |
| 693 | return devm_kmalloc_array(dev, n, size, flags | __GFP_ZERO); | 695 | return devm_kmalloc_array(dev, n, size, flags | __GFP_ZERO); |
| 694 | } | 696 | } |
| 695 | extern void devm_kfree(struct device *dev, void *p); | 697 | extern void devm_kfree(struct device *dev, const void *p); |
| 696 | extern char *devm_kstrdup(struct device *dev, const char *s, gfp_t gfp) __malloc; | 698 | extern char *devm_kstrdup(struct device *dev, const char *s, gfp_t gfp) __malloc; |
| 699 | extern const char *devm_kstrdup_const(struct device *dev, | ||
| 700 | const char *s, gfp_t gfp); | ||
| 697 | extern void *devm_kmemdup(struct device *dev, const void *src, size_t len, | 701 | extern void *devm_kmemdup(struct device *dev, const void *src, size_t len, |
| 698 | gfp_t gfp); | 702 | gfp_t gfp); |
| 699 | 703 | ||
diff --git a/include/linux/kernfs.h b/include/linux/kernfs.h index 814643f7ee52..5b36b1287a5a 100644 --- a/include/linux/kernfs.h +++ b/include/linux/kernfs.h | |||
| @@ -477,10 +477,11 @@ static inline void kernfs_init(void) { } | |||
| 477 | * @buf: buffer to copy @kn's name into | 477 | * @buf: buffer to copy @kn's name into |
| 478 | * @buflen: size of @buf | 478 | * @buflen: size of @buf |
| 479 | * | 479 | * |
| 480 | * Builds and returns the full path of @kn in @buf of @buflen bytes. The | 480 | * If @kn is NULL result will be "(null)". |
| 481 | * path is built from the end of @buf so the returned pointer usually | 481 | * |
| 482 | * doesn't match @buf. If @buf isn't long enough, @buf is nul terminated | 482 | * Returns the length of the full path. If the full length is equal to or |
| 483 | * and %NULL is returned. | 483 | * greater than @buflen, @buf contains the truncated path with the trailing |
| 484 | * '\0'. On error, -errno is returned. | ||
| 484 | */ | 485 | */ |
| 485 | static inline int kernfs_path(struct kernfs_node *kn, char *buf, size_t buflen) | 486 | static inline int kernfs_path(struct kernfs_node *kn, char *buf, size_t buflen) |
| 486 | { | 487 | { |
| @@ -15,17 +15,10 @@ | |||
| 15 | #include <linux/vmalloc.h> | 15 | #include <linux/vmalloc.h> |
| 16 | #include <linux/userfaultfd_k.h> | 16 | #include <linux/userfaultfd_k.h> |
| 17 | 17 | ||
| 18 | #include <asm/sections.h> | ||
| 19 | #include <linux/uaccess.h> | 18 | #include <linux/uaccess.h> |
| 20 | 19 | ||
| 21 | #include "internal.h" | 20 | #include "internal.h" |
| 22 | 21 | ||
| 23 | static inline int is_kernel_rodata(unsigned long addr) | ||
| 24 | { | ||
| 25 | return addr >= (unsigned long)__start_rodata && | ||
| 26 | addr < (unsigned long)__end_rodata; | ||
| 27 | } | ||
| 28 | |||
| 29 | /** | 22 | /** |
| 30 | * kfree_const - conditionally free memory | 23 | * kfree_const - conditionally free memory |
| 31 | * @x: pointer to the memory | 24 | * @x: pointer to the memory |
