Hello All,
SoftRoCE driver (drivers/infiniband/sw/rxe) contains several tasklets:
rxe_requester (in rxe_req.c), rxe_completer (rxe_comp.c), and
rxe_responder (in rxe_resp.c).
All of these tasklets can be scheduled for asynchronous execution by
calling function rxe_run_task (rxe_task.c) with sched=1. In this case
the tasklet is passed to tasklet_schedule.
These tasklets receive as a parameter a queue pair (QP) object that is
allocated from a dedicated memory pool implemented in rxe_pool.c and is
reference counted.
The first thing this tasklets do is increasing reference count for a QP
object by calling rxe_add_ref (call kref_get).
I thin this behavior is erroneous. It is possible for reference counter
to go down to zero, when a tasklet is scheduled for execution. This can
happen, for example, if a tasklet is scheduled and then the process that
created a QP is destroyed before the tasklet runs. When a process is
destroyed, the reference count for QP will go down and can reach zero.
As result, the QP object can be already destroyed by the time the
tasklet is actually run. This will result into use-after-free.
The proper way to implement this case would be to call rxe_add_ref
*before* tasklet_schedule: Either inside rxe_run_task, when sched equals
1, or before rxe_run_task.
If you think my reasoning is correct, I can prepare a patch.
I would be happy to see any comment from you before that, as I'm new to
kernel programming.
--
Regards,
Maksym Planeta