0

In the futex_wake_op function of futex.c in the Linux kernel source,I was trying to understand how the control reaches this point.This happens when in the above said function,the futex_atomic_op_inuser returns -EFAULT,and yet the uaddr2 is writable.

But from the source of futex_atomic_op_inuser, I see that it returns -EFAULT only on if (!access_ok(VERIFY_WRITE, uaddr, sizeof(int))).

futex_atomic_op_inuserin turn calls a the __futex_atomic_op macro where I see a -EFAULT in the code but I'm told that path to EFAULT does not involve calling __futex_atomic_op

How does the control reach the aforementioned point (i.e.if (!fshared)goto retry_private;)then?

Thanks in advance!

itisravi
  • 3,406
  • 3
  • 23
  • 30

1 Answers1

0

access_ok is only meant to check if the address range is valid for the given access, and even for that it can not always give a definite answer. See the comments in the source:

 * Returns true (nonzero) if the memory block may be valid, false (zero)
 * if it is definitely invalid.
 *
 * Note that, depending on architecture, this function probably just
 * checks that the pointer is in the user space range - after calling
 * this function, memory access functions may still return -EFAULT.

Next, even if the block is valid, it may not be present in memory (swapped out). futex_atomic_op_inuser calls pagefault_disable, which disables the normal swap-in process so you will get a hard fault, returning -EFAULT from __futex_atomic_op.

In conclusion all this means that the point in question will be reached if:

  1. the address is invalid but slips past the check in access_ok, or
  2. it is valid but currently swapped out.
Jester
  • 56,577
  • 4
  • 81
  • 125