security_stack.c 16.1 KB
Newer Older
1
/*
2
 * Copyright (C) 2010-2013 Red Hat, Inc.
3 4 5 6 7 8 9 10 11 12 13 14
 *
 * 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
15
 * License along with this library.  If not, see
O
Osier Yang 已提交
16
 * <http://www.gnu.org/licenses/>.
17 18 19 20 21 22 23 24
 *
 * Stacked security driver
 */

#include <config.h>

#include "security_stack.h"

25
#include "virerror.h"
26
#include "viralloc.h"
27 28 29 30 31

#define VIR_FROM_THIS VIR_FROM_SECURITY

typedef struct _virSecurityStackData virSecurityStackData;
typedef virSecurityStackData *virSecurityStackDataPtr;
32 33 34 35 36 37 38
typedef struct _virSecurityStackItem virSecurityStackItem;
typedef virSecurityStackItem* virSecurityStackItemPtr;

struct _virSecurityStackItem {
    virSecurityManagerPtr securityManager;
    virSecurityStackItemPtr next;
};
39 40

struct _virSecurityStackData {
41
    virSecurityStackItemPtr itemsHead;
42 43
};

44 45 46 47 48 49
int
virSecurityStackAddNested(virSecurityManagerPtr mgr,
                          virSecurityManagerPtr nested)
{
    virSecurityStackItemPtr item = NULL;
    virSecurityStackDataPtr priv = virSecurityManagerGetPrivateData(mgr);
50 51 52 53 54
    virSecurityStackItemPtr tmp;

    tmp = priv->itemsHead;
    while (tmp && tmp->next)
        tmp = tmp->next;
55

56
    if (VIR_ALLOC(item) < 0)
57 58
        return -1;
    item->securityManager = nested;
59 60 61 62 63
    if (tmp)
        tmp->next = item;
    else
        priv->itemsHead = item;

64 65 66 67 68 69 70
    return 0;
}

virSecurityManagerPtr
virSecurityStackGetPrimary(virSecurityManagerPtr mgr)
{
    virSecurityStackDataPtr priv = virSecurityManagerGetPrivateData(mgr);
71
    return priv->itemsHead->securityManager;
72 73 74
}

static virSecurityDriverStatus
75
virSecurityStackProbe(const char *virtDriver ATTRIBUTE_UNUSED)
76 77 78 79 80 81 82 83 84 85 86
{
    return SECURITY_DRIVER_ENABLE;
}

static int
virSecurityStackOpen(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED)
{
    return 0;
}

static int
E
Eric Blake 已提交
87
virSecurityStackClose(virSecurityManagerPtr mgr)
88
{
E
Eric Blake 已提交
89
    virSecurityStackDataPtr priv = virSecurityManagerGetPrivateData(mgr);
90
    virSecurityStackItemPtr next, item = priv->itemsHead;
E
Eric Blake 已提交
91

92 93
    while (item) {
        next = item->next;
94
        virObjectUnref(item->securityManager);
95 96 97
        VIR_FREE(item);
        item = next;
    }
E
Eric Blake 已提交
98

99 100 101 102 103 104
    return 0;
}

static const char *
virSecurityStackGetModel(virSecurityManagerPtr mgr)
{
105
    return virSecurityManagerGetModel(virSecurityStackGetPrimary(mgr));
106 107 108 109 110
}

static const char *
virSecurityStackGetDOI(virSecurityManagerPtr mgr)
{
111
    return virSecurityManagerGetDOI(virSecurityStackGetPrimary(mgr));
112 113 114 115 116 117 118
}

static int
virSecurityStackVerify(virSecurityManagerPtr mgr,
                       virDomainDefPtr def)
{
    virSecurityStackDataPtr priv = virSecurityManagerGetPrivateData(mgr);
119
    virSecurityStackItemPtr item = priv->itemsHead;
120 121
    int rc = 0;

122
    for (; item; item = item->next) {
123 124 125 126 127
        if (virSecurityManagerVerify(item->securityManager, def) < 0) {
            rc = -1;
            break;
        }
    }
128 129 130 131 132 133 134

    return rc;
}


static int
virSecurityStackGenLabel(virSecurityManagerPtr mgr,
135
                         virDomainDefPtr vm)
136 137 138
{
    int rc = 0;

139
    if (virSecurityManagerGenLabel(virSecurityStackGetPrimary(mgr), vm) < 0)
140 141
        rc = -1;

142
// TODO
143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159
#if 0
    /* We don't allow secondary drivers to generate labels.
     * This may have to change in the future, but requires
     * changes elsewhere in domain_conf.c and capabilities.c
     * XML formats first, to allow recording of multiple
     * labels
     */
    if (virSecurityManagerGenLabel(priv->secondary, vm) < 0)
        rc = -1;
#endif

    return rc;
}


static int
virSecurityStackReleaseLabel(virSecurityManagerPtr mgr,
160
                             virDomainDefPtr vm)
161 162 163
{
    int rc = 0;

164
    if (virSecurityManagerReleaseLabel(virSecurityStackGetPrimary(mgr), vm) < 0)
165
        rc = -1;
166 167

// TODO
168 169 170 171 172 173 174 175 176 177 178 179
#if 0
    /* XXX See note in GenLabel */
    if (virSecurityManagerReleaseLabel(priv->secondary, vm) < 0)
        rc = -1;
#endif

    return rc;
}


static int
virSecurityStackReserveLabel(virSecurityManagerPtr mgr,
180 181
                             virDomainDefPtr vm,
                             pid_t pid)
182 183 184
{
    int rc = 0;

185
    if (virSecurityManagerReserveLabel(virSecurityStackGetPrimary(mgr), vm, pid) < 0)
186
        rc = -1;
187
// TODO
188 189
#if 0
    /* XXX See note in GenLabel */
190
    if (virSecurityManagerReserveLabel(priv->secondary, vm, pid) < 0)
191 192 193 194 195 196 197 198 199
        rc = -1;
#endif

    return rc;
}


static int
virSecurityStackSetSecurityImageLabel(virSecurityManagerPtr mgr,
200
                                      virDomainDefPtr vm,
201 202 203
                                      virDomainDiskDefPtr disk)
{
    virSecurityStackDataPtr priv = virSecurityManagerGetPrivateData(mgr);
204
    virSecurityStackItemPtr item = priv->itemsHead;
205 206
    int rc = 0;

207 208 209 210
    for (; item; item = item->next) {
        if (virSecurityManagerSetImageLabel(item->securityManager, vm, disk) < 0)
            rc = -1;
    }
211 212 213 214 215 216 217

    return rc;
}


static int
virSecurityStackRestoreSecurityImageLabel(virSecurityManagerPtr mgr,
218
                                          virDomainDefPtr vm,
219 220 221
                                          virDomainDiskDefPtr disk)
{
    virSecurityStackDataPtr priv = virSecurityManagerGetPrivateData(mgr);
222
    virSecurityStackItemPtr item = priv->itemsHead;
223 224
    int rc = 0;

225 226 227 228
    for (; item; item = item->next) {
        if (virSecurityManagerRestoreImageLabel(item->securityManager, vm, disk) < 0)
            rc = -1;
    }
229 230 231 232 233 234 235

    return rc;
}


static int
virSecurityStackSetSecurityHostdevLabel(virSecurityManagerPtr mgr,
236
                                        virDomainDefPtr vm,
237 238
                                        virDomainHostdevDefPtr dev,
                                        const char *vroot)
239 240 241

{
    virSecurityStackDataPtr priv = virSecurityManagerGetPrivateData(mgr);
242
    virSecurityStackItemPtr item = priv->itemsHead;
243 244
    int rc = 0;

245
    for (; item; item = item->next) {
246 247 248 249
        if (virSecurityManagerSetHostdevLabel(item->securityManager,
                                              vm,
                                              dev,
                                              vroot) < 0)
250 251
            rc = -1;
    }
252 253 254 255 256 257 258

    return rc;
}


static int
virSecurityStackRestoreSecurityHostdevLabel(virSecurityManagerPtr mgr,
259
                                            virDomainDefPtr vm,
260 261
                                            virDomainHostdevDefPtr dev,
                                            const char *vroot)
262 263
{
    virSecurityStackDataPtr priv = virSecurityManagerGetPrivateData(mgr);
264
    virSecurityStackItemPtr item = priv->itemsHead;
265 266
    int rc = 0;

267
    for (; item; item = item->next) {
268 269 270 271
        if (virSecurityManagerRestoreHostdevLabel(item->securityManager,
                                                  vm,
                                                  dev,
                                                  vroot) < 0)
272 273
            rc = -1;
    }
274 275 276 277 278 279 280

    return rc;
}


static int
virSecurityStackSetSecurityAllLabel(virSecurityManagerPtr mgr,
281
                                    virDomainDefPtr vm,
282 283 284
                                    const char *stdin_path)
{
    virSecurityStackDataPtr priv = virSecurityManagerGetPrivateData(mgr);
285
    virSecurityStackItemPtr item = priv->itemsHead;
286 287
    int rc = 0;

288 289 290 291
    for (; item; item = item->next) {
        if (virSecurityManagerSetAllLabel(item->securityManager, vm, stdin_path) < 0)
            rc = -1;
    }
292 293 294 295 296 297 298

    return rc;
}


static int
virSecurityStackRestoreSecurityAllLabel(virSecurityManagerPtr mgr,
299
                                        virDomainDefPtr vm,
300 301 302
                                        int migrated)
{
    virSecurityStackDataPtr priv = virSecurityManagerGetPrivateData(mgr);
303
    virSecurityStackItemPtr item = priv->itemsHead;
304 305
    int rc = 0;

306 307 308 309
    for (; item; item = item->next) {
        if (virSecurityManagerRestoreAllLabel(item->securityManager, vm, migrated) < 0)
            rc = -1;
    }
310 311 312 313 314 315 316

    return rc;
}


static int
virSecurityStackSetSavedStateLabel(virSecurityManagerPtr mgr,
317
                                   virDomainDefPtr vm,
318 319 320
                                   const char *savefile)
{
    virSecurityStackDataPtr priv = virSecurityManagerGetPrivateData(mgr);
321
    virSecurityStackItemPtr item = priv->itemsHead;
322 323
    int rc = 0;

324 325 326 327
    for (; item; item = item->next) {
        if (virSecurityManagerSetSavedStateLabel(item->securityManager, vm, savefile) < 0)
            rc = -1;
    }
328 329 330 331 332 333 334

    return rc;
}


static int
virSecurityStackRestoreSavedStateLabel(virSecurityManagerPtr mgr,
335
                                       virDomainDefPtr vm,
336 337 338
                                       const char *savefile)
{
    virSecurityStackDataPtr priv = virSecurityManagerGetPrivateData(mgr);
339
    virSecurityStackItemPtr item = priv->itemsHead;
340 341
    int rc = 0;

342 343 344 345
    for (; item; item = item->next) {
        if (virSecurityManagerRestoreSavedStateLabel(item->securityManager, vm, savefile) < 0)
            rc = -1;
    }
346 347 348 349 350 351 352

    return rc;
}


static int
virSecurityStackSetProcessLabel(virSecurityManagerPtr mgr,
353
                                virDomainDefPtr vm)
354 355
{
    virSecurityStackDataPtr priv = virSecurityManagerGetPrivateData(mgr);
356
    virSecurityStackItemPtr item = priv->itemsHead;
357 358
    int rc = 0;

359 360 361 362
    for (; item; item = item->next) {
        if (virSecurityManagerSetProcessLabel(item->securityManager, vm) < 0)
            rc = -1;
    }
363 364 365 366

    return rc;
}

367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383
static int
virSecurityStackSetChildProcessLabel(virSecurityManagerPtr mgr,
                                     virDomainDefPtr vm,
                                     virCommandPtr cmd)
{
    virSecurityStackDataPtr priv = virSecurityManagerGetPrivateData(mgr);
    virSecurityStackItemPtr item = priv->itemsHead;
    int rc = 0;

    for (; item; item = item->next) {
        if (virSecurityManagerSetChildProcessLabel(item->securityManager, vm, cmd) < 0)
            rc = -1;
    }

    return rc;
}

384 385
static int
virSecurityStackGetProcessLabel(virSecurityManagerPtr mgr,
386 387
                                virDomainDefPtr vm,
                                pid_t pid,
388 389 390 391
                                virSecurityLabelPtr seclabel)
{
    int rc = 0;

392
// TODO
393
#if 0
394
    if (virSecurityManagerGetProcessLabel(priv->secondary, vm, pid, seclabel) < 0)
395 396
        rc = -1;
#endif
397
    if (virSecurityManagerGetProcessLabel(virSecurityStackGetPrimary(mgr), vm, pid, seclabel) < 0)
398 399 400 401 402 403 404
        rc = -1;

    return rc;
}


static int
405
virSecurityStackSetDaemonSocketLabel(virSecurityManagerPtr mgr,
406
                                     virDomainDefPtr vm)
407 408
{
    virSecurityStackDataPtr priv = virSecurityManagerGetPrivateData(mgr);
409
    virSecurityStackItemPtr item = priv->itemsHead;
410 411
    int rc = 0;

412 413 414 415
    for (; item; item = item->next) {
        if (virSecurityManagerSetDaemonSocketLabel(item->securityManager, vm) < 0)
            rc = -1;
    }
416 417 418 419 420

    return rc;
}


421 422
static int
virSecurityStackSetSocketLabel(virSecurityManagerPtr mgr,
423
                               virDomainDefPtr vm)
424 425
{
    virSecurityStackDataPtr priv = virSecurityManagerGetPrivateData(mgr);
426
    virSecurityStackItemPtr item = priv->itemsHead;
427 428
    int rc = 0;

429 430 431 432
    for (; item; item = item->next) {
        if (virSecurityManagerSetSocketLabel(item->securityManager, vm) < 0)
            rc = -1;
    }
433 434 435 436 437

    return rc;
}


438 439
static int
virSecurityStackClearSocketLabel(virSecurityManagerPtr mgr,
440
                                 virDomainDefPtr vm)
441 442
{
    virSecurityStackDataPtr priv = virSecurityManagerGetPrivateData(mgr);
443
    virSecurityStackItemPtr item = priv->itemsHead;
444 445
    int rc = 0;

446 447 448 449
    for (; item; item = item->next) {
        if (virSecurityManagerClearSocketLabel(item->securityManager, vm) < 0)
            rc = -1;
    }
450 451 452 453

    return rc;
}

454
static int
455
virSecurityStackSetImageFDLabel(virSecurityManagerPtr mgr,
456
                                virDomainDefPtr vm,
457
                                int fd)
458 459
{
    virSecurityStackDataPtr priv = virSecurityManagerGetPrivateData(mgr);
460
    virSecurityStackItemPtr item = priv->itemsHead;
461 462
    int rc = 0;

463 464 465 466
    for (; item; item = item->next) {
        if (virSecurityManagerSetImageFDLabel(item->securityManager, vm, fd) < 0)
            rc = -1;
    }
467 468 469 470

    return rc;
}

471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487
static int
virSecurityStackSetTapFDLabel(virSecurityManagerPtr mgr,
                              virDomainDefPtr vm,
                              int fd)
{
    virSecurityStackDataPtr priv = virSecurityManagerGetPrivateData(mgr);
    virSecurityStackItemPtr item = priv->itemsHead;
    int rc = 0;

    for (; item; item = item->next) {
        if (virSecurityManagerSetTapFDLabel(item->securityManager, vm, fd) < 0)
            rc = -1;
    }

    return rc;
}

488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504
static int
virSecurityStackSetHugepages(virSecurityManagerPtr mgr,
                              virDomainDefPtr vm,
                              const char *path)
{
    virSecurityStackDataPtr priv = virSecurityManagerGetPrivateData(mgr);
    virSecurityStackItemPtr item = priv->itemsHead;
    int rc = 0;

    for (; item; item = item->next) {
        if (virSecurityManagerSetHugepages(item->securityManager, vm, path) < 0)
            rc = -1;
    }

    return rc;
}

505 506 507 508
static char *virSecurityStackGetMountOptions(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED,
                                             virDomainDefPtr vm ATTRIBUTE_UNUSED) {
    return NULL;
}
509

510 511 512 513 514 515
virSecurityManagerPtr*
virSecurityStackGetNested(virSecurityManagerPtr mgr)
{
    virSecurityManagerPtr *list = NULL;
    virSecurityStackDataPtr priv = virSecurityManagerGetPrivateData(mgr);
    virSecurityStackItemPtr item;
516 517
    int len = 0;
    size_t i;
518 519 520 521

    for (item = priv->itemsHead; item; item = item->next)
        len++;

522
    if (VIR_ALLOC_N(list, len + 1) < 0)
523 524
        return NULL;

525
    for (i = 0, item = priv->itemsHead; item; item = item->next, i++)
526 527 528 529 530 531
        list[i] = item->securityManager;
    list[len] = NULL;

    return list;
}

532
virSecurityDriver virSecurityDriverStack = {
533 534 535 536 537
    .privateDataLen                     = sizeof(virSecurityStackData),
    .name                               = "stack",
    .probe                              = virSecurityStackProbe,
    .open                               = virSecurityStackOpen,
    .close                              = virSecurityStackClose,
538

539 540
    .getModel                           = virSecurityStackGetModel,
    .getDOI                             = virSecurityStackGetDOI,
541

542
    .domainSecurityVerify               = virSecurityStackVerify,
543

544 545
    .domainSetSecurityImageLabel        = virSecurityStackSetSecurityImageLabel,
    .domainRestoreSecurityImageLabel    = virSecurityStackRestoreSecurityImageLabel,
546

547 548 549
    .domainSetSecurityDaemonSocketLabel = virSecurityStackSetDaemonSocketLabel,
    .domainSetSecuritySocketLabel       = virSecurityStackSetSocketLabel,
    .domainClearSecuritySocketLabel     = virSecurityStackClearSocketLabel,
550

551 552 553
    .domainGenSecurityLabel             = virSecurityStackGenLabel,
    .domainReserveSecurityLabel         = virSecurityStackReserveLabel,
    .domainReleaseSecurityLabel         = virSecurityStackReleaseLabel,
554

555 556
    .domainGetSecurityProcessLabel      = virSecurityStackGetProcessLabel,
    .domainSetSecurityProcessLabel      = virSecurityStackSetProcessLabel,
557
    .domainSetSecurityChildProcessLabel = virSecurityStackSetChildProcessLabel,
558

559 560
    .domainSetSecurityAllLabel          = virSecurityStackSetSecurityAllLabel,
    .domainRestoreSecurityAllLabel      = virSecurityStackRestoreSecurityAllLabel,
561

562 563
    .domainSetSecurityHostdevLabel      = virSecurityStackSetSecurityHostdevLabel,
    .domainRestoreSecurityHostdevLabel  = virSecurityStackRestoreSecurityHostdevLabel,
564

565 566
    .domainSetSavedStateLabel           = virSecurityStackSetSavedStateLabel,
    .domainRestoreSavedStateLabel       = virSecurityStackRestoreSavedStateLabel,
567

568
    .domainSetSecurityImageFDLabel      = virSecurityStackSetImageFDLabel,
569
    .domainSetSecurityTapFDLabel        = virSecurityStackSetTapFDLabel,
570

571
    .domainGetSecurityMountOptions      = virSecurityStackGetMountOptions,
572 573

    .domainSetSecurityHugepages         = virSecurityStackSetHugepages,
574
};