1 /*
2 * This file and its contents are supplied under the terms of the
3 * Common Development and Distribution License ("CDDL"), version 1.0.
4 * You may only use this file in accordance with the terms of version
5 * 1.0 of the CDDL.
6 *
7 * A full copy of the text of the CDDL should have accompanied this
8 * source. A copy of the CDDL is also available via the Internet at
9 * http://www.illumos.org/license/CDDL.
10 */
11
12 /*
13 * Copyright 2021 Oxide Computer Company
14 */
15
16 /*
17 * Tests for SMBIOS type 46 - SMB_TYPE_STRPROP.
18 */
19
20 #include "smbios_test.h"
21
22 static const char *smbios_fwinfo_name = "Sheikah Slate";
23 static const char *smbios_fwinfo_vers = "1.3.1";
24 static const char *smbios_fwinfo_id = "ganon";
25 static const char *smbios_fwinfo_reldate = "2017-03-03";
26 static const char *smbios_fwinfo_mfg = "The Goddess Hylia";
27 static const char *smbios_fwinfo_lsv = "zelda";
28 static const uint64_t smbios_fwinfo_size = 0xb0111b;
29 static const uint_t smbios_fwinfo_ncomps = 23;
30 static const uint8_t smbios_fwinfo_versid = 0x66;
31
32 static void
smbios_test_fwinfo_mktable_common_fwinfo(smb_fwinfo_t * fw)33 smbios_test_fwinfo_mktable_common_fwinfo(smb_fwinfo_t *fw)
34 {
35 fw->smbfwii_hdr.smbh_type = SMB_TYPE_FWINFO;
36 fw->smbfwii_hdr.smbh_len = sizeof (*fw);
37 fw->smbfwii_name = 1;
38 fw->smbfwii_vers = 2;
39 fw->smbfwii_vers_fmt = smbios_fwinfo_versid;
40 fw->smbfwii_id = 3;
41 fw->smbfwii_id_fmt = smbios_fwinfo_versid;
42 fw->smbfwii_reldate = 4;
43 fw->smbfwii_mfg = 5;
44 fw->smbfwii_lsv = 6;
45 fw->smbfwii_imgsz = htole64(smbios_fwinfo_size);
46 fw->smbfwii_chars = SMB_FWC_WP;
47 fw->smbfwii_state = SMB_FWS_UA_OFFLINE;
48 fw->smbfwii_ncomps = 0;
49 }
50
51 static void
smbios_test_fwinfo_mktable_common_fini(smbios_test_table_t * table)52 smbios_test_fwinfo_mktable_common_fini(smbios_test_table_t *table)
53 {
54 smbios_test_table_append_string(table, smbios_fwinfo_name);
55 smbios_test_table_append_string(table, smbios_fwinfo_vers);
56 smbios_test_table_append_string(table, smbios_fwinfo_id);
57 smbios_test_table_append_string(table, smbios_fwinfo_reldate);
58 smbios_test_table_append_string(table, smbios_fwinfo_mfg);
59 smbios_test_table_append_string(table, smbios_fwinfo_lsv);
60 smbios_test_table_str_fini(table);
61 smbios_test_table_append_eot(table);
62 }
63
64 /*
65 * Generate a table that's too short to get basic info.
66 */
67 boolean_t
smbios_test_fwinfo_mktable_invlen_base(smbios_test_table_t * table)68 smbios_test_fwinfo_mktable_invlen_base(smbios_test_table_t *table)
69 {
70 smb_header_t hdr;
71
72 hdr.smbh_type = SMB_TYPE_FWINFO;
73 hdr.smbh_len = sizeof (hdr);
74
75 (void) smbios_test_table_append(table, &hdr, sizeof (hdr));
76 smbios_test_table_append_eot(table);
77
78 return (B_TRUE);
79 }
80
81 /*
82 * Generate a table where the table is too short for a specified number of
83 * components.
84 */
85 boolean_t
smbios_test_fwinfo_mktable_invlen_comps(smbios_test_table_t * table)86 smbios_test_fwinfo_mktable_invlen_comps(smbios_test_table_t *table)
87 {
88 smb_fwinfo_t fw;
89
90 smbios_test_fwinfo_mktable_common_fwinfo(&fw);
91 fw.smbfwii_ncomps = smbios_fwinfo_ncomps;
92 (void) smbios_test_table_append(table, &fw, sizeof (fw));
93 smbios_test_fwinfo_mktable_common_fini(table);
94
95 return (B_TRUE);
96 }
97
98 boolean_t
smbios_test_fwinfo_mktable_nocomps(smbios_test_table_t * table)99 smbios_test_fwinfo_mktable_nocomps(smbios_test_table_t *table)
100 {
101 smb_fwinfo_t fw;
102
103 smbios_test_fwinfo_mktable_common_fwinfo(&fw);
104 (void) smbios_test_table_append(table, &fw, sizeof (fw));
105 smbios_test_fwinfo_mktable_common_fini(table);
106
107 return (B_TRUE);
108 }
109
110 boolean_t
smbios_test_fwinfo_mktable_comps(smbios_test_table_t * table)111 smbios_test_fwinfo_mktable_comps(smbios_test_table_t *table)
112 {
113 smb_fwinfo_t fw;
114
115 smbios_test_fwinfo_mktable_common_fwinfo(&fw);
116
117 fw.smbfwii_hdr.smbh_len += smbios_fwinfo_ncomps * sizeof (uint16_t);
118 fw.smbfwii_ncomps = smbios_fwinfo_ncomps;
119 (void) smbios_test_table_append(table, &fw, sizeof (fw));
120
121 for (uint_t i = 0; i < fw.smbfwii_ncomps; i++) {
122 uint16_t comp = 0x2300 + i;
123
124 smbios_test_table_append_raw(table, &comp, sizeof (comp));
125 }
126 smbios_test_fwinfo_mktable_common_fini(table);
127
128 return (B_TRUE);
129 }
130
131 boolean_t
smbios_test_fwinfo_verify_badtype(smbios_hdl_t * hdl)132 smbios_test_fwinfo_verify_badtype(smbios_hdl_t *hdl)
133 {
134 smbios_struct_t sp;
135 smbios_fwinfo_t fw;
136
137 if (smbios_lookup_type(hdl, SMB_TYPE_MEMDEVICE, &sp) == -1) {
138 warnx("failed to lookup SMBIOS memory device: %s",
139 smbios_errmsg(smbios_errno(hdl)));
140 return (B_FALSE);
141 }
142
143 if (smbios_info_fwinfo(hdl, sp.smbstr_id, &fw) != -1) {
144 warnx("accidentally parsed invalid fwinfo information as "
145 "valid");
146 return (B_FALSE);
147 }
148
149 if (smbios_errno(hdl) != ESMB_TYPE) {
150 warnx("encountered wrong error for fwinfo, expected: "
151 "0x%x, found: 0x%x", ESMB_SHORT, smbios_errno(hdl));
152 return (B_FALSE);
153 }
154
155 return (B_TRUE);
156 }
157
158 boolean_t
smbios_test_fwinfo_verify_invlen_base(smbios_hdl_t * hdl)159 smbios_test_fwinfo_verify_invlen_base(smbios_hdl_t *hdl)
160 {
161 smbios_struct_t sp;
162 smbios_fwinfo_t fw;
163
164 if (smbios_lookup_type(hdl, SMB_TYPE_FWINFO, &sp) == -1) {
165 warnx("failed to lookup SMBIOS fwinfo: %s",
166 smbios_errmsg(smbios_errno(hdl)));
167 return (B_FALSE);
168 }
169
170 if (smbios_info_fwinfo(hdl, sp.smbstr_id, &fw) != -1) {
171 warnx("accidentally parsed invalid fwinfo information as "
172 "valid");
173 return (B_FALSE);
174 }
175
176 if (smbios_errno(hdl) != ESMB_SHORT) {
177 warnx("encountered wrong error for fwinfo, expected: "
178 "0x%x, found: 0x%x", ESMB_SHORT, smbios_errno(hdl));
179 return (B_FALSE);
180 }
181
182 return (B_TRUE);
183 }
184
185 static boolean_t
smbios_test_fwinfo_verify_common(smbios_hdl_t * hdl,smbios_struct_t * sp,const smbios_fwinfo_t * fw)186 smbios_test_fwinfo_verify_common(smbios_hdl_t *hdl, smbios_struct_t *sp,
187 const smbios_fwinfo_t *fw)
188 {
189 boolean_t ret = B_TRUE;
190 smbios_info_t info;
191
192 if (strcmp(fw->smbfw_name, smbios_fwinfo_name) != 0) {
193 warnx("firmware inventory name mismatch, found %s",
194 fw->smbfw_name);
195 ret = B_FALSE;
196 }
197
198 if (strcmp(fw->smbfw_id, smbios_fwinfo_id) != 0) {
199 warnx("firmware inventory id mismatch, found %s",
200 fw->smbfw_id);
201 ret = B_FALSE;
202 }
203
204 if (strcmp(fw->smbfw_reldate, smbios_fwinfo_reldate) != 0) {
205 warnx("firmware inventory release date mismatch, found %s",
206 fw->smbfw_reldate);
207 ret = B_FALSE;
208 }
209
210 if (strcmp(fw->smbfw_lsv, smbios_fwinfo_lsv) != 0) {
211 warnx("firmware inventory lsv mismatch, found %s",
212 fw->smbfw_lsv);
213 ret = B_FALSE;
214 }
215
216 if (fw->smbfw_imgsz != smbios_fwinfo_size) {
217 warnx("firmware inventory size mismatch, found 0x%" PRIx64,
218 fw->smbfw_imgsz);
219 ret = B_FALSE;
220 }
221
222 if (fw->smbfw_chars != SMB_FWC_WP) {
223 warnx("firmware inventory chars mismatch, found 0x%x",
224 fw->smbfw_chars);
225 ret = B_FALSE;
226 }
227
228 if (fw->smbfw_state != SMB_FWS_UA_OFFLINE) {
229 warnx("firmware inventory state mismatch, found 0x%x",
230 fw->smbfw_state);
231 ret = B_FALSE;
232 }
233
234 if (fw->smbfw_vers_fmt != smbios_fwinfo_versid) {
235 warnx("firmware inventory version format mismatch, found 0x%x",
236 fw->smbfw_vers_fmt);
237 ret = B_FALSE;
238 }
239
240 if (fw->smbfw_id_fmt != smbios_fwinfo_versid) {
241 warnx("firmware inventory ID format mismatch, found 0x%x",
242 fw->smbfw_id_fmt);
243 ret = B_FALSE;
244 }
245
246 if (smbios_info_common(hdl, sp->smbstr_id, &info) == -1) {
247 warnx("failed to get firmware inventory common items: %s",
248 smbios_errmsg(smbios_errno(hdl)));
249 return (B_FALSE);
250 }
251
252 if (strcmp(info.smbi_manufacturer, smbios_fwinfo_mfg) != 0) {
253 warnx("firmware inventory manufacturer mismatch, found %s",
254 info.smbi_manufacturer);
255 ret = B_FALSE;
256 }
257
258 if (strcmp(info.smbi_version, smbios_fwinfo_vers) != 0) {
259 warnx("firmware inventory version mismatch, found %s",
260 info.smbi_version);
261 ret = B_FALSE;
262 }
263
264 return (ret);
265 }
266
267 boolean_t
smbios_test_fwinfo_verify_nocomps(smbios_hdl_t * hdl)268 smbios_test_fwinfo_verify_nocomps(smbios_hdl_t *hdl)
269 {
270 smbios_struct_t sp;
271 smbios_fwinfo_t fw;
272 uint_t ncomps;
273 smbios_fwinfo_comp_t *comps;
274 boolean_t ret = B_TRUE;
275
276 if (smbios_lookup_type(hdl, SMB_TYPE_FWINFO, &sp) == -1) {
277 warnx("failed to lookup SMBIOS fwinfo: %s",
278 smbios_errmsg(smbios_errno(hdl)));
279 return (B_FALSE);
280 }
281
282 if (smbios_info_fwinfo(hdl, sp.smbstr_id, &fw) == -1) {
283 warnx("failed to get firmware inventory: %s",
284 smbios_errmsg(smbios_errno(hdl)));
285 return (B_FALSE);
286 }
287
288 if (!smbios_test_fwinfo_verify_common(hdl, &sp, &fw)) {
289 ret = B_FALSE;
290 }
291
292 if (fw.smbfw_ncomps != 0) {
293 warnx("firmware inventory ncomps mismatch, found 0x%x",
294 fw.smbfw_ncomps);
295 ret = B_FALSE;
296 }
297
298 if (smbios_info_fwinfo_comps(hdl, sp.smbstr_id, &ncomps, &comps) != 0) {
299 warnx("failed to get components: %s",
300 smbios_errmsg(smbios_errno(hdl)));
301 ret = B_FALSE;
302 }
303
304 if (ncomps != 0) {
305 warnx("smbios_info_fwinfo_comps() returned wrong number of "
306 "comps: 0x%x", ncomps);
307 ret = B_FALSE;
308 }
309
310 if (comps != NULL) {
311 warnx("smbios_info_fwinfo_comps() gave a non-NULL comps "
312 "pointer: %p", comps);
313 ret = B_FALSE;
314 }
315
316 smbios_info_fwinfo_comps_free(hdl, ncomps, comps);
317
318 return (ret);
319 }
320
321 boolean_t
smbios_test_fwinfo_verify_invlen_comps(smbios_hdl_t * hdl)322 smbios_test_fwinfo_verify_invlen_comps(smbios_hdl_t *hdl)
323 {
324 smbios_struct_t sp;
325 smbios_fwinfo_t fw;
326 uint_t ncomps;
327 smbios_fwinfo_comp_t *comps;
328 boolean_t ret = B_TRUE;
329
330 if (smbios_lookup_type(hdl, SMB_TYPE_FWINFO, &sp) == -1) {
331 warnx("failed to lookup SMBIOS fwinfo: %s",
332 smbios_errmsg(smbios_errno(hdl)));
333 return (B_FALSE);
334 }
335
336 if (smbios_info_fwinfo(hdl, sp.smbstr_id, &fw) == -1) {
337 warnx("failed to get firmware inventory: %s",
338 smbios_errmsg(smbios_errno(hdl)));
339 return (B_FALSE);
340 }
341
342 if (!smbios_test_fwinfo_verify_common(hdl, &sp, &fw)) {
343 ret = B_FALSE;
344 }
345
346 if (fw.smbfw_ncomps != smbios_fwinfo_ncomps) {
347 warnx("firmware inventory ncomps mismatch, found 0x%x",
348 fw.smbfw_ncomps);
349 ret = B_FALSE;
350 }
351
352 if (smbios_info_fwinfo_comps(hdl, sp.smbstr_id, &ncomps, &comps) !=
353 -1) {
354 warnx("accidentally parsed invalid fwinfo components as "
355 "valid");
356 return (B_FALSE);
357 }
358
359 if (smbios_errno(hdl) != ESMB_SHORT) {
360 warnx("encountered wrong error for fwinfo comps, expected: "
361 "0x%x, found: 0x%x", ESMB_SHORT, smbios_errno(hdl));
362 return (B_FALSE);
363 }
364
365 return (ret);
366 }
367
368
369
370 boolean_t
smbios_test_fwinfo_verify_comps(smbios_hdl_t * hdl)371 smbios_test_fwinfo_verify_comps(smbios_hdl_t *hdl)
372 {
373 smbios_struct_t sp;
374 smbios_fwinfo_t fw;
375 uint_t ncomps;
376 smbios_fwinfo_comp_t *comps;
377 boolean_t ret = B_TRUE;
378
379 if (smbios_lookup_type(hdl, SMB_TYPE_FWINFO, &sp) == -1) {
380 warnx("failed to lookup SMBIOS fwinfo: %s",
381 smbios_errmsg(smbios_errno(hdl)));
382 return (B_FALSE);
383 }
384
385 if (smbios_info_fwinfo(hdl, sp.smbstr_id, &fw) == -1) {
386 warnx("failed to get firmware inventory: %s",
387 smbios_errmsg(smbios_errno(hdl)));
388 return (B_FALSE);
389 }
390
391 if (!smbios_test_fwinfo_verify_common(hdl, &sp, &fw)) {
392 ret = B_FALSE;
393 }
394
395 if (fw.smbfw_ncomps != smbios_fwinfo_ncomps) {
396 warnx("firmware inventory ncomps mismatch, found 0x%x",
397 fw.smbfw_ncomps);
398 ret = B_FALSE;
399 }
400
401 if (smbios_info_fwinfo_comps(hdl, sp.smbstr_id, &ncomps, &comps) != 0) {
402 warnx("failed to get components: %s",
403 smbios_errmsg(smbios_errno(hdl)));
404 ret = B_FALSE;
405 }
406
407 if (ncomps != smbios_fwinfo_ncomps) {
408 warnx("smbios_info_fwinfo_comps() returned wrong number of "
409 "comps: 0x%x", ncomps);
410 ret = B_FALSE;
411 }
412
413 if (comps == NULL) {
414 warnx("smbios_info_fwinfo_comps() gave a NULL comps pointer");
415 ret = B_FALSE;
416 } else {
417 for (uint_t i = 0; i < smbios_fwinfo_ncomps; i++) {
418 if (comps[i].smbfwe_id != 0x2300 + i) {
419 warnx("component id %u is wrong: 0x%" _PRIxID,
420 i, comps[i].smbfwe_id);
421 ret = B_FALSE;
422 }
423 }
424 }
425
426 smbios_info_fwinfo_comps_free(hdl, ncomps, comps);
427
428 return (ret);
429 }
430