cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

manifest.c (14752B)


      1// SPDX-License-Identifier: GPL-2.0
      2/*
      3 * Greybus manifest parsing
      4 *
      5 * Copyright 2014-2015 Google Inc.
      6 * Copyright 2014-2015 Linaro Ltd.
      7 */
      8
      9#include <linux/greybus.h>
     10
     11static const char *get_descriptor_type_string(u8 type)
     12{
     13	switch (type) {
     14	case GREYBUS_TYPE_INVALID:
     15		return "invalid";
     16	case GREYBUS_TYPE_STRING:
     17		return "string";
     18	case GREYBUS_TYPE_INTERFACE:
     19		return "interface";
     20	case GREYBUS_TYPE_CPORT:
     21		return "cport";
     22	case GREYBUS_TYPE_BUNDLE:
     23		return "bundle";
     24	default:
     25		WARN_ON(1);
     26		return "unknown";
     27	}
     28}
     29
     30/*
     31 * We scan the manifest once to identify where all the descriptors
     32 * are.  The result is a list of these manifest_desc structures.  We
     33 * then pick through them for what we're looking for (starting with
     34 * the interface descriptor).  As each is processed we remove it from
     35 * the list.  When we're done the list should (probably) be empty.
     36 */
     37struct manifest_desc {
     38	struct list_head		links;
     39
     40	size_t				size;
     41	void				*data;
     42	enum greybus_descriptor_type	type;
     43};
     44
     45static void release_manifest_descriptor(struct manifest_desc *descriptor)
     46{
     47	list_del(&descriptor->links);
     48	kfree(descriptor);
     49}
     50
     51static void release_manifest_descriptors(struct gb_interface *intf)
     52{
     53	struct manifest_desc *descriptor;
     54	struct manifest_desc *next;
     55
     56	list_for_each_entry_safe(descriptor, next, &intf->manifest_descs, links)
     57		release_manifest_descriptor(descriptor);
     58}
     59
     60static void release_cport_descriptors(struct list_head *head, u8 bundle_id)
     61{
     62	struct manifest_desc *desc, *tmp;
     63	struct greybus_descriptor_cport *desc_cport;
     64
     65	list_for_each_entry_safe(desc, tmp, head, links) {
     66		desc_cport = desc->data;
     67
     68		if (desc->type != GREYBUS_TYPE_CPORT)
     69			continue;
     70
     71		if (desc_cport->bundle == bundle_id)
     72			release_manifest_descriptor(desc);
     73	}
     74}
     75
     76static struct manifest_desc *get_next_bundle_desc(struct gb_interface *intf)
     77{
     78	struct manifest_desc *descriptor;
     79	struct manifest_desc *next;
     80
     81	list_for_each_entry_safe(descriptor, next, &intf->manifest_descs, links)
     82		if (descriptor->type == GREYBUS_TYPE_BUNDLE)
     83			return descriptor;
     84
     85	return NULL;
     86}
     87
     88/*
     89 * Validate the given descriptor.  Its reported size must fit within
     90 * the number of bytes remaining, and it must have a recognized
     91 * type.  Check that the reported size is at least as big as what
     92 * we expect to see.  (It could be bigger, perhaps for a new version
     93 * of the format.)
     94 *
     95 * Returns the (non-zero) number of bytes consumed by the descriptor,
     96 * or a negative errno.
     97 */
     98static int identify_descriptor(struct gb_interface *intf,
     99			       struct greybus_descriptor *desc, size_t size)
    100{
    101	struct greybus_descriptor_header *desc_header = &desc->header;
    102	struct manifest_desc *descriptor;
    103	size_t desc_size;
    104	size_t expected_size;
    105
    106	if (size < sizeof(*desc_header)) {
    107		dev_err(&intf->dev, "manifest too small (%zu < %zu)\n", size,
    108			sizeof(*desc_header));
    109		return -EINVAL;		/* Must at least have header */
    110	}
    111
    112	desc_size = le16_to_cpu(desc_header->size);
    113	if (desc_size > size) {
    114		dev_err(&intf->dev, "descriptor too big (%zu > %zu)\n",
    115			desc_size, size);
    116		return -EINVAL;
    117	}
    118
    119	/* Descriptor needs to at least have a header */
    120	expected_size = sizeof(*desc_header);
    121
    122	switch (desc_header->type) {
    123	case GREYBUS_TYPE_STRING:
    124		expected_size += sizeof(struct greybus_descriptor_string);
    125		expected_size += desc->string.length;
    126
    127		/* String descriptors are padded to 4 byte boundaries */
    128		expected_size = ALIGN(expected_size, 4);
    129		break;
    130	case GREYBUS_TYPE_INTERFACE:
    131		expected_size += sizeof(struct greybus_descriptor_interface);
    132		break;
    133	case GREYBUS_TYPE_BUNDLE:
    134		expected_size += sizeof(struct greybus_descriptor_bundle);
    135		break;
    136	case GREYBUS_TYPE_CPORT:
    137		expected_size += sizeof(struct greybus_descriptor_cport);
    138		break;
    139	case GREYBUS_TYPE_INVALID:
    140	default:
    141		dev_err(&intf->dev, "invalid descriptor type (%u)\n",
    142			desc_header->type);
    143		return -EINVAL;
    144	}
    145
    146	if (desc_size < expected_size) {
    147		dev_err(&intf->dev, "%s descriptor too small (%zu < %zu)\n",
    148			get_descriptor_type_string(desc_header->type),
    149			desc_size, expected_size);
    150		return -EINVAL;
    151	}
    152
    153	/* Descriptor bigger than what we expect */
    154	if (desc_size > expected_size) {
    155		dev_warn(&intf->dev, "%s descriptor size mismatch (want %zu got %zu)\n",
    156			 get_descriptor_type_string(desc_header->type),
    157			 expected_size, desc_size);
    158	}
    159
    160	descriptor = kzalloc(sizeof(*descriptor), GFP_KERNEL);
    161	if (!descriptor)
    162		return -ENOMEM;
    163
    164	descriptor->size = desc_size;
    165	descriptor->data = (char *)desc + sizeof(*desc_header);
    166	descriptor->type = desc_header->type;
    167	list_add_tail(&descriptor->links, &intf->manifest_descs);
    168
    169	/* desc_size is positive and is known to fit in a signed int */
    170
    171	return desc_size;
    172}
    173
    174/*
    175 * Find the string descriptor having the given id, validate it, and
    176 * allocate a duplicate copy of it.  The duplicate has an extra byte
    177 * which guarantees the returned string is NUL-terminated.
    178 *
    179 * String index 0 is valid (it represents "no string"), and for
    180 * that a null pointer is returned.
    181 *
    182 * Otherwise returns a pointer to a newly-allocated copy of the
    183 * descriptor string, or an error-coded pointer on failure.
    184 */
    185static char *gb_string_get(struct gb_interface *intf, u8 string_id)
    186{
    187	struct greybus_descriptor_string *desc_string;
    188	struct manifest_desc *descriptor;
    189	bool found = false;
    190	char *string;
    191
    192	/* A zero string id means no string (but no error) */
    193	if (!string_id)
    194		return NULL;
    195
    196	list_for_each_entry(descriptor, &intf->manifest_descs, links) {
    197		if (descriptor->type != GREYBUS_TYPE_STRING)
    198			continue;
    199
    200		desc_string = descriptor->data;
    201		if (desc_string->id == string_id) {
    202			found = true;
    203			break;
    204		}
    205	}
    206	if (!found)
    207		return ERR_PTR(-ENOENT);
    208
    209	/* Allocate an extra byte so we can guarantee it's NUL-terminated */
    210	string = kmemdup(&desc_string->string, desc_string->length + 1,
    211			 GFP_KERNEL);
    212	if (!string)
    213		return ERR_PTR(-ENOMEM);
    214	string[desc_string->length] = '\0';
    215
    216	/* Ok we've used this string, so we're done with it */
    217	release_manifest_descriptor(descriptor);
    218
    219	return string;
    220}
    221
    222/*
    223 * Find cport descriptors in the manifest associated with the given
    224 * bundle, and set up data structures for the functions that use
    225 * them.  Returns the number of cports set up for the bundle, or 0
    226 * if there is an error.
    227 */
    228static u32 gb_manifest_parse_cports(struct gb_bundle *bundle)
    229{
    230	struct gb_interface *intf = bundle->intf;
    231	struct greybus_descriptor_cport *desc_cport;
    232	struct manifest_desc *desc, *next, *tmp;
    233	LIST_HEAD(list);
    234	u8 bundle_id = bundle->id;
    235	u16 cport_id;
    236	u32 count = 0;
    237	int i;
    238
    239	/* Set up all cport descriptors associated with this bundle */
    240	list_for_each_entry_safe(desc, next, &intf->manifest_descs, links) {
    241		if (desc->type != GREYBUS_TYPE_CPORT)
    242			continue;
    243
    244		desc_cport = desc->data;
    245		if (desc_cport->bundle != bundle_id)
    246			continue;
    247
    248		cport_id = le16_to_cpu(desc_cport->id);
    249		if (cport_id > CPORT_ID_MAX)
    250			goto exit;
    251
    252		/* Nothing else should have its cport_id as control cport id */
    253		if (cport_id == GB_CONTROL_CPORT_ID) {
    254			dev_err(&bundle->dev, "invalid cport id found (%02u)\n",
    255				cport_id);
    256			goto exit;
    257		}
    258
    259		/*
    260		 * Found one, move it to our temporary list after checking for
    261		 * duplicates.
    262		 */
    263		list_for_each_entry(tmp, &list, links) {
    264			desc_cport = tmp->data;
    265			if (cport_id == le16_to_cpu(desc_cport->id)) {
    266				dev_err(&bundle->dev,
    267					"duplicate CPort %u found\n", cport_id);
    268				goto exit;
    269			}
    270		}
    271		list_move_tail(&desc->links, &list);
    272		count++;
    273	}
    274
    275	if (!count)
    276		return 0;
    277
    278	bundle->cport_desc = kcalloc(count, sizeof(*bundle->cport_desc),
    279				     GFP_KERNEL);
    280	if (!bundle->cport_desc)
    281		goto exit;
    282
    283	bundle->num_cports = count;
    284
    285	i = 0;
    286	list_for_each_entry_safe(desc, next, &list, links) {
    287		desc_cport = desc->data;
    288		memcpy(&bundle->cport_desc[i++], desc_cport,
    289		       sizeof(*desc_cport));
    290
    291		/* Release the cport descriptor */
    292		release_manifest_descriptor(desc);
    293	}
    294
    295	return count;
    296exit:
    297	release_cport_descriptors(&list, bundle_id);
    298	/*
    299	 * Free all cports for this bundle to avoid 'excess descriptors'
    300	 * warnings.
    301	 */
    302	release_cport_descriptors(&intf->manifest_descs, bundle_id);
    303
    304	return 0;	/* Error; count should also be 0 */
    305}
    306
    307/*
    308 * Find bundle descriptors in the manifest and set up their data
    309 * structures.  Returns the number of bundles set up for the
    310 * given interface.
    311 */
    312static u32 gb_manifest_parse_bundles(struct gb_interface *intf)
    313{
    314	struct manifest_desc *desc;
    315	struct gb_bundle *bundle;
    316	struct gb_bundle *bundle_next;
    317	u32 count = 0;
    318	u8 bundle_id;
    319	u8 class;
    320
    321	while ((desc = get_next_bundle_desc(intf))) {
    322		struct greybus_descriptor_bundle *desc_bundle;
    323
    324		/* Found one.  Set up its bundle structure*/
    325		desc_bundle = desc->data;
    326		bundle_id = desc_bundle->id;
    327		class = desc_bundle->class;
    328
    329		/* Done with this bundle descriptor */
    330		release_manifest_descriptor(desc);
    331
    332		/* Ignore any legacy control bundles */
    333		if (bundle_id == GB_CONTROL_BUNDLE_ID) {
    334			dev_dbg(&intf->dev, "%s - ignoring control bundle\n",
    335				__func__);
    336			release_cport_descriptors(&intf->manifest_descs,
    337						  bundle_id);
    338			continue;
    339		}
    340
    341		/* Nothing else should have its class set to control class */
    342		if (class == GREYBUS_CLASS_CONTROL) {
    343			dev_err(&intf->dev,
    344				"bundle %u cannot use control class\n",
    345				bundle_id);
    346			goto cleanup;
    347		}
    348
    349		bundle = gb_bundle_create(intf, bundle_id, class);
    350		if (!bundle)
    351			goto cleanup;
    352
    353		/*
    354		 * Now go set up this bundle's functions and cports.
    355		 *
    356		 * A 'bundle' represents a device in greybus. It may require
    357		 * multiple cports for its functioning. If we fail to setup any
    358		 * cport of a bundle, we better reject the complete bundle as
    359		 * the device may not be able to function properly then.
    360		 *
    361		 * But, failing to setup a cport of bundle X doesn't mean that
    362		 * the device corresponding to bundle Y will not work properly.
    363		 * Bundles should be treated as separate independent devices.
    364		 *
    365		 * While parsing manifest for an interface, treat bundles as
    366		 * separate entities and don't reject entire interface and its
    367		 * bundles on failing to initialize a cport. But make sure the
    368		 * bundle which needs the cport, gets destroyed properly.
    369		 */
    370		if (!gb_manifest_parse_cports(bundle)) {
    371			gb_bundle_destroy(bundle);
    372			continue;
    373		}
    374
    375		count++;
    376	}
    377
    378	return count;
    379cleanup:
    380	/* An error occurred; undo any changes we've made */
    381	list_for_each_entry_safe(bundle, bundle_next, &intf->bundles, links) {
    382		gb_bundle_destroy(bundle);
    383		count--;
    384	}
    385	return 0;	/* Error; count should also be 0 */
    386}
    387
    388static bool gb_manifest_parse_interface(struct gb_interface *intf,
    389					struct manifest_desc *interface_desc)
    390{
    391	struct greybus_descriptor_interface *desc_intf = interface_desc->data;
    392	struct gb_control *control = intf->control;
    393	char *str;
    394
    395	/* Handle the strings first--they can fail */
    396	str = gb_string_get(intf, desc_intf->vendor_stringid);
    397	if (IS_ERR(str))
    398		return false;
    399	control->vendor_string = str;
    400
    401	str = gb_string_get(intf, desc_intf->product_stringid);
    402	if (IS_ERR(str))
    403		goto out_free_vendor_string;
    404	control->product_string = str;
    405
    406	/* Assign feature flags communicated via manifest */
    407	intf->features = desc_intf->features;
    408
    409	/* Release the interface descriptor, now that we're done with it */
    410	release_manifest_descriptor(interface_desc);
    411
    412	/* An interface must have at least one bundle descriptor */
    413	if (!gb_manifest_parse_bundles(intf)) {
    414		dev_err(&intf->dev, "manifest bundle descriptors not valid\n");
    415		goto out_err;
    416	}
    417
    418	return true;
    419out_err:
    420	kfree(control->product_string);
    421	control->product_string = NULL;
    422out_free_vendor_string:
    423	kfree(control->vendor_string);
    424	control->vendor_string = NULL;
    425
    426	return false;
    427}
    428
    429/*
    430 * Parse a buffer containing an interface manifest.
    431 *
    432 * If we find anything wrong with the content/format of the buffer
    433 * we reject it.
    434 *
    435 * The first requirement is that the manifest's version is
    436 * one we can parse.
    437 *
    438 * We make an initial pass through the buffer and identify all of
    439 * the descriptors it contains, keeping track for each its type
    440 * and the location size of its data in the buffer.
    441 *
    442 * Next we scan the descriptors, looking for an interface descriptor;
    443 * there must be exactly one of those.  When found, we record the
    444 * information it contains, and then remove that descriptor (and any
    445 * string descriptors it refers to) from further consideration.
    446 *
    447 * After that we look for the interface's bundles--there must be at
    448 * least one of those.
    449 *
    450 * Returns true if parsing was successful, false otherwise.
    451 */
    452bool gb_manifest_parse(struct gb_interface *intf, void *data, size_t size)
    453{
    454	struct greybus_manifest *manifest;
    455	struct greybus_manifest_header *header;
    456	struct greybus_descriptor *desc;
    457	struct manifest_desc *descriptor;
    458	struct manifest_desc *interface_desc = NULL;
    459	u16 manifest_size;
    460	u32 found = 0;
    461	bool result;
    462
    463	/* Manifest descriptor list should be empty here */
    464	if (WARN_ON(!list_empty(&intf->manifest_descs)))
    465		return false;
    466
    467	/* we have to have at _least_ the manifest header */
    468	if (size < sizeof(*header)) {
    469		dev_err(&intf->dev, "short manifest (%zu < %zu)\n",
    470			size, sizeof(*header));
    471		return false;
    472	}
    473
    474	/* Make sure the size is right */
    475	manifest = data;
    476	header = &manifest->header;
    477	manifest_size = le16_to_cpu(header->size);
    478	if (manifest_size != size) {
    479		dev_err(&intf->dev, "manifest size mismatch (%zu != %u)\n",
    480			size, manifest_size);
    481		return false;
    482	}
    483
    484	/* Validate major/minor number */
    485	if (header->version_major > GREYBUS_VERSION_MAJOR) {
    486		dev_err(&intf->dev, "manifest version too new (%u.%u > %u.%u)\n",
    487			header->version_major, header->version_minor,
    488			GREYBUS_VERSION_MAJOR, GREYBUS_VERSION_MINOR);
    489		return false;
    490	}
    491
    492	/* OK, find all the descriptors */
    493	desc = manifest->descriptors;
    494	size -= sizeof(*header);
    495	while (size) {
    496		int desc_size;
    497
    498		desc_size = identify_descriptor(intf, desc, size);
    499		if (desc_size < 0) {
    500			result = false;
    501			goto out;
    502		}
    503		desc = (struct greybus_descriptor *)((char *)desc + desc_size);
    504		size -= desc_size;
    505	}
    506
    507	/* There must be a single interface descriptor */
    508	list_for_each_entry(descriptor, &intf->manifest_descs, links) {
    509		if (descriptor->type == GREYBUS_TYPE_INTERFACE)
    510			if (!found++)
    511				interface_desc = descriptor;
    512	}
    513	if (found != 1) {
    514		dev_err(&intf->dev, "manifest must have 1 interface descriptor (%u found)\n",
    515			found);
    516		result = false;
    517		goto out;
    518	}
    519
    520	/* Parse the manifest, starting with the interface descriptor */
    521	result = gb_manifest_parse_interface(intf, interface_desc);
    522
    523	/*
    524	 * We really should have no remaining descriptors, but we
    525	 * don't know what newer format manifests might leave.
    526	 */
    527	if (result && !list_empty(&intf->manifest_descs))
    528		dev_info(&intf->dev, "excess descriptors in interface manifest\n");
    529out:
    530	release_manifest_descriptors(intf);
    531
    532	return result;
    533}