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