public inbox for gcc@gcc.gnu.org
 help / color / mirror / Atom feed
From: Alejandro Colomar <alx.manpages@gmail.com>
To: GCC <gcc@gcc.gnu.org>
Cc: Kees Cook <keescook@chromium.org>,
	Alejandro Colomar <alx@nginx.com>,
	Andrew Clayton <a.clayton@nginx.com>,
	Andrew Clayton <andrew@digital-domain.net>
Subject: Re: [wish] Flexible array members in unions
Date: Thu, 11 May 2023 18:29:10 +0200	[thread overview]
Message-ID: <44940599-7b43-99f6-5b09-4f050d645c7b@gmail.com> (raw)
In-Reply-To: <ac2550e0-2f5c-3680-08e6-0c224d043036@gmail.com>


[-- Attachment #1.1: Type: text/plain, Size: 4271 bytes --]

[CC += Kees, Andrew]

[start of thread: <https://inbox.sourceware.org/gcc/ac2550e0-2f5c-3680-08e6-0c224d043036@gmail.com/T/#u>]

On 5/11/23 18:07, Alejandro Colomar wrote:
> Hi!
> 
> Currently, one can have pseudo-flexible array members in unions with
> [0] syntax, but it's not allowed with [] syntax.
> 
> Here's an example of how it is possible today:
> 
> struct s {
> 	...
> 
> 	size_t  n;
> 	union {
> 		ptrdiff_t  off[0];  // [n]; offsets from s->data.
> 		char       data[0];
> 	};
> };
> 
> which is useful to have a structure with two (or really several)
> consecutive flexible arrays: one of offsets, which mark the positions
> of data, and another with the actual data.  Below goes an example
> program, which works fine with GCC, and I believe rewriting it to
> not use the union would make it less clear, since I'd need to add
> casts to it.
> 
> It works thanks to [0] pseudo-flexible arrays, but it doesn't
> compile with C99 flexible arrays.  And of course, [0] arrays have
> issues with -fstrict-flex-arrays=3.
> 
> 
> $ cat flexi4.c 
> #include <stddef.h>
> #include <stdlib.h>
> #include <stdio.h>
> #include <string.h>
> 
> struct s {
> 	size_t     n;
> 	union {
> 		ptrdiff_t  off[0];
> 		char       data[0];
> 	};
> };
> 
> int
> main(void)
> {
> 	char      *p;
> 	struct s  *s;
> 
> 	s = malloc(offsetof(struct s, off) +
> 	           sizeof(ptrdiff_t) * 2 +
> 	           sizeof("foobar") + sizeof("baz"));
> 
> 	s->n = 2;
> 	p = s->data + sizeof(ptrdiff_t) * s->n;
> 
> 	s->off[0] = p - s->data;
> 	p = stpcpy(p, "foobar") + 1;
> 	s->off[1] = p - s->data;
> 	p = stpcpy(p, "baz") + 1;
> 
> 	puts(s->data + s->off[0]);
> 	puts(s->data + s->off[1]);
> 
> 	free(s);
> }
> $ gcc-13 -Wall -Wextra -Werror -fanalyzer \
>          -fsanitize=undefined -fsanitize=address \
>          -D_FORTIFY_SOURCE=3 -fstrict-flex-arrays=2 \
>          flexi4.c 
> $ ./a.out 
> foobar
> baz
> $ gcc-13 -Wall -Wextra -Werror -fanalyzer \
>          -fsanitize=undefined -fsanitize=address \
>          -D_FORTIFY_SOURCE=3 -fstrict-flex-arrays=3 \
>          flexi4.c 
> $ ./a.out 
> flexi4.c:27:8: runtime error: index 0 out of bounds for type 'ptrdiff_t [*]'
> flexi4.c:29:8: runtime error: index 1 out of bounds for type 'ptrdiff_t [*]'
> flexi4.c:32:23: runtime error: index 0 out of bounds for type 'ptrdiff_t [*]'
> foobar
> flexi4.c:33:23: runtime error: index 1 out of bounds for type 'ptrdiff_t [*]'
> baz
> 
> 
> Would you allow flexible array members in unions?  Is there any
> strong reason to disallow them?
> 
> Currently, I get:
> 
> $ gcc-13 -Wall -Wextra -fanalyzer \
>          -fsanitize=undefined -fsanitize=address \
>          -D_FORTIFY_SOURCE=3 -fstrict-flex-arrays=3 \
>          flexi4-true.c 
> flexi4-true.c:9:28: error: flexible array member in union
>     9 |                 ptrdiff_t  off[];
>       |                            ^~~
> flexi4-true.c:10:28: error: flexible array member in union
>    10 |                 char       data[];
>       |                            ^~~~
> 
> 

Currently, the Linux kernel has to go through some hoops due to this
restriction:


$ grepc -tm __DECLARE_FLEX_ARRAY *
include/uapi/linux/stddef.h:42:
#define __DECLARE_FLEX_ARRAY(TYPE, NAME)	\
	struct { \
		struct { } __empty_ ## NAME; \
		TYPE NAME[]; \
	}


tools/include/uapi/linux/stddef.h:42:
#define __DECLARE_FLEX_ARRAY(TYPE, NAME)	\
	struct { \
		struct { } __empty_ ## NAME; \
		TYPE NAME[]; \
	}
$ grep -rnB2 __DECLARE_FLEX_ARRAY * | head
include/uapi/rdma/rdma_user_rxe.h-153-	__u32			reserved;
include/uapi/rdma/rdma_user_rxe.h-154-	union {
include/uapi/rdma/rdma_user_rxe.h:155:		__DECLARE_FLEX_ARRAY(__u8, inline_data);
include/uapi/rdma/rdma_user_rxe.h:156:		__DECLARE_FLEX_ARRAY(__u8, atomic_wr);
include/uapi/rdma/rdma_user_rxe.h:157:		__DECLARE_FLEX_ARRAY(struct rxe_sge, sge);
--
include/uapi/scsi/scsi_netlink_fc.h-53-	union {
include/uapi/scsi/scsi_netlink_fc.h-54-		__u32 event_data;
include/uapi/scsi/scsi_netlink_fc.h:55:		__DECLARE_FLEX_ARRAY(__u8, event_data_flex);
--




-- 
<http://www.alejandro-colomar.es/>
GPG key fingerprint: A9348594CE31283A826FBDD8D57633D441E25BB5

[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

  reply	other threads:[~2023-05-11 16:29 UTC|newest]

Thread overview: 16+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-05-11 16:07 Alejandro Colomar
2023-05-11 16:29 ` Alejandro Colomar [this message]
2023-05-11 19:07   ` Kees Cook
2023-05-11 20:53     ` Joseph Myers
2023-05-11 21:13       ` Kees Cook
2023-05-11 21:43         ` Joseph Myers
2023-05-11 22:16           ` Kees Cook
2023-05-11 22:52             ` Joseph Myers
2023-05-12  0:25               ` Alejandro Colomar
2023-05-12  7:49             ` Jonathan Wakely
2023-05-12  6:16         ` Richard Biener
2023-05-12 12:32           ` David Brown
2023-05-15 19:58           ` Qing Zhao
2023-05-18 16:25           ` Martin Uecker
2023-05-18 20:59             ` Qing Zhao
2023-05-19 12:08               ` Martin Uecker

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=44940599-7b43-99f6-5b09-4f050d645c7b@gmail.com \
    --to=alx.manpages@gmail.com \
    --cc=a.clayton@nginx.com \
    --cc=alx@nginx.com \
    --cc=andrew@digital-domain.net \
    --cc=gcc@gcc.gnu.org \
    --cc=keescook@chromium.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).