diff options
| author | Dmitry Torokhov <[email protected]> | 2023-08-30 16:06:38 -0700 | 
|---|---|---|
| committer | Dmitry Torokhov <[email protected]> | 2023-08-30 16:06:38 -0700 | 
| commit | 1ac731c529cd4d6adbce134754b51ff7d822b145 (patch) | |
| tree | 143ab3f35ca5f3b69f583c84e6964b17139c2ec1 /drivers/base/firmware_loader/main.c | |
| parent | 07b4c950f27bef0362dc6ad7ee713aab61d58149 (diff) | |
| parent | 54116d442e001e1b6bd482122043b1870998a1f3 (diff) | |
Merge branch 'next' into for-linus
Prepare input updates for 6.6 merge window.
Diffstat (limited to 'drivers/base/firmware_loader/main.c')
| -rw-r--r-- | drivers/base/firmware_loader/main.c | 65 | 
1 files changed, 60 insertions, 5 deletions
diff --git a/drivers/base/firmware_loader/main.c b/drivers/base/firmware_loader/main.c index 017c4cdb219e..b58c42f1b1ce 100644 --- a/drivers/base/firmware_loader/main.c +++ b/drivers/base/firmware_loader/main.c @@ -493,9 +493,9 @@ fw_get_filesystem_firmware(struct device *device, struct fw_priv *fw_priv,  					     const void *in_buffer))  {  	size_t size; -	int i, len; +	int i, len, maxlen = 0;  	int rc = -ENOENT; -	char *path; +	char *path, *nt = NULL;  	size_t msize = INT_MAX;  	void *buffer = NULL; @@ -518,8 +518,17 @@ fw_get_filesystem_firmware(struct device *device, struct fw_priv *fw_priv,  		if (!fw_path[i][0])  			continue; -		len = snprintf(path, PATH_MAX, "%s/%s%s", -			       fw_path[i], fw_priv->fw_name, suffix); +		/* strip off \n from customized path */ +		maxlen = strlen(fw_path[i]); +		if (i == 0) { +			nt = strchr(fw_path[i], '\n'); +			if (nt) +				maxlen = nt - fw_path[i]; +		} + +		len = snprintf(path, PATH_MAX, "%.*s/%s%s", +			       maxlen, fw_path[i], +			       fw_priv->fw_name, suffix);  		if (len >= PATH_MAX) {  			rc = -ENAMETOOLONG;  			break; @@ -791,6 +800,50 @@ static void fw_abort_batch_reqs(struct firmware *fw)  	mutex_unlock(&fw_lock);  } +#if defined(CONFIG_FW_LOADER_DEBUG) +#include <crypto/hash.h> +#include <crypto/sha2.h> + +static void fw_log_firmware_info(const struct firmware *fw, const char *name, struct device *device) +{ +	struct shash_desc *shash; +	struct crypto_shash *alg; +	u8 *sha256buf; +	char *outbuf; + +	alg = crypto_alloc_shash("sha256", 0, 0); +	if (IS_ERR(alg)) +		return; + +	sha256buf = kmalloc(SHA256_DIGEST_SIZE, GFP_KERNEL); +	outbuf = kmalloc(SHA256_BLOCK_SIZE + 1, GFP_KERNEL); +	shash = kmalloc(sizeof(*shash) + crypto_shash_descsize(alg), GFP_KERNEL); +	if (!sha256buf || !outbuf || !shash) +		goto out_free; + +	shash->tfm = alg; + +	if (crypto_shash_digest(shash, fw->data, fw->size, sha256buf) < 0) +		goto out_shash; + +	for (int i = 0; i < SHA256_DIGEST_SIZE; i++) +		sprintf(&outbuf[i * 2], "%02x", sha256buf[i]); +	outbuf[SHA256_BLOCK_SIZE] = 0; +	dev_dbg(device, "Loaded FW: %s, sha256: %s\n", name, outbuf); + +out_shash: +	crypto_free_shash(alg); +out_free: +	kfree(shash); +	kfree(outbuf); +	kfree(sha256buf); +} +#else +static void fw_log_firmware_info(const struct firmware *fw, const char *name, +				 struct device *device) +{} +#endif +  /* called from request_firmware() and request_firmware_work_func() */  static int  _request_firmware(const struct firmware **firmware_p, const char *name, @@ -861,11 +914,13 @@ _request_firmware(const struct firmware **firmware_p, const char *name,  	revert_creds(old_cred);  	put_cred(kern_cred); - out: +out:  	if (ret < 0) {  		fw_abort_batch_reqs(fw);  		release_firmware(fw);  		fw = NULL; +	} else { +		fw_log_firmware_info(fw, name, device);  	}  	*firmware_p = fw;  |