[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [PATCH 033/104] virtiofsd: passthrough_ll: add lo_map for ino/fh ind
From: |
Masayoshi Mizuma |
Subject: |
Re: [PATCH 033/104] virtiofsd: passthrough_ll: add lo_map for ino/fh indirection |
Date: |
Fri, 17 Jan 2020 16:44:41 -0500 |
On Thu, Dec 12, 2019 at 04:37:53PM +0000, Dr. David Alan Gilbert (git) wrote:
> From: Stefan Hajnoczi <address@hidden>
>
> A layer of indirection is needed because passthrough_ll cannot expose
> pointers or file descriptor numbers to untrusted clients. Malicious
> clients could send invalid pointers or file descriptors in order to
> crash or exploit the file system daemon.
>
> lo_map provides an integer key->value mapping. This will be used for
> ino and fh fields in the patches that follow.
>
> Signed-off-by: Stefan Hajnoczi <address@hidden>
> ---
> tools/virtiofsd/passthrough_ll.c | 124 +++++++++++++++++++++++++++++++
> 1 file changed, 124 insertions(+)
>
> diff --git a/tools/virtiofsd/passthrough_ll.c
> b/tools/virtiofsd/passthrough_ll.c
> index 0188cd9ad6..0a94c3e1f2 100644
> --- a/tools/virtiofsd/passthrough_ll.c
> +++ b/tools/virtiofsd/passthrough_ll.c
> @@ -74,6 +74,21 @@ struct _uintptr_to_must_hold_fuse_ino_t_dummy_struct {
> };
> #endif
>
> +struct lo_map_elem {
> + union {
> + /* Element values will go here... */
> + ssize_t freelist;
> + };
> + bool in_use;
> +};
> +
> +/* Maps FUSE fh or ino values to internal objects */
> +struct lo_map {
> + struct lo_map_elem *elems;
> + size_t nelems;
> + ssize_t freelist;
> +};
> +
> struct lo_inode {
> struct lo_inode *next; /* protected by lo->mutex */
> struct lo_inode *prev; /* protected by lo->mutex */
> @@ -130,6 +145,115 @@ static struct lo_data *lo_data(fuse_req_t req)
> return (struct lo_data *)fuse_req_userdata(req);
> }
>
> +__attribute__((unused)) static void lo_map_init(struct lo_map *map)
> +{
> + map->elems = NULL;
> + map->nelems = 0;
> + map->freelist = -1;
> +}
> +
> +__attribute__((unused)) static void lo_map_destroy(struct lo_map *map)
> +{
> + free(map->elems);
> +}
> +
> +static int lo_map_grow(struct lo_map *map, size_t new_nelems)
> +{
> + struct lo_map_elem *new_elems;
> + size_t i;
> +
> + if (new_nelems <= map->nelems) {
> + return 1;
> + }
> +
> + new_elems = realloc(map->elems, sizeof(map->elems[0]) * new_nelems);
> + if (!new_elems) {
> + return 0;
> + }
> +
> + for (i = map->nelems; i < new_nelems; i++) {
> + new_elems[i].freelist = i + 1;
> + new_elems[i].in_use = false;
> + }
> + new_elems[new_nelems - 1].freelist = -1;
> +
> + map->elems = new_elems;
> + map->freelist = map->nelems;
> + map->nelems = new_nelems;
> + return 1;
> +}
> +
> +__attribute__((unused)) static struct lo_map_elem *
> +lo_map_alloc_elem(struct lo_map *map)
> +{
> + struct lo_map_elem *elem;
> +
> + if (map->freelist == -1 && !lo_map_grow(map, map->nelems + 256)) {
> + return NULL;
> + }
> +
> + elem = &map->elems[map->freelist];
> + map->freelist = elem->freelist;
> +
> + elem->in_use = true;
> +
> + return elem;
> +}
> +
> +__attribute__((unused)) static struct lo_map_elem *
> +lo_map_reserve(struct lo_map *map, size_t key)
> +{
> + ssize_t *prev;
> +
> + if (!lo_map_grow(map, key + 1)) {
> + return NULL;
> + }
> +
> + for (prev = &map->freelist; *prev != -1;
> + prev = &map->elems[*prev].freelist) {
> + if (*prev == key) {
> + struct lo_map_elem *elem = &map->elems[key];
> +
> + *prev = elem->freelist;
> + elem->in_use = true;
> + return elem;
> + }
> + }
> + return NULL;
> +}
> +
> +__attribute__((unused)) static struct lo_map_elem *
> +lo_map_get(struct lo_map *map, size_t key)
> +{
> + if (key >= map->nelems) {
> + return NULL;
> + }
> + if (!map->elems[key].in_use) {
> + return NULL;
> + }
> + return &map->elems[key];
> +}
> +
> +__attribute__((unused)) static void lo_map_remove(struct lo_map *map,
> + size_t key)
> +{
> + struct lo_map_elem *elem;
> +
> + if (key >= map->nelems) {
> + return;
> + }
> +
> + elem = &map->elems[key];
> + if (!elem->in_use) {
> + return;
> + }
> +
> + elem->in_use = false;
> +
> + elem->freelist = map->freelist;
> + map->freelist = key;
> +}
> +
> static struct lo_inode *lo_inode(fuse_req_t req, fuse_ino_t ino)
> {
> if (ino == FUSE_ROOT_ID) {
Looks good to me.
Reviewed-by: Masayoshi Mizuma <address@hidden>
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- Re: [PATCH 033/104] virtiofsd: passthrough_ll: add lo_map for ino/fh indirection,
Masayoshi Mizuma <=