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 --]
next prev parent 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).