also provide credentials in ExecStartPre#24734
Conversation
Systemd's credential interface is not yet natively supported by all programs yet. Hence it's often required to run scripts to massage secrets in the way the programs expect it. This commit allows the ExecStartPre commands to access credentials. Fixes systemd#19604
|
cc @keszybz (#19604 (comment)) |
|
Using |
|
In some cases |
|
Would it be possible to backport this to systemd-stable, or does this need to wait for a new release? |
And it's causing the brokenness in this issue. Following is a minimal reproduction case: In one terminal: In another terminal: This issue happens because which creates the credentials are created twice (courtesy: |
Currently, exec_setup_credential always rewrite all credentials on exec_invoke, i.e. each ExecCommand invocation. This is problematic though: * When writing tmp cred files, we essentially double the size of each credential. Therefore, if one cred is bigger than half of CREDENTIALS_TOTAL_SIZE_MAX, confusing error occurs (see also systemd#24734 (comment)) * Credential is a unit thing and should not change during the whole lifetime of the unit. However, if e.g. a on-disk credential or unit file (SetCredential=) changes between ExecStart= and ExecStartPost=, the credentials are overwritten and the main process is suddenly seeing completely different creds when ExecStartPost= gets executed. So, let's always reuse final cred dir if mounted and not empty, so that the creds used is stable and probably more efficient.
Currently, exec_setup_credential always rewrite all credentials on exec_invoke, i.e. each ExecCommand invocation. This is problematic though: * When writing tmp cred files, we essentially double the size of each credential. Therefore, if one cred is bigger than half of CREDENTIALS_TOTAL_SIZE_MAX, confusing error occurs (see also systemd#24734 (comment)) * Credential is a unit thing and should not change during the whole lifetime of the unit. However, if e.g. a on-disk credential or unit file (SetCredential=) changes between ExecStart= and ExecStartPost=, the credentials are overwritten and the main process is suddenly seeing completely different creds when ExecStartPost= gets executed. So, let's always reuse final cred dir if mounted and not empty, so that the creds used is stable and probably more efficient.
Currently, exec_setup_credential always rewrite all credentials on exec_invoke, i.e. each ExecCommand invocation. This is problematic though: * When writing tmp cred files, we essentially double the size of each credential. Therefore, if one cred is bigger than half of CREDENTIALS_TOTAL_SIZE_MAX, confusing error occurs (see also systemd#24734 (comment)) * Credential is a unit thing and should not change during the whole lifetime of the unit. However, if e.g. a on-disk credential or unit file (SetCredential=) changes between ExecStart= and ExecStartPost=, the credentials are overwritten and the main process is suddenly seeing completely different creds when ExecStartPost= gets executed. So, let's always reuse final cred dir if mounted and not empty, so that the creds used is stable and probably more efficient.
Currently, exec_setup_credential always rewrite all credentials on exec_invoke, i.e. each ExecCommand invocation. This is problematic though: * When writing tmp cred files, we essentially double the size of each credential. Therefore, if one cred is bigger than half of CREDENTIALS_TOTAL_SIZE_MAX, confusing error occurs (see also systemd#24734 (comment)) * Credential is a unit thing and should not change during the whole lifetime of the unit. However, if e.g. a on-disk credential or unit file (SetCredential=) changes between ExecStart= and ExecStartPost=, the credentials are overwritten and the main process is suddenly seeing completely different creds when ExecStartPost= gets executed. So, let's always reuse final cred dir if mounted and not empty, so that the creds used is stable and probably more efficient.
Currently, exec_setup_credential always rewrite all credentials on exec_invoke, i.e. each ExecCommand invocation. This is problematic though: * When writing tmp cred files, we essentially double the size of each credential. Therefore, if one cred is bigger than half of CREDENTIALS_TOTAL_SIZE_MAX, confusing error occurs (see also systemd#24734 (comment)) * Credential is a unit thing and should not change during the whole lifetime of the unit. However, if e.g. a on-disk credential or unit file (SetCredential=) changes between ExecStart= and ExecStartPost=, the credentials are overwritten and the main process is suddenly seeing completely different creds when ExecStartPost= gets executed. So, let's always reuse final cred dir if mounted and not empty, so that the creds used is stable and probably more efficient.
Currently, exec_setup_credential always rewrite all credentials on exec_invoke, i.e. each ExecCommand invocation. This is problematic though: * When writing tmp cred files, we essentially double the size of each credential. Therefore, if one cred is bigger than half of CREDENTIALS_TOTAL_SIZE_MAX, confusing error occurs (see also systemd#24734 (comment)) * Credential is a unit thing and should not change during the whole lifetime of the unit. However, if e.g. a on-disk credential or unit file (SetCredential=) changes between ExecStart= and ExecStartPost=, the credentials are overwritten and the main process is suddenly seeing completely different creds when ExecStartPost= gets executed. So, let's always reuse final cred dir if mounted and not empty, so that the creds used is stable and probably more efficient.
Currently, exec_setup_credential always rewrite all credentials on exec_invoke, i.e. each ExecCommand invocation. This is problematic though: * When writing tmp cred files, we essentially double the size of each credential. Therefore, if one cred is bigger than half of CREDENTIALS_TOTAL_SIZE_MAX, confusing error occurs (see also systemd#24734 (comment)) * Credential is a unit thing and should not change during the whole lifetime of the unit. However, if e.g. a on-disk credential or unit file (SetCredential=) changes between ExecStart= and ExecStartPost=, the credentials are overwritten and the main process is suddenly seeing completely different creds when ExecStartPost= gets executed. So, let's always reuse final cred dir if mounted and not empty, so that the creds used is stable and probably more efficient.
Currently, exec_setup_credential() always rewrite all credentials upon exec_invoke(), i.e. invocation of each ExecCommand. This is problematic though: * When writing each tmp cred file, we essentially double the size of the credential. Therefore, if one cred is bigger than half of CREDENTIALS_TOTAL_SIZE_MAX, confusing ENOSPC occurs (see also systemd#24734 (comment)) * Credential is a unit-wide thing and thus should not change during the whole lifetime of the unit. However, if e.g. a on-disk credential or SetCredential= in unit file changes between ExecStart= and ExecStartPost=, the credentials are overwritten when the latter gets to run, and the already-running main process is suddenly seeing completely different creds. This one is especially awkward IMO, say if people use a timer to regularly update local creds. So, let's always reuse final cred dir if mounted and not empty, so that the creds used is stable and each exec_invoke() is probably more efficient.
fresh otherwise Currently, exec_setup_credential() always rewrite all credentials upon exec_invoke(), i.e. invocation of each ExecCommand, and within a single tmpfs instance. This is problematic though: * When writing each tmp cred file, we essentially double the size of the credential. Therefore, if one cred is bigger than half of CREDENTIALS_TOTAL_SIZE_MAX, confusing ENOSPC occurs (see also systemd#24734 (comment)) * Credential is a unit-wide thing and thus should not change during the whole lifetime of main process. However, if e.g. a on-disk credential or SetCredential= in unit file changes between ExecStart= and ExecStartPost=, the credentials are overwritten when the latter gets to run, and the already-running main process is suddenly seeing completely different creds. So, let's try to reuse final cred dir if the main process has started and the tmpfs has been populated, so that the creds used is stable across all ExecStart= and ExecStartPost=-s. We still want to retain the ability of updating creds through ExecStartPre= though, therefore we forcibly use a fresh cred dir for those. 'Fresh' means to actually unmount the old tmpfs first, so the first problem goes away, too.
fresh otherwise Currently, exec_setup_credential() always rewrite all credentials upon exec_invoke(), i.e. invocation of each ExecCommand, and within a single tmpfs instance. This is problematic though: * When writing each tmp cred file, we essentially double the size of the credential. Therefore, if one cred is bigger than half of CREDENTIALS_TOTAL_SIZE_MAX, confusing ENOSPC occurs (see also systemd#24734 (comment)) * Credential is a unit-wide thing and thus should not change during the whole lifetime of main process. However, if e.g. a on-disk credential or SetCredential= in unit file changes between ExecStart= and ExecStartPost=, the credentials are overwritten when the latter gets to run, and the already-running main process is suddenly seeing completely different creds. So, let's try to reuse final cred dir if the main process has started and the tmpfs has been populated, so that the creds used is stable across all ExecStart= and ExecStartPost=-s. We still want to retain the ability of updating creds through ExecStartPre= though, therefore we forcibly use a fresh cred dir for those. 'Fresh' means to actually unmount the old tmpfs first, so the first problem goes away, too.
fresh otherwise Currently, exec_setup_credential() always rewrite all credentials upon exec_invoke(), i.e. invocation of each ExecCommand, and within a single tmpfs instance. This is problematic though: * When writing each tmp cred file, we essentially double the size of the credential. Therefore, if one cred is bigger than half of CREDENTIALS_TOTAL_SIZE_MAX, confusing ENOSPC occurs (see also systemd#24734 (comment)) * Credential is a unit-wide thing and thus should not change during the whole lifetime of main process. However, if e.g. a on-disk credential or SetCredential= in unit file changes between ExecStart= and ExecStartPost=, the credentials are overwritten when the latter gets to run, and the already-running main process is suddenly seeing completely different creds. So, let's try to reuse final cred dir if the main process has started and the tmpfs has been populated, so that the creds used is stable across all ExecStart= and ExecStartPost=-s. We still want to retain the ability of updating creds through ExecStartPre= though, therefore we forcibly use a fresh cred dir for those. 'Fresh' means to actually unmount the old tmpfs first, so the first problem goes away, too.
fresh otherwise Currently, exec_setup_credential() always rewrite all credentials upon exec_invoke(), i.e. invocation of each ExecCommand, and within a single tmpfs instance. This is problematic though: * When writing each tmp cred file, we essentially double the size of the credential. Therefore, if one cred is bigger than half of CREDENTIALS_TOTAL_SIZE_MAX, confusing ENOSPC occurs (see also systemd#24734 (comment)) * Credential is a unit-wide thing and thus should not change during the whole lifetime of main process. However, if e.g. a on-disk credential or SetCredential= in unit file changes between ExecStart= and ExecStartPost=, the credentials are overwritten when the latter gets to run, and the already-running main process is suddenly seeing completely different creds. So, let's try to reuse final cred dir if the main process has started and the tmpfs has been populated, so that the creds used is stable across all ExecStart= and ExecStartPost=-s. We still want to retain the ability of updating creds through ExecStartPre= though, therefore we forcibly use a fresh cred dir for those. 'Fresh' means to actually unmount the old tmpfs first, so the first problem goes away, too.
fresh otherwise Currently, exec_setup_credential() always rewrite all credentials upon exec_invoke(), i.e. invocation of each ExecCommand, and within a single tmpfs instance. This is problematic though: * When writing each tmp cred file, we essentially double the size of the credential. Therefore, if one cred is bigger than half of CREDENTIALS_TOTAL_SIZE_MAX, confusing ENOSPC occurs (see also systemd#24734 (comment)) * Credential is a unit-wide thing and thus should not change during the whole lifetime of main process. However, if e.g. a on-disk credential or SetCredential= in unit file changes between ExecStart= and ExecStartPost=, the credentials are overwritten when the latter gets to run, and the already-running main process is suddenly seeing completely different creds. So, let's try to reuse final cred dir if the main process has started and the tmpfs has been populated, so that the creds used is stable across all ExecStart= and ExecStartPost=-s. We still want to retain the ability of updating creds through ExecStartPre= though, therefore we forcibly use a fresh cred dir for those. 'Fresh' means to actually unmount the old tmpfs first, so the first problem goes away, too.
fresh otherwise Currently, exec_setup_credential() always rewrite all credentials upon exec_invoke(), i.e. invocation of each ExecCommand, and within a single tmpfs instance. This is problematic though: * When writing each tmp cred file, we essentially double the size of the credential. Therefore, if one cred is bigger than half of CREDENTIALS_TOTAL_SIZE_MAX, confusing ENOSPC occurs (see also systemd#24734 (comment)) * Credential is a unit-wide thing and thus should not change during the whole lifetime of main process. However, if e.g. a on-disk credential or SetCredential= in unit file changes between ExecStart= and ExecStartPost=, the credentials are overwritten when the latter gets to run, and the already-running main process is suddenly seeing completely different creds. So, let's try to reuse final cred dir if the main process has started and the tmpfs has been populated, so that the creds used is stable across all ExecStart= and ExecStartPost=-s. We still want to retain the ability of updating creds through ExecStartPre= though, therefore we forcibly use a fresh cred dir for those. 'Fresh' means to actually unmount the old tmpfs first, so the first problem goes away, too.
fresh otherwise Currently, exec_setup_credential() always rewrite all credentials upon exec_invoke(), i.e. invocation of each ExecCommand, and within a single tmpfs instance. This is problematic though: * When writing each tmp cred file, we essentially double the size of the credential. Therefore, if one cred is bigger than half of CREDENTIALS_TOTAL_SIZE_MAX, confusing ENOSPC occurs (see also systemd#24734 (comment)) * Credential is a unit-wide thing and thus should not change during the whole lifetime of main process. However, if e.g. a on-disk credential or SetCredential= in unit file changes between ExecStart= and ExecStartPost=, the credentials are overwritten when the latter gets to run, and the already-running main process is suddenly seeing completely different creds. So, let's try to reuse final cred dir if the main process has started and the tmpfs has been populated, so that the creds used is stable across all ExecStart= and ExecStartPost=-s. We still want to retain the ability of updating creds through ExecStartPre= though, therefore we forcibly use a fresh cred dir for those. 'Fresh' means to actually unmount the old tmpfs first, so the first problem goes away, too.
fresh otherwise Currently, exec_setup_credential() always rewrite all credentials upon exec_invoke(), i.e. invocation of each ExecCommand, and within a single tmpfs instance. This is problematic though: * When writing each tmp cred file, we essentially double the size of the credential. Therefore, if one cred is bigger than half of CREDENTIALS_TOTAL_SIZE_MAX, confusing ENOSPC occurs (see also systemd#24734 (comment)) * Credential is a unit-wide thing and thus should not change during the whole lifetime of main process. However, if e.g. a on-disk credential or SetCredential= in unit file changes between ExecStart= and ExecStartPost=, the credentials are overwritten when the latter gets to run, and the already-running main process is suddenly seeing completely different creds. So, let's try to reuse final cred dir if the main process has started and the tmpfs has been populated, so that the creds used is stable across all ExecStart= and ExecStartPost=-s. We still want to retain the ability of updating creds through ExecStartPre= though, therefore we forcibly use a fresh cred dir for those. 'Fresh' means to actually unmount the old tmpfs first, so the first problem goes away, too.
Systemd's credential interface is not yet natively supported by all programs yet. Hence it's often required to run scripts to massage secrets in the way the programs expect it.
This commit allows the ExecStartPre commands to access credentials.
Fixes #19604