|
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [PATCH 08/12] xen/hypfs: support dynamic hypfs nodes
On 17.11.2020 15:29, Jürgen Groß wrote:
> On 17.11.20 13:37, Jan Beulich wrote:
>> On 26.10.2020 10:13, Juergen Gross wrote:
>>> --- a/xen/common/hypfs.c
>>> +++ b/xen/common/hypfs.c
>>> @@ -19,28 +19,29 @@
>>> CHECK_hypfs_dirlistentry;
>>> #endif
>>>
>>> -#define DIRENTRY_NAME_OFF offsetof(struct xen_hypfs_dirlistentry, name)
>>> -#define DIRENTRY_SIZE(name_len) \
>>> - (DIRENTRY_NAME_OFF + \
>>> - ROUNDUP((name_len) + 1, alignof(struct xen_hypfs_direntry)))
>>> -
>>> struct hypfs_funcs hypfs_dir_funcs = {
>>> .read = hypfs_read_dir,
>>> + .getsize = hypfs_getsize,
>>> + .findentry = hypfs_dir_findentry,
>>> };
>>> struct hypfs_funcs hypfs_leaf_ro_funcs = {
>>> .read = hypfs_read_leaf,
>>> + .getsize = hypfs_getsize,
>>> };
>>> struct hypfs_funcs hypfs_leaf_wr_funcs = {
>>> .read = hypfs_read_leaf,
>>> .write = hypfs_write_leaf,
>>> + .getsize = hypfs_getsize,
>>> };
>>> struct hypfs_funcs hypfs_bool_wr_funcs = {
>>> .read = hypfs_read_leaf,
>>> .write = hypfs_write_bool,
>>> + .getsize = hypfs_getsize,
>>> };
>>> struct hypfs_funcs hypfs_custom_wr_funcs = {
>>> .read = hypfs_read_leaf,
>>> .write = hypfs_write_custom,
>>> + .getsize = hypfs_getsize,
>>> };
>>
>> With the increasing number of fields that may (deliberately or
>> by mistake) be NULL, should we gain some form of proactive
>> guarding against calls through such pointers?
>
> Hmm, up to now I think such a bug would be detected rather fast.
Not sure: Are there any unavoidable uses of all affected code
paths?
> I can add some ASSERT()s for mandatory functions not being NULL when
> a node is added dynamically or during hypfs initialization for the
> static nodes.
I'm not sure ASSERT()s alone are enough. I'd definitely prefer
something which at least avoids the obvious x86 PV privilege
escalation attack in case a call through NULL has gone
unnoticed earlier on. E.g. rather than storing NULL in unused
entries, store a non-canonical pointer so that the effect will
"just" be a DoS.
>>> @@ -88,6 +93,23 @@ static void hypfs_unlock(void)
>>> }
>>> }
>>>
>>> +void *hypfs_alloc_dyndata(unsigned long size, unsigned long align)
>>
>> Will callers really need to specify (high) alignment values? IOW ...
>>
>>> +{
>>> + unsigned int cpu = smp_processor_id();
>>> +
>>> + ASSERT(per_cpu(hypfs_locked, cpu) != hypfs_unlocked);
>>> + ASSERT(per_cpu(hypfs_dyndata, cpu) == NULL);
>>> +
>>> + per_cpu(hypfs_dyndata, cpu) = _xzalloc(size, align);
>>
>> ... is xzalloc_bytes() not suitable for use here?
>
> Good question.
>
> Up to now I think we could get away without specific alignment.
>
> I can drop that parameter for now if you'd like that better.
I think control over alignment should be limited to those
special cases really needing it.
>>> @@ -275,22 +305,25 @@ int hypfs_read_leaf(const struct hypfs_entry *entry,
>>>
>>> l = container_of(entry, const struct hypfs_entry_leaf, e);
>>>
>>> - return copy_to_guest(uaddr, l->u.content, entry->size) ? -EFAULT: 0;
>>> + return copy_to_guest(uaddr, l->u.content,
>>> entry->funcs->getsize(entry)) ?
>>> + -EFAULT : 0;
>>
>> With the intended avoiding of locking, how is this ->getsize()
>> guaranteed to not ...
>>
>>> @@ -298,7 +331,7 @@ static int hypfs_read(const struct hypfs_entry *entry,
>>> goto out;
>>>
>>> ret = -ENOBUFS;
>>> - if ( ulen < entry->size + sizeof(e) )
>>> + if ( ulen < size + sizeof(e) )
>>> goto out;
>>
>> ... invalidate the checking done here? (A similar risk looks to
>> exist on the write path, albeit there we have at least the
>> ->max_size checks, where I hope that field isn't mean to become
>> dynamic as well.)
>
> I think you are right. I should add the size value as a parameter to the
> read and write functions.
Except that a function like hypfs_read_leaf() shouldn't really
require its caller to pass in the size of the leaf's payload.
Jan
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |