[Devel] [PATCH vz10] selftests/clone3: fix libcap interface usage

Pavel Tikhomirov ptikhomirov at virtuozzo.com
Mon May 18 16:15:57 MSK 2026


This should totaly be sent to upstream.

On 5/17/26 22:00, Eva Kurchatova wrote:
> The test's set_capability() function needs to set CAP_CHECKPOINT_RESTORE
> (bit 40). But libcap's API (cap_set_flag) didn't support cap 40 when the
> test was written - it was too new. So the author worked around it by
> casting cap_t to an assumed internal layout.
> 
> This worked with older libcap versions where cap_t pointed directly to
> that layout.

I would reword to:

... where cap_t and libcap structures had same layout.

Newer libcap internally restructured its cap_t opaque type.

We may want to also point to the exact commit and version where it happened:

https://git.kernel.org/pub/scm/libs/libcap/libcap.git/commit/?id=aca07644

libcap$ git describe --contains aca07644
libcap-2.60~7

After this commit our local libcap becomes incompatible with cap_t.

> 
> Since 2.43, libcap natively supports CAP_CHECKPOINT_RESTORE, workaround
> is no longer needed. The fix directly uses the library interface.
> 
> Signed-off-by: Eva Kurchatova <eva.kurchatova at virtuozzo.com>

Reviewed-by: Pavel Tikhomirov <ptikhomirov at virtuozzo.com>

> 
> https://virtuozzo.atlassian.net/browse/VSTOR-130940

Fixes tag is missing:

Fixes: 1d27a0be16d6c ("selftests: add clone3() CAP_CHECKPOINT_RESTORE test")

> Feature: Fix kselftests
> ---
>  .../clone3/clone3_cap_checkpoint_restore.c    | 20 +++++--------------
>  1 file changed, 5 insertions(+), 15 deletions(-)
> 
> diff --git a/tools/testing/selftests/clone3/clone3_cap_checkpoint_restore.c b/tools/testing/selftests/clone3/clone3_cap_checkpoint_restore.c
> index 976e92c259fc..739e0ee544de 100644
> --- a/tools/testing/selftests/clone3/clone3_cap_checkpoint_restore.c
> +++ b/tools/testing/selftests/clone3/clone3_cap_checkpoint_restore.c
> @@ -84,15 +84,11 @@ static int test_clone3_set_tid(struct __test_metadata *_metadata,
>  	return ret;
>  }
>  
> -struct libcap {
> -	struct __user_cap_header_struct hdr;
> -	struct __user_cap_data_struct data[2];
> -};
> -
>  static int set_capability(void)
>  {
> -	cap_value_t cap_values[] = { CAP_SETUID, CAP_SETGID };
> -	struct libcap *cap;
> +	cap_value_t cap_values[] = {
> +		CAP_SETUID, CAP_SETGID, CAP_CHECKPOINT_RESTORE
> +	};
>  	int ret = -1;
>  	cap_t caps;
>  
> @@ -108,14 +104,8 @@ static int set_capability(void)
>  		goto out;
>  	}
>  
> -	cap_set_flag(caps, CAP_EFFECTIVE, 2, cap_values, CAP_SET);
> -	cap_set_flag(caps, CAP_PERMITTED, 2, cap_values, CAP_SET);
> -
> -	cap = (struct libcap *) caps;
> -
> -	/* 40 -> CAP_CHECKPOINT_RESTORE */
> -	cap->data[1].effective |= 1 << (40 - 32);
> -	cap->data[1].permitted |= 1 << (40 - 32);
> +	cap_set_flag(caps, CAP_EFFECTIVE, 3, cap_values, CAP_SET);
> +	cap_set_flag(caps, CAP_PERMITTED, 3, cap_values, CAP_SET);
>  
>  	if (cap_set_proc(caps)) {
>  		perror("cap_set_proc");

-- 
Best regards, Pavel Tikhomirov
Senior Software Developer, Virtuozzo.



More information about the Devel mailing list