[libvirt PATCH v2 03/10] util: generate a persistent system token

Michal Prívozník mprivozn at redhat.com
Mon May 10 11:32:19 UTC 2021


On 5/7/21 6:24 PM, Daniel P. Berrangé wrote:
> When creating the system identity set the system token. The system
> token is currently stored in a local path
> 
>    /var/run/libvirt/common/system.token
> 
> Obviously with only traditional UNIX DAC in effect, this is largely
> security through obscurity, if the client is running at the same
> privilege level as the daemon. It does, however, reliably distinguish
> an unprivilegd client from the system daemons.
> 
> With a MAC system like SELinux though, or possible use of containers,
> access can be further restricted.
> 
> A possible future improvement for Linux would be to populate the
> kernel keyring with a secret for libvirt daemons to share.
> 
> Reviewed-by: Michal Privoznik <mprivozn at redhat.com>
> Signed-off-by: Daniel P. Berrangé <berrange at redhat.com>
> ---
>  src/util/viridentity.c | 102 +++++++++++++++++++++++++++++++++++++++++
>  1 file changed, 102 insertions(+)
> 
> diff --git a/src/util/viridentity.c b/src/util/viridentity.c
> index 7da4ea12f5..8c939a507e 100644
> --- a/src/util/viridentity.c
> +++ b/src/util/viridentity.c

> @@ -144,6 +154,98 @@ int virIdentitySetCurrent(virIdentity *ident)
>  }
>  
>  
> +#define TOKEN_BYTES 16
> +#define TOKEN_STRLEN (TOKEN_BYTES * 2)
> +
> +static char *
> +virIdentityConstructSystemTokenPath(void)
> +{
> +    g_autofree char *commondir = NULL;
> +    if (geteuid() == 0) {
> +        commondir = g_strdup(RUNSTATEDIR "/libvirt/common");
> +    } else {
> +        g_autofree char *rundir = virGetUserRuntimeDirectory();
> +        commondir = g_strdup_printf("%s/common", rundir);
> +    }
> +
> +    if (g_mkdir_with_parents(commondir, 0700) < 0) {
> +        virReportSystemError(errno,
> +                             _("Cannot create daemon common directory '%s'"),
> +                             commondir);
> +        return NULL;
> +    }
> +
> +    return g_strdup_printf("%s/system.token", commondir);
> +}
> +
> +
> +static char *
> +virIdentityEnsureSystemToken(void)
> +{
> +    g_autofree char *tokenfile = virIdentityConstructSystemTokenPath();
> +    g_autofree char *token = NULL;
> +    VIR_AUTOCLOSE fd = -1;
> +    struct stat st;
> +

Sorry for not spotting this in v1, but @tokenfile can be NULL here, in
which case virIdentityConstructSystemTokenPath() already reported
accurate error. Something like: if (!tokenfile) return NULL;  is sufficient.

> +    fd = open(tokenfile, O_RDWR|O_APPEND|O_CREAT, 0600);
> +    if (fd < 0) {
> +        virReportSystemError(errno,
> +                             _("Unable to open system token %s"),
> +                             tokenfile);
> +        return NULL;
> +    }
> +


Also, I believe you will want to mock this function, because if you
don't then the viridentitytest starts failing after next patch.
Something among these lines:

https://gitlab.com/MichalPrivoznik/libvirt/-/commit/5594631df3b3512adecea0f5a0056611b324fa5d

Michal




More information about the libvir-list mailing list