forked from Mirrors/opensbi
		
	lib: sbi: change sbi_hart_features.extensions as an array
In the future there may be a lot of ISA extensions, a 'long' may not
be able to accommodate, changed to an array for the future.
Addresses-Coverity-ID: 1568357 Out-of-bounds access
Fixes: 6259b2ec2d ("lib: utils/fdt: Fix fdt_parse_isa_extensions()
implementation")
Signed-off-by: Xiang W <wxjstz@126.com>
Reviewed-by: Heinrich Schuchardt <heinrich.schuchardt@canonical.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
			
			
This commit is contained in:
		@@ -11,6 +11,7 @@
 | 
			
		||||
#define __SBI_HART_H__
 | 
			
		||||
 | 
			
		||||
#include <sbi/sbi_types.h>
 | 
			
		||||
#include <sbi/sbi_bitops.h>
 | 
			
		||||
 | 
			
		||||
/** Possible privileged specification versions of a hart */
 | 
			
		||||
enum sbi_hart_priv_versions {
 | 
			
		||||
@@ -67,7 +68,7 @@ enum sbi_hart_extensions {
 | 
			
		||||
struct sbi_hart_features {
 | 
			
		||||
	bool detected;
 | 
			
		||||
	int priv_version;
 | 
			
		||||
	unsigned long extensions;
 | 
			
		||||
	unsigned long extensions[BITS_TO_LONGS(SBI_HART_EXT_MAX)];
 | 
			
		||||
	unsigned int pmp_count;
 | 
			
		||||
	unsigned int pmp_addr_bits;
 | 
			
		||||
	unsigned long pmp_gran;
 | 
			
		||||
 
 | 
			
		||||
@@ -620,9 +620,9 @@ static inline void __sbi_hart_update_extension(
 | 
			
		||||
					bool enable)
 | 
			
		||||
{
 | 
			
		||||
	if (enable)
 | 
			
		||||
		hfeatures->extensions |= BIT(ext);
 | 
			
		||||
		__set_bit(ext, hfeatures->extensions);
 | 
			
		||||
	else
 | 
			
		||||
		hfeatures->extensions &= ~BIT(ext);
 | 
			
		||||
		__clear_bit(ext, hfeatures->extensions);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
@@ -655,7 +655,7 @@ bool sbi_hart_has_extension(struct sbi_scratch *scratch,
 | 
			
		||||
	struct sbi_hart_features *hfeatures =
 | 
			
		||||
			sbi_scratch_offset_ptr(scratch, hart_features_offset);
 | 
			
		||||
 | 
			
		||||
	if (hfeatures->extensions & BIT(ext))
 | 
			
		||||
	if (__test_bit(ext, hfeatures->extensions))
 | 
			
		||||
		return true;
 | 
			
		||||
	else
 | 
			
		||||
		return false;
 | 
			
		||||
@@ -721,24 +721,16 @@ void sbi_hart_get_extensions_str(struct sbi_scratch *scratch,
 | 
			
		||||
		return;
 | 
			
		||||
	sbi_memset(extensions_str, 0, nestr);
 | 
			
		||||
 | 
			
		||||
	if (!hfeatures->extensions)
 | 
			
		||||
		goto done;
 | 
			
		||||
 | 
			
		||||
	do {
 | 
			
		||||
		if (hfeatures->extensions & BIT(ext)) {
 | 
			
		||||
			temp = sbi_hart_extension_id2string(ext);
 | 
			
		||||
			if (temp) {
 | 
			
		||||
				sbi_snprintf(extensions_str + offset,
 | 
			
		||||
					     nestr - offset,
 | 
			
		||||
					     "%s,", temp);
 | 
			
		||||
				offset = offset + sbi_strlen(temp) + 1;
 | 
			
		||||
			}
 | 
			
		||||
	for_each_set_bit(ext, hfeatures->extensions, SBI_HART_EXT_MAX) {
 | 
			
		||||
		temp = sbi_hart_extension_id2string(ext);
 | 
			
		||||
		if (temp) {
 | 
			
		||||
			sbi_snprintf(extensions_str + offset,
 | 
			
		||||
				     nestr - offset,
 | 
			
		||||
				     "%s,", temp);
 | 
			
		||||
			offset = offset + sbi_strlen(temp) + 1;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
		ext++;
 | 
			
		||||
	} while (ext < SBI_HART_EXT_MAX);
 | 
			
		||||
 | 
			
		||||
done:
 | 
			
		||||
	if (offset)
 | 
			
		||||
		extensions_str[offset - 1] = '\0';
 | 
			
		||||
	else
 | 
			
		||||
@@ -808,7 +800,7 @@ static int hart_detect_features(struct sbi_scratch *scratch)
 | 
			
		||||
		return 0;
 | 
			
		||||
 | 
			
		||||
	/* Clear hart features */
 | 
			
		||||
	hfeatures->extensions = 0;
 | 
			
		||||
	sbi_memset(hfeatures->extensions, 0, sizeof(hfeatures->extensions));
 | 
			
		||||
	hfeatures->pmp_count = 0;
 | 
			
		||||
	hfeatures->mhpm_mask = 0;
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -215,7 +215,7 @@ static int generic_extensions_init(struct sbi_hart_features *hfeatures)
 | 
			
		||||
 | 
			
		||||
	/* Parse the ISA string from FDT and enable the listed extensions */
 | 
			
		||||
	rc = fdt_parse_isa_extensions(fdt_get_address(), current_hartid(),
 | 
			
		||||
				      &hfeatures->extensions);
 | 
			
		||||
				      hfeatures->extensions);
 | 
			
		||||
 | 
			
		||||
	if (rc)
 | 
			
		||||
		return rc;
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user