[PATCH 1/2] preallocate: do not allow to change BDS permission improperly

Denis V. Lunev via posted 2 patches 1 month, 2 weeks ago
There is a newer version of this series
[PATCH 1/2] preallocate: do not allow to change BDS permission improperly
Posted by Denis V. Lunev via 1 month, 2 weeks ago
RW permissions could not be lifted from the preallocation filter if
truncate operation has not been finished. In the other case this would
mean WRITE operation (image truncate) called after the return from
inactivate call. This is definitely a contract violation.

Signed-off-by: Denis V. Lunev <den@openvz.org>
CC: Andrey Drobyshev <andrey.drobyshev@virtuozzo.com>
CC: Vladimir Sementsov-Ogievskiy <vsementsov@yandex-team.ru>
CC: Kevin Wolf <kwolf@redhat.com>
---
 block/preallocate.c | 12 ++++++++++++
 1 file changed, 12 insertions(+)

diff --git a/block/preallocate.c b/block/preallocate.c
index bfb638d8b1..1cf854966c 100644
--- a/block/preallocate.c
+++ b/block/preallocate.c
@@ -581,6 +581,17 @@ static void preallocate_child_perm(BlockDriverState *bs, BdrvChild *c,
     }
 }
 
+static int preallocate_check_perm(BlockDriverState *bs, uint64_t perm,
+                                  uint64_t shared, Error **errp)
+{
+    BDRVPreallocateState *s = bs->opaque;
+    if (!can_write_resize(perm) && s->data_end != -EINVAL) {
+        error_setg_errno(errp, EPERM, "Write access is required for truncate");
+        return -EPERM;
+    }
+    return 0;
+}
+
 static BlockDriver bdrv_preallocate_filter = {
     .format_name = "preallocate",
     .instance_size = sizeof(BDRVPreallocateState),
@@ -602,6 +613,7 @@ static BlockDriver bdrv_preallocate_filter = {
 
     .bdrv_set_perm = preallocate_set_perm,
     .bdrv_child_perm = preallocate_child_perm,
+    .bdrv_check_perm = preallocate_check_perm,
 
     .is_filter = true,
 };
-- 
2.43.5
Re: [PATCH 1/2] preallocate: do not allow to change BDS permission improperly
Posted by Andrey Drobyshev 1 month, 2 weeks ago
On 10/9/24 4:58 PM, Denis V. Lunev wrote:
> RW permissions could not be lifted from the preallocation filter if
> truncate operation has not been finished. In the other case this would
> mean WRITE operation (image truncate) called after the return from
> inactivate call. This is definitely a contract violation.
> 
> Signed-off-by: Denis V. Lunev <den@openvz.org>
> CC: Andrey Drobyshev <andrey.drobyshev@virtuozzo.com>
> CC: Vladimir Sementsov-Ogievskiy <vsementsov@yandex-team.ru>
> CC: Kevin Wolf <kwolf@redhat.com>
> ---
>  block/preallocate.c | 12 ++++++++++++
>  1 file changed, 12 insertions(+)
> 
> diff --git a/block/preallocate.c b/block/preallocate.c
> index bfb638d8b1..1cf854966c 100644
> --- a/block/preallocate.c
> +++ b/block/preallocate.c
> @@ -581,6 +581,17 @@ static void preallocate_child_perm(BlockDriverState *bs, BdrvChild *c,
>      }
>  }
>  
> +static int preallocate_check_perm(BlockDriverState *bs, uint64_t perm,
> +                                  uint64_t shared, Error **errp)
> +{
> +    BDRVPreallocateState *s = bs->opaque;
> +    if (!can_write_resize(perm) && s->data_end != -EINVAL) {
> +        error_setg_errno(errp, EPERM, "Write access is required for truncate");
> +        return -EPERM;
> +    }
> +    return 0;
> +}
> +
>  static BlockDriver bdrv_preallocate_filter = {
>      .format_name = "preallocate",
>      .instance_size = sizeof(BDRVPreallocateState),
> @@ -602,6 +613,7 @@ static BlockDriver bdrv_preallocate_filter = {
>  
>      .bdrv_set_perm = preallocate_set_perm,
>      .bdrv_child_perm = preallocate_child_perm,
> +    .bdrv_check_perm = preallocate_check_perm,
>  
>      .is_filter = true,
>  };

Reviewed-by: Andrey Drobyshev <andrey.drobyshev@virtuozzo.com>