[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [Xen-devel] [PATCH v5 06/28] xen/xsplice: Hypervisor implementation of XEN_XSPLICE_op
>>> On 24.03.16 at 21:00, <konrad.wilk@xxxxxxxxxx> wrote: > +static struct payload *find_payload(const xen_xsplice_name_t *name) > +{ > + struct payload *data, *found = NULL; > + char n[XEN_XSPLICE_NAME_SIZE]; > + int rc; > + > + rc = verify_name(name); > + if ( rc ) > + return ERR_PTR(rc); > + > + if ( __copy_from_guest(n, name->name, name->size) ) > + return ERR_PTR(-EFAULT); > + > + if ( n[name->size - 1] ) > + return ERR_PTR(-EINVAL); > + > + spin_lock_recursive(&payload_lock); > + > + list_for_each_entry ( data, &payload_list, list ) > + { > + if ( !strcmp(data->name, n) ) > + { > + found = data; > + break; > + } > + } > + > + spin_unlock_recursive(&payload_lock); > + > + return found; > +} So I've mentioned this before: Dropping the lock here means the caller may (in general) not de-reference the returned pointer. While it's only xsplice_upload() that calls this with the lock not held, and that function indeed doesn't de-ref the pointer, it's still racy: Two xsplice_upload() invocations for identically named payloads would then possibly insert both instead of one of them detecting the collision reliably. Hence I think all callers need to hold the lock, and hence the need for a recursive lock goes away. > +static int xsplice_upload(xen_sysctl_xsplice_upload_t *upload) > +{ > + struct payload *data; > + int rc; > + > + rc = verify_payload(upload); > + if ( rc ) > + return rc; > + > + data = find_payload(&upload->name); > + if ( data && !IS_ERR(data) /* Found. */ ) > + return -EEXIST; > + > + if ( IS_ERR(data) ) > + return PTR_ERR(data); > + > + data = xzalloc(struct payload); > + if ( !data ) > + return -ENOMEM; > + > + rc = -EFAULT; > + if ( __copy_from_guest(data->name, upload->name.name, upload->name.size) > ) > + goto out; You're reading the string from guest memory a second time here, invalidating the verification done earlier. > +static int xsplice_list(xen_sysctl_xsplice_list_t *list) > +{ > + xen_xsplice_status_t status; > + struct payload *data; > + unsigned int idx = 0, i = 0; > + int rc = 0; > + > + if ( list->nr > 1024 ) > + return -E2BIG; > + > + if ( list->pad ) > + return -EINVAL; > + > + if ( list->nr && > + (!guest_handle_okay(list->status, list->nr) || > + !guest_handle_okay(list->name, XEN_XSPLICE_NAME_SIZE * list->nr) || > + !guest_handle_okay(list->len, list->nr)) ) > + return -EINVAL; > + > + spin_lock_recursive(&payload_lock); > + if ( list->idx > payload_cnt ) >= ? Jan _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxx http://lists.xen.org/xen-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |