grub-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [PATCH 3/6] commands/i386/pc/sendkey: Fix "writing 1 byte into a reg


From: Michael Chang
Subject: Re: [PATCH 3/6] commands/i386/pc/sendkey: Fix "writing 1 byte into a region of size 0" build error
Date: Mon, 14 Mar 2022 12:16:16 +0800
User-agent: Mutt/1.10.1 (2018-07-13)

On Fri, Mar 11, 2022 at 12:35:57AM +0100, Daniel Kiper wrote:
> Latest GCC may complain in that way:
> 
>   commands/i386/pc/sendkey.c: In function ‘grub_sendkey_postboot’:
>   commands/i386/pc/sendkey.c:223:21: error: writing 1 byte into a region of 
> size 0 [-Werror=stringop-overflow=]
>     223 |   *((char *) 0x41a) = 0x1e;
>         |   ~~~~~~~~~~~~~~~~~~^~~~~~
> 
> The volatile keyword addition helps and additionally assures us the
> compiler will not optimize out fixed assignments.
> 
> Signed-off-by: Daniel Kiper <daniel.kiper@oracle.com>
> ---
>  grub-core/commands/i386/pc/sendkey.c | 8 ++++----
>  1 file changed, 4 insertions(+), 4 deletions(-)
> 
> diff --git a/grub-core/commands/i386/pc/sendkey.c 
> b/grub-core/commands/i386/pc/sendkey.c
> index 26d9acd3d..ab4bca9e9 100644
> --- a/grub-core/commands/i386/pc/sendkey.c
> +++ b/grub-core/commands/i386/pc/sendkey.c
> @@ -220,8 +220,8 @@ grub_sendkey_postboot (void)
>  
>    *flags = oldflags;
>  
> -  *((char *) 0x41a) = 0x1e;
> -  *((char *) 0x41c) = 0x1e;
> +  *((volatile char *) 0x41a) = 0x1e;
> +  *((volatile char *) 0x41c) = 0x1e;
>  
>    return GRUB_ERR_NONE;
>  }
> @@ -236,8 +236,8 @@ grub_sendkey_preboot (int noret __attribute__ ((unused)))
>    oldflags = *flags;
>    
>    /* Set the sendkey.  */
> -  *((char *) 0x41a) = 0x1e;
> -  *((char *) 0x41c) = keylen + 0x1e;
> +  *((volatile char *) 0x41a) = 0x1e;
> +  *((volatile char *) 0x41c) = keylen + 0x1e;
>    grub_memcpy ((char *) 0x41e, sendkey, 0x20);
>  
>    /* Transform "any ctrl" to "right ctrl" flag.  */
> -- 
> 2.11.0

Unfortunately the volatile keyword doesn't help on a more recent gcc-12
build [1]. With that -Warray-bounds warning [2] is emitted this time
than -Wstringop-overflow.

I believe this is caused by this gcc regression in which hardwired
literal address is treated as NULL plus an offset, while there's no good
way to tell that literal address being an invalid accesses at non-zero
offsets to null pointers or not:

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=99578

Before upstream comes up with a solution or introducing new annotation
for literal pointer. For the time being their recommedation is to
suppress the warning with #pragma or use volatile pointer which appears
to not work for gcc-12.

Instead of inserting #pragma all over the places to avoid the diagnose
of Warray-bounds. I think we can try to port absolute_pointer [3] and
RELOC_HIDE [4] used by the linux kernel to disconnect a pointer using
literal address from its original object hence gcc won't make
assumptions on the boundary while doing pointer arithmetic. This sounds
a better way to go as it can work across gcc versions.

I am halfway in preparing the patch to wrap literal pointers in
absolute_pointer. Before posting it here, I'd like to know do we have
any other prefernece like just disabling it via #pragma as that sounds
more like a norm?

Thanks,
Michael

[3]
https://elixir.bootlin.com/linux/v5.16.14/source/include/linux/compiler.h#L180

[4]
https://elixir.bootlin.com/linux/v5.16.14/source/include/linux/compiler-gcc.h#L31

[1]
abuild@local:~> gcc --version
gcc (SUSE Linux) 12.0.1 20220228 (experimental) [revision 
37b583b9d7719f663656ce65ac822c11471fb540]
Copyright (C) 2022 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

[2]
[  195s] ../../grub-core/commands/i386/pc/sendkey.c: In function 
'grub_sendkey_postboot':
[  195s] ../../grub-core/commands/i386/pc/sendkey.c:221:3: error: array 
subscript 0 is outside array bounds of 'grub_uint32_t[0]' {aka 'unsigned 
int[]'} [-Werror=array-bounds]
[  195s]   221 |   *flags = oldflags;
[  195s]       |   ^~~~~~
[  195s] ../../grub-core/commands/i386/pc/sendkey.c:223:3: error: array 
subscript 0 is outside array bounds of 'volatile char[0]' [-Werror=array-bounds]
[  195s]   223 |   *((volatile char *) 0x41a) = 0x1e;
[  195s]       |   ^~~~~~~~~~~~~~~~~~~~~~~~~~
[  195s] ../../grub-core/commands/i386/pc/sendkey.c:224:3: error: array 
subscript 0 is outside array bounds of 'volatile char[0]' [-Werror=array-bounds]
[  195s]   224 |   *((volatile char *) 0x41c) = 0x1e;
[  195s]       |   ^~~~~~~~~~~~~~~~~~~~~~~~~~
[  195s] ../../grub-core/term/ns8250.c: In function 'grub_ns8250_init':
[  195s] ../../grub-core/term/ns8250.c:242:26: error: array subscript 0 is 
outside array bounds of 'const short unsigned int[0]' [-Werror=array-bounds]
[  195s]   242 |     if (serial_hw_io_addr[i])
[  195s]       |         ~~~~~~~~~~~~~~~~~^~~
[  195s] ../../grub-core/term/ns8250.c:262:46: error: array subscript 0 is 
outside array bounds of 'const short unsigned int[0]' [-Werror=array-bounds]
[  195s]   262 |         com_ports[i].port = serial_hw_io_addr[i];
[  195s]       |                             ~~~~~~~~~~~~~~~~~^~~
[  195s] ../../grub-core/term/ns8250.c: In function 'grub_ns8250_hw_get_port':
[  195s] ../../grub-core/term/ns8250.c:277:29: error: array subscript 0 is 
outside array bounds of 'const short unsigned int[0]' [-Werror=array-bounds]
[  195s]   277 |     return serial_hw_io_addr[unit];
[  195s]       |            ~~~~~~~~~~~~~~~~~^~~~~~
[  195s] cc1: all warnings being treated as errors
[  195s] ../../grub-core/commands/i386/pc/sendkey.c: In function 
'grub_sendkey_preboot':
[  195s] ../../grub-core/commands/i386/pc/sendkey.c:236:14: error: array 
subscript 0 is outside array bounds of 'grub_uint32_t[0]' {aka 'unsigned 
int[]'} [-Werror=array-bounds]
[  195s]   236 |   oldflags = *flags;
[  195s]       |              ^~~~~~
[  195s] ../../grub-core/commands/i386/pc/sendkey.c:239:3: error: array 
subscript 0 is outside array bounds of 'volatile char[0]' [-Werror=array-bounds]
[  195s]   239 |   *((volatile char *) 0x41a) = 0x1e;
[  195s]       |   ^~~~~~~~~~~~~~~~~~~~~~~~~~
[  195s] ../../grub-core/commands/i386/pc/sendkey.c:240:3: error: array 
subscript 0 is outside array bounds of 'volatile char[0]' [-Werror=array-bounds]
[  195s]   240 |   *((volatile char *) 0x41c) = keylen + 0x1e;
[  195s]       |   ^~~~~~~~~~~~~~~~~~~~~~~~~~
[  195s] ../../grub-core/commands/i386/pc/sendkey.c:244:7: error: array 
subscript 0 is outside array bounds of 'grub_uint32_t[0]' {aka 'unsigned 
int[]'} [-Werror=array-bounds]
[  195s]   244 |   if (*flags & (1 << 8))
[  195s]       |       ^~~~~~
[  195s] ../../grub-core/commands/i386/pc/sendkey.c:245:5: error: array 
subscript 0 is outside array bounds of 'grub_uint32_t[0]' {aka 'unsigned 
int[]'} [-Werror=array-bounds]
[  195s]   245 |     *flags &= ~(1 << 2);
[  195s]       |     ^~~~~~
[  195s] ../../grub-core/commands/i386/pc/sendkey.c:248:7: error: array 
subscript 0 is outside array bounds of 'grub_uint32_t[0]' {aka 'unsigned 
int[]'} [-Werror=array-bounds]
[  195s]   248 |   if (*flags & (1 << 9))
[  195s]       |       ^~~~~~
[  195s] ../../grub-core/commands/i386/pc/sendkey.c:249:5: error: array 
subscript 0 is outside array bounds of 'grub_uint32_t[0]' {aka 'unsigned 
int[]'} [-Werror=array-bounds]
[  195s]   249 |     *flags &= ~(1 << 3);
[  195s]       |     ^~~~~~
[  195s] ../../grub-core/commands/i386/pc/sendkey.c:251:13: error: array 
subscript 0 is outside array bounds of 'grub_uint32_t[0]' {aka 'unsigned 
int[]'} [-Werror=array-bounds]
[  195s]   251 |   *flags = (*flags & andmask) | ormask;
[  195s]       |             ^~~~~~
[  195s] ../../grub-core/commands/i386/pc/sendkey.c:251:3: error: array 
subscript 0 is outside array bounds of 'grub_uint32_t[0]' {aka 'unsigned 
int[]'} [-Werror=array-bounds]
[  195s]   251 |   *flags = (*flags & andmask) | ormask;
[  195s]       |   ^~~~~~
[  195s] ../../grub-core/commands/i386/pc/sendkey.c:255:5: error: array 
subscript 0 is outside array bounds of 'grub_uint32_t[0]' {aka 'unsigned 
int[]'} [-Werror=array-bounds]
[  195s]   255 |     *flags |= (1 << 2);
[  195s]       |     ^~~~~~
[  195s] make[3]: *** [Makefile:46365: term/serial_module-ns8250.o] Error 1
[  195s] make[3]: *** Waiting for unfinished jobs....
[  195s] ../../grub-core/commands/i386/pc/sendkey.c:258:7: error: array 
subscript 0 is outside array bounds of 'grub_uint32_t[0]' {aka 'unsigned 
int[]'} [-Werror=array-bounds]
[  195s]   258 |   if (*flags & (1 << 9))
[  195s]       |       ^~~~~~
[  195s] ../../grub-core/commands/i386/pc/sendkey.c:259:5: error: array 
subscript 0 is outside array bounds of 'grub_uint32_t[0]' {aka 'unsigned 
int[]'} [-Werror=array-bounds]
[  195s]   259 |     *flags |= (1 << 3);
[  195s]       |     ^~~~~~
[  195s] ../../grub-core/commands/i386/pc/sendkey.c:281:27: error: array 
subscript 0 is outside array bounds of 'grub_uint32_t[0]' {aka 'unsigned 
int[]'} [-Werror=array-bounds]
[  195s]   281 |               grub_outb ((*flags >> 4) & 7, 0x60);
[  195s]       |                           ^~~~~~
[  195s] cc1: all warnings being treated as errors

Thanks,
Michael

> 
> 
> _______________________________________________
> Grub-devel mailing list
> Grub-devel@gnu.org
> https://lists.gnu.org/mailman/listinfo/grub-devel




reply via email to

[Prev in Thread] Current Thread [Next in Thread]