https://bugs.kde.org/show_bug.cgi?id=376956

--- Comment #6 from Philippe Waroquiers <philippe.waroqui...@skynet.be> ---
(In reply to Daniel Glöckner from comment #5)
> Created attachment 104511 [details]
> First half of the fix
> 
> Part of the problem is that SNDRV_PCM_IOCTL_PREPARE was not handled
> correctly.
> There is a "break" missing in the post-syscall function. I have attached a
> patch.
So, IIUC, due to this missing break, the code was falling through
VKI_SNDRV_CTL_IOCTL_PVERSION:
which was then setting sizeof(int) bytes as defined at ARG3 
so, randomly setting some bytes as defined, and I suppose in your case
at address 0x0.
Thanks for the analysis and the patch, this fix was committed as
revision 16266.



> 
> The other half of the problem is that DRM_IOCTL_VERSION will not write more
> than name_len/date_len/desc_len bytes into name/date/desc but always sets
> name_len/date_len/desc_len to the number of bytes that would have been
> needed.
> Libdrm first tests how much is needed by setting all fields to 0/NULL before
> it calls the ioctl a second time with allocated buffers.
> 
> Is there any way to pass the input values of name_len/date_len/desc_len from
> PRE(sys_ioctl) to POST(sys_ioctl)?
No easy way that I know of.

I suppose that for this second half, the problem is that the
the resulting *_len causes again the bytes from 0x0 to be marked
as defined.

A quick/partially correct (for your case) fix is to avoid setting bytes
as defined if name/date/desc are NULL.
But that will not cover the cases where these are not NULL, but are too
small : too many bytes will be marked as defined.

As you suggest the proper fix is in the POST to see what were the initial
buffer lengths given by the user, and only mark as defined either the effective
lengths touched by the kernel (if <= to the user lengths), or else the
user lengths.

As far as I know, a possibility to do what you need is :
* In the PRE, allocate a block of memory big enough to 
   1. copy the struct the user has given
   2. store after this struct user the 3 input length and the user
       original struct address.
* In the POST, copy back the kernel result to the user struct, using
  the kernel returned length and the user saved length to decide what to copy
  and what to set define.
  I guess you also need to restore the ARG3 value.
  Then free the allocated block.

This is a hack somewhat similar to what is done in e.g. pselect6
and ppoll PRE and POST.

-- 
You are receiving this mail because:
You are watching all bug changes.

Reply via email to