Re: [PATCH] image: Ensure image header name is null terminated
Hi, On Wed, 14 Sept 2022 at 16:11, Tom Rini wrote: > > On Tue, Aug 23, 2022 at 03:59:07PM +1000, Joel Stanley wrote: > > > When building with GCC 12: > > > > ../include/image.h:779:9: warning: ‘strncpy’ specified bound 32 equals > > destination size [-Wstringop-truncation] > > 779 | strncpy(image_get_name(hdr), name, IH_NMLEN); > > | ^~~~ > > > > Ensure the copied string is null terminated by always setting the final > > byte to 0. Shorten the strncpy to IH_NMLEN-1 as we will always overwrite > > the last byte. > > > > We can't use strlcpy as this is code is built on the host as well as the > > target. > > > > Fixes: b97a2a0a21f2 ("[new uImage] Define a API for image handling > > operations") > > Signed-off-by: Joel Stanley > > So this breaks some tests: > https://source.denx.de/u-boot/u-boot/-/jobs/496773#L201 > and it's not clear to me if the problem is the tests or the fix itself > (should we be doing a buffer of IH_NMLEN+1 and ensuring that's NULL > terminated? I don't know). My reading of it is that the field is of length IH_NMLEN and there is only a terminator if the string is shorter than that. So I don't think this patch is correct / needed. Perhaps we can find a way to silence the warning, e.g. using memcyp(xx,yy, min(IH_NMLEN, strnlen(yy, ...) + 1)) ? Regards, Simon
Re: [PATCH] image: Ensure image header name is null terminated
On Tue, Aug 23, 2022 at 03:59:07PM +1000, Joel Stanley wrote: > When building with GCC 12: > > ../include/image.h:779:9: warning: ‘strncpy’ specified bound 32 equals > destination size [-Wstringop-truncation] > 779 | strncpy(image_get_name(hdr), name, IH_NMLEN); > | ^~~~ > > Ensure the copied string is null terminated by always setting the final > byte to 0. Shorten the strncpy to IH_NMLEN-1 as we will always overwrite > the last byte. > > We can't use strlcpy as this is code is built on the host as well as the > target. > > Fixes: b97a2a0a21f2 ("[new uImage] Define a API for image handling > operations") > Signed-off-by: Joel Stanley So this breaks some tests: https://source.denx.de/u-boot/u-boot/-/jobs/496773#L201 and it's not clear to me if the problem is the tests or the fix itself (should we be doing a buffer of IH_NMLEN+1 and ensuring that's NULL terminated? I don't know). -- Tom signature.asc Description: PGP signature
Re: [PATCH] image: Ensure image header name is null terminated
On 23/08/2022 15.38, Simon Glass wrote: > Hi John, > > On Tue, 23 Aug 2022 at 03:46, John Keeping wrote: >> >> On Tue, Aug 23, 2022 at 03:59:07PM +1000, Joel Stanley wrote: >>> When building with GCC 12: >>> >>> ../include/image.h:779:9: warning: ‘strncpy’ specified bound 32 equals >>> destination size [-Wstringop-truncation] >>> 779 | strncpy(image_get_name(hdr), name, IH_NMLEN); >>> | ^~~~ >>> >>> Ensure the copied string is null terminated by always setting the final >>> byte to 0. Shorten the strncpy to IH_NMLEN-1 as we will always overwrite >>> the last byte. >>> >>> We can't use strlcpy as this is code is built on the host as well as the >>> target. >> >> Since this is in the header, isn't the point that it doesn't need to be >> null-terminated? >> >> When printing we're careful to use: >> >> "%.*s", IH_NMLEN, ... >> >> so I think the warning is wrong here - we want both of the strncpy() >> behaviours that are normally considered strange: >> >> - it's okay not to null terminate as this is an explicitly sized field >> >> - we want to pad the whole field with zeroes if the string is short > > That's my understanding too. We are careful to avoid expecting a > terminator. I am not sure what to do with the warning though Maybe this could be some inspiration: info gcc 'nonstring' The 'nonstring' variable attribute specifies that an object or member declaration with type array of 'char', 'signed char', or 'unsigned char', or pointer to such a type is intended to store character arrays that do not necessarily contain a terminating 'NUL'. This is useful in detecting uses of such arrays or pointers with functions that expect 'NUL'-terminated strings, and to avoid warnings when such an array or pointer is used as an argument to a bounded string manipulation function such as 'strncpy'. For example, without the attribute, GCC will issue a warning for the 'strncpy' call below because it may truncate the copy without appending the terminating 'NUL' character. Using the attribute makes it possible to suppress the warning. However, when the array is declared with the attribute the call to 'strlen' is diagnosed because when the array doesn't contain a 'NUL'-terminated string the call is undefined. To copy, compare, of search non-string character arrays use the 'memcpy', 'memcmp', 'memchr', and other functions that operate on arrays of bytes. In addition, calling 'strnlen' and 'strndup' with such arrays is safe provided a suitable bound is specified, and not diagnosed. struct Data { char name [32] __attribute__ ((nonstring)); }; int f (struct Data *pd, const char *s) { strncpy (pd->name, s, sizeof pd->name); ... return strlen (pd->name); // unsafe, gets a warning } [https://gcc.gnu.org/onlinedocs/gcc-12.2.0/gcc/Common-Variable-Attributes.html#Common-Variable-Attributes]
Re: [PATCH] image: Ensure image header name is null terminated
Hi John, On Tue, 23 Aug 2022 at 03:46, John Keeping wrote: > > On Tue, Aug 23, 2022 at 03:59:07PM +1000, Joel Stanley wrote: > > When building with GCC 12: > > > > ../include/image.h:779:9: warning: ‘strncpy’ specified bound 32 equals > > destination size [-Wstringop-truncation] > > 779 | strncpy(image_get_name(hdr), name, IH_NMLEN); > > | ^~~~ > > > > Ensure the copied string is null terminated by always setting the final > > byte to 0. Shorten the strncpy to IH_NMLEN-1 as we will always overwrite > > the last byte. > > > > We can't use strlcpy as this is code is built on the host as well as the > > target. > > Since this is in the header, isn't the point that it doesn't need to be > null-terminated? > > When printing we're careful to use: > > "%.*s", IH_NMLEN, ... > > so I think the warning is wrong here - we want both of the strncpy() > behaviours that are normally considered strange: > > - it's okay not to null terminate as this is an explicitly sized field > > - we want to pad the whole field with zeroes if the string is short That's my understanding too. We are careful to avoid expecting a terminator. I am not sure what to do with the warning though Regards, Simon > > > Fixes: b97a2a0a21f2 ("[new uImage] Define a API for image handling > > operations") > > Signed-off-by: Joel Stanley > > --- > > include/image.h | 5 - > > 1 file changed, 4 insertions(+), 1 deletion(-) > > > > diff --git a/include/image.h b/include/image.h > > index e4c6a50b885f..665b2278b7fb 100644 > > --- a/include/image.h > > +++ b/include/image.h > > @@ -776,7 +776,10 @@ image_set_hdr_b(comp)/* image_set_comp */ > > > > static inline void image_set_name(image_header_t *hdr, const char *name) > > { > > - strncpy(image_get_name(hdr), name, IH_NMLEN); > > + char *hdr_name = image_get_name(hdr); > > + > > + strncpy(hdr_name, name, IH_NMLEN - 1); > > + hdr_name[IH_NMLEN - 1] = '\0'; > > } > > > > int image_check_hcrc(const image_header_t *hdr); > > -- > > 2.35.1 > >
Re: [PATCH] image: Ensure image header name is null terminated
On Tue, Aug 23, 2022 at 03:59:07PM +1000, Joel Stanley wrote: > When building with GCC 12: > > ../include/image.h:779:9: warning: ‘strncpy’ specified bound 32 equals > destination size [-Wstringop-truncation] > 779 | strncpy(image_get_name(hdr), name, IH_NMLEN); > | ^~~~ > > Ensure the copied string is null terminated by always setting the final > byte to 0. Shorten the strncpy to IH_NMLEN-1 as we will always overwrite > the last byte. > > We can't use strlcpy as this is code is built on the host as well as the > target. Since this is in the header, isn't the point that it doesn't need to be null-terminated? When printing we're careful to use: "%.*s", IH_NMLEN, ... so I think the warning is wrong here - we want both of the strncpy() behaviours that are normally considered strange: - it's okay not to null terminate as this is an explicitly sized field - we want to pad the whole field with zeroes if the string is short > Fixes: b97a2a0a21f2 ("[new uImage] Define a API for image handling > operations") > Signed-off-by: Joel Stanley > --- > include/image.h | 5 - > 1 file changed, 4 insertions(+), 1 deletion(-) > > diff --git a/include/image.h b/include/image.h > index e4c6a50b885f..665b2278b7fb 100644 > --- a/include/image.h > +++ b/include/image.h > @@ -776,7 +776,10 @@ image_set_hdr_b(comp)/* image_set_comp */ > > static inline void image_set_name(image_header_t *hdr, const char *name) > { > - strncpy(image_get_name(hdr), name, IH_NMLEN); > + char *hdr_name = image_get_name(hdr); > + > + strncpy(hdr_name, name, IH_NMLEN - 1); > + hdr_name[IH_NMLEN - 1] = '\0'; > } > > int image_check_hcrc(const image_header_t *hdr); > -- > 2.35.1 >
Re: [PATCH] image: Ensure image header name is null terminated
Dear Joel, In message <20220823055907.416060-1-j...@jms.id.au> you wrote: > When building with GCC 12: > > ../include/image.h:779:9: warning: ‘strncpy’ specified bound 32 equals > destination size [-Wstringop-truncation] > 779 | strncpy(image_get_name(hdr), name, IH_NMLEN); > | ^~~~ > > Ensure the copied string is null terminated by always setting the final > byte to 0. Shorten the strncpy to IH_NMLEN-1 as we will always overwrite > the last byte. > > We can't use strlcpy as this is code is built on the host as well as the > target. > > Fixes: b97a2a0a21f2 ("[new uImage] Define a API for image handling > operations") > Signed-off-by: Joel Stanley > --- > include/image.h | 5 - > 1 file changed, 4 insertions(+), 1 deletion(-) > > diff --git a/include/image.h b/include/image.h > index e4c6a50b885f..665b2278b7fb 100644 > --- a/include/image.h > +++ b/include/image.h > @@ -776,7 +776,10 @@ image_set_hdr_b(comp)/* image_set_comp */ > > static inline void image_set_name(image_header_t *hdr, const char *name) > { > - strncpy(image_get_name(hdr), name, IH_NMLEN); > + char *hdr_name = image_get_name(hdr); > + > + strncpy(hdr_name, name, IH_NMLEN - 1); > + hdr_name[IH_NMLEN - 1] = '\0'; > } Why don't you use strlcpy() instead? This covers exactly the situation we have here. Best regards, Wolfgang Denk -- DENX Software Engineering GmbH, Managing Director: Wolfgang Denk HRB 165235 Munich, Office: Kirchenstr. 5, 82194 Groebenzell, Germany Phone: (+49)-8142-66989-10 Fax: (+49)-8142-66989-80 Email: w...@denx.de panic: can't find /
[PATCH] image: Ensure image header name is null terminated
When building with GCC 12: ../include/image.h:779:9: warning: ‘strncpy’ specified bound 32 equals destination size [-Wstringop-truncation] 779 | strncpy(image_get_name(hdr), name, IH_NMLEN); | ^~~~ Ensure the copied string is null terminated by always setting the final byte to 0. Shorten the strncpy to IH_NMLEN-1 as we will always overwrite the last byte. We can't use strlcpy as this is code is built on the host as well as the target. Fixes: b97a2a0a21f2 ("[new uImage] Define a API for image handling operations") Signed-off-by: Joel Stanley --- include/image.h | 5 - 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/include/image.h b/include/image.h index e4c6a50b885f..665b2278b7fb 100644 --- a/include/image.h +++ b/include/image.h @@ -776,7 +776,10 @@ image_set_hdr_b(comp) /* image_set_comp */ static inline void image_set_name(image_header_t *hdr, const char *name) { - strncpy(image_get_name(hdr), name, IH_NMLEN); + char *hdr_name = image_get_name(hdr); + + strncpy(hdr_name, name, IH_NMLEN - 1); + hdr_name[IH_NMLEN - 1] = '\0'; } int image_check_hcrc(const image_header_t *hdr); -- 2.35.1