Skip to content

Commit 88292ef

Browse files
DaanDeMeyerkeszybz
authored andcommitted
execute: Chown credentials files and directories to service group
For a userns root user to be able to access the credentials, both the uid and gid of the credentials directory have to be mapped into the userns. Currently, the credentials directory group is root, which we obviously do not want to map in to a userns, so let's make sure that the credentials directory and files are owned by the service group instead, which can generally be safely mapped into the userns. Since we use permissions mode 0600, this shouldn't cause any change in who is able to access the credentials. Fixes #28747 (cherry picked from commit 3a78b0e)
1 parent 0d1198a commit 88292ef

File tree

1 file changed

+27
-11
lines changed

1 file changed

+27
-11
lines changed

src/core/execute.c

Lines changed: 27 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -2746,6 +2746,7 @@ static int write_credential(
27462746
const void *data,
27472747
size_t size,
27482748
uid_t uid,
2749+
gid_t gid,
27492750
bool ownership_ok) {
27502751

27512752
_cleanup_(unlink_and_freep) char *tmp = NULL;
@@ -2783,7 +2784,7 @@ static int write_credential(
27832784
* user can no longer chmod() the file to gain write access. */
27842785
return r;
27852786

2786-
if (fchown(fd, uid, GID_INVALID) < 0)
2787+
if (fchown(fd, uid, gid) < 0)
27872788
return -errno;
27882789
}
27892790
}
@@ -2845,6 +2846,7 @@ static int maybe_decrypt_and_write_credential(
28452846
const char *id,
28462847
bool encrypted,
28472848
uid_t uid,
2849+
gid_t gid,
28482850
bool ownership_ok,
28492851
const char *data,
28502852
size_t size,
@@ -2870,7 +2872,7 @@ static int maybe_decrypt_and_write_credential(
28702872
if (add > *left)
28712873
return -E2BIG;
28722874

2873-
r = write_credential(dir_fd, id, data, size, uid, ownership_ok);
2875+
r = write_credential(dir_fd, id, data, size, uid, gid, ownership_ok);
28742876
if (r < 0)
28752877
return log_debug_errno(r, "Failed to write credential '%s': %m", id);
28762878

@@ -2885,6 +2887,7 @@ static int load_credential_glob(
28852887
ReadFullFileFlags flags,
28862888
int write_dfd,
28872889
uid_t uid,
2890+
gid_t gid,
28882891
bool ownership_ok,
28892892
uint64_t *left) {
28902893

@@ -2932,6 +2935,7 @@ static int load_credential_glob(
29322935
fn,
29332936
encrypted,
29342937
uid,
2938+
gid,
29352939
ownership_ok,
29362940
data, size,
29372941
left);
@@ -2955,6 +2959,7 @@ static int load_credential(
29552959
int read_dfd,
29562960
int write_dfd,
29572961
uid_t uid,
2962+
gid_t gid,
29582963
bool ownership_ok,
29592964
uint64_t *left) {
29602965

@@ -3066,7 +3071,7 @@ static int load_credential(
30663071
if (r < 0)
30673072
return log_debug_errno(r, "Failed to read credential '%s': %m", path);
30683073

3069-
return maybe_decrypt_and_write_credential(write_dfd, id, encrypted, uid, ownership_ok, data, size, left);
3074+
return maybe_decrypt_and_write_credential(write_dfd, id, encrypted, uid, gid, ownership_ok, data, size, left);
30703075
}
30713076

30723077
struct load_cred_args {
@@ -3076,6 +3081,7 @@ struct load_cred_args {
30763081
const char *unit;
30773082
int dfd;
30783083
uid_t uid;
3084+
gid_t gid;
30793085
bool ownership_ok;
30803086
uint64_t *left;
30813087
};
@@ -3123,6 +3129,7 @@ static int load_cred_recurse_dir_cb(
31233129
dir_fd,
31243130
args->dfd,
31253131
args->uid,
3132+
args->gid,
31263133
args->ownership_ok,
31273134
args->left);
31283135
if (r < 0)
@@ -3137,6 +3144,7 @@ static int acquire_credentials(
31373144
const char *unit,
31383145
const char *p,
31393146
uid_t uid,
3147+
gid_t gid,
31403148
bool ownership_ok) {
31413149

31423150
uint64_t left = CREDENTIALS_TOTAL_SIZE_MAX;
@@ -3186,6 +3194,7 @@ static int acquire_credentials(
31863194
AT_FDCWD,
31873195
dfd,
31883196
uid,
3197+
gid,
31893198
ownership_ok,
31903199
&left);
31913200
else
@@ -3204,6 +3213,7 @@ static int acquire_credentials(
32043213
.unit = unit,
32053214
.dfd = dfd,
32063215
.uid = uid,
3216+
.gid = gid,
32073217
.ownership_ok = ownership_ok,
32083218
.left = &left,
32093219
});
@@ -3227,6 +3237,7 @@ static int acquire_credentials(
32273237
READ_FULL_FILE_SECURE|READ_FULL_FILE_FAIL_WHEN_LARGER,
32283238
dfd,
32293239
uid,
3240+
gid,
32303241
ownership_ok,
32313242
&left);
32323243
if (r < 0)
@@ -3244,6 +3255,7 @@ static int acquire_credentials(
32443255
READ_FULL_FILE_SECURE|READ_FULL_FILE_FAIL_WHEN_LARGER|READ_FULL_FILE_UNBASE64,
32453256
dfd,
32463257
uid,
3258+
gid,
32473259
ownership_ok,
32483260
&left);
32493261
if (r < 0)
@@ -3281,7 +3293,7 @@ static int acquire_credentials(
32813293
if (add > left)
32823294
return -E2BIG;
32833295

3284-
r = write_credential(dfd, sc->id, data, size, uid, ownership_ok);
3296+
r = write_credential(dfd, sc->id, data, size, uid, gid, ownership_ok);
32853297
if (r < 0)
32863298
return r;
32873299

@@ -3304,7 +3316,7 @@ static int acquire_credentials(
33043316
if (!ownership_ok)
33053317
return r;
33063318

3307-
if (fchown(dfd, uid, GID_INVALID) < 0)
3319+
if (fchown(dfd, uid, gid) < 0)
33083320
return -errno;
33093321
}
33103322
}
@@ -3320,7 +3332,8 @@ static int setup_credentials_internal(
33203332
const char *workspace, /* This is where we can prepare it before moving it to the final place */
33213333
bool reuse_workspace, /* Whether to reuse any existing workspace mount if it already is a mount */
33223334
bool must_mount, /* Whether to require that we mount something, it's not OK to use the plain directory fall back */
3323-
uid_t uid) {
3335+
uid_t uid,
3336+
gid_t gid) {
33243337

33253338
int r, workspace_mounted; /* negative if we don't know yet whether we have/can mount something; true
33263339
* if we mounted something; false if we definitely can't mount anything */
@@ -3406,7 +3419,7 @@ static int setup_credentials_internal(
34063419

34073420
(void) label_fix_full(AT_FDCWD, where, final, 0);
34083421

3409-
r = acquire_credentials(context, params, unit, where, uid, workspace_mounted);
3422+
r = acquire_credentials(context, params, unit, where, uid, gid, workspace_mounted);
34103423
if (r < 0)
34113424
return r;
34123425

@@ -3461,7 +3474,8 @@ static int setup_credentials(
34613474
const ExecContext *context,
34623475
const ExecParameters *params,
34633476
const char *unit,
3464-
uid_t uid) {
3477+
uid_t uid,
3478+
gid_t gid) {
34653479

34663480
_cleanup_free_ char *p = NULL, *q = NULL;
34673481
int r;
@@ -3528,7 +3542,8 @@ static int setup_credentials(
35283542
u, /* temporary workspace to overmount */
35293543
true, /* reuse the workspace if it is already a mount */
35303544
false, /* it's OK to fall back to a plain directory if we can't mount anything */
3531-
uid);
3545+
uid,
3546+
gid);
35323547

35333548
(void) rmdir(u); /* remove the workspace again if we can. */
35343549

@@ -3566,7 +3581,8 @@ static int setup_credentials(
35663581
"/dev/shm", /* temporary workspace to overmount */
35673582
false, /* do not reuse /dev/shm if it is already a mount, under no circumstances */
35683583
true, /* insist that something is mounted, do not allow fallback to plain directory */
3569-
uid);
3584+
uid,
3585+
gid);
35703586
if (r < 0)
35713587
goto child_fail;
35723588

@@ -5295,7 +5311,7 @@ static int exec_child(
52955311
}
52965312

52975313
if (FLAGS_SET(params->flags, EXEC_WRITE_CREDENTIALS)) {
5298-
r = setup_credentials(context, params, unit->id, uid);
5314+
r = setup_credentials(context, params, unit->id, uid, gid);
52995315
if (r < 0) {
53005316
*exit_status = EXIT_CREDENTIALS;
53015317
return log_unit_error_errno(unit, r, "Failed to set up credentials: %m");

0 commit comments

Comments
 (0)