[Intel-gfx] [PATCH 02/13] drm/i915: Introduce the i915_user_extension_method

Chris Wilson chris at chris-wilson.co.uk
Wed Mar 13 11:21:15 UTC 2019


Quoting Tvrtko Ursulin (2019-03-13 11:13:10)
> 
> On 13/03/2019 10:50, Chris Wilson wrote:
> > Quoting Tvrtko Ursulin (2019-03-08 14:33:02)
> >>
> >> On 08/03/2019 14:12, Chris Wilson wrote:
> >>> +int i915_user_extensions(struct i915_user_extension __user *ext,
> >>> +                      const i915_user_extension_fn *tbl,
> >>> +                      unsigned long count,
> >>> +                      void *data)
> >>> +{
> >>> +     unsigned int stackdepth = 512;
> >>
> >> I have doubts about usefulness of trying to impose some limit now. And
> >> also reservations about using the name stack. But both are irrelevant
> >> implementation details at this stage so meh.
> > 
> > We need defence against malice userspace doing
> >       struct i915_user_extension ext = {
> >               .next_extension = &ext,
> >       };
> > so sadly some limit is required.
> 
> Oh yes, good point. I wasn't thinking maliciously enough.
> 
> S possible alternative solution could be, in conjunction with the result 
> field from below, to only allow visiting any extension once. It would 
> require reserving some value as meaning "not visited". Probably zero, so 
> non-zero in result would immediately fail the chain, but would also I 
> think mean we only support negative values in result as output, mapping 
> zeros to one.

I've avoided using the struct itself for markup so far.
Ugh, it would also mean that userspace has to sanitize the extension
chain between uses.

> >>> +
> >>> +     while (ext) {
> >>> +             int err;
> >>> +             u64 x;
> >>> +
> >>> +             if (!stackdepth--) /* recursion vs useful flexibility */
> >>> +                     return -EINVAL;
> >>> +
> >>> +             if (get_user(x, &ext->name))
> >>> +                     return -EFAULT;
> >>> +
> >>> +             err = -EINVAL;
> >>> +             if (x < count && tbl[x])
> >>> +                     err = tbl[x](ext, data);
> >>
> >> How about:
> >>
> >>                  put_user(err, &ext->result);
> >>
> >> And:
> >>
> >> struct i915_user_extension {
> >>          __u64 next_extension;
> >>          __u64 name;
> >>          __u32 result;
> >>          __u32 mbz;
> >> };
> >>
> >> So we add the ability for each extension to store it's exit code giving
> >> userspace opportunity to know which one failed.
> >>
> >> With this I would be satisfied usability is future proof enough.
> > 
> > I'm sorely tempted. The biggest objection I have is this defeats the
> > elegance of a read-only chain. So who would actually use it?
> > 
> > err = gem_context_create_ext(&chain);
> > if (err) {
> >       struct i915_user_extension *ext = (struct i915_user_extension *)chain;
> >       while (ext && !ext->result)
> >               ext = (struct i915_user_extension *)ext->next_extension;
> >       if (ext)
> >               fprintf(stderr, "context creation failed at extension: %lld", ext->name);
> > }
> > 
> > What exactly are they going to do? They are not going to do anything
> > like
> >       while (err) {
> >               ext = first_faulty_ext(&chain);
> >               switch (ext->name) {
> >               case ...:  do_fixup_A(ext);
> >               }
> >               err = gem_context_create_ext(&chain);
> >       }
> > 
> > I'm not really seeing how they benefit over, and above, handling the
> > ioctl error by printing out the entire erroneous struct and chain, and
> > falling back to avoiding that ioctl.
> > 
> > I think what you really want is a per-application/fd debug log, so that
> > we can dump the actual errors as they arise (without leaking them into
> > the general syslog).
> 
> Maybe.. could be an extension of the existing problem of "What EINVAL 
> you mean exactly?" indeed.
> 
> I don't see a problem with writing back though?

Writing anything gives me the heebie-jeebies. If we keep it a read-only
struct, we can never be tricked into overwriting something important.

It also makes it harder for userspace to reuse as they have to clear the
result field?
-Chris


More information about the Intel-gfx mailing list