of/device: Fix of_device_get_modalias() buffer handling
authorBjorn Andersson <bjorn.andersson@linaro.org>
Thu, 24 Aug 2017 01:03:52 +0000 (18:03 -0700)
committerRob Herring <robh@kernel.org>
Thu, 24 Aug 2017 16:52:51 +0000 (11:52 -0500)
commit8c2a75e5687e0137ddbb35454c7a1a468079f790
tree25d148d8ac6bd6e9c8f858e6a6645d073706cecd
parent08ab58d9de3eb8498ae0585001d0975e46217a39
of/device: Fix of_device_get_modalias() buffer handling

of_device_request_module() calls of_device_get_modalias() with "len" 0,
to calculate the size of the buffer needed to store the result, but due
to integer promotion the ssize_t "len" will be compared as unsigned with
strlen(compat) and the loop will generally never break. This results in
a call to snprintf() with a negative len, which triggers below warning,
followed by a dereference of a invalid pointer:

  [    3.060067] WARNING: CPU: 0 PID: 51 at lib/vsprintf.c:2122 vsnprintf+0x348/0x6d8
  ...
  [    3.060301] [<ffffff800891ede8>] vsnprintf+0x348/0x6d8
  [    3.060308] [<ffffff800891f248>] snprintf+0x48/0x50
  [    3.060316] [<ffffff80086a7c80>] of_device_get_modalias+0x108/0x160
  [    3.060322] [<ffffff80086a7cf8>] of_device_request_module+0x20/0x88
  ...

Further more of_device_get_modalias() is supposed to return the number
of bytes needed to store the entire modalias, so the loop needs to
continue accumulate the total size even though the buffer is full.

Finally the function is not expected to ensure space for the NUL, nor
include it in the returned size, so only 1 should be added to the length
of "compat" in the loop (to account for the character 'C').

Fixes: bc575064d688 ("of/device: use of_property_for_each_string to parse compatible strings")
Cc: Rob Herring <robh@kernel.org>
Signed-off-by: Bjorn Andersson <bjorn.andersson@linaro.org>
Signed-off-by: Rob Herring <robh@kernel.org>
drivers/of/device.c