aboutsummaryrefslogtreecommitdiffstats
path: root/include/linux
diff options
context:
space:
mode:
authorGrant Likely <grant.likely@linaro.org>2014-11-03 10:15:35 -0500
committerGrant Likely <grant.likely@linaro.org>2014-11-04 05:19:48 -0500
commita87fa1d81a9fb5e9adca9820e16008c40ad09f33 (patch)
treea6938084b9639c2aa54b3f7cc5fd0bebbbf3097d /include/linux
parent0df1f2487d2f0d04703f142813d53615d62a1da4 (diff)
of: Fix overflow bug in string property parsing functions
The string property read helpers will run off the end of the buffer if it is handed a malformed string property. Rework the parsers to make sure that doesn't happen. At the same time add new test cases to make sure the functions behave themselves. The original implementations of of_property_read_string_index() and of_property_count_strings() both open-coded the same block of parsing code, each with it's own subtly different bugs. The fix here merges functions into a single helper and makes the original functions static inline wrappers around the helper. One non-bugfix aspect of this patch is the addition of a new wrapper, of_property_read_string_array(). The new wrapper is needed by the device_properties feature that Rafael is working on and planning to merge for v3.19. The implementation is identical both with and without the new static inline wrapper, so it just got left in to reduce the churn on the header file. Signed-off-by: Grant Likely <grant.likely@linaro.org> Cc: Rafael J. Wysocki <rafael.j.wysocki@intel.com> Cc: Mika Westerberg <mika.westerberg@linux.intel.com> Cc: Rob Herring <robh+dt@kernel.org> Cc: Arnd Bergmann <arnd@arndb.de> Cc: Darren Hart <darren.hart@intel.com> Cc: <stable@vger.kernel.org> # v3.3+: Drop selftest hunks that don't apply
Diffstat (limited to 'include/linux')
-rw-r--r--include/linux/of.h84
1 files changed, 70 insertions, 14 deletions
diff --git a/include/linux/of.h b/include/linux/of.h
index 6545e7aec7bb..29f0adc5f3e4 100644
--- a/include/linux/of.h
+++ b/include/linux/of.h
@@ -267,14 +267,12 @@ extern int of_property_read_u64(const struct device_node *np,
267extern int of_property_read_string(struct device_node *np, 267extern int of_property_read_string(struct device_node *np,
268 const char *propname, 268 const char *propname,
269 const char **out_string); 269 const char **out_string);
270extern int of_property_read_string_index(struct device_node *np,
271 const char *propname,
272 int index, const char **output);
273extern int of_property_match_string(struct device_node *np, 270extern int of_property_match_string(struct device_node *np,
274 const char *propname, 271 const char *propname,
275 const char *string); 272 const char *string);
276extern int of_property_count_strings(struct device_node *np, 273extern int of_property_read_string_helper(struct device_node *np,
277 const char *propname); 274 const char *propname,
275 const char **out_strs, size_t sz, int index);
278extern int of_device_is_compatible(const struct device_node *device, 276extern int of_device_is_compatible(const struct device_node *device,
279 const char *); 277 const char *);
280extern int of_device_is_available(const struct device_node *device); 278extern int of_device_is_available(const struct device_node *device);
@@ -486,15 +484,9 @@ static inline int of_property_read_string(struct device_node *np,
486 return -ENOSYS; 484 return -ENOSYS;
487} 485}
488 486
489static inline int of_property_read_string_index(struct device_node *np, 487static inline int of_property_read_string_helper(struct device_node *np,
490 const char *propname, int index, 488 const char *propname,
491 const char **out_string) 489 const char **out_strs, size_t sz, int index)
492{
493 return -ENOSYS;
494}
495
496static inline int of_property_count_strings(struct device_node *np,
497 const char *propname)
498{ 490{
499 return -ENOSYS; 491 return -ENOSYS;
500} 492}
@@ -668,6 +660,70 @@ static inline int of_property_count_u64_elems(const struct device_node *np,
668} 660}
669 661
670/** 662/**
663 * of_property_read_string_array() - Read an array of strings from a multiple
664 * strings property.
665 * @np: device node from which the property value is to be read.
666 * @propname: name of the property to be searched.
667 * @out_strs: output array of string pointers.
668 * @sz: number of array elements to read.
669 *
670 * Search for a property in a device tree node and retrieve a list of
671 * terminated string values (pointer to data, not a copy) in that property.
672 *
673 * If @out_strs is NULL, the number of strings in the property is returned.
674 */
675static inline int of_property_read_string_array(struct device_node *np,
676 const char *propname, const char **out_strs,
677 size_t sz)
678{
679 return of_property_read_string_helper(np, propname, out_strs, sz, 0);
680}
681
682/**
683 * of_property_count_strings() - Find and return the number of strings from a
684 * multiple strings property.
685 * @np: device node from which the property value is to be read.
686 * @propname: name of the property to be searched.
687 *
688 * Search for a property in a device tree node and retrieve the number of null
689 * terminated string contain in it. Returns the number of strings on
690 * success, -EINVAL if the property does not exist, -ENODATA if property
691 * does not have a value, and -EILSEQ if the string is not null-terminated
692 * within the length of the property data.
693 */
694static inline int of_property_count_strings(struct device_node *np,
695 const char *propname)
696{
697 return of_property_read_string_helper(np, propname, NULL, 0, 0);
698}
699
700/**
701 * of_property_read_string_index() - Find and read a string from a multiple
702 * strings property.
703 * @np: device node from which the property value is to be read.
704 * @propname: name of the property to be searched.
705 * @index: index of the string in the list of strings
706 * @out_string: pointer to null terminated return string, modified only if
707 * return value is 0.
708 *
709 * Search for a property in a device tree node and retrieve a null
710 * terminated string value (pointer to data, not a copy) in the list of strings
711 * contained in that property.
712 * Returns 0 on success, -EINVAL if the property does not exist, -ENODATA if
713 * property does not have a value, and -EILSEQ if the string is not
714 * null-terminated within the length of the property data.
715 *
716 * The out_string pointer is modified only if a valid string can be decoded.
717 */
718static inline int of_property_read_string_index(struct device_node *np,
719 const char *propname,
720 int index, const char **output)
721{
722 int rc = of_property_read_string_helper(np, propname, output, 1, index);
723 return rc < 0 ? rc : 0;
724}
725
726/**
671 * of_property_read_bool - Findfrom a property 727 * of_property_read_bool - Findfrom a property
672 * @np: device node from which the property value is to be read. 728 * @np: device node from which the property value is to be read.
673 * @propname: name of the property to be searched. 729 * @propname: name of the property to be searched.