2006-03-17

Report-an-Apple-bug Friday! 7

So much for filing these earlier in the week. I spent the whole week pounding on the test cases.

This bug is kevent read events' .data is random when st_size > ULONG_MAX. It was filed on 2006-03-17 at 01:55.


Summary:

When the size of a regular file exceeds ULONG_MAX, the value of the event's data member can be truncated.

Steps to Reproduce:

  1. Create a kqueue.
  2. Open a file for reading.
  3. Add a kevent description to the queue from step 1 with EVFILT_READ and the fd from step 2.
  4. Poll the queue for events.

Expected Results:

The data member of the returned kevent structure, indicating the amount of data between the file's current position and the end of file, is capped to ULONG_MAX to work around truncation issues.

Actual Results:

The data member of the returned kevent structure, indicating the naked size of the file, may be truncated or appear negative.

Regression:

None known.

Notes:

The st_size member of struct stat is an off_t (a long long), which is 8 bytes. The data member of struct kevent is an intptr_t (a long), which is 4 bytes.

kevent appears to simply assign the .st_size value directly to event.data in all read events. This produces the exhibited effect: only the low 4 bytes are copied; the high 4 bytes are thrown away. If the .st_size value exceeds ULONG_MAX, then the resulting 4-byte value would appear random if you didn't know what was going on.

The other problem is that, unless I'm wrong about what a 'vnode' is, this behavior does not match the manpage's description:

EVFILT_READ

Takes a file descriptor as the identifier, and returns whenever there is data available to read. The behavior of the filter is slightly different depending on the descriptor type.

Vnodes
Returns when the file pointer is not at the end of file. data contains the offset from current position to end of file, and may be negative.

.data only contains the offset to the end of file when the open file's position is at the start of the file, since at that time, that value is equal to the length of the file.

.data should always contain the offset, unless that value exceeds ULONG_MAX, in which case it should be ULONG_MAX (that is to say, .data should be capped to ULONG_MAX).

Workarounds:

  • Don't use kevent.
  • Ignore event.data and only use results from fstat/read/fread.
  • Use mmap.

A test case is included.


(Note: GeoCities is being cranky today. The test case will be up eventually.)

Technorati tags: ,

3 comments:

at 3/17/2006 09:37:00 AM, Blogger jkp said...

kevent == buggy as hell, my kernel panicing bug is still not fixed :(

 
at 3/17/2006 01:22:00 PM, Blogger Peter Hosey said...

What's the rdar:// URL?

 
at 3/18/2006 12:42:00 AM, Blogger jkp said...

rdar://4450881 :)

 

Post a Comment

links to this post:

Create a Link

<< Home