opennebula-4.12.0-sanitizelibvirtxml.diff

Sanitize LibVirt XML Patch - Roy Keene, 11/16/2015 04:53 PM

Download (17 KB)

View differences:

opennebula-4.12.0-sanitizelibvirtxml/src/vmm/LibVirtDriverKVM.cc 2015-04-08 00:13:27.801640375 -0500
19 19
#include "Nebula.h"
20 20
#include <sstream>
21 21
#include <fstream>
22
#include <string>
22 23
#include <libgen.h>
23 24
#include <math.h>
24 25

  
26
namespace patch
27
{
28
    template < typename T > std::string to_string( const T& n )
29
    {
30
        std::ostringstream stm ;
31
        stm << n ;
32
        return stm.str() ;
33
    }
34
}
35

  
25 36
const float LibVirtDriver::CGROUP_BASE_CPU_SHARES = 1024;
26 37

  
27 38
const int LibVirtDriver::CEPH_DEFAULT_PORT = 6789;
28 39

  
29 40
const int LibVirtDriver::GLUSTER_DEFAULT_PORT = 24007;
30 41

  
42
/*
43
 * Wrap input in a CDATA section
44
 */
45
static string wrapper_contents(string input) {
46
	if (input.find("]]>") != std::string::npos) {
47
		return("");
48
	}
49

  
50
	return("<![CDATA[" + input + "]]>");
51
}
52

  
53
static string wrapper_attribute(string input) {
54
	if (input.find("'") != std::string::npos) {
55
		return("''");
56
	}
57

  
58
	return("'" + input + "'");
59
}
60

  
31 61
/**
32 62
 *  This function generates the <host> element for network disks
33 63
 */
......
38 68
{
39 69
    if (cg_host.empty())
40 70
    {
41
        file << "'/>" << endl;
71
        file << "/>" << endl;
42 72
        return;
43 73
    }
44 74

  
......
47 77

  
48 78
    hosts = one_util::split(cg_host, ' ');
49 79

  
50
    file << "'>" << endl;
80
    file << ">" << endl;
51 81

  
52 82
    for (it = hosts.begin(); it != hosts.end(); it++)
53 83
    {
......
58 88
            continue;
59 89
        }
60 90

  
61
        file << "\t\t\t\t<host name='" << parts[0];
91
        file << "\t\t\t\t<host name=" << wrapper_attribute(parts[0]);
62 92

  
63 93
        if (parts.size() > 1)
64 94
        {
65
            file << "' port='" << parts[1];
95
            file << " port=" << wrapper_attribute(parts[1]);
66 96
        }
67 97
        else if ( default_port != -1 )
68 98
        {
69
            file << "' port='" << default_port;
99
            file << " port=" << wrapper_attribute(patch::to_string(default_port));
70 100
        }
71 101

  
72 102
        if (!transport.empty())
73 103
        {
74
            file << "' transport='" << transport;
104
            file << " transport=" << wrapper_attribute(transport);
75 105
        }
76 106

  
77
        file << "'/>" << endl;
107
        file << "/>" << endl;
78 108
    }
79 109

  
80 110
    file << "\t\t\t</source>" << endl;
......
204 234
    // Starting XML document
205 235
    // ------------------------------------------------------------------------
206 236

  
207
    file << "<domain type='"
208
         << emulator
209
         << "' xmlns:qemu='http://libvirt.org/schemas/domain/qemu/1.0'>"
237
    file << "<domain type="
238
         << wrapper_attribute(emulator)
239
         << " xmlns:qemu='http://libvirt.org/schemas/domain/qemu/1.0'>"
210 240
         << endl;
211 241

  
212 242
    // ------------------------------------------------------------------------
......
228 258

  
229 259
    if (!vcpu.empty())
230 260
    {
231
        file << "\t<vcpu>" << vcpu << "</vcpu>" << endl;
261
        file << "\t<vcpu>" << wrapper_contents(vcpu) << "</vcpu>" << endl;
232 262
    }
233 263

  
234 264
    //Every process gets 1024 shares by default (cgroups), scale this with CPU
......
294 324
        get_default("OS", "MACHINE", machine);
295 325
    }
296 326

  
297
    file << "\t\t<type arch='" << arch << "'";
327
    file << "\t\t<type arch=" << wrapper_attribute(arch);
298 328

  
299 329
    if ( !machine.empty() )
300 330
    {
301
        file << " machine='" << machine << "'";
331
        file << " machine=" << wrapper_attribute(machine);
302 332
    }
303 333

  
304 334
    file << ">hvm</type>" << endl;
......
342 372

  
343 373
    if ( !kernel.empty() )
344 374
    {
345
        file << "\t\t<kernel>" << kernel << "</kernel>" << endl;
375
        file << "\t\t<kernel>" << wrapper_contents(kernel) << "</kernel>" << endl;
346 376

  
347 377
        if ( !initrd.empty() )
348 378
        {
349
            file << "\t\t<initrd>" << initrd << "</initrd>" << endl;
379
            file << "\t\t<initrd>" << wrapper_contents(initrd) << "</initrd>" << endl;
350 380
        }
351 381

  
352 382
        if ( !root.empty() )
......
356 386

  
357 387
        if (!kernel_cmd.empty())
358 388
        {
359
            file << "\t\t<cmdline>" << kernel_cmd << "</cmdline>" << endl;
389
            file << "\t\t<cmdline>" << wrapper_contents(kernel_cmd) << "</cmdline>" << endl;
360 390
        }
361 391
    }
362 392
    else if ( !bootloader.empty() )
363 393
    {
364
        file << "\t\t<bootloader>" << bootloader << "</bootloader>" << endl;
394
        file << "\t\t<bootloader>" << wrapper_contents(bootloader) << "</bootloader>" << endl;
365 395
    }
366 396

  
367 397
    boots = one_util::split(boot, ',');
368 398

  
369 399
    for (vector<string>::const_iterator it=boots.begin(); it!=boots.end(); it++)
370 400
    {
371
        file << "\t\t<boot dev='" << *it << "'/>" << endl;
401
        file << "\t\t<boot dev=" << wrapper_attribute(*it) << "/>" << endl;
372 402
    }
373 403

  
374 404
    file << "\t</os>" << endl;
......
387 417
        emulator_path = "/usr/bin/kvm";
388 418
    }
389 419

  
390
    file << "\t\t<emulator>" << emulator_path << "</emulator>" << endl;
420
    file << "\t\t<emulator>" << wrapper_contents(emulator_path) << "</emulator>" << endl;
391 421

  
392 422
    // ------------------------------------------------------------------------
393 423
    // Disks
......
508 538
        if ( type == "BLOCK" )
509 539
        {
510 540
            file << "\t\t<disk type='block' device='disk'>" << endl
511
                 << "\t\t\t<source dev='" << vm->get_remote_system_dir()
512
                 << "/disk." << disk_id << "'/>" << endl;
541
                 << "\t\t\t<source dev=" << wrapper_attribute(vm->get_remote_system_dir() + "/disk." + patch::to_string(disk_id))
542
                 << "/>" << endl;
513 543
        }
514 544
        else if ( type == "RBD" || type == "RBD_CDROM" )
515 545
        {
......
522 552
                file << "\t\t<disk type='network' device='cdrom'>" << endl;
523 553
            }
524 554

  
525
            file << "\t\t\t<source protocol='rbd' name='" << source;
555
            file << "\t\t\t<source protocol='rbd' name=";
526 556

  
527 557
            if ( clone == "YES" )
528 558
            {
529
                file << "-" << vm->get_oid() << "-" << disk_id;
559
                file << wrapper_attribute(source + "-" + patch::to_string(vm->get_oid()) + "-" + patch::to_string(disk_id));
560
            } else {
561
                file << wrapper_attribute(source);
530 562
            }
531 563

  
532 564
            do_network_hosts(file, ceph_host, "", CEPH_DEFAULT_PORT);
533 565

  
534 566
            if ( !ceph_secret.empty() && !ceph_user.empty())
535 567
            {
536
                file << "\t\t\t<auth username='"<< ceph_user <<"'>" << endl
537
                     << "\t\t\t\t<secret type='ceph' uuid='"
538
                     << ceph_secret <<"'/>" << endl
568
                file << "\t\t\t<auth username=" << wrapper_attribute(ceph_user) << ">" << endl
569
                     << "\t\t\t\t<secret type='ceph' uuid="
570
                     << wrapper_attribute(ceph_secret) <<"/>" << endl
539 571
                     << "\t\t\t</auth>" << endl;
540 572
            }
541 573
        }
......
550 582
                file << "\t\t<disk type='network' device='cdrom'>" << endl;
551 583
            }
552 584

  
553
            file << "\t\t\t<source protocol='sheepdog' name='" << source;
585
            file << "\t\t\t<source protocol='sheepdog' name=";
554 586

  
555 587
            if ( clone == "YES" )
556 588
            {
557
                file << "-" << vm->get_oid() << "-" << disk_id;
589
                file << wrapper_attribute(source + "-" + patch::to_string(vm->get_oid()) + "-" + patch::to_string(disk_id));
590
            } else {
591
                file << wrapper_attribute(source);
558 592
            }
559 593

  
560 594
    	    do_network_hosts(file, sheepdog_host, "tcp", -1);
......
570 604
                file << "\t\t<disk type='network' device='cdrom'>" << endl;
571 605
            }
572 606

  
573
            file << "\t\t\t<source protocol='gluster' name='" << gluster_volume
574
                 << "/";
607
            file << "\t\t\t<source protocol='gluster' name=";
575 608

  
576 609
            if ( clone == "YES" )
577 610
            {
578
                file << vm->get_oid() << "/disk." << disk_id;
611
                file << wrapper_attribute(gluster_volume + "/" + patch::to_string(vm->get_oid()) + "/disk." + patch::to_string(disk_id));
579 612
            }
580 613
            else
581 614
            {
582
                file << one_util::split(source, '/').back();
615
                file << wrapper_attribute(gluster_volume + "/" + one_util::split(source, '/').back());
583 616
            }
584 617

  
585 618
            do_network_hosts(file, gluster_host, "tcp", GLUSTER_DEFAULT_PORT);
......
587 620
        else if ( type == "CDROM" )
588 621
        {
589 622
            file << "\t\t<disk type='file' device='cdrom'>" << endl
590
                 << "\t\t\t<source file='" << vm->get_remote_system_dir()
591
                 << "/disk." << disk_id << "'/>" << endl;
623
                 << "\t\t\t<source file=" << wrapper_attribute(vm->get_remote_system_dir() + "/disk." + patch::to_string(disk_id))
624
                 << "/>" << endl;
592 625
        }
593 626
        else
594 627
        {
595 628
            file << "\t\t<disk type='file' device='disk'>" << endl
596
                 << "\t\t\t<source file='" << vm->get_remote_system_dir()
597
                 << "/disk." << disk_id << "'/>" << endl;
629
                 << "\t\t\t<source file=" << wrapper_attribute(vm->get_remote_system_dir() + "/disk." + patch::to_string(disk_id))
630
                 << "/>" << endl;
598 631
        }
599 632

  
600 633
        // ---- target device to map the disk ----
601 634

  
602
        file << "\t\t\t<target dev='" << target << "'/>" << endl;
635
        file << "\t\t\t<target dev=" << wrapper_attribute(target) << "/>" << endl;
603 636

  
604 637
        // ---- readonly attribute for the disk ----
605 638

  
......
610 643

  
611 644
        // ---- Image Format using qemu driver ----
612 645

  
613
        file << "\t\t\t<driver name='qemu' type='";
646
        file << "\t\t\t<driver name='qemu' type=";
614 647

  
615 648
        if ( type == "CDROM" ) // Use driver raw for CD's
616 649
        {
617
            file << "raw";
650
            file << "'raw'";
618 651
        }
619 652
        else if ( !driver.empty() )
620 653
        {
621
            file << driver;
654
            file << wrapper_attribute(driver);
622 655
        }
623 656
        else
624 657
        {
625
            file << default_driver;
658
            file << wrapper_attribute(default_driver);
626 659
        }
627 660

  
628
        file << "' cache='";
661
        file << " cache=";
629 662

  
630 663
        if ( !cache.empty() )
631 664
        {
632
            file << cache << "'";
665
            file << wrapper_attribute(cache);
633 666
        }
634 667
        else
635 668
        {
636
            file << default_driver_cache << "'";
669
            file << wrapper_attribute(default_driver_cache);
637 670
        }
638 671

  
639 672
        if ( !disk_io.empty() )
640 673
        {
641
            file << " io='" << disk_io << "'";
674
            file << " io=" << wrapper_attribute(disk_io);
642 675
        }
643 676
        else if ( !default_driver_disk_io.empty() )
644 677
        {
645
            file << " io='" << default_driver_disk_io << "'";
678
            file << " io=" << wrapper_attribute(default_driver_disk_io);
646 679
        }
647 680

  
648 681
        file << "/>" << endl;
......
657 690

  
658 691
            if ( !total_bytes_sec.empty() )
659 692
            {
660
                file << "\t\t\t\t<total_bytes_sec>" << total_bytes_sec
693
                file << "\t\t\t\t<total_bytes_sec>" << wrapper_contents(total_bytes_sec)
661 694
                     << "</total_bytes_sec>" << endl;
662 695
            }
663 696

  
664 697
            if ( !read_bytes_sec.empty() )
665 698
            {
666
                file << "\t\t\t\t<read_bytes_sec>" << read_bytes_sec
699
                file << "\t\t\t\t<read_bytes_sec>" << wrapper_contents(read_bytes_sec)
667 700
                     << "</read_bytes_sec>" << endl;
668 701
            }
669 702

  
670 703
            if ( !write_bytes_sec.empty() )
671 704
            {
672
                file << "\t\t\t\t<write_bytes_sec>" << write_bytes_sec
705
                file << "\t\t\t\t<write_bytes_sec>" << wrapper_contents(write_bytes_sec)
673 706
                     << "</write_bytes_sec>" << endl;
674 707
            }
675 708

  
676 709
            if ( !total_iops_sec.empty() )
677 710
            {
678
                file << "\t\t\t\t<total_iops_sec>" << total_iops_sec
711
                file << "\t\t\t\t<total_iops_sec>" << wrapper_contents(total_iops_sec)
679 712
                     << "</total_iops_sec>" << endl;
680 713
            }
681 714

  
682 715
            if ( !read_iops_sec.empty() )
683 716
            {
684
                file << "\t\t\t\t<read_iops_sec>" << read_iops_sec
717
                file << "\t\t\t\t<read_iops_sec>" << wrapper_contents(read_iops_sec)
685 718
                     << "</read_iops_sec>" << endl;
686 719
            }
687 720

  
688 721
            if ( !write_iops_sec.empty() )
689 722
            {
690
                file << "\t\t\t\t<write_iops_sec>" << write_iops_sec
723
                file << "\t\t\t\t<write_iops_sec>" << wrapper_contents(write_iops_sec)
691 724
                     << "</write_iops_sec>" << endl;
692 725
            }
693 726

  
......
715 748
        {
716 749
            file << "\t\t<disk type='file' device='cdrom'>" << endl;
717 750

  
718
            file << "\t\t\t<source file='" << vm->get_remote_system_dir()
719
                 << "/disk." << disk_id << "'/>" << endl;
751
            file << "\t\t\t<source file=" << wrapper_attribute(vm->get_remote_system_dir() + "/disk." + patch::to_string(disk_id))
752
                 << "/>" << endl;
720 753

  
721
            file << "\t\t\t<target dev='" << target << "'/>" << endl;
754
            file << "\t\t\t<target dev=" << wrapper_attribute(target) << "/>" << endl;
722 755
            file << "\t\t\t<readonly/>" << endl;
723 756

  
724 757
            file << "\t\t\t<driver name='qemu' type='raw'/>" << endl;
......
783 816
                file << "\t\t\t<virtualport type='openvswitch'/>" << endl;
784 817
            }
785 818

  
786
            file << "\t\t\t<source bridge='" << *the_bridge << "'/>" << endl;
819
            file << "\t\t\t<source bridge=" << wrapper_attribute(*the_bridge) << "/>" << endl;
787 820
        }
788 821

  
789 822
        if( !mac.empty() )
790 823
        {
791
            file << "\t\t\t<mac address='" << mac << "'/>" << endl;
824
            file << "\t\t\t<mac address=" << wrapper_attribute(mac) << "/>" << endl;
792 825
        }
793 826

  
794 827
        if( !target.empty() )
795 828
        {
796
            file << "\t\t\t<target dev='" << target << "'/>" << endl;
829
            file << "\t\t\t<target dev=" << wrapper_attribute(target) << "/>" << endl;
797 830
        }
798 831

  
799 832
        if( !script.empty() )
800 833
        {
801
            file << "\t\t\t<script path='" << script << "'/>" << endl;
834
#if 0
835
            /*
836
             * Do not allow the user to specify a script
837
             * We do not want them running arbitrary scripts on our hosts.
838
             */
839
            file << "\t\t\t<script path=" << wrapper_attribute(script) << "/>" << endl;
840
#endif
802 841
        }
803 842

  
804 843
        string * the_model = 0;
......
814 853

  
815 854
        if (the_model != 0)
816 855
        {
817
            file << "\t\t\t<model type='" << *the_model << "'/>" << endl;
856
            file << "\t\t\t<model type=" << wrapper_attribute(*the_model) << "/>" << endl;
818 857
        }
819 858

  
820 859
        if (!ip.empty() )
......
832 871

  
833 872
            if ( the_filter != 0 )
834 873
            {
835
                file <<"\t\t\t<filterref filter='"<< *the_filter <<"'>"<<endl;
836
                file << "\t\t\t\t<parameter name='IP' value='"
837
                     << ip << "'/>" << endl;
874
                file <<"\t\t\t<filterref filter="<< wrapper_attribute(*the_filter) <<">"<<endl;
875
                file << "\t\t\t\t<parameter name='IP' value="
876
                     << wrapper_attribute(ip) << "/>" << endl;
838 877
                file << "\t\t\t</filterref>" << endl;
839 878
            }
840 879
        }
......
864 903

  
865 904
            if ( type == "vnc" || type == "spice" )
866 905
            {
867
                file << "\t\t<graphics type='" << type << "'";
906
                file << "\t\t<graphics type=" << wrapper_attribute(type);
868 907

  
869 908
                if ( !listen.empty() )
870 909
                {
871
                    file << " listen='" << listen << "'";
910
                    file << " listen=" << wrapper_attribute(listen);
872 911
                }
873 912

  
874 913
                if ( !port.empty() )
875 914
                {
876
                    file << " port='" << port << "'";
915
                    file << " port=" << wrapper_attribute(port);
877 916
                }
878 917

  
879 918
                if ( !passwd.empty() )
880 919
                {
881
                    file << " passwd='" << passwd << "'";
920
                    file << " passwd=" << wrapper_attribute(passwd);
882 921
                }
883 922

  
884 923
                if ( !keymap.empty() )
885 924
                {
886
                    file << " keymap='" << keymap << "'";
925
                    file << " keymap=" << wrapper_attribute(keymap);
887 926
                }
888 927

  
889 928
                file << "/>" << endl;
......
923 962

  
924 963
            if ( !type.empty() )
925 964
            {
926
                file << "\t\t<input type='" << type << "'";
965
                file << "\t\t<input type=" << wrapper_attribute(type);
927 966

  
928 967
                if ( !bus.empty() )
929 968
                {
930
                    file << " bus='" << bus << "'";
969
                    file << " bus=" << wrapper_attribute(bus);
931 970
                }
932 971

  
933 972
                file << "/>" << endl;
......
1044 1083
        if ( type == "KVM" )
1045 1084
        {
1046 1085
            data = raw->vector_value("DATA");
1086
#if 0
1087
            /*
1088
             * Do not allow unverified XML in the libvirt document
1089
             */
1047 1090
            file << "\t" << data << endl;
1091
#endif
1048 1092
        }
1049 1093
    }
1050 1094