[Skiboot] [PATCH 1/2] Add infrastructure for pointer validation
Stewart Smith
stewart at linux.vnet.ibm.com
Wed Aug 10 11:45:35 AEST 2016
Balbir Singh <bsingharora at gmail.com> writes:
> On 09/08/16 17:17, Stewart Smith wrote:
>> Balbir Singh <bsingharora at gmail.com> writes:
>>> If the kernel called an OPAL API with vmalloc'd address
>>> or any other address range in real mode, we would hit
>>> a problem with aliasing. Since the top 4 bits are ignored
>>> in real mode, pointers from 0xc.. and 0xd.. (and other ranges)
>>> could collide and lead to hard to solve bugs. This patch
>>> adds the infrastructure for pointer validation and a simple
>>> test case for testing the API
>>>
>>> Signed-off-by: Balbir Singh <bsingharora at gmail.com>
>>> ---
>>> core/test/Makefile.check | 1 +
>>> core/test/run-api-test.c | 51 ++++++++++++++++++++++++++++++++++++++++++++++++
>>> include/opal-api.h | 23 ++++++++++++++++++++++
>>> 3 files changed, 75 insertions(+)
>>> create mode 100644 core/test/run-api-test.c
>>
>> Finally got a chance to poke at this and think about it.
>>
>> I like it.
>>
>> I have a few thoughts that'd be great to address before merging,
>> although I'm rather keen to merge.
>>
>>> --- /dev/null
>>> +++ b/core/test/run-api-test.c
>>> @@ -0,0 +1,51 @@
>>> +/* Copyright 2014-2015 IBM Corp.
>>
>> Should be to 2016.
>>
> I'll fix this
>
>>> diff --git a/include/opal-api.h b/include/opal-api.h
>>> index c86244b..e717ca3 100644
>>> --- a/include/opal-api.h
>>> +++ b/include/opal-api.h
>>> @@ -213,6 +213,9 @@
>>>
>>> #ifndef __ASSEMBLY__
>>>
>>> +#include <stdbool.h>
>>> +#include <types.h>
>>> +
>>> /* Other enums */
>>> enum OpalVendorApiTokens {
>>> OPAL_START_VENDOR_API_RANGE = 1000, OPAL_END_VENDOR_API_RANGE = 1999
>>> @@ -1043,6 +1046,26 @@ enum {
>>> OPAL_PCI_TCE_KILL_ALL,
>>> };
>>>
>>> +extern unsigned long top_of_ram;
>>> +
>>> +/*
>>> + * Returns true if the address is valid, false otherwise
>>> + *
>>> + * Checks if the passed address belongs to real address space
>>> + * or 0xc000... kernel address space. It also checks that
>>> + * addr <= total physical memory
>>> + */
>>> +static inline bool opal_addr_valid(const void *addr)
>>> +{
>>> + unsigned long val = (unsigned long)addr;
>>> + if ((val >> 60) != 0xc && (val >> 60) != 0x0)
>>
>> I think it would be good to point to section 5.7 of the ISA as to where
>> the 60 comes from. We *could* check for a implementation specific value
>> too, P8 seems to be 50 bits (although other procs are
>> different). Although I'm not sure if there's any real value to be had
>> from that?
>
>
> I'll add a reference to the ISA, BTW in the kernel we assume 60 bits
> and I think it should be fine. I think checking for top 4 bits and
> size of ram should be sufficient. Does doing the implementation
> specific check gain us any more?
I don't think so... I guess we could end up erroring out rather than
checkstopping?
>>
>>> + return false;
>>> + val &= ~0xf000000000000000;
>>> + if (val > top_of_ram)
>>> + return false;
>>> + return true;
>>> +}
>>
>> I'm wondering how we can hook this up to prlog(PR_ERROR) or something,
>> and then have FWTS annotation for it so that fwts would pick it up from
>> the skiboot log... maybe a macro around it?
>>
>
> Good idea, I would like do that incrementally, I'm trying to
> understand how to integrate the error with FWTS, so that the error log
> makes sense.
I'm pretty sure that error logs making sense is rather non-traditional :)
--
Stewart Smith
OPAL Architect, IBM.
More information about the Skiboot
mailing list