Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update my fork with torvalds #4

Merged
merged 70 commits into from
Nov 12, 2014
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
70 commits
Select commit Hold shift + click to select a range
9599815
usb: dwc2: gadget: fix enumeration issues
mszyprow Oct 20, 2014
f4fd36b
arm64: psci: fix cpu_suspend to check idle state type for index
Oct 30, 2014
1912528
USB: kobil_sct: fix non-atomic allocation in write path
jhovold Oct 29, 2014
e681286
USB: opticon: fix non-atomic allocation in write path
jhovold Oct 29, 2014
cf84a69
USB: cdc-acm: add device id for GW Instek AFG-2225
jhovold Oct 27, 2014
24cb450
cdc-acm: ensure that termios get set when the port is activated
jimparis Oct 30, 2014
90a646c
usb: Do not allow usb_alloc_streams on unconfigured devices
jwrdegoede Oct 1, 2014
93c9bf4
usb-storage: handle a skipped data phase
AlanStern Oct 31, 2014
aee0ce3
uas: Add US_FL_NO_ATA_1X quirk for 1 more Seagate model
jwrdegoede Oct 31, 2014
cee2448
USB: HWA: fix a warning message
Oct 29, 2014
2391eac
xhci: Disable streams on Asmedia 1042 xhci controllers
jwrdegoede Oct 28, 2014
673029f
uas: Add NO_ATA_1X for VIA VL711 devices
jwrdegoede Oct 9, 2014
cd6e245
usb: Remove references to non-existent PLAT_S5P symbol
Oct 7, 2014
ec5633b
usb: storage: fix build warnings !CONFIG_PM
Oct 1, 2014
2e06923
MAINTAINERS: Remove duplicate entry for usbip driver
einonm Oct 19, 2014
876af5d
USB: quirks: enable device-qualifier quirk for another Elan touchscreen
Oct 9, 2014
d749947
USB: quirks: enable device-qualifier quirk for yet another Elan touch…
Oct 9, 2014
b45abac
xhci: no switching back on non-ULT Haswell
Oct 27, 2014
d1d9548
uas: Add US_FL_NO_ATA_1X quirk for 2 more Seagate models
jwrdegoede Oct 23, 2014
01ed67d
usb: core: need to call usb_phy_notify_connect after device setup
Oct 17, 2014
b2108f1
usb: core: notify disconnection when core detects disconnect
Nov 4, 2014
c72c553
ARM: imx: clk-vf610: define PLL's clock tree
agners Oct 27, 2014
a87fa1d
of: Fix overflow bug in string property parsing functions
glikely Nov 3, 2014
89fbec5
ARM: imx: Fix the removal of CONFIG_SPI option
Nov 4, 2014
6e5aafb
Btrfs: fix kfree on list_head in btrfs_lookup_csums_range error cleanup
masoncl Nov 4, 2014
83b3d53
Merge tag 'imx-fixes-3.18-2' of git://git.kernel.org/pub/scm/linux/ke…
olofj Nov 5, 2014
8bcdd92
MAINTAINERS: update bcm2835 entry
swarren Nov 5, 2014
97b56be
arm64: compat: Enable bpf syscall
ctmarinas Nov 5, 2014
2d39ad6
arm64: defconfig: update defconfig for 3.18
wildea01 Nov 5, 2014
4a53d3a
staging:iio:ad5933: Fix NULL pointer deref when enabling buffer
larsclausen Sep 25, 2014
97fb303
staging:iio:ad5933: Drop "raw" from channel names
larsclausen Sep 25, 2014
c6b4cac
iio: st_sensors: Fix buffer copy
rvdgracht Sep 29, 2014
4748119
iio: adc: mxs-lradc: Disable the clock on probe failure
Oct 4, 2014
03045bc
iio: tsl4531: Fix compiler error when CONFIG_PM_OPS is not defined
Oct 20, 2014
25afffe
io: accel: kxcjk-1013: Fix iio_event_spec direction
Oct 10, 2014
f73cde6
iio: as3935: allocate correct iio_device size
gmccollister Oct 31, 2014
e105547
staging:iio:ade7758: Fix NULL pointer deref when enabling buffer
larsclausen Nov 4, 2014
79fa64e
staging:iio:ade7758: Fix check if channels are enabled in prenable
larsclausen Nov 4, 2014
b598aac
staging:iio:ade7758: Remove "raw" from channel name
larsclausen Nov 4, 2014
ab699bc
ARM: dts: vf610: add SD node to cosmic dts
olofj Nov 5, 2014
ac0225f
Revert "storage: Replace magic number with define in usb_stor_euscsi_…
gregkh Nov 5, 2014
4473d05
USB: cdc-acm: only raise DTR on transitions from B0
jhovold Nov 5, 2014
bce20b2
Merge tag 'iio-fixes-for-3.18b' of git://git.kernel.org/pub/scm/linux…
gregkh Nov 5, 2014
a88098b
USB: storage: Fix timeout in usb_stor_euscsi_init() and usb_stor_huaw…
M-a-r-k Nov 4, 2014
f20531a
phy: omap-usb2: Enable runtime PM of omap-usb2 phy properly
Nov 4, 2014
547039e
serial: Fix divide-by-zero fault in uart_get_divisor()
peterhurley Oct 16, 2014
37b1645
tty: Fix high cpu load if tty is unreleaseable
peterhurley Oct 16, 2014
494c1ea
tty: Prevent "read/write wait queue active!" log flooding
peterhurley Oct 16, 2014
5305e4d
dma: edma: move device registration to platform code
arndb Oct 24, 2014
cd92208
tty: serial: 8250_mtk: Fix quot calculation
mbgg Oct 9, 2014
9e326f7
tty/vt: don't set font mappings on vc not supporting this
ideak Oct 2, 2014
7e12e67
serial: of-serial: fix uninitialized kmalloc variable
Oct 21, 2014
5002921
Merge tag 'usb-serial-3.18-rc4' of git://git.kernel.org/pub/scm/linux…
gregkh Nov 6, 2014
c4dc304
tty: Fix pty master poll() after slave closes v2
Oct 10, 2014
e5452dd
Merge tag 'fixes-for-v3.18-rc4' of git://git.kernel.org/pub/scm/linux…
gregkh Nov 6, 2014
2a8cdfd
USB: cdc-acm: add quirk for control-line state requests
jhovold Nov 6, 2014
e4a60d1
sysfs: driver core: Fix glue dir race condition by gdp_mutex
YijingWang Nov 7, 2014
1910195
USB: Update default usb-storage delay_use value in kernel-parameters.txt
M-a-r-k Nov 4, 2014
9c60269
tiny: reverse logic for DISABLE_DEV_COREDUMP
aristeu Oct 16, 2014
cd3d9ea
tiny: rename ENABLE_DEV_COREDUMP to ALLOW_DEV_COREDUMP
jmberg-intel Oct 30, 2014
92c9e0c
ARM: dts: zynq: Enable PL clocks for Parallella
afaerber Nov 6, 2014
b942791
Merge tag 'usb-3.18-rc4' of git://git.kernel.org/pub/scm/linux/kernel…
torvalds Nov 9, 2014
45a4c07
Merge tag 'tty-3.18-rc4' of git://git.kernel.org/pub/scm/linux/kernel…
torvalds Nov 9, 2014
86a7a16
Merge tag 'staging-3.18-rc4' of git://git.kernel.org/pub/scm/linux/ke…
torvalds Nov 9, 2014
0b0c7db
Merge tag 'driver-core-3.18-rc4' of git://git.kernel.org/pub/scm/linu…
torvalds Nov 9, 2014
c4c23fb
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel…
torvalds Nov 9, 2014
a315780
Merge branch 'devicetree/merge' of git://git.kernel.org/pub/scm/linux…
torvalds Nov 9, 2014
b1f368b
Merge tag 'armsoc-for-rc4' of git://git.kernel.org/pub/scm/linux/kern…
torvalds Nov 9, 2014
ee867cf
Merge tag 'arm64-fixes' of git://git.kernel.org/pub/scm/linux/kernel/…
torvalds Nov 9, 2014
206c5f6
Linux 3.18-rc4
torvalds Nov 9, 2014
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
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 <[email protected]>
Cc: Rafael J. Wysocki <[email protected]>
Cc: Mika Westerberg <[email protected]>
Cc: Rob Herring <[email protected]>
Cc: Arnd Bergmann <[email protected]>
Cc: Darren Hart <[email protected]>
Cc: <[email protected]>  # v3.3+: Drop selftest hunks that don't apply
  • Loading branch information
glikely committed Nov 4, 2014
commit a87fa1d81a9fb5e9adca9820e16008c40ad09f33
88 changes: 22 additions & 66 deletions drivers/of/base.c
Original file line number Diff line number Diff line change
Expand Up @@ -1279,52 +1279,6 @@ int of_property_read_string(struct device_node *np, const char *propname,
}
EXPORT_SYMBOL_GPL(of_property_read_string);

/**
* of_property_read_string_index - Find and read a string from a multiple
* strings property.
* @np: device node from which the property value is to be read.
* @propname: name of the property to be searched.
* @index: index of the string in the list of strings
* @out_string: pointer to null terminated return string, modified only if
* return value is 0.
*
* Search for a property in a device tree node and retrieve a null
* terminated string value (pointer to data, not a copy) in the list of strings
* contained in that property.
* Returns 0 on success, -EINVAL if the property does not exist, -ENODATA if
* property does not have a value, and -EILSEQ if the string is not
* null-terminated within the length of the property data.
*
* The out_string pointer is modified only if a valid string can be decoded.
*/
int of_property_read_string_index(struct device_node *np, const char *propname,
int index, const char **output)
{
struct property *prop = of_find_property(np, propname, NULL);
int i = 0;
size_t l = 0, total = 0;
const char *p;

if (!prop)
return -EINVAL;
if (!prop->value)
return -ENODATA;
if (strnlen(prop->value, prop->length) >= prop->length)
return -EILSEQ;

p = prop->value;

for (i = 0; total < prop->length; total += l, p += l) {
l = strlen(p) + 1;
if (i++ == index) {
*output = p;
return 0;
}
}
return -ENODATA;
}
EXPORT_SYMBOL_GPL(of_property_read_string_index);

/**
* of_property_match_string() - Find string in a list and return index
* @np: pointer to node containing string list property
Expand All @@ -1351,7 +1305,7 @@ int of_property_match_string(struct device_node *np, const char *propname,
end = p + prop->length;

for (i = 0; p < end; i++, p += l) {
l = strlen(p) + 1;
l = strnlen(p, end - p) + 1;
if (p + l > end)
return -EILSEQ;
pr_debug("comparing %s with %s\n", string, p);
Expand All @@ -1363,39 +1317,41 @@ int of_property_match_string(struct device_node *np, const char *propname,
EXPORT_SYMBOL_GPL(of_property_match_string);

/**
* of_property_count_strings - Find and return the number of strings from a
* multiple strings property.
* of_property_read_string_util() - Utility helper for parsing string properties
* @np: device node from which the property value is to be read.
* @propname: name of the property to be searched.
* @out_strs: output array of string pointers.
* @sz: number of array elements to read.
* @skip: Number of strings to skip over at beginning of list.
*
* Search for a property in a device tree node and retrieve the number of null
* terminated string contain in it. Returns the number of strings on
* success, -EINVAL if the property does not exist, -ENODATA if property
* does not have a value, and -EILSEQ if the string is not null-terminated
* within the length of the property data.
* Don't call this function directly. It is a utility helper for the
* of_property_read_string*() family of functions.
*/
int of_property_count_strings(struct device_node *np, const char *propname)
int of_property_read_string_helper(struct device_node *np, const char *propname,
const char **out_strs, size_t sz, int skip)
{
struct property *prop = of_find_property(np, propname, NULL);
int i = 0;
size_t l = 0, total = 0;
const char *p;
int l = 0, i = 0;
const char *p, *end;

if (!prop)
return -EINVAL;
if (!prop->value)
return -ENODATA;
if (strnlen(prop->value, prop->length) >= prop->length)
return -EILSEQ;

p = prop->value;
end = p + prop->length;

for (i = 0; total < prop->length; total += l, p += l, i++)
l = strlen(p) + 1;

return i;
for (i = 0; p < end && (!out_strs || i < skip + sz); i++, p += l) {
l = strnlen(p, end - p) + 1;
if (p + l > end)
return -EILSEQ;
if (out_strs && i >= skip)
*out_strs++ = p;
}
i -= skip;
return i <= 0 ? -ENODATA : i;
}
EXPORT_SYMBOL_GPL(of_property_count_strings);
EXPORT_SYMBOL_GPL(of_property_read_string_helper);

void of_print_phandle_args(const char *msg, const struct of_phandle_args *args)
{
Expand Down
66 changes: 60 additions & 6 deletions drivers/of/selftest.c
Original file line number Diff line number Diff line change
Expand Up @@ -339,8 +339,9 @@ static void __init of_selftest_parse_phandle_with_args(void)
selftest(rc == -EINVAL, "expected:%i got:%i\n", -EINVAL, rc);
}

static void __init of_selftest_property_match_string(void)
static void __init of_selftest_property_string(void)
{
const char *strings[4];
struct device_node *np;
int rc;

Expand All @@ -357,13 +358,66 @@ static void __init of_selftest_property_match_string(void)
rc = of_property_match_string(np, "phandle-list-names", "third");
selftest(rc == 2, "third expected:0 got:%i\n", rc);
rc = of_property_match_string(np, "phandle-list-names", "fourth");
selftest(rc == -ENODATA, "unmatched string; rc=%i", rc);
selftest(rc == -ENODATA, "unmatched string; rc=%i\n", rc);
rc = of_property_match_string(np, "missing-property", "blah");
selftest(rc == -EINVAL, "missing property; rc=%i", rc);
selftest(rc == -EINVAL, "missing property; rc=%i\n", rc);
rc = of_property_match_string(np, "empty-property", "blah");
selftest(rc == -ENODATA, "empty property; rc=%i", rc);
selftest(rc == -ENODATA, "empty property; rc=%i\n", rc);
rc = of_property_match_string(np, "unterminated-string", "blah");
selftest(rc == -EILSEQ, "unterminated string; rc=%i", rc);
selftest(rc == -EILSEQ, "unterminated string; rc=%i\n", rc);

/* of_property_count_strings() tests */
rc = of_property_count_strings(np, "string-property");
selftest(rc == 1, "Incorrect string count; rc=%i\n", rc);
rc = of_property_count_strings(np, "phandle-list-names");
selftest(rc == 3, "Incorrect string count; rc=%i\n", rc);
rc = of_property_count_strings(np, "unterminated-string");
selftest(rc == -EILSEQ, "unterminated string; rc=%i\n", rc);
rc = of_property_count_strings(np, "unterminated-string-list");
selftest(rc == -EILSEQ, "unterminated string array; rc=%i\n", rc);

/* of_property_read_string_index() tests */
rc = of_property_read_string_index(np, "string-property", 0, strings);
selftest(rc == 0 && !strcmp(strings[0], "foobar"), "of_property_read_string_index() failure; rc=%i\n", rc);
strings[0] = NULL;
rc = of_property_read_string_index(np, "string-property", 1, strings);
selftest(rc == -ENODATA && strings[0] == NULL, "of_property_read_string_index() failure; rc=%i\n", rc);
rc = of_property_read_string_index(np, "phandle-list-names", 0, strings);
selftest(rc == 0 && !strcmp(strings[0], "first"), "of_property_read_string_index() failure; rc=%i\n", rc);
rc = of_property_read_string_index(np, "phandle-list-names", 1, strings);
selftest(rc == 0 && !strcmp(strings[0], "second"), "of_property_read_string_index() failure; rc=%i\n", rc);
rc = of_property_read_string_index(np, "phandle-list-names", 2, strings);
selftest(rc == 0 && !strcmp(strings[0], "third"), "of_property_read_string_index() failure; rc=%i\n", rc);
strings[0] = NULL;
rc = of_property_read_string_index(np, "phandle-list-names", 3, strings);
selftest(rc == -ENODATA && strings[0] == NULL, "of_property_read_string_index() failure; rc=%i\n", rc);
strings[0] = NULL;
rc = of_property_read_string_index(np, "unterminated-string", 0, strings);
selftest(rc == -EILSEQ && strings[0] == NULL, "of_property_read_string_index() failure; rc=%i\n", rc);
rc = of_property_read_string_index(np, "unterminated-string-list", 0, strings);
selftest(rc == 0 && !strcmp(strings[0], "first"), "of_property_read_string_index() failure; rc=%i\n", rc);
strings[0] = NULL;
rc = of_property_read_string_index(np, "unterminated-string-list", 2, strings); /* should fail */
selftest(rc == -EILSEQ && strings[0] == NULL, "of_property_read_string_index() failure; rc=%i\n", rc);
strings[1] = NULL;

/* of_property_read_string_array() tests */
rc = of_property_read_string_array(np, "string-property", strings, 4);
selftest(rc == 1, "Incorrect string count; rc=%i\n", rc);
rc = of_property_read_string_array(np, "phandle-list-names", strings, 4);
selftest(rc == 3, "Incorrect string count; rc=%i\n", rc);
rc = of_property_read_string_array(np, "unterminated-string", strings, 4);
selftest(rc == -EILSEQ, "unterminated string; rc=%i\n", rc);
/* -- An incorrectly formed string should cause a failure */
rc = of_property_read_string_array(np, "unterminated-string-list", strings, 4);
selftest(rc == -EILSEQ, "unterminated string array; rc=%i\n", rc);
/* -- parsing the correctly formed strings should still work: */
strings[2] = NULL;
rc = of_property_read_string_array(np, "unterminated-string-list", strings, 2);
selftest(rc == 2 && strings[2] == NULL, "of_property_read_string_array() failure; rc=%i\n", rc);
strings[1] = NULL;
rc = of_property_read_string_array(np, "phandle-list-names", strings, 1);
selftest(rc == 1 && strings[1] == NULL, "Overwrote end of string array; rc=%i, str='%s'\n", rc, strings[1]);
}

#define propcmp(p1, p2) (((p1)->length == (p2)->length) && \
Expand Down Expand Up @@ -881,7 +935,7 @@ static int __init of_selftest(void)
of_selftest_find_node_by_name();
of_selftest_dynamic();
of_selftest_parse_phandle_with_args();
of_selftest_property_match_string();
of_selftest_property_string();
of_selftest_property_copy();
of_selftest_changeset();
of_selftest_parse_interrupts();
Expand Down
2 changes: 2 additions & 0 deletions drivers/of/testcase-data/tests-phandle.dtsi
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,9 @@
phandle-list-bad-args = <&provider2 1 0>,
<&provider3 0>;
empty-property;
string-property = "foobar";
unterminated-string = [40 41 42 43];
unterminated-string-list = "first", "second", [40 41 42 43];
};
};
};
Expand Down
84 changes: 70 additions & 14 deletions include/linux/of.h
Original file line number Diff line number Diff line change
Expand Up @@ -267,14 +267,12 @@ extern int of_property_read_u64(const struct device_node *np,
extern int of_property_read_string(struct device_node *np,
const char *propname,
const char **out_string);
extern int of_property_read_string_index(struct device_node *np,
const char *propname,
int index, const char **output);
extern int of_property_match_string(struct device_node *np,
const char *propname,
const char *string);
extern int of_property_count_strings(struct device_node *np,
const char *propname);
extern int of_property_read_string_helper(struct device_node *np,
const char *propname,
const char **out_strs, size_t sz, int index);
extern int of_device_is_compatible(const struct device_node *device,
const char *);
extern int of_device_is_available(const struct device_node *device);
Expand Down Expand Up @@ -486,15 +484,9 @@ static inline int of_property_read_string(struct device_node *np,
return -ENOSYS;
}

static inline int of_property_read_string_index(struct device_node *np,
const char *propname, int index,
const char **out_string)
{
return -ENOSYS;
}

static inline int of_property_count_strings(struct device_node *np,
const char *propname)
static inline int of_property_read_string_helper(struct device_node *np,
const char *propname,
const char **out_strs, size_t sz, int index)
{
return -ENOSYS;
}
Expand Down Expand Up @@ -667,6 +659,70 @@ static inline int of_property_count_u64_elems(const struct device_node *np,
return of_property_count_elems_of_size(np, propname, sizeof(u64));
}

/**
* of_property_read_string_array() - Read an array of strings from a multiple
* strings property.
* @np: device node from which the property value is to be read.
* @propname: name of the property to be searched.
* @out_strs: output array of string pointers.
* @sz: number of array elements to read.
*
* Search for a property in a device tree node and retrieve a list of
* terminated string values (pointer to data, not a copy) in that property.
*
* If @out_strs is NULL, the number of strings in the property is returned.
*/
static inline int of_property_read_string_array(struct device_node *np,
const char *propname, const char **out_strs,
size_t sz)
{
return of_property_read_string_helper(np, propname, out_strs, sz, 0);
}

/**
* of_property_count_strings() - Find and return the number of strings from a
* multiple strings property.
* @np: device node from which the property value is to be read.
* @propname: name of the property to be searched.
*
* Search for a property in a device tree node and retrieve the number of null
* terminated string contain in it. Returns the number of strings on
* success, -EINVAL if the property does not exist, -ENODATA if property
* does not have a value, and -EILSEQ if the string is not null-terminated
* within the length of the property data.
*/
static inline int of_property_count_strings(struct device_node *np,
const char *propname)
{
return of_property_read_string_helper(np, propname, NULL, 0, 0);
}

/**
* of_property_read_string_index() - Find and read a string from a multiple
* strings property.
* @np: device node from which the property value is to be read.
* @propname: name of the property to be searched.
* @index: index of the string in the list of strings
* @out_string: pointer to null terminated return string, modified only if
* return value is 0.
*
* Search for a property in a device tree node and retrieve a null
* terminated string value (pointer to data, not a copy) in the list of strings
* contained in that property.
* Returns 0 on success, -EINVAL if the property does not exist, -ENODATA if
* property does not have a value, and -EILSEQ if the string is not
* null-terminated within the length of the property data.
*
* The out_string pointer is modified only if a valid string can be decoded.
*/
static inline int of_property_read_string_index(struct device_node *np,
const char *propname,
int index, const char **output)
{
int rc = of_property_read_string_helper(np, propname, output, 1, index);
return rc < 0 ? rc : 0;
}

/**
* of_property_read_bool - Findfrom a property
* @np: device node from which the property value is to be read.
Expand Down