$NetBSD: patch-CVE-2015-2752,v 1.1 2015/04/19 13:13:21 spz Exp $ Patch for CVE-2015-2752 aka XSA-125 from http://xenbits.xenproject.org/xsa/xsa125-4.2.patch --- libxc/xc_domain.c.orig 2013-09-10 06:42:18.000000000 +0000 +++ libxc/xc_domain.c @@ -1322,6 +1322,13 @@ int xc_domain_bind_pt_isa_irq( PT_IRQ_TYPE_ISA, 0, 0, 0, machine_irq)); } +#ifndef min +#define min(X, Y) ({ \ + const typeof (X) _x = (X); \ + const typeof (Y) _y = (Y); \ + (void) (&_x == &_y); \ + (_x < _y) ? _x : _y; }) +#endif int xc_domain_memory_mapping( xc_interface *xch, uint32_t domid, @@ -1331,17 +1338,55 @@ int xc_domain_memory_mapping( uint32_t add_mapping) { DECLARE_DOMCTL; + int ret = 0, err; + unsigned long done = 0, nr, max_batch_sz; + + if ( !nr_mfns ) + return 0; domctl.cmd = XEN_DOMCTL_memory_mapping; domctl.domain = domid; - domctl.u.memory_mapping.first_gfn = first_gfn; - domctl.u.memory_mapping.first_mfn = first_mfn; - domctl.u.memory_mapping.nr_mfns = nr_mfns; domctl.u.memory_mapping.add_mapping = add_mapping; + max_batch_sz = nr_mfns; + do + { + nr = min(nr_mfns - done, max_batch_sz); + domctl.u.memory_mapping.nr_mfns = nr; + domctl.u.memory_mapping.first_gfn = first_gfn + done; + domctl.u.memory_mapping.first_mfn = first_mfn + done; + err = do_domctl(xch, &domctl); + if ( err && errno == E2BIG ) + { + if ( max_batch_sz <= 1 ) + break; + max_batch_sz >>= 1; + continue; + } + /* Save the first error... */ + if ( !ret ) + ret = err; + /* .. and ignore the rest of them when removing. */ + if ( err && add_mapping != DPCI_REMOVE_MAPPING ) + break; + + done += nr; + } while ( done < nr_mfns ); + + /* + * Undo what we have done unless unmapping, by unmapping the entire region. + * Errors here are ignored. + */ + if ( ret && add_mapping != DPCI_REMOVE_MAPPING ) + xc_domain_memory_mapping(xch, domid, first_gfn, first_mfn, nr_mfns, + DPCI_REMOVE_MAPPING); + + /* We might get E2BIG so many times that we never advance. */ + if ( !done && !ret ) + ret = -1; - return do_domctl(xch, &domctl); + return ret; } - +#undef min int xc_domain_ioport_mapping( xc_interface *xch, uint32_t domid,