diff options
author | Prakash Surya <[email protected]> | 2011-12-16 14:57:31 -0800 |
---|---|---|
committer | Brian Behlendorf <[email protected]> | 2011-12-16 16:54:00 -0800 |
commit | 8f2503e0af490ea253d6db1a15b4901437171cc1 (patch) | |
tree | 5aa2d69dd5838d2495d698595b9ff11a2e8f5335 /include/sharefs/share.h | |
parent | e7e5f78e7bf6dc86337483f4d9f01becc017d185 (diff) |
Store copy of tqent_flags prior to servicing task
A preallocated taskq_ent_t's tqent_flags must be checked prior to
servicing the taskq_ent_t. Once a preallocated taskq entry is serviced,
the ownership of the entry is handed back to the caller of
taskq_dispatch, thus the entry's contents can potentially be mangled.
In particular, this is a problem in the case where a preallocated taskq
entry is serviced, and the caller clears it's tqent_flags field. Thus,
when the function returns and task_done is called, it looks as though
the entry is **not** a preallocated task (when in fact it **is** a
preallocated task).
In this situation, task_done will place the preallocated taskq_ent_t
structure onto the taskq_t's free list. This is a **huge** mistake. If
the taskq_ent_t is then freed by the caller of taskq_dispatch, the
taskq_t's free list will hold a pointer to garbage data. Even worse, if
nothing has over written the freed memory before the pointer is
dereferenced, it may still look as though it points to a valid list_head
belonging to a taskq_ent_t structure.
Thus, the task entry's flags are now copied prior to servicing the task.
This copy is then checked to see if it is a preallocated task, and
determine if the entry needs to be passed down to the task_done
function.
Signed-off-by: Prakash Surya <[email protected]>
Signed-off-by: Brian Behlendorf <[email protected]>
Closes #71
Diffstat (limited to 'include/sharefs/share.h')
0 files changed, 0 insertions, 0 deletions