[V2,3/5] firmware: tegra: print version tag at full

Message ID 1539885344-18974-4-git-send-email-talho@nvidia.com
State New
Headers show
Series
  • BPMP-FW version query ("tag") update
Related show

Commit Message

Timo Alho Oct. 18, 2018, 5:55 p.m.
Last two characters of the version tag that is 32 bytes long were
stripped out.

Signed-off-by: Timo Alho <talho@nvidia.com>
---
 drivers/firmware/tegra/bpmp.c | 11 ++++++-----
 1 file changed, 6 insertions(+), 5 deletions(-)

Comments

Sivaram Nair Oct. 18, 2018, 6:15 p.m. | #1
On Thu, Oct 18, 2018 at 08:55:42PM +0300, Timo Alho wrote:
> Last two characters of the version tag that is 32 bytes long were
> stripped out.
> 
> Signed-off-by: Timo Alho <talho@nvidia.com>
> ---
>  drivers/firmware/tegra/bpmp.c | 11 ++++++-----
>  1 file changed, 6 insertions(+), 5 deletions(-)

Acked-by: Sivaram Nair <sivaramn@nvidia.com>
Jon Hunter Oct. 19, 2018, 12:07 p.m. | #2
On 18/10/2018 18:55, Timo Alho wrote:
> Last two characters of the version tag that is 32 bytes long were
> stripped out.
> 
> Signed-off-by: Timo Alho <talho@nvidia.com>
> ---
>  drivers/firmware/tegra/bpmp.c | 11 ++++++-----
>  1 file changed, 6 insertions(+), 5 deletions(-)
> 
> diff --git a/drivers/firmware/tegra/bpmp.c b/drivers/firmware/tegra/bpmp.c
> index 79859ab..a7d8954 100644
> --- a/drivers/firmware/tegra/bpmp.c
> +++ b/drivers/firmware/tegra/bpmp.c
> @@ -558,8 +558,9 @@ static int tegra_bpmp_get_firmware_tag(struct tegra_bpmp *bpmp, char *tag,
>  	dma_addr_t phys;
>  	void *virt;
>  	int err;
> +	const size_t tag_sz = 32;

Why not a #define for this?

>  
> -	virt = dma_alloc_coherent(bpmp->dev, MSG_DATA_MIN_SZ, &phys,
> +	virt = dma_alloc_coherent(bpmp->dev, tag_sz, &phys,
>  				  GFP_KERNEL | GFP_DMA32);
>  	if (!virt)
>  		return -ENOMEM;
> @@ -577,9 +578,9 @@ static int tegra_bpmp_get_firmware_tag(struct tegra_bpmp *bpmp, char *tag,
>  	local_irq_restore(flags);
>  
>  	if (err == 0)
> -		strlcpy(tag, virt, size);
> +		memcpy(tag, virt, min(size, tag_sz));

Should it be an error if size is less than 32? Otherwise characters
could be silently stripped.

Cheers
Jon
Thierry Reding Oct. 22, 2018, 9:37 a.m. | #3
On Fri, Oct 19, 2018 at 01:07:19PM +0100, Jon Hunter wrote:
> 
> 
> On 18/10/2018 18:55, Timo Alho wrote:
> > Last two characters of the version tag that is 32 bytes long were
> > stripped out.
> > 
> > Signed-off-by: Timo Alho <talho@nvidia.com>
> > ---
> >  drivers/firmware/tegra/bpmp.c | 11 ++++++-----
> >  1 file changed, 6 insertions(+), 5 deletions(-)
> > 
> > diff --git a/drivers/firmware/tegra/bpmp.c b/drivers/firmware/tegra/bpmp.c
> > index 79859ab..a7d8954 100644
> > --- a/drivers/firmware/tegra/bpmp.c
> > +++ b/drivers/firmware/tegra/bpmp.c
> > @@ -558,8 +558,9 @@ static int tegra_bpmp_get_firmware_tag(struct tegra_bpmp *bpmp, char *tag,
> >  	dma_addr_t phys;
> >  	void *virt;
> >  	int err;
> > +	const size_t tag_sz = 32;
> 
> Why not a #define for this?
> 
> >  
> > -	virt = dma_alloc_coherent(bpmp->dev, MSG_DATA_MIN_SZ, &phys,
> > +	virt = dma_alloc_coherent(bpmp->dev, tag_sz, &phys,
> >  				  GFP_KERNEL | GFP_DMA32);
> >  	if (!virt)
> >  		return -ENOMEM;
> > @@ -577,9 +578,9 @@ static int tegra_bpmp_get_firmware_tag(struct tegra_bpmp *bpmp, char *tag,
> >  	local_irq_restore(flags);
> >  
> >  	if (err == 0)
> > -		strlcpy(tag, virt, size);
> > +		memcpy(tag, virt, min(size, tag_sz));
> 
> Should it be an error if size is less than 32? Otherwise characters
> could be silently stripped.

Is the tag guaranteed to always be 32 characters? If it was possible for
it to be less, we'd now be copying out uninitialized characters, right?
I think dma_alloc_coherent() zeroes memory, so this should be safe, but
we should double-check to make sure we're not potentially leaking data
here.

Thierry
Timo Alho Oct. 22, 2018, 11:35 a.m. | #4
On 22.10.2018 12.37, Thierry Reding wrote:
> On Fri, Oct 19, 2018 at 01:07:19PM +0100, Jon Hunter wrote:
>>
>>
>> On 18/10/2018 18:55, Timo Alho wrote:
>>> Last two characters of the version tag that is 32 bytes long were
>>> stripped out.
>>>
>>> Signed-off-by: Timo Alho <talho@nvidia.com>
>>> ---
>>>   drivers/firmware/tegra/bpmp.c | 11 ++++++-----
>>>   1 file changed, 6 insertions(+), 5 deletions(-)
>>>
>>> diff --git a/drivers/firmware/tegra/bpmp.c b/drivers/firmware/tegra/bpmp.c
>>> index 79859ab..a7d8954 100644
>>> --- a/drivers/firmware/tegra/bpmp.c
>>> +++ b/drivers/firmware/tegra/bpmp.c
>>> @@ -558,8 +558,9 @@ static int tegra_bpmp_get_firmware_tag(struct tegra_bpmp *bpmp, char *tag,
>>>   	dma_addr_t phys;
>>>   	void *virt;
>>>   	int err;
>>> +	const size_t tag_sz = 32;
>>
>> Why not a #define for this?
>>
>>>   
>>> -	virt = dma_alloc_coherent(bpmp->dev, MSG_DATA_MIN_SZ, &phys,
>>> +	virt = dma_alloc_coherent(bpmp->dev, tag_sz, &phys,
>>>   				  GFP_KERNEL | GFP_DMA32);
>>>   	if (!virt)
>>>   		return -ENOMEM;
>>> @@ -577,9 +578,9 @@ static int tegra_bpmp_get_firmware_tag(struct tegra_bpmp *bpmp, char *tag,
>>>   	local_irq_restore(flags);
>>>   
>>>   	if (err == 0)
>>> -		strlcpy(tag, virt, size);
>>> +		memcpy(tag, virt, min(size, tag_sz));
>>
>> Should it be an error if size is less than 32? Otherwise characters
>> could be silently stripped.
> 
> Is the tag guaranteed to always be 32 characters? If it was possible for
> it to be less, we'd now be copying out uninitialized characters, right?
> I think dma_alloc_coherent() zeroes memory, so this should be safe, but
> we should double-check to make sure we're not potentially leaking data
> here.

tag is always 32 characters. So I'll just update the code to check that 
'size' parameter always equals to 32 to avoid any further complexity here.

-Timo

Patch

diff --git a/drivers/firmware/tegra/bpmp.c b/drivers/firmware/tegra/bpmp.c
index 79859ab..a7d8954 100644
--- a/drivers/firmware/tegra/bpmp.c
+++ b/drivers/firmware/tegra/bpmp.c
@@ -558,8 +558,9 @@  static int tegra_bpmp_get_firmware_tag(struct tegra_bpmp *bpmp, char *tag,
 	dma_addr_t phys;
 	void *virt;
 	int err;
+	const size_t tag_sz = 32;
 
-	virt = dma_alloc_coherent(bpmp->dev, MSG_DATA_MIN_SZ, &phys,
+	virt = dma_alloc_coherent(bpmp->dev, tag_sz, &phys,
 				  GFP_KERNEL | GFP_DMA32);
 	if (!virt)
 		return -ENOMEM;
@@ -577,9 +578,9 @@  static int tegra_bpmp_get_firmware_tag(struct tegra_bpmp *bpmp, char *tag,
 	local_irq_restore(flags);
 
 	if (err == 0)
-		strlcpy(tag, virt, size);
+		memcpy(tag, virt, min(size, tag_sz));
 
-	dma_free_coherent(bpmp->dev, MSG_DATA_MIN_SZ, virt, phys);
+	dma_free_coherent(bpmp->dev, tag_sz, virt, phys);
 
 	return err;
 }
@@ -820,13 +821,13 @@  static int tegra_bpmp_probe(struct platform_device *pdev)
 		goto free_mrq;
 	}
 
-	err = tegra_bpmp_get_firmware_tag(bpmp, tag, sizeof(tag) - 1);
+	err = tegra_bpmp_get_firmware_tag(bpmp, tag, sizeof(tag));
 	if (err < 0) {
 		dev_err(&pdev->dev, "failed to get firmware tag: %d\n", err);
 		goto free_mrq;
 	}
 
-	dev_info(&pdev->dev, "firmware: %s\n", tag);
+	dev_info(&pdev->dev, "firmware: %.*s\n", sizeof(tag), tag);
 
 	platform_set_drvdata(pdev, bpmp);