aboutsummaryrefslogtreecommitdiff
path: root/drivers/firmware/google/vpd_decode.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2019-09-18 11:14:31 -0700
committerLinus Torvalds <torvalds@linux-foundation.org>2019-09-18 11:14:31 -0700
commit6cfae0c26b21dce323fe8799b66cf4bc996e3565 (patch)
tree647f80442929de7ed17cc436c546c21c8c2b2aa9 /drivers/firmware/google/vpd_decode.c
parente6874fc29410fabfdbc8c12b467f41a16cbcfd2b (diff)
parent16a0f687cac70301f49d6f99c4115824e6aad42b (diff)
Merge tag 'char-misc-5.4-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/char-misc
Pull char/misc driver updates from Greg KH: "Here is the big char/misc driver pull request for 5.4-rc1. As has been happening in previous releases, more and more individual driver subsystem trees are ending up in here. Now if that is good or bad I can't tell, but hopefully it makes your life easier as it's more of an aggregation of trees together to one merge point for you. Anyway, lots of stuff in here: - habanalabs driver updates - thunderbolt driver updates - misc driver updates - coresight and intel_th hwtracing driver updates - fpga driver updates - extcon driver updates - some dma driver updates - char driver updates - android binder driver updates - nvmem driver updates - phy driver updates - parport driver fixes - pcmcia driver fix - uio driver updates - w1 driver updates - configfs fixes - other assorted driver updates All of these have been in linux-next for a long time with no reported issues" * tag 'char-misc-5.4-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/char-misc: (200 commits) misc: mic: Use PTR_ERR_OR_ZERO rather than its implementation habanalabs: correctly cast variable to __le32 habanalabs: show correct id in error print habanalabs: stop using the acronym KMD habanalabs: display card name as sensors header habanalabs: add uapi to retrieve aggregate H/W events habanalabs: add uapi to retrieve device utilization habanalabs: Make the Coresight timestamp perpetual habanalabs: explicitly set the queue-id enumerated numbers habanalabs: print to kernel log when reset is finished habanalabs: replace __le32_to_cpu with le32_to_cpu habanalabs: replace __cpu_to_le32/64 with cpu_to_le32/64 habanalabs: Handle HW_IP_INFO if device disabled or in reset habanalabs: Expose devices after initialization is done habanalabs: improve security in Debug IOCTL habanalabs: use default structure for user input in Debug IOCTL habanalabs: Add descriptive name to PSOC app status register habanalabs: Add descriptive names to PSOC scratch-pad registers habanalabs: create two char devices per ASIC habanalabs: change device_setup_cdev() to be more generic ...
Diffstat (limited to 'drivers/firmware/google/vpd_decode.c')
-rw-r--r--drivers/firmware/google/vpd_decode.c55
1 files changed, 32 insertions, 23 deletions
diff --git a/drivers/firmware/google/vpd_decode.c b/drivers/firmware/google/vpd_decode.c
index 92e3258552fc..dda525c0f968 100644
--- a/drivers/firmware/google/vpd_decode.c
+++ b/drivers/firmware/google/vpd_decode.c
@@ -9,8 +9,8 @@
#include "vpd_decode.h"
-static int vpd_decode_len(const s32 max_len, const u8 *in,
- s32 *length, s32 *decoded_len)
+static int vpd_decode_len(const u32 max_len, const u8 *in,
+ u32 *length, u32 *decoded_len)
{
u8 more;
int i = 0;
@@ -30,18 +30,39 @@ static int vpd_decode_len(const s32 max_len, const u8 *in,
} while (more);
*decoded_len = i;
+ return VPD_OK;
+}
+
+static int vpd_decode_entry(const u32 max_len, const u8 *input_buf,
+ u32 *_consumed, const u8 **entry, u32 *entry_len)
+{
+ u32 decoded_len;
+ u32 consumed = *_consumed;
+
+ if (vpd_decode_len(max_len - consumed, &input_buf[consumed],
+ entry_len, &decoded_len) != VPD_OK)
+ return VPD_FAIL;
+ if (max_len - consumed < decoded_len)
+ return VPD_FAIL;
+
+ consumed += decoded_len;
+ *entry = input_buf + consumed;
+
+ /* entry_len is untrusted data and must be checked again. */
+ if (max_len - consumed < *entry_len)
+ return VPD_FAIL;
+ consumed += decoded_len;
+ *_consumed = consumed;
return VPD_OK;
}
-int vpd_decode_string(const s32 max_len, const u8 *input_buf, s32 *consumed,
+int vpd_decode_string(const u32 max_len, const u8 *input_buf, u32 *consumed,
vpd_decode_callback callback, void *callback_arg)
{
int type;
- int res;
- s32 key_len;
- s32 value_len;
- s32 decoded_len;
+ u32 key_len;
+ u32 value_len;
const u8 *key;
const u8 *value;
@@ -56,26 +77,14 @@ int vpd_decode_string(const s32 max_len, const u8 *input_buf, s32 *consumed,
case VPD_TYPE_STRING:
(*consumed)++;
- /* key */
- res = vpd_decode_len(max_len - *consumed, &input_buf[*consumed],
- &key_len, &decoded_len);
- if (res != VPD_OK || *consumed + decoded_len >= max_len)
+ if (vpd_decode_entry(max_len, input_buf, consumed, &key,
+ &key_len) != VPD_OK)
return VPD_FAIL;
- *consumed += decoded_len;
- key = &input_buf[*consumed];
- *consumed += key_len;
-
- /* value */
- res = vpd_decode_len(max_len - *consumed, &input_buf[*consumed],
- &value_len, &decoded_len);
- if (res != VPD_OK || *consumed + decoded_len > max_len)
+ if (vpd_decode_entry(max_len, input_buf, consumed, &value,
+ &value_len) != VPD_OK)
return VPD_FAIL;
- *consumed += decoded_len;
- value = &input_buf[*consumed];
- *consumed += value_len;
-
if (type == VPD_TYPE_STRING)
return callback(key, key_len, value, value_len,
callback_arg);