libfdt: Check for multiple/invalid root nodes
It is possible to construct a devicetree blob with multiple root nodes. Update fdt_check_full() to check for this, along with a root node with an invalid name. CVE-2021-27097 Signed-off-by: Simon Glass <sjg@chromium.org> Reported-by: Bruce Monroe <bruce.monroe@intel.com> Reported-by: Arie Haenel <arie.haenel@intel.com> Reported-by: Julien Lenoir <julien.lenoir@intel.com>
This commit is contained in:
		
							parent
							
								
									6f3c2d8aa5
								
							
						
					
					
						commit
						124c255731
					
				|  | @ -867,6 +867,7 @@ int fdt_check_full(const void *fdt, size_t bufsize) | |||
| 	unsigned depth = 0; | ||||
| 	const void *prop; | ||||
| 	const char *propname; | ||||
| 	bool expect_end = false; | ||||
| 
 | ||||
| 	if (bufsize < FDT_V1_SIZE) | ||||
| 		return -FDT_ERR_TRUNCATED; | ||||
|  | @ -887,6 +888,10 @@ int fdt_check_full(const void *fdt, size_t bufsize) | |||
| 		if (nextoffset < 0) | ||||
| 			return nextoffset; | ||||
| 
 | ||||
| 		/* If we see two root nodes, something is wrong */ | ||||
| 		if (expect_end && tag != FDT_END) | ||||
| 			return -FDT_ERR_BADLAYOUT; | ||||
| 
 | ||||
| 		switch (tag) { | ||||
| 		case FDT_NOP: | ||||
| 			break; | ||||
|  | @ -900,12 +905,24 @@ int fdt_check_full(const void *fdt, size_t bufsize) | |||
| 			depth++; | ||||
| 			if (depth > INT_MAX) | ||||
| 				return -FDT_ERR_BADSTRUCTURE; | ||||
| 
 | ||||
| 			/* The root node must have an empty name */ | ||||
| 			if (depth == 1) { | ||||
| 				const char *name; | ||||
| 				int len; | ||||
| 
 | ||||
| 				name = fdt_get_name(fdt, offset, &len); | ||||
| 				if (*name || len) | ||||
| 					return -FDT_ERR_BADLAYOUT; | ||||
| 			} | ||||
| 			break; | ||||
| 
 | ||||
| 		case FDT_END_NODE: | ||||
| 			if (depth == 0) | ||||
| 				return -FDT_ERR_BADSTRUCTURE; | ||||
| 			depth--; | ||||
| 			if (depth == 0) | ||||
| 				expect_end = true; | ||||
| 			break; | ||||
| 
 | ||||
| 		case FDT_PROP: | ||||
|  |  | |||
|  | @ -255,7 +255,8 @@ def test_vboot(u_boot_console, sha_algo, padding, sign_options, required, | |||
|             util.run_and_log_expect_exception( | ||||
|                 cons, [fit_check_sign, '-f', efit, '-k', dtb], | ||||
|                 1, 'Failed to verify required signature') | ||||
|             run_bootm(sha_algo, 'evil fakeroot', 'Bad Data Hash', False, efit) | ||||
|             run_bootm(sha_algo, 'evil fakeroot', 'Bad FIT kernel image format', | ||||
|                       False, efit) | ||||
| 
 | ||||
|             # Try adding an @ to the kernel node name. This should be detected. | ||||
|             efit = '%stest.evilk.fit' % tmpdir | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue