ia64/xen-unstable

changeset 19807:468561f3c8ee

Only allow DOMCTL_max_vcpus to increase vcpus from zero.

Otherwise reallocation of the vcpus array is unsafe.

Signed-off-by: Jan Beulich <jbeulich@novell.com>
Signed-off-by: Keir Fraser <keir.fraser@citrix.com>
author Keir Fraser <keir.fraser@citrix.com>
date Tue Jun 23 11:10:29 2009 +0100 (2009-06-23)
parents 703ced548925
children 16c2806b09c6
files xen/common/domctl.c
line diff
     1.1 --- a/xen/common/domctl.c	Fri Jun 19 08:45:55 2009 +0100
     1.2 +++ b/xen/common/domctl.c	Tue Jun 23 11:10:29 2009 +0100
     1.3 @@ -463,24 +463,34 @@ long do_domctl(XEN_GUEST_HANDLE(xen_domc
     1.4          if ( (max < d->max_vcpus) && (d->vcpu[max] != NULL) )
     1.5              goto maxvcpu_out;
     1.6  
     1.7 +        /*
     1.8 +         * For now don't allow increasing the vcpu count from a non-zero
     1.9 +         * value: This code and all readers of d->vcpu would otherwise need
    1.10 +         * to be converted to use RCU, but at present there's no tools side
    1.11 +         * code path that would issue such a request.
    1.12 +         */
    1.13 +        ret = -EBUSY;
    1.14 +        if ( (d->max_vcpus > 0) && (max > d->max_vcpus) )
    1.15 +            goto maxvcpu_out;
    1.16 +
    1.17          ret = -ENOMEM;
    1.18          if ( max > d->max_vcpus )
    1.19          {
    1.20 -            struct vcpu **vcpus = xmalloc_array(struct vcpu *, max);
    1.21 -            void *ptr;
    1.22 +            struct vcpu **vcpus;
    1.23  
    1.24 -            if ( !vcpus )
    1.25 +            BUG_ON(d->vcpu != NULL);
    1.26 +            BUG_ON(d->max_vcpus != 0);
    1.27 +
    1.28 +            if ( (vcpus = xmalloc_array(struct vcpu *, max)) == NULL )
    1.29                  goto maxvcpu_out;
    1.30 -            memcpy(vcpus, d->vcpu, d->max_vcpus * sizeof(*vcpus));
    1.31 -            memset(vcpus + d->max_vcpus, 0,
    1.32 -                   (max - d->max_vcpus) * sizeof(*vcpus));
    1.33 +            memset(vcpus, 0, max * sizeof(*vcpus));
    1.34  
    1.35 -            ptr = d->vcpu;
    1.36 +            /* Install vcpu array /then/ update max_vcpus. */
    1.37              d->vcpu = vcpus;
    1.38              wmb();
    1.39              d->max_vcpus = max;
    1.40 -            xfree(ptr);
    1.41          }
    1.42 +
    1.43          for ( i = 0; i < max; i++ )
    1.44          {
    1.45              if ( d->vcpu[i] != NULL )