I work as a company engineer at Media.
I'm also a storyteller on my free time, and so I try to make two jobs lit together for
these talks, so it's basically, it's not super technical, but it's a story I live through
the past month, and I thought it would be nice to share it, and that's why I'm here.
My main topic will be about a specific intrinsic, that is available to see and see
plus plus users, from GCC and Clang, and probably also a C-compiler, which is built in
object size, and this is interesting, you can pass it to argument, the first one is a pointer,
and so the one is some properties, and basically what this is interesting is, it's a
vanity at compile time, and it tries to compute the amount of memory that is surely
allocated from that pointer, up to the end of the original allocation, like you
can add up some memory, then you move your pointer around, and you say, okay, there is only
three bytes remaining after that pointer, and the compiler should use it of that information
statically, so no one can cost.
If it fails to compute the origin of the pointer, then it returns minus one, if you pass
your certain argument, and if the original location for the pointer, then maybe there are
two different possibilities, possibilities of remaining memory area, and then, again,
if it's zero as a certain argument, then it returns the maximum amount of three memory,
so it's optimistic, but you can also pass one as a certain argument.
In that case, you get the minimum of all the memory allocation sites, so that's a pessimistic
assumption, but you can also pass two as arguments, in that case, you're back to the
maximum that in case of the compiler fails to statically compute where this pointer comes from
which are all the allocation sites, then you return zero, and this what, to complete the
matrix, if you pass three, then it's the minimum and zero, so now we have enough luggage to
understand human parts of the took, which is why does that built in exist, so if you
rep for a detailed exercise in your user, including others, then you will see that it's
actually defined as a detailed exercise here, and it's used on the 45 source, so 45 source
is the process of fly, you can pass to 45, somewhat your leapsy function, or the 45,
this STPNCP function has a 45 variant with a check suffix, which states as last argument,
the size of the buffer, so it prevents overflow on the buffer, because the compiler statically
computed the actual size of the buffer, and if you try to wrap overwrite the buffer, you will get
an error, so that's cool, you use your compiler super power to actually adjust extra information
that is not available from the long range in your function, so between the exact size,
super important for 45 source, but if you have a look to the internal equivalent of
bit in the exercise, that is the actual machinery used to expand bit in the exercise to a constant,
and if you grab that in everything so scroll, you see the other sanitizer is involved,
and the bomb shaking is also involved, which somehow makes sense, if you want to verify that
all the oxests are inbound, you have the compiler, what does it on, and then you can inject a check,
if you want to sanitize address, it's question, so if you can prove that the exercise is correct,
with an pessimistic assumption in the bit in the exercise mode, I describe it earlier,
then you can remove some checks, so bit in the exercise is first, a fun, interesting,
but it's also super useful for security features, keep that in mind,
I used to work at redat, and there are 25 foreign engineers now, is that you
you change your employer, but you didn't change your topic, and so one I worked on bit in the
exercise at redat, I studied by a small benchmark where I wrote civil situation, where I bit in the
exercise should expand correctly, and I tested it with GCC and Cang, and there were some
fewer on GCC, but well, failure were not good for that, you just said minus one or zero,
which is I can't find the origin, and that's fine, I mean it's still correct,
with respect to a semantic of between the exercise, it was just not perfect, I was working on Cang,
and at the time, so that's what I get on my figure, there are still errors, which was a bit
disturbing to me because two years ago there was no error, so why did you do have you
need tests in LVM and Cang, so that was very troubling, is this last one was already
warming the path, we are like a ray, that's a function that is not perceived, but supported by
GCC, and it was not modelled in a client or in LVM, but that's fine, this is three one
we're working to do see, so yeah, I still have to fix bugs that I did not introduce,
so I had a look at the scales and it's super simple, we have a static buffer, we take an address
on it, we eventually move the pointer around and we ask between the object size,
super simple, that's a basic test case, it should work, but it was not anymore, why it's good
back here, minus O2, okay, because if you translate that into LVM IR, you've got your
fields and your branching and the way between the exercises explaining you can do with that,
but if you keep your fields under I optimization level, you just have to track pointers,
if you optimize the fields into select instruction, then you're no longer only working with
pointers, but with pointers and offsets, which means that instead of doing only pointer computation,
plus offset computation, and this opens a new area of analysis, which between the
object size further was unaware of, and so you say, okay, a field instruction,
understanding instruction is basically the same, so let's just add the remaining bits,
but then you realize that the selected instruction may indicate the exporters, but integrates
and then you need to fold the edges in taggers, and you don't see that at all,
and so what happened in modern LVM was just, yeah, we improved the optimizer and turned
field instruction in selecting instruction in more cases, and these cases were quoted by my personal
statistics. But then you say, there's a letter, you have compute constants range in LVM,
you give it value and you compute bounds on this value, which looks exactly what we want,
because then you have the bounds of your upset, you have that to the pointer, and you have
your user maximum, also minimum, perfect. But remember, we're working on security stuff,
and so if we are super smart, you may take advantage of a defined deliver,
because it's correct from a compiler perspective, you take advantage of them. But at the same
time, the logic size is used to create dots to prevent a defined deliver, like accessing
out-of-band buffers. So it would be a content predictive to try to create checks while assuming
that the thing you want to check doesn't happen, so actually, that's actually a good news for me.
I don't need to be smart. So being smart was a problem here, I just want to super
analyze this, that takes care of my range, because what I want to take care to take advantage of
UB, could it be not? If I do very large overlap approximation, like if you can mask one bit
of a value compute constants range, you say, oh, okay, you mask is a highest bit, so here is a range
you can access. This is true, that's true, they are approximating for what I need in between the
object size, which basically means that, okay, I can have a constant range, but that's not where
people for 12 friends are designed between the object size. They actually want to create
allocation information from different sites and takes an XC normal minimum of that, and not being
over smart, which not being smart is something I'm very good at, and so that's the path for
I took, so a simple value tracking analysis, I go through the value, and if there is anything
dynamic, big out, that I can still have an interesting information we're doing, so being defined
behavior nothing else, there's a peer for that, you've got to manage a few months ago, and that's
so that multi-states, well actually you can see that the realloc array parts also disappear,
but more about this year, and I'm back to the state I was two years ago, and then with my past,
it seems good, and then you point the rest of this realloc array, so I just implemented
modeling for this instruction, it's basically the fusion of C-alloc, you've got the plan, yes,
so the fusion of realloc and C-alloc in one function, it's not supposed to be, it's too good that
we support it, so my real test shoot now passes, well I said everything is simple, you do
a computer science, you know that nothing is simple in the end, even when you click so,
let's have a look to the results, you are like like allocates static memory, or
statically known amount of memory, and you move between the two, okay, so this one is fairly because
here, when you increase your upset, you actually take the minimal value of this, if you want the
maximum amount of memory available there, so there is a small dance between mean value and
much value depending on if you are evaluating the depth or select, but that wasn't too hard.
If then back on your slide, the second line up on the comment, should it say zero, it's okay,
we are, yes, it should, thank you, do they write my slide, do you still don't you train,
maybe, maybe, so yeah, special thanks, so first that's, I'd actually be a big
engineer at Media, that work was quite far from what I was supposed to do, but I was able to do that,
so thank you for my manager and such to let me work on this, and also Harra from this, I don't know
that you've provided me a lot of this case, we are super nice reviewer, so if you happen to
vote Zaptok, thank you, thank you to you too, and hopefully some of the cooking words,
so this image size is very powerful to shake, because it gives you access to actually your
component analysis, but from your secret or super special, so well that's always funny,
you can also put a way to where the range is now, that's the point of my talk,
a level of check size, which is what the check size expense to, at the level of easy
important for security, but nowadays, between the exercise is getting replaced by between dynamic
of the exercise, which instead of trying to statically compute the amount of memory that remains,
it creates an LLMIR expression that represents the amount of memories that remains, so it can
be used both to track dynamic allocation from other concepts, and also it can take care of conditions,
instead of taking the maximum or minimum, it just follows a data flow and gets actual value,
it is an extra runtime cost, but without the need of building a folder on your side, because it's dynamic,
and now 20 minutes, 20 slides, perfect, that means for question,
so building object size should not make use of identifying behavior,
that's my opinion, right, and is that written down in the specific case?
No, not so, actually, so the question was, is this a defined behavior,
which I mean you had is that we turn anywhere, and the answer is no actually, just looking for
the specification of building the exercise, I looked in the GCC manual, which is, as you probably know,
much more documented, that there is no existing info page, and so I got my definition from there,
and it wasn't very clear, with that respect, but from the usage of the building, I thought,
yeah, let's not try, yeah, let's just say, the fetch the update, the documentation,
yeah, contribute to GCC, perfect, I think that in mine, I knew the question,
if you don't have question, you're still, you won't get rid of me because I'm still the next picker,
so if I understand you correctly, you added a stupid value tracking, and definitely to the
smart value tracking that's already there, to not make use of amplified behavior,
so you expanded the what the compiler has to do, doesn't have a notable influence on compile time
and compile a memory usage. So, it's unfortunate that you understood that, so the question was,
you had it more complexity in the compiler to do simpler things, and the short answer is yes,
but that's not what you should be reading the book, and previously there was no analyzes of
offsets in the GCC size folder. Now there is an analyzes, but instead of using an existing
components or that LVM, I had to write a very simple, and not that many lines of code,
trust me, to do it in a simple but solid way, yeah, if it was already being active on the pipeline,
so can you repeat it? So, it's a question was, is there any relationship,
a potential relationship with the attributor, and I have limited knowledge on the attributor,
but my understanding is that it propagates attribute information from function to go south of
the core graph, and with my limited brains that I made explicit before, I failed to understand the link,
but we can discuss that after with. Thanks.