Revision 61b6c499 hw/virtio-9p-local.c

b/hw/virtio-9p-local.c
477 477
static ssize_t local_lgetxattr(FsContext *ctx, const char *path,
478 478
                               const char *name, void *value, size_t size)
479 479
{
480
    if ((ctx->fs_sm == SM_MAPPED) &&
481
        (strncmp(name, "user.virtfs.", 12) == 0)) {
482
        /*
483
         * Don't allow fetch of user.virtfs namesapce
484
         * in case of mapped security
485
         */
486
        errno = ENOATTR;
487
        return -1;
488
    }
489

  
480 490
    return lgetxattr(rpath(ctx, path), name, value, size);
481 491
}
482 492

  
483 493
static ssize_t local_llistxattr(FsContext *ctx, const char *path,
484 494
                                void *value, size_t size)
485 495
{
486
    return llistxattr(rpath(ctx, path), value, size);
496
    ssize_t retval;
497
    ssize_t actual_len = 0;
498
    char *orig_value, *orig_value_start;
499
    char *temp_value, *temp_value_start;
500
    ssize_t xattr_len, parsed_len = 0, attr_len;
501

  
502
    if (ctx->fs_sm != SM_MAPPED) {
503
        return llistxattr(rpath(ctx, path), value, size);
504
    }
505

  
506
    /* Get the actual len */
507
    xattr_len = llistxattr(rpath(ctx, path), value, 0);
508

  
509
    /* Now fetch the xattr and find the actual size */
510
    orig_value = qemu_malloc(xattr_len);
511
    xattr_len = llistxattr(rpath(ctx, path), orig_value, xattr_len);
512

  
513
    /*
514
     * For mapped security model drop user.virtfs namespace
515
     * from the list
516
     */
517
    temp_value = qemu_mallocz(xattr_len);
518
    temp_value_start = temp_value;
519
    orig_value_start = orig_value;
520
    while (xattr_len > parsed_len) {
521
        attr_len = strlen(orig_value) + 1;
522
        if (strncmp(orig_value, "user.virtfs.", 12) != 0) {
523
            /* Copy this entry */
524
            strcat(temp_value, orig_value);
525
            temp_value  += attr_len;
526
            actual_len += attr_len;
527
        }
528
        parsed_len += attr_len;
529
        orig_value += attr_len;
530
    }
531
    if (!size) {
532
        retval = actual_len;
533
        goto out;
534
    } else if (size >= actual_len) {
535
        /* now copy the parsed attribute list back */
536
        memset(value, 0, size);
537
        memcpy(value, temp_value_start, actual_len);
538
        retval = actual_len;
539
        goto out;
540
    }
541
    errno = ERANGE;
542
    retval = -1;
543
out:
544
    qemu_free(orig_value_start);
545
    qemu_free(temp_value_start);
546
    return retval;
487 547
}
488 548

  
489 549
static int local_lsetxattr(FsContext *ctx, const char *path, const char *name,
490 550
                           void *value, size_t size, int flags)
491 551
{
552
    if ((ctx->fs_sm == SM_MAPPED) &&
553
        (strncmp(name, "user.virtfs.", 12) == 0)) {
554
        /*
555
         * Don't allow fetch of user.virtfs namesapce
556
         * in case of mapped security
557
         */
558
        errno = EACCES;
559
        return -1;
560
    }
492 561
    return lsetxattr(rpath(ctx, path), name, value, size, flags);
493 562
}
494 563

  

Also available in: Unified diff