mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-11-11 12:28:41 +08:00
xen/gntalloc: safely delete grefs in add_grefs() undo path
If a gref could not be added (perhaps because the limit has been reached or there are no more grant references available), the undo path may crash because __del_gref() frees the gref while it is being used for a list iteration. A comment suggests that using list_for_each_entry() is safe since the gref isn't removed from the list being iterated over, but it is freed and thus list_for_each_entry_safe() must be used. Also, explicitly delete the gref from the local per-file list, even though this is not strictly necessary. Signed-off-by: David Vrabel <david.vrabel@citrix.com> Reviewed-by: Boris Ostrovsky <boris.ostrovsky@oracle.com>
This commit is contained in:
parent
e9de2e5fd6
commit
5903c6bd1a
@ -124,7 +124,7 @@ static int add_grefs(struct ioctl_gntalloc_alloc_gref *op,
|
||||
int i, rc, readonly;
|
||||
LIST_HEAD(queue_gref);
|
||||
LIST_HEAD(queue_file);
|
||||
struct gntalloc_gref *gref;
|
||||
struct gntalloc_gref *gref, *next;
|
||||
|
||||
readonly = !(op->flags & GNTALLOC_FLAG_WRITABLE);
|
||||
rc = -ENOMEM;
|
||||
@ -160,8 +160,8 @@ undo:
|
||||
mutex_lock(&gref_mutex);
|
||||
gref_size -= (op->count - i);
|
||||
|
||||
list_for_each_entry(gref, &queue_file, next_file) {
|
||||
/* __del_gref does not remove from queue_file */
|
||||
list_for_each_entry_safe(gref, next, &queue_file, next_file) {
|
||||
list_del(&gref->next_file);
|
||||
__del_gref(gref);
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user