]> git.proxmox.com Git - mirror_spl-debian.git/commit
Store copy of tqent_flags prior to servicing task
authorPrakash Surya <surya1@llnl.gov>
Fri, 16 Dec 2011 22:57:31 +0000 (14:57 -0800)
committerBrian Behlendorf <behlendorf1@llnl.gov>
Sat, 17 Dec 2011 00:54:00 +0000 (16:54 -0800)
commit8f2503e0af490ea253d6db1a15b4901437171cc1
tree5aa2d69dd5838d2495d698595b9ff11a2e8f5335
parente7e5f78e7bf6dc86337483f4d9f01becc017d185
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 <surya1@llnl.gov>
Signed-off-by: Brian Behlendorf <behlendorf1@llnl.gov>
Closes #71
include/sys/taskq.h
module/spl/spl-taskq.c