public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
From: Qing Zhao <qing.zhao@oracle.com>
To: Martin Uecker <uecker@tugraz.at>
Cc: Kees Cook <keescook@chromium.org>,
	Siddhesh Poyarekar <siddhesh@gotplt.org>,
	Richard Biener <richard.guenther@gmail.com>,
	Joseph Myers <joseph@codesourcery.com>,
	Jakub Jelinek <jakub@redhat.com>,
	gcc Patches <gcc-patches@gcc.gnu.org>,
	"isanbard@gmail.com" <isanbard@gmail.com>
Subject: Re: HELP: Will the reordering happen? Re: [V3][PATCH 0/3] New attribute "counted_by" to annotate bounds for C99 FAM(PR108896)
Date: Fri, 27 Oct 2023 14:32:41 +0000	[thread overview]
Message-ID: <E0A67849-F1EA-43A6-9AF1-AEE8B1C19DCC@oracle.com> (raw)
In-Reply-To: <5a95d30d4e7cbfa71e24935072412c6d6ff55324.camel@tugraz.at>



> On Oct 27, 2023, at 3:21 AM, Martin Uecker <uecker@tugraz.at> wrote:
> 
> Am Donnerstag, dem 26.10.2023 um 19:57 +0000 schrieb Qing Zhao:
>> I guess that what Kees wanted, ""fill the array without knowing the actual final size" code pattern”, as following:
>> 
>>>> 	struct foo *f;
>>>> 	char *p;
>>>> 	int i;
>>>> 
>>>> 	f = alloc(maximum_possible);
>>>> 	f->count = 0;
>>>> 	p = f->buf;
>>>> 
>>>> 	for (i; data_is_available() && i < maximum_possible; i++) {
>>>> 		f->count ++;
>>>> 		p[i] = next_data_item();
>>>> 	}
>> 
>> actually is a dynamic array, or more accurately, Bounded-size dynamic array: ( but not a dynamic allocated array as we discussed so far)
>> 
>> https://en.wikipedia.org/wiki/Dynamic_array
>> 
>> This dynamic array, also is called growable array, or resizable array, whose size can 
>> be changed during the lifetime. 
>> 
>> For VLA or FAM, I believe that they are both dynamic allocated array, i.e, even though the size is not know at the compilation time, but the size
>> will be fixed after the array is allocated. 
>> 
>> I am not sure whether C has support to such Dynamic array? Or whether it’s easy to provide dynamic array support in C?
> 
> It is possible to support dynamic arrays in C even with
> good checking, but not safely using the pattern above
> where you derive a pointer which you later use independently.
> 
> While we could track the connection to the original struct,
> the necessary synchronization between the counter and the
> access to the buffer is difficult.  I do not see how this
> could be supported with reasonable effort and cost.
> 
> 
> But with this restriction in mind, we can do a lot in C.
> For example, see my experimental (!) container library
> which has vector type.
> https://github.com/uecker/noplate/blob/main/test.c
> You can get an array view for the vector (which then
> also can decay to a pointer), so it interoperates nicely
> with C but you can get good bounds checking.
> 
> 
> But once you derive a pointer and pass it on, it gets
> difficult.  But if you want safety, you just have to 
> to simply avoid this in code. 

So, for the following modified code: (without the additional pointer “p”)

struct foo
{
 size_t count;
 char buf[] __attribute__((counted_by(count)));
};

struct foo *f;
int i;  

f = alloc(maximum_possible);
f->count = 0;

for (i; data_is_available() && i < maximum_possible; i++) {
  f->count ++;  
  f->buf[i] = next_data_item();
}       

The support for dynamic array should be possible? 


> 
> What we could potentially do is add restrictions so 
> that the access to buf always has to go via x->buf 
> or you get at least a warning.

Are the following two restrictions to the user enough:

1. The access to buf should always go via x->buf, 
    no assignment to another independent pointer 
    and access buf through this new pointer.
2.  User need to keep the synchronization between
      the counter and the access to the buffer all the time.


Qing
> 
> Martin
> 
> 
> 
> 
>> 
>> Qing
>> 
>> 
>>> On Oct 26, 2023, at 12:45 PM, Martin Uecker <uecker@tugraz.at> wrote:
>>> 
>>> Am Donnerstag, dem 26.10.2023 um 09:13 -0700 schrieb Kees Cook:
>>>> On Thu, Oct 26, 2023 at 10:15:10AM +0200, Martin Uecker wrote:
>>>>> but not this:
>>>>> 
>>> 
>>> x->count = 11;
>>>>> char *p = &x->buf;
>>>>> x->count = 1;
>>>>> p[10] = 1; // !
>>>> 
>>>> This seems fine to me -- it's how I'd expect it to work: "10" is beyond
>>>> "1".
>>> 
>>> Note that the store would be allowed.
>>> 
>>>> 
>>>>> (because the pointer is passed around the
>>>>> store to the counter)
>>>>> 
>>>>> and also here the second store is then irrelevant
>>>>> for the access:
>>>>> 
>>>>> x->count = 10;
>>>>> char* p = &x->buf;
>>>>> ...
>>>>> x->count = 1; // somewhere else
>>>>> ----
>>>>> p[9] = 1; // ok, because count matter when buf was accesssed.
>>>> 
>>>> This is less great, but I can understand why it happens. "p" loses the
>>>> association with "x". It'd be nice if "p" had to way to retain that it
>>>> was just an alias for x->buf, so future p access would check count.
>>> 
>>> The problem is not to discover that p is an alias to x->buf, 
>>> but that it seems difficult to make sure that stores to 
>>> x->count are not reordered relative to the final access to
>>> p[i] you want to check, so that you then get the right value.
>>> 
>>>> 
>>>> But this appears to be an existing limitation in other areas where an
>>>> assignment will cause the loss of object association. (I've run into
>>>> this before.) It's just more surprising in the above example because in
>>>> the past the loss of association would cause __bdos() to revert back to
>>>> "SIZE_MAX" results ("I don't know the size") rather than an "outdated"
>>>> size, which may get us into unexpected places...
>>>> 
>>>>> IMHO this makes sense also from the user side and
>>>>> are the desirable semantics we discussed before.
>>>>> 
>>>>> But can you take a look at this?
>>>>> 
>>>>> 
>>>>> This should simulate it fairly well:
>>>>> https://godbolt.org/z/xq89aM7Gr
>>>>> 
>>>>> (the call to the noinline function would go away,
>>>>> but not necessarily its impact on optimization)
>>>> 
>>>> Yeah, this example should be a very rare situation: a leaf function is
>>>> changing the characteristics of the struct but returning a buffer within
>>>> it to the caller. The more likely glitch would be from:
>>>> 
>>>> int main()
>>>> {
>>>> 	struct foo *f = foo_alloc(7);
>>>> 	char *p = FAM_ACCESS(f, size, buf);
>>>> 
>>>> 	printf("%ld\n", __builtin_dynamic_object_size(p, 0));
>>>> 	test1(f); // or just "f->count = 10;" no function call needed
>>>> 	printf("%ld\n", __builtin_dynamic_object_size(p, 0));
>>>> 
>>>> 	return 0;
>>>> }
>>>> 
>>>> which reports:
>>>> 7
>>>> 7
>>>> 
>>>> instead of:
>>>> 7
>>>> 10
>>>> 
>>>> This kind of "get an alias" situation is pretty common in the kernel
>>>> as a way to have a convenient "handle" to the array. In the case of a
>>>> "fill the array without knowing the actual final size" code pattern,
>>>> things would immediately break:
>>>> 
>>>> 	struct foo *f;
>>>> 	char *p;
>>>> 	int i;
>>>> 
>>>> 	f = alloc(maximum_possible);
>>>> 	f->count = 0;
>>>> 	p = f->buf;
>>>> 
>>>> 	for (i; data_is_available() && i < maximum_possible; i++) {
>>>> 		f->count ++;
>>>> 		p[i] = next_data_item();
>>>> 	}
>>>> 
>>>> Now perhaps the problem here is that "count" cannot be used for a count
>>>> of "logically valid members in the array" but must always be a count of
>>>> "allocated member space in the array", which I guess is tolerable, but
>>>> isn't ideal -- I'd like to catch logic bugs in addition to allocation
>>>> bugs, but the latter is certainly much more important to catch.
>>> 
>>> Maybe we could have a warning when f->buf is not directly
>>> accessed.
>>> 
>>> Martin
>>> 
>>>> 
>>> 
>> 
> 


  reply	other threads:[~2023-10-27 14:32 UTC|newest]

Thread overview: 116+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-08-25 15:24 Qing Zhao
2023-08-25 15:24 ` [V3][PATCH 1/3] Provide counted_by attribute to flexible array member field (PR108896) Qing Zhao
2023-09-08 14:12   ` Qing Zhao
2023-09-20 13:44   ` Ping * 2: " Qing Zhao
2023-10-05 18:51   ` Siddhesh Poyarekar
2023-10-05 19:31     ` Siddhesh Poyarekar
2023-10-18 14:51       ` Qing Zhao
2023-10-18 15:18         ` Siddhesh Poyarekar
2023-10-18 15:37           ` Qing Zhao
2023-10-18 14:41     ` Qing Zhao
2023-08-25 15:24 ` [V3][PATCH 2/3] Use the counted_by atribute info in builtin object size [PR108896] Qing Zhao
2023-09-08 14:12   ` Qing Zhao
2023-09-20 13:44   ` PING *2: " Qing Zhao
2023-10-05 20:01   ` Siddhesh Poyarekar
2023-10-18 20:39     ` Qing Zhao
2023-08-25 15:24 ` [V3][PATCH 3/3] Use the counted_by attribute information in bound sanitizer[PR108896] Qing Zhao
2023-09-08 14:12   ` Qing Zhao
2023-09-20 13:45   ` PING * 2: " Qing Zhao
2023-08-25 19:51 ` [V3][PATCH 0/3] New attribute "counted_by" to annotate bounds for C99 FAM(PR108896) Kees Cook
2023-09-08 14:11 ` Qing Zhao
2023-09-20 13:43 ` PING * 2: " Qing Zhao
2023-10-05 20:08 ` Siddhesh Poyarekar
2023-10-05 22:35   ` Kees Cook
2023-10-06  5:11     ` Martin Uecker
2023-10-06 10:50       ` Siddhesh Poyarekar
2023-10-06 20:01         ` Martin Uecker
2023-10-18 15:37           ` Siddhesh Poyarekar
2023-10-18 19:35           ` Qing Zhao
2023-10-18 21:11   ` Qing Zhao
2023-10-19 23:33     ` Kees Cook
2023-10-20  9:50       ` Martin Uecker
2023-10-20 18:34         ` Kees Cook
2023-10-20 18:48           ` Qing Zhao
2023-10-20 19:54             ` Martin Uecker
2023-10-23 18:17               ` Qing Zhao
2023-10-23 19:52               ` Kees Cook
2023-10-23 19:57                 ` Martin Uecker
2023-10-23 22:03                   ` Kees Cook
2023-10-20 17:08     ` HELP: Will the reordering happen? " Qing Zhao
2023-10-20 18:22       ` Richard Biener
2023-10-20 18:38         ` Qing Zhao
2023-10-20 19:10           ` Siddhesh Poyarekar
2023-10-20 20:41             ` Qing Zhao
2023-10-23  7:57               ` Richard Biener
2023-10-23 11:27                 ` Siddhesh Poyarekar
2023-10-23 12:34                   ` Richard Biener
2023-10-23 13:23                     ` Siddhesh Poyarekar
2023-10-23 15:14                     ` Qing Zhao
2023-10-23 14:56                 ` Qing Zhao
2023-10-23 15:57                   ` Richard Biener
2023-10-23 16:37                     ` Qing Zhao
2023-10-23 18:06                       ` Martin Uecker
2023-10-23 18:31                         ` Martin Uecker
2023-10-23 19:00                           ` Qing Zhao
2023-10-23 19:37                             ` Martin Uecker
2023-10-23 20:33                               ` Qing Zhao
2023-10-23 18:33                         ` Qing Zhao
2023-10-23 18:43                         ` Siddhesh Poyarekar
2023-10-23 18:55                           ` Martin Uecker
2023-10-23 19:43                           ` Qing Zhao
2023-10-23 22:48                             ` Siddhesh Poyarekar
2023-10-24 20:30                               ` Qing Zhao
2023-10-24 20:38                                 ` Martin Uecker
2023-10-24 21:09                                   ` Siddhesh Poyarekar
2023-10-24 22:51                                   ` Qing Zhao
2023-10-24 23:56                                     ` Siddhesh Poyarekar
2023-10-25 13:27                                       ` Qing Zhao
2023-10-25 14:50                                         ` Siddhesh Poyarekar
2023-10-25 15:38                                           ` Richard Biener
2023-10-25 19:03                                             ` Qing Zhao
2023-10-26  5:21                                               ` Jakub Jelinek
2023-10-26  8:56                                                 ` Richard Biener
2023-10-26 14:58                                                   ` Qing Zhao
2023-10-26 15:48                                                     ` Richard Biener
2023-10-26 16:16                                                       ` Martin Uecker
2023-10-26 14:41                                                 ` Qing Zhao
2023-10-25 18:44                                           ` Qing Zhao
2023-10-25 22:06                                         ` Kees Cook
2023-10-25 22:27                                           ` Qing Zhao
2023-10-25 22:32                                             ` Kees Cook
2023-10-26  8:15                                               ` Martin Uecker
2023-10-26 16:13                                                 ` Kees Cook
2023-10-26 16:45                                                   ` Martin Uecker
2023-10-26 19:57                                                     ` Qing Zhao
2023-10-27  7:21                                                       ` Martin Uecker
2023-10-27 14:32                                                         ` Qing Zhao [this message]
2023-10-27 14:53                                                           ` Martin Uecker
2023-10-27 15:10                                                             ` Qing Zhao
2023-10-27 17:19                                                               ` Kees Cook
2023-10-27 18:13                                                                 ` Qing Zhao
2023-10-25  5:26                                     ` Martin Uecker
2023-10-25  6:43                                   ` Richard Biener
2023-10-25  8:16                                     ` Martin Uecker
2023-10-25 10:25                                       ` Siddhesh Poyarekar
2023-10-25 10:47                                         ` Martin Uecker
2023-10-25 11:13                                           ` Richard Biener
2023-10-25 18:16                                             ` Martin Uecker
2023-10-26  8:45                                               ` Richard Biener
2023-10-26  9:20                                                 ` Martin Uecker
2023-10-26 10:14                                                   ` Martin Uecker
2023-10-26 14:05                                                     ` Richard Biener
2023-10-26 18:54                                                       ` Qing Zhao
2023-10-27 16:43                                                         ` Qing Zhao
2023-10-26 16:41                                                   ` Qing Zhao
2023-10-26 17:05                                                     ` Martin Uecker
2023-10-26 17:35                                                       ` Richard Biener
2023-10-26 19:20                                                       ` Qing Zhao
2023-10-25 18:17                                             ` Qing Zhao
2023-10-25 10:25                                       ` Richard Biener
2023-10-25 10:39                                         ` Martin Uecker
2023-10-25 18:06                                           ` Qing Zhao
2023-10-24 21:03                                 ` Siddhesh Poyarekar
2023-10-24 22:41                                   ` Qing Zhao
2023-10-24 23:51                                     ` Siddhesh Poyarekar
2023-10-25 21:59                                       ` Kees Cook
2023-10-23 18:10                       ` Joseph Myers

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=E0A67849-F1EA-43A6-9AF1-AEE8B1C19DCC@oracle.com \
    --to=qing.zhao@oracle.com \
    --cc=gcc-patches@gcc.gnu.org \
    --cc=isanbard@gmail.com \
    --cc=jakub@redhat.com \
    --cc=joseph@codesourcery.com \
    --cc=keescook@chromium.org \
    --cc=richard.guenther@gmail.com \
    --cc=siddhesh@gotplt.org \
    --cc=uecker@tugraz.at \
    /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).