]> git.karo-electronics.de Git - karo-tx-linux.git/blob - drivers/staging/greybus/manifest.c
greybus: manifest: clean up properly when parsing bundles
[karo-tx-linux.git] / drivers / staging / greybus / manifest.c
1 /*
2  * Greybus manifest parsing
3  *
4  * Copyright 2014-2015 Google Inc.
5  * Copyright 2014-2015 Linaro Ltd.
6  *
7  * Released under the GPLv2 only.
8  */
9
10 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
11
12 #include "greybus.h"
13
14 static const char *get_descriptor_type_string(u8 type)
15 {
16         switch(type) {
17         case GREYBUS_TYPE_INVALID:
18                 return "invalid";
19         case GREYBUS_TYPE_STRING:
20                 return "string";
21         case GREYBUS_TYPE_INTERFACE:
22                 return "interface";
23         case GREYBUS_TYPE_CPORT:
24                 return "cport";
25         case GREYBUS_TYPE_BUNDLE:
26                 return "bundle";
27         default:
28                 WARN_ON(1);
29                 return "unknown";
30         }
31 }
32
33 /*
34  * We scan the manifest once to identify where all the descriptors
35  * are.  The result is a list of these manifest_desc structures.  We
36  * then pick through them for what we're looking for (starting with
37  * the interface descriptor).  As each is processed we remove it from
38  * the list.  When we're done the list should (probably) be empty.
39  */
40 struct manifest_desc {
41         struct list_head                links;
42
43         size_t                          size;
44         void                            *data;
45         enum greybus_descriptor_type    type;
46 };
47
48 static void release_manifest_descriptor(struct manifest_desc *descriptor)
49 {
50         list_del(&descriptor->links);
51         kfree(descriptor);
52 }
53
54 static void release_manifest_descriptors(struct gb_interface *intf)
55 {
56         struct manifest_desc *descriptor;
57         struct manifest_desc *next;
58
59         list_for_each_entry_safe(descriptor, next, &intf->manifest_descs, links)
60                 release_manifest_descriptor(descriptor);
61 }
62
63 /*
64  * Validate the given descriptor.  Its reported size must fit within
65  * the number of bytes remaining, and it must have a recognized
66  * type.  Check that the reported size is at least as big as what
67  * we expect to see.  (It could be bigger, perhaps for a new version
68  * of the format.)
69  *
70  * Returns the (non-zero) number of bytes consumed by the descriptor,
71  * or a negative errno.
72  */
73 static int identify_descriptor(struct gb_interface *intf,
74                                struct greybus_descriptor *desc, size_t size)
75 {
76         struct greybus_descriptor_header *desc_header = &desc->header;
77         struct manifest_desc *descriptor;
78         size_t desc_size;
79         size_t expected_size;
80
81         if (size < sizeof(*desc_header)) {
82                 pr_err("manifest too small (%zu < %zu)\n",
83                                 size, sizeof(*desc_header));
84                 return -EINVAL;         /* Must at least have header */
85         }
86
87         desc_size = le16_to_cpu(desc_header->size);
88         if (desc_size > size) {
89                 pr_err("descriptor too big (%zu > %zu)\n", desc_size, size);
90                 return -EINVAL;
91         }
92
93         /* Descriptor needs to at least have a header */
94         expected_size = sizeof(*desc_header);
95
96         switch (desc_header->type) {
97         case GREYBUS_TYPE_STRING:
98                 expected_size += sizeof(struct greybus_descriptor_string);
99                 expected_size += desc->string.length;
100
101                 /* String descriptors are padded to 4 byte boundaries */
102                 expected_size = ALIGN(expected_size, 4);
103                 break;
104         case GREYBUS_TYPE_INTERFACE:
105                 expected_size += sizeof(struct greybus_descriptor_interface);
106                 break;
107         case GREYBUS_TYPE_BUNDLE:
108                 expected_size += sizeof(struct greybus_descriptor_bundle);
109                 break;
110         case GREYBUS_TYPE_CPORT:
111                 expected_size += sizeof(struct greybus_descriptor_cport);
112                 break;
113         case GREYBUS_TYPE_INVALID:
114         default:
115                 pr_err("invalid descriptor type (%hhu)\n", desc_header->type);
116                 return -EINVAL;
117         }
118
119         if (desc_size < expected_size) {
120                 pr_err("%s descriptor too small (%zu < %zu)\n",
121                        get_descriptor_type_string(desc_header->type),
122                        desc_size, expected_size);
123                 return -EINVAL;
124         }
125
126         /* Descriptor bigger than what we expect */
127         if (desc_size > expected_size) {
128                 pr_warn("%s descriptor size mismatch (want %zu got %zu)\n",
129                         get_descriptor_type_string(desc_header->type),
130                         expected_size, desc_size);
131         }
132
133         descriptor = kzalloc(sizeof(*descriptor), GFP_KERNEL);
134         if (!descriptor)
135                 return -ENOMEM;
136
137         descriptor->size = desc_size;
138         descriptor->data = (char *)desc + sizeof(*desc_header);
139         descriptor->type = desc_header->type;
140         list_add_tail(&descriptor->links, &intf->manifest_descs);
141
142         /* desc_size is positive and is known to fit in a signed int */
143
144         return desc_size;
145 }
146
147 /*
148  * Find the string descriptor having the given id, validate it, and
149  * allocate a duplicate copy of it.  The duplicate has an extra byte
150  * which guarantees the returned string is NUL-terminated.
151  *
152  * String index 0 is valid (it represents "no string"), and for
153  * that a null pointer is returned.
154  *
155  * Otherwise returns a pointer to a newly-allocated copy of the
156  * descriptor string, or an error-coded pointer on failure.
157  */
158 static char *gb_string_get(struct gb_interface *intf, u8 string_id)
159 {
160         struct greybus_descriptor_string *desc_string;
161         struct manifest_desc *descriptor;
162         bool found = false;
163         char *string;
164
165         /* A zero string id means no string (but no error) */
166         if (!string_id)
167                 return NULL;
168
169         list_for_each_entry(descriptor, &intf->manifest_descs, links) {
170                 if (descriptor->type != GREYBUS_TYPE_STRING)
171                         continue;
172
173                 desc_string = descriptor->data;
174                 if (desc_string->id == string_id) {
175                         found = true;
176                         break;
177                 }
178         }
179         if (!found)
180                 return ERR_PTR(-ENOENT);
181
182         /* Allocate an extra byte so we can guarantee it's NUL-terminated */
183         string = kmemdup(&desc_string->string, desc_string->length + 1,
184                                 GFP_KERNEL);
185         if (!string)
186                 return ERR_PTR(-ENOMEM);
187         string[desc_string->length] = '\0';
188
189         /* Ok we've used this string, so we're done with it */
190         release_manifest_descriptor(descriptor);
191
192         return string;
193 }
194
195 /*
196  * Find cport descriptors in the manifest associated with the given
197  * bundle, and set up data structures for the functions that use
198  * them.  Returns the number of cports set up for the bundle, or 0
199  * if there is an error.
200  */
201 static u32 gb_manifest_parse_cports(struct gb_bundle *bundle)
202 {
203         struct gb_interface *intf = bundle->intf;
204         struct gb_connection *connection;
205         struct gb_connection *connection_next;
206         struct manifest_desc *desc;
207         struct manifest_desc *next;
208         u8 bundle_id = bundle->id;
209         u32 count = 0;
210
211         if (WARN_ON(!list_empty(&bundle->connections)))
212                 return 0;
213
214         /* Set up all cport descriptors associated with this bundle */
215         list_for_each_entry_safe(desc, next, &intf->manifest_descs, links) {
216                 struct greybus_descriptor_cport *desc_cport;
217                 u8 protocol_id;
218                 u16 cport_id;
219
220                 if (desc->type != GREYBUS_TYPE_CPORT)
221                         continue;
222
223                 desc_cport = desc->data;
224                 if (desc_cport->bundle != bundle_id)
225                         continue;
226
227                 /* Found one.  Set up its function structure */
228                 protocol_id = desc_cport->protocol_id;
229                 cport_id = le16_to_cpu(desc_cport->id);
230                 if (!gb_connection_create(bundle, cport_id, protocol_id))
231                         goto cleanup;
232
233                 count++;
234
235                 /* Release the cport descriptor */
236                 release_manifest_descriptor(desc);
237         }
238
239         return count;
240 cleanup:
241         /* An error occurred; undo any changes we've made */
242         list_for_each_entry_safe(connection, connection_next,
243                         &bundle->connections, bundle_links) {
244                 gb_connection_destroy(connection);
245                 count--;
246         }
247         return 0;       /* Error; count should also be 0 */
248 }
249
250 /*
251  * Find bundle descriptors in the manifest and set up their data
252  * structures.  Returns the number of bundles set up for the
253  * given interface.
254  */
255 static u32 gb_manifest_parse_bundles(struct gb_interface *intf)
256 {
257         struct manifest_desc *desc;
258         struct manifest_desc *next;
259         struct gb_bundle *bundle;
260         struct gb_bundle *bundle_next;
261         u32 count = 0;
262
263         if (WARN_ON(!list_empty(&intf->bundles)))
264                 return 0;
265
266         list_for_each_entry_safe(desc, next, &intf->manifest_descs, links) {
267                 struct greybus_descriptor_bundle *desc_bundle;
268
269                 if (desc->type != GREYBUS_TYPE_BUNDLE)
270                         continue;
271
272                 /* Found one.  Set up its bundle structure*/
273                 desc_bundle = desc->data;
274                 bundle = gb_bundle_create(intf, desc_bundle->id,
275                                           desc_bundle->class);
276                 if (!bundle)
277                         goto cleanup;
278
279                 /* Now go set up this bundle's functions and cports */
280                 if (!gb_manifest_parse_cports(bundle))
281                         goto cleanup;
282
283                 count++;
284
285                 /* Done with this bundle descriptor */
286                 release_manifest_descriptor(desc);
287         }
288
289         return count;
290 cleanup:
291         /* An error occurred; undo any changes we've made */
292         list_for_each_entry_safe(bundle, bundle_next, &intf->bundles, links) {
293                 gb_bundle_destroy(bundle);
294                 count--;
295         }
296         return 0;       /* Error; count should also be 0 */
297 }
298
299 static bool gb_manifest_parse_interface(struct gb_interface *intf,
300                                         struct manifest_desc *interface_desc)
301 {
302         struct greybus_descriptor_interface *desc_intf = interface_desc->data;
303
304         /* Handle the strings first--they can fail */
305         intf->vendor_string = gb_string_get(intf, desc_intf->vendor_stringid);
306         if (IS_ERR(intf->vendor_string))
307                 return false;
308
309         intf->product_string = gb_string_get(intf, desc_intf->product_stringid);
310         if (IS_ERR(intf->product_string))
311                 goto out_free_vendor_string;
312
313         // FIXME
314         // Vendor, Product and Unique id must come via control protocol
315         intf->vendor = 0xffff;
316         intf->product = 0x0001;
317         intf->unique_id = 0;
318
319         /* Release the interface descriptor, now that we're done with it */
320         release_manifest_descriptor(interface_desc);
321
322         /* An interface must have at least one bundle descriptor */
323         if (!gb_manifest_parse_bundles(intf)) {
324                 pr_err("manifest bundle descriptors not valid\n");
325                 goto out_err;
326         }
327
328         return true;
329 out_err:
330         kfree(intf->product_string);
331         intf->product_string = NULL;
332 out_free_vendor_string:
333         kfree(intf->vendor_string);
334         intf->vendor_string = NULL;
335
336         return false;
337 }
338
339 /*
340  * Parse a buffer containing an interface manifest.
341  *
342  * If we find anything wrong with the content/format of the buffer
343  * we reject it.
344  *
345  * The first requirement is that the manifest's version is
346  * one we can parse.
347  *
348  * We make an initial pass through the buffer and identify all of
349  * the descriptors it contains, keeping track for each its type
350  * and the location size of its data in the buffer.
351  *
352  * Next we scan the descriptors, looking for an interface descriptor;
353  * there must be exactly one of those.  When found, we record the
354  * information it contains, and then remove that descriptor (and any
355  * string descriptors it refers to) from further consideration.
356  *
357  * After that we look for the interface's bundles--there must be at
358  * least one of those.
359  *
360  * Returns true if parsing was successful, false otherwise.
361  */
362 bool gb_manifest_parse(struct gb_interface *intf, void *data, size_t size)
363 {
364         struct greybus_manifest *manifest;
365         struct greybus_manifest_header *header;
366         struct greybus_descriptor *desc;
367         struct manifest_desc *descriptor;
368         struct manifest_desc *interface_desc = NULL;
369         u16 manifest_size;
370         u32 found = 0;
371         bool result;
372
373         /* Manifest descriptor list should be empty here */
374         if (WARN_ON(!list_empty(&intf->manifest_descs)))
375                 return false;
376
377         /* we have to have at _least_ the manifest header */
378         if (size < sizeof(*header)) {
379                 pr_err("short manifest (%zu < %zu)\n", size, sizeof(*header));
380                 return false;
381         }
382
383         /* Make sure the size is right */
384         manifest = data;
385         header = &manifest->header;
386         manifest_size = le16_to_cpu(header->size);
387         if (manifest_size != size) {
388                 pr_err("manifest size mismatch (%zu != %hu)\n",
389                         size, manifest_size);
390                 return false;
391         }
392
393         /* Validate major/minor number */
394         if (header->version_major > GREYBUS_VERSION_MAJOR) {
395                 pr_err("manifest version too new (%hhu.%hhu > %hhu.%hhu)\n",
396                         header->version_major, header->version_minor,
397                         GREYBUS_VERSION_MAJOR, GREYBUS_VERSION_MINOR);
398                 return false;
399         }
400
401         /* OK, find all the descriptors */
402         desc = (struct greybus_descriptor *)(header + 1);
403         size -= sizeof(*header);
404         while (size) {
405                 int desc_size;
406
407                 desc_size = identify_descriptor(intf, desc, size);
408                 if (desc_size < 0) {
409                         result = false;
410                         goto out;
411                 }
412                 desc = (struct greybus_descriptor *)((char *)desc + desc_size);
413                 size -= desc_size;
414         }
415
416         /* There must be a single interface descriptor */
417         list_for_each_entry(descriptor, &intf->manifest_descs, links) {
418                 if (descriptor->type == GREYBUS_TYPE_INTERFACE)
419                         if (!found++)
420                                 interface_desc = descriptor;
421         }
422         if (found != 1) {
423                 pr_err("manifest must have 1 interface descriptor (%u found)\n",
424                         found);
425                 result = false;
426                 goto out;
427         }
428
429         /* Parse the manifest, starting with the interface descriptor */
430         result = gb_manifest_parse_interface(intf, interface_desc);
431
432         /*
433          * We really should have no remaining descriptors, but we
434          * don't know what newer format manifests might leave.
435          */
436         if (result && !list_empty(&intf->manifest_descs))
437                 pr_info("excess descriptors in interface manifest\n");
438 out:
439         release_manifest_descriptors(intf);
440
441         return result;
442 }