security_manager.c 21.5 KB
Newer Older
1 2 3
/*
 * security_manager.c: Internal security manager API
 *
4
 * Copyright (C) 2010-2014 Red Hat, Inc.
5 6 7 8 9 10 11 12 13 14 15 16
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
17
 * License along with this library.  If not, see
O
Osier Yang 已提交
18
 * <http://www.gnu.org/licenses/>.
19 20 21 22 23 24 25 26 27 28
 *
 * Author: Daniel P. Berrange <berrange@redhat.com>
 */

#include <config.h>


#include "security_driver.h"
#include "security_stack.h"
#include "security_dac.h"
29
#include "virerror.h"
30
#include "viralloc.h"
31
#include "virobject.h"
32
#include "virlog.h"
33 34 35

#define VIR_FROM_THIS VIR_FROM_SECURITY

36
VIR_LOG_INIT("security.security_manager");
37 38

struct _virSecurityManager {
39 40
    virObjectLockable parent;

41 42
    virSecurityDriverPtr drv;
    bool allowDiskFormatProbing;
43 44
    bool defaultConfined;
    bool requireConfined;
45
    const char *virtDriver;
46
    void *privateData;
47 48
};

49 50
static virClassPtr virSecurityManagerClass;

51 52 53 54 55 56 57 58 59 60 61

static
void virSecurityManagerDispose(void *obj)
{
    virSecurityManagerPtr mgr = obj;

    if (mgr->drv->close)
        mgr->drv->close(mgr);
    VIR_FREE(mgr->privateData);
}

62 63 64 65 66 67 68 69 70 71 72 73 74 75

static int virSecurityManagerOnceInit(void)
{
    if (!(virSecurityManagerClass = virClassNew(virClassForObjectLockable(),
                                                "virSecurityManagerClass",
                                                sizeof(virSecurityManager),
                                                virSecurityManagerDispose)))
        return -1;

    return 0;
}

VIR_ONCE_GLOBAL_INIT(virSecurityManager);

76
static virSecurityManagerPtr virSecurityManagerNewDriver(virSecurityDriverPtr drv,
77
                                                         const char *virtDriver,
78 79 80
                                                         bool allowDiskFormatProbing,
                                                         bool defaultConfined,
                                                         bool requireConfined)
81 82
{
    virSecurityManagerPtr mgr;
83 84 85 86
    char *privateData;

    if (virSecurityManagerInitialize() < 0)
        return NULL;
87

88 89 90 91 92 93
    VIR_DEBUG("drv=%p (%s) virtDriver=%s allowDiskFormatProbing=%d "
              "defaultConfined=%d requireConfined=%d",
              drv, drv->name, virtDriver,
              allowDiskFormatProbing, defaultConfined,
              requireConfined);

94
    if (VIR_ALLOC_N(privateData, drv->privateDataLen) < 0)
95 96
        return NULL;

97 98 99 100 101
    if (!(mgr = virObjectLockableNew(virSecurityManagerClass))) {
        VIR_FREE(privateData);
        return NULL;
    }

102 103
    mgr->drv = drv;
    mgr->allowDiskFormatProbing = allowDiskFormatProbing;
104 105
    mgr->defaultConfined = defaultConfined;
    mgr->requireConfined = requireConfined;
106
    mgr->virtDriver = virtDriver;
107
    mgr->privateData = privateData;
108 109

    if (drv->open(mgr) < 0) {
110
        virObjectUnref(mgr);
111 112 113 114 115 116
        return NULL;
    }

    return mgr;
}

117
virSecurityManagerPtr virSecurityManagerNewStack(virSecurityManagerPtr primary)
118 119 120
{
    virSecurityManagerPtr mgr =
        virSecurityManagerNewDriver(&virSecurityDriverStack,
121
                                    virSecurityManagerGetDriver(primary),
122 123 124
                                    virSecurityManagerGetAllowDiskFormatProbing(primary),
                                    virSecurityManagerGetDefaultConfined(primary),
                                    virSecurityManagerGetRequireConfined(primary));
125 126 127 128

    if (!mgr)
        return NULL;

129
    virSecurityStackAddNested(mgr, primary);
130 131 132 133

    return mgr;
}

134 135 136 137 138 139 140 141
int virSecurityManagerStackAddNested(virSecurityManagerPtr stack,
                                     virSecurityManagerPtr nested)
{
    if (!STREQ("stack", stack->drv->name))
        return -1;
    return virSecurityStackAddNested(stack, nested);
}

142 143
virSecurityManagerPtr virSecurityManagerNewDAC(const char *virtDriver,
                                               uid_t user,
144 145
                                               gid_t group,
                                               bool allowDiskFormatProbing,
146 147
                                               bool defaultConfined,
                                               bool requireConfined,
148 149 150 151
                                               bool dynamicOwnership)
{
    virSecurityManagerPtr mgr =
        virSecurityManagerNewDriver(&virSecurityDriverDAC,
152
                                    virtDriver,
153 154 155
                                    allowDiskFormatProbing,
                                    defaultConfined,
                                    requireConfined);
156 157 158 159

    if (!mgr)
        return NULL;

160 161 162 163
    if (virSecurityDACSetUserAndGroup(mgr, user, group) < 0) {
        virSecurityManagerDispose(mgr);
        return NULL;
    }
164 165 166 167 168 169
    virSecurityDACSetDynamicOwnership(mgr, dynamicOwnership);

    return mgr;
}

virSecurityManagerPtr virSecurityManagerNew(const char *name,
170
                                            const char *virtDriver,
171 172 173
                                            bool allowDiskFormatProbing,
                                            bool defaultConfined,
                                            bool requireConfined)
174
{
175
    virSecurityDriverPtr drv = virSecurityDriverLookup(name, virtDriver);
176 177 178
    if (!drv)
        return NULL;

179 180 181
    /* driver "none" needs some special handling of *Confined bools */
    if (STREQ(drv->name, "none")) {
        if (requireConfined) {
182 183
            virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                           _("Security driver \"none\" cannot create confined guests"));
184 185 186 187 188 189 190 191 192 193 194 195 196 197 198
            return NULL;
        }

        if (defaultConfined) {
            if (name != NULL) {
                VIR_WARN("Configured security driver \"none\" disables default"
                         " policy to create confined guests");
            } else {
                VIR_DEBUG("Auto-probed security driver is \"none\";"
                          " confined guests will not be created");
            }
            defaultConfined = false;
        }
    }

199
    return virSecurityManagerNewDriver(drv,
200
                                       virtDriver,
201 202 203
                                       allowDiskFormatProbing,
                                       defaultConfined,
                                       requireConfined);
204 205
}

206 207 208

/*
 * Must be called before fork()'ing to ensure mutex state
209 210 211 212
 * is sane for the child to use. A negative return means the
 * child must not be forked; a successful return must be
 * followed by a call to virSecurityManagerPostFork() in both
 * parent and child.
213
 */
214
int virSecurityManagerPreFork(virSecurityManagerPtr mgr)
215
{
216 217
    int ret = 0;

218
    virObjectLock(mgr);
219 220 221 222 223 224 225
    if (mgr->drv->preFork) {
        ret = mgr->drv->preFork(mgr);
        if (ret < 0)
            virObjectUnlock(mgr);
    }

    return ret;
226 227 228 229 230 231 232 233 234 235 236 237
}


/*
 * Must be called after fork()'ing in both parent and child
 * to ensure mutex state is sane for the child to use
 */
void virSecurityManagerPostFork(virSecurityManagerPtr mgr)
{
    virObjectUnlock(mgr);
}

238 239
void *virSecurityManagerGetPrivateData(virSecurityManagerPtr mgr)
{
240
    return mgr->privateData;
241 242 243
}


244 245 246 247 248 249
const char *
virSecurityManagerGetDriver(virSecurityManagerPtr mgr)
{
    return mgr->virtDriver;
}

250 251 252
const char *
virSecurityManagerGetDOI(virSecurityManagerPtr mgr)
{
253 254 255 256 257 258 259
    if (mgr->drv->getDOI) {
        const char *ret;
        virObjectLock(mgr);
        ret = mgr->drv->getDOI(mgr);
        virObjectUnlock(mgr);
        return ret;
    }
260

261
    virReportUnsupportedError();
262 263 264 265 266 267
    return NULL;
}

const char *
virSecurityManagerGetModel(virSecurityManagerPtr mgr)
{
268 269 270 271 272 273 274
    if (mgr->drv->getModel) {
        const char *ret;
        virObjectLock(mgr);
        ret = mgr->drv->getModel(mgr);
        virObjectUnlock(mgr);
        return ret;
    }
275

276
    virReportUnsupportedError();
277 278 279
    return NULL;
}

280 281 282 283 284 285 286 287 288 289 290 291 292 293 294
/* return NULL if a base label is not present */
const char *
virSecurityManagerGetBaseLabel(virSecurityManagerPtr mgr, int virtType)
{
    if (mgr->drv->getBaseLabel) {
        const char *ret;
        virObjectLock(mgr);
        ret = mgr->drv->getBaseLabel(mgr, virtType);
        virObjectUnlock(mgr);
        return ret;
    }

    return NULL;
}

295 296 297 298 299
bool virSecurityManagerGetAllowDiskFormatProbing(virSecurityManagerPtr mgr)
{
    return mgr->allowDiskFormatProbing;
}

300 301 302 303 304 305 306 307 308 309
bool virSecurityManagerGetDefaultConfined(virSecurityManagerPtr mgr)
{
    return mgr->defaultConfined;
}

bool virSecurityManagerGetRequireConfined(virSecurityManagerPtr mgr)
{
    return mgr->requireConfined;
}

310 311 312
int virSecurityManagerRestoreDiskLabel(virSecurityManagerPtr mgr,
                                       virDomainDefPtr vm,
                                       virDomainDiskDefPtr disk)
313
{
314
    if (mgr->drv->domainRestoreSecurityDiskLabel) {
315 316
        int ret;
        virObjectLock(mgr);
317
        ret = mgr->drv->domainRestoreSecurityDiskLabel(mgr, vm, disk);
318 319 320
        virObjectUnlock(mgr);
        return ret;
    }
321

322
    virReportUnsupportedError();
323 324 325
    return -1;
}

326
int virSecurityManagerSetDaemonSocketLabel(virSecurityManagerPtr mgr,
327
                                           virDomainDefPtr vm)
328
{
329 330 331 332 333 334 335
    if (mgr->drv->domainSetSecurityDaemonSocketLabel) {
        int ret;
        virObjectLock(mgr);
        ret = mgr->drv->domainSetSecurityDaemonSocketLabel(mgr, vm);
        virObjectUnlock(mgr);
        return ret;
    }
336

337
    virReportUnsupportedError();
338 339 340
    return -1;
}

341
int virSecurityManagerSetSocketLabel(virSecurityManagerPtr mgr,
342
                                     virDomainDefPtr vm)
343
{
344 345 346 347 348 349 350
    if (mgr->drv->domainSetSecuritySocketLabel) {
        int ret;
        virObjectLock(mgr);
        ret = mgr->drv->domainSetSecuritySocketLabel(mgr, vm);
        virObjectUnlock(mgr);
        return ret;
    }
351

352
    virReportUnsupportedError();
353 354 355
    return -1;
}

356
int virSecurityManagerClearSocketLabel(virSecurityManagerPtr mgr,
357
                                       virDomainDefPtr vm)
358
{
359 360 361 362 363 364 365
    if (mgr->drv->domainClearSecuritySocketLabel) {
        int ret;
        virObjectLock(mgr);
        ret = mgr->drv->domainClearSecuritySocketLabel(mgr, vm);
        virObjectUnlock(mgr);
        return ret;
    }
366

367
    virReportUnsupportedError();
368 369 370
    return -1;
}

371 372 373
int virSecurityManagerSetDiskLabel(virSecurityManagerPtr mgr,
                                   virDomainDefPtr vm,
                                   virDomainDiskDefPtr disk)
374
{
375
    if (mgr->drv->domainSetSecurityDiskLabel) {
376 377
        int ret;
        virObjectLock(mgr);
378
        ret = mgr->drv->domainSetSecurityDiskLabel(mgr, vm, disk);
379 380 381
        virObjectUnlock(mgr);
        return ret;
    }
382

383
    virReportUnsupportedError();
384 385 386 387
    return -1;
}

int virSecurityManagerRestoreHostdevLabel(virSecurityManagerPtr mgr,
388
                                          virDomainDefPtr vm,
389 390
                                          virDomainHostdevDefPtr dev,
                                          const char *vroot)
391
{
392 393 394 395 396 397 398
    if (mgr->drv->domainRestoreSecurityHostdevLabel) {
        int ret;
        virObjectLock(mgr);
        ret = mgr->drv->domainRestoreSecurityHostdevLabel(mgr, vm, dev, vroot);
        virObjectUnlock(mgr);
        return ret;
    }
399

400
    virReportUnsupportedError();
401 402 403 404
    return -1;
}

int virSecurityManagerSetHostdevLabel(virSecurityManagerPtr mgr,
405
                                      virDomainDefPtr vm,
406 407
                                      virDomainHostdevDefPtr dev,
                                      const char *vroot)
408
{
409 410 411 412 413 414 415
    if (mgr->drv->domainSetSecurityHostdevLabel) {
        int ret;
        virObjectLock(mgr);
        ret = mgr->drv->domainSetSecurityHostdevLabel(mgr, vm, dev, vroot);
        virObjectUnlock(mgr);
        return ret;
    }
416

417
    virReportUnsupportedError();
418 419 420 421
    return -1;
}

int virSecurityManagerSetSavedStateLabel(virSecurityManagerPtr mgr,
422
                                         virDomainDefPtr vm,
423 424
                                         const char *savefile)
{
425 426 427 428 429 430 431
    if (mgr->drv->domainSetSavedStateLabel) {
        int ret;
        virObjectLock(mgr);
        ret = mgr->drv->domainSetSavedStateLabel(mgr, vm, savefile);
        virObjectUnlock(mgr);
        return ret;
    }
432

433
    virReportUnsupportedError();
434 435 436 437
    return -1;
}

int virSecurityManagerRestoreSavedStateLabel(virSecurityManagerPtr mgr,
438
                                             virDomainDefPtr vm,
439 440
                                             const char *savefile)
{
441 442 443 444 445 446 447
    if (mgr->drv->domainRestoreSavedStateLabel) {
        int ret;
        virObjectLock(mgr);
        ret = mgr->drv->domainRestoreSavedStateLabel(mgr, vm, savefile);
        virObjectUnlock(mgr);
        return ret;
    }
448

449
    virReportUnsupportedError();
450 451 452 453
    return -1;
}

int virSecurityManagerGenLabel(virSecurityManagerPtr mgr,
454
                               virDomainDefPtr vm)
455
{
456
    int ret = -1;
457
    size_t i, j;
458 459
    virSecurityManagerPtr* sec_managers = NULL;
    virSecurityLabelDefPtr seclabel;
460
    bool generated = false;
461

462
    if (mgr == NULL || mgr->drv == NULL)
463
        return ret;
464 465

    if ((sec_managers = virSecurityManagerGetNested(mgr)) == NULL)
466
        return ret;
467

468
    virObjectLock(mgr);
469
    for (i = 0; i < vm->nseclabels; i++) {
470 471 472
        if (!vm->seclabels[i]->model)
            continue;

473 474 475 476 477 478 479 480 481 482 483 484
        for (j = 0; sec_managers[j]; j++)
            if (STREQ(vm->seclabels[i]->model, sec_managers[j]->drv->name))
                break;

        if (!sec_managers[j]) {
            virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
                           _("Unable to find security driver for label %s"),
                           vm->seclabels[i]->model);
            goto cleanup;
        }
    }

485
    for (i = 0; sec_managers[i]; i++) {
486 487 488
        generated = false;
        seclabel = virDomainDefGetSecurityLabelDef(vm, sec_managers[i]->drv->name);
        if (!seclabel) {
489
            if (!(seclabel = virSecurityLabelDefNew(sec_managers[i]->drv->name)))
490 491
                goto cleanup;
            generated = seclabel->implicit = true;
492
        }
493

494
        if (seclabel->type == VIR_DOMAIN_SECLABEL_DEFAULT) {
495
            if (sec_managers[i]->defaultConfined) {
496
                seclabel->type = VIR_DOMAIN_SECLABEL_DYNAMIC;
497
            } else {
498
                seclabel->type = VIR_DOMAIN_SECLABEL_NONE;
499 500
                seclabel->norelabel = true;
            }
501 502
        }

503 504 505 506 507 508 509 510
        if (seclabel->type == VIR_DOMAIN_SECLABEL_NONE) {
            if (sec_managers[i]->requireConfined) {
                virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                               _("Unconfined guests are not allowed on this host"));
                goto cleanup;
            } else if (vm->nseclabels && generated) {
                VIR_DEBUG("Skipping auto generated seclabel of type none");
                virSecurityLabelDefFree(seclabel);
511
                seclabel = NULL;
512 513
                continue;
            }
514 515 516
        }

        if (!sec_managers[i]->drv->domainGenSecurityLabel) {
517
            virReportUnsupportedError();
518 519
            virSecurityLabelDefFree(seclabel);
            seclabel = NULL;
520
        } else {
521 522
            /* The seclabel must be added to @vm prior calling domainGenSecurityLabel
             * which may require seclabel to be presented already */
523
            if (generated &&
524
                VIR_APPEND_ELEMENT(vm->seclabels, vm->nseclabels, seclabel) < 0)
525 526 527 528 529 530
                goto cleanup;

            if (sec_managers[i]->drv->domainGenSecurityLabel(sec_managers[i], vm) < 0) {
                if (VIR_DELETE_ELEMENT(vm->seclabels,
                                       vm->nseclabels -1, vm->nseclabels) < 0)
                    vm->nseclabels--;
531
                goto cleanup;
532
            }
533 534

            seclabel = NULL;
535 536 537
        }
    }

538 539
    ret = 0;

540
 cleanup:
541
    virObjectUnlock(mgr);
542 543
    if (generated)
        virSecurityLabelDefFree(seclabel);
544
    VIR_FREE(sec_managers);
545
    return ret;
546 547 548
}

int virSecurityManagerReserveLabel(virSecurityManagerPtr mgr,
549 550
                                   virDomainDefPtr vm,
                                   pid_t pid)
551
{
552 553 554 555 556 557 558
    if (mgr->drv->domainReserveSecurityLabel) {
        int ret;
        virObjectLock(mgr);
        ret = mgr->drv->domainReserveSecurityLabel(mgr, vm, pid);
        virObjectUnlock(mgr);
        return ret;
    }
559

560
    virReportUnsupportedError();
561 562 563 564
    return -1;
}

int virSecurityManagerReleaseLabel(virSecurityManagerPtr mgr,
565
                                   virDomainDefPtr vm)
566
{
567 568 569 570 571 572 573
    if (mgr->drv->domainReleaseSecurityLabel) {
        int ret;
        virObjectLock(mgr);
        ret = mgr->drv->domainReleaseSecurityLabel(mgr, vm);
        virObjectUnlock(mgr);
        return ret;
    }
574

575
    virReportUnsupportedError();
576 577 578 579
    return -1;
}

int virSecurityManagerSetAllLabel(virSecurityManagerPtr mgr,
580
                                  virDomainDefPtr vm,
581 582
                                  const char *stdin_path)
{
583 584 585 586 587 588 589
    if (mgr->drv->domainSetSecurityAllLabel) {
        int ret;
        virObjectLock(mgr);
        ret = mgr->drv->domainSetSecurityAllLabel(mgr, vm, stdin_path);
        virObjectUnlock(mgr);
        return ret;
    }
590

591
    virReportUnsupportedError();
592 593 594 595
    return -1;
}

int virSecurityManagerRestoreAllLabel(virSecurityManagerPtr mgr,
596
                                      virDomainDefPtr vm,
597
                                      bool migrated)
598
{
599 600 601 602 603 604 605
    if (mgr->drv->domainRestoreSecurityAllLabel) {
        int ret;
        virObjectLock(mgr);
        ret = mgr->drv->domainRestoreSecurityAllLabel(mgr, vm, migrated);
        virObjectUnlock(mgr);
        return ret;
    }
606

607
    virReportUnsupportedError();
608 609 610 611
    return -1;
}

int virSecurityManagerGetProcessLabel(virSecurityManagerPtr mgr,
612 613
                                      virDomainDefPtr vm,
                                      pid_t pid,
614 615
                                      virSecurityLabelPtr sec)
{
616 617 618 619 620 621 622
    if (mgr->drv->domainGetSecurityProcessLabel) {
        int ret;
        virObjectLock(mgr);
        ret = mgr->drv->domainGetSecurityProcessLabel(mgr, vm, pid, sec);
        virObjectUnlock(mgr);
        return ret;
    }
623

624
    virReportUnsupportedError();
625 626 627 628
    return -1;
}

int virSecurityManagerSetProcessLabel(virSecurityManagerPtr mgr,
629
                                      virDomainDefPtr vm)
630
{
631 632 633 634 635 636 637
    if (mgr->drv->domainSetSecurityProcessLabel) {
        int ret;
        virObjectLock(mgr);
        ret = mgr->drv->domainSetSecurityProcessLabel(mgr, vm);
        virObjectUnlock(mgr);
        return ret;
    }
638

639
    virReportUnsupportedError();
640 641 642
    return -1;
}

643 644 645 646 647 648 649
int virSecurityManagerSetChildProcessLabel(virSecurityManagerPtr mgr,
                                           virDomainDefPtr vm,
                                           virCommandPtr cmd)
{
    if (mgr->drv->domainSetSecurityChildProcessLabel)
       return mgr->drv->domainSetSecurityChildProcessLabel(mgr, vm, cmd);

650
    virReportUnsupportedError();
651 652 653
    return -1;
}

654 655 656
int virSecurityManagerVerify(virSecurityManagerPtr mgr,
                             virDomainDefPtr def)
{
657 658 659 660 661
    virSecurityLabelDefPtr secdef;

    if (mgr == NULL || mgr->drv == NULL)
        return 0;

662 663 664 665
    /* NULL model == dynamic labelling, with whatever driver
     * is active, so we can short circuit verify check to
     * avoid drivers de-referencing NULLs by accident
     */
666 667
    secdef = virDomainDefGetSecurityLabelDef(def, mgr->drv->name);
    if (secdef == NULL || secdef->model == NULL)
668 669
        return 0;

670 671 672 673 674 675 676
    if (mgr->drv->domainSecurityVerify) {
        int ret;
        virObjectLock(mgr);
        ret = mgr->drv->domainSecurityVerify(mgr, def);
        virObjectUnlock(mgr);
        return ret;
    }
677

678
    virReportUnsupportedError();
679 680
    return -1;
}
681

682
int virSecurityManagerSetImageFDLabel(virSecurityManagerPtr mgr,
683
                                      virDomainDefPtr vm,
684
                                      int fd)
685
{
686 687 688 689 690 691 692
    if (mgr->drv->domainSetSecurityImageFDLabel) {
        int ret;
        virObjectLock(mgr);
        ret = mgr->drv->domainSetSecurityImageFDLabel(mgr, vm, fd);
        virObjectUnlock(mgr);
        return ret;
    }
693

694
    virReportUnsupportedError();
695 696
    return -1;
}
697

698 699 700 701
int virSecurityManagerSetTapFDLabel(virSecurityManagerPtr mgr,
                                    virDomainDefPtr vm,
                                    int fd)
{
702 703 704 705 706 707 708
    if (mgr->drv->domainSetSecurityTapFDLabel) {
        int ret;
        virObjectLock(mgr);
        ret = mgr->drv->domainSetSecurityTapFDLabel(mgr, vm, fd);
        virObjectUnlock(mgr);
        return ret;
    }
709

710
    virReportUnsupportedError();
711 712 713
    return -1;
}

714 715 716
char *virSecurityManagerGetMountOptions(virSecurityManagerPtr mgr,
                                        virDomainDefPtr vm)
{
717 718 719 720 721 722 723
    if (mgr->drv->domainGetSecurityMountOptions) {
        char *ret;
        virObjectLock(mgr);
        ret = mgr->drv->domainGetSecurityMountOptions(mgr, vm);
        virObjectUnlock(mgr);
        return ret;
    }
724

725
    virReportUnsupportedError();
726 727
    return NULL;
}
728 729 730 731 732 733 734 735 736 737

virSecurityManagerPtr*
virSecurityManagerGetNested(virSecurityManagerPtr mgr)
{
    virSecurityManagerPtr* list = NULL;

    if (STREQ("stack", mgr->drv->name)) {
        return virSecurityStackGetNested(mgr);
    }

738
    if (VIR_ALLOC_N(list, 2) < 0)
739 740 741 742 743 744
        return NULL;

    list[0] = mgr;
    list[1] = NULL;
    return list;
}
745 746 747 748 749

int virSecurityManagerSetHugepages(virSecurityManagerPtr mgr,
                                    virDomainDefPtr vm,
                                    const char *path)
{
750 751 752 753 754 755 756
    if (mgr->drv->domainSetSecurityHugepages) {
        int ret;
        virObjectLock(mgr);
        ret = mgr->drv->domainSetSecurityHugepages(mgr, vm, path);
        virObjectUnlock(mgr);
        return ret;
    }
757 758 759

    return 0;
}