[CRIU] [PATCH 3/7] seccomp: add support for SECCOMP_MODE_FILTER
Pavel Emelyanov
xemul at parallels.com
Wed Nov 11 23:58:22 PST 2015
>>> + continue;
>>> + }
>>> +
>>> + info = xmalloc(sizeof(*info));
>>> + if (!info)
>>> + goto out;
>>> + seccomp_filter__init(&info->filter);
>>> +
>>> + info->filter.filter.len = len * sizeof(struct sock_filter);
>>> + info->filter.filter.data = xmalloc(info->filter.filter.len);
>>> + if (!info->filter.filter.data)
>>> + goto out;
>>> +
>>> + memcpy(info->filter.filter.data, buf, info->filter.filter.len);
>>> +
>>> + info->prev = infos;
>>> + infos = info;
>>> + }
>>> +
>>> +save_infos:
>>> + info_count = i;
>>> +
>>> + m = xrealloc(filters, sizeof(*filters) * (next_filter_id + info_count));
>>
>> Why do we allocate that many memory? Part of the filters where "inherited".
>> Can you describe what kind of data structure is built behind the filters
>> pointer? It's some tree, but I don't get how it exactly looks and how pstree
>> items point inside it.
>
> Yeah, this is a little strange. There are two sets of pointers to the
> filters. The first is the "tree" style from pstree, used for resolving
> inheritance relationships. The second set is this one, which is just a
> big array with everything. This is used for dumping (and freeing) the
> actual filters.
>
> We could ditch the tree style ones from pstree and just use the big
> array (and keep array ids in pstree), but it seemed a little nicer to
> me this way. But I could be convinced otherwise :)
No no, keeping the tree relations inside the filters image and data structures
is nice. But as far as the "big array" thing is concerned --
> --- /dev/null
> +++ b/protobuf/seccomp.proto
> @@ -0,0 +1,8 @@
> +message seccomp_filter {
> + required bytes filter = 1;
> + optional uint32 prev = 2;
> +}
> +
> +message seccomp_entry {
> + repeated seccomp_filter seccomp_filters = 1;
> +}
why do we need the seccomp_entry? Why not just put seccomp_filter entries
into the image file one by one like it's done with pstree_entry-s?
>>> +int seccomp_filters_get_rst_pos(CoreEntry *core, int *count, unsigned long *pos)
>>> +{
>>> + SeccompFilter *sf = NULL;
>>> + struct sock_fprog *arr = NULL;
>>> + int ret = -1, i;
>>> +
>>> + if (!core->tc->has_seccomp_filter) {
>>> + *count = 0;
>>> + return 0;
>>> + }
>>> +
>>> + *count = 0;
>>> + *pos = rst_mem_cpos(RM_PRIVATE);
>>> +
>>> + BUG_ON(core->tc->seccomp_filter > se->n_seccomp_filters);
>>> + sf = se->seccomp_filters[core->tc->seccomp_filter];
>>> +
>>> + while (1) {
>>> + (*count)++;
>>> +
>>> + if (!sf->has_prev)
>>> + break;
>>> +
>>> + sf = se->seccomp_filters[sf->prev];
>>> + }
>>> +
>>> + arr = rst_mem_alloc(sizeof(*arr) * (*count), RM_PRIVATE);
>>> + if (!arr)
>>> + goto out;
>>> +
>>> + sf = se->seccomp_filters[core->tc->seccomp_filter];
>>> + for (i = 0; i < *count; i++) {
>>> + struct sock_fprog *fprog = &arr[i];
>>> + // XXX: this is a bit fugly; is there a better way?
>>
>> I didn't get a better way for what you were looking for :)
>
> The problem here is that we want to send a struct sock_fprog to the
> restorer blob, which itself has a pointer to the actual instruction
> array. So we want to pass a double pointer to the restorer blob. I
> could do something like pack the second array onto the end of the
> struct sock_fprog,
But you do it already, don't you? After you've allocated the arr thing
in which sock_fprog-s are stored, you allocate more memory to the
fprog->filter and put the fprog there.
> but it is nice to be able to refer to the first
> array without having to do math by hand.
>
> The solution here is to just save the rst_mem_alloc value into the
> struct where the second level pointer goes, and then remap the result
> after we remap the struct. That feels sort of broken, though :). But
> maybe not.
Ah I see :) I can only one thing that comes to my mind, as you told above,
in the seccomp_filters_get_rst_pos in fprog->filter you can save offset
to fprog, omit the loop with remap_ptr-s in sigreturn_restore() and do
the "math by hand" in pie's restore_seccomp. This would save us one for()
loop and would keep all the logic in less code.
-- Pavel
More information about the CRIU
mailing list