Skip to content

Commit 7fe47e4

Browse files
authored
Merge pull request #1910 from giuseppe/use-host-proc-fd
linux: initial hardening for /proc paths
2 parents 993ad9d + 50e9898 commit 7fe47e4

File tree

11 files changed

+524
-323
lines changed

11 files changed

+524
-323
lines changed

Makefile.am

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -164,6 +164,7 @@ EXTRA_DIST = COPYING COPYING.libcrun README.md NEWS SECURITY.md rpm/crun.spec au
164164
src/libcrun/scheduler.h src/libcrun/mempolicy.h src/libcrun/status.h src/libcrun/terminal.h \
165165
src/libcrun/mount_flags.h src/libcrun/intelrdt.h src/libcrun/ring_buffer.h src/libcrun/string_map.h \
166166
src/libcrun/net_device.h \
167+
src/libcrun/syscalls.h \
167168
crun.1.md crun.1 libcrun.lds \
168169
krun.1.md krun.1 \
169170
lua/luacrun.rockspec

src/libcrun/cgroup-systemd.c

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -304,16 +304,22 @@ systemd_finalize (struct libcrun_cgroup_args *args, char **path_out,
304304
int cgroup_mode, const char *suffix, libcrun_error_t *err)
305305
{
306306
runtime_spec_schema_config_linux_resources *resources = args->resources;
307-
cleanup_free char *cgroup_path = NULL;
308307
cleanup_free char *content = NULL;
309308
cleanup_free char *path = NULL;
310309
pid_t pid = args->pid;
311310
int ret;
312311
char *from, *to;
313312
char *saveptr = NULL;
314313

315-
xasprintf (&cgroup_path, "/proc/%d/cgroup", pid);
316-
ret = read_all_file (cgroup_path, &content, NULL, err);
314+
cleanup_free char *proc_path = NULL;
315+
cleanup_close int fd = -1;
316+
317+
xasprintf (&proc_path, "%d/cgroup", pid);
318+
fd = libcrun_open_proc_file (args->container, proc_path, O_RDONLY, err);
319+
if (UNLIKELY (fd < 0))
320+
return fd;
321+
322+
ret = read_all_fd (fd, "cgroup path", &content, NULL, err);
317323
if (UNLIKELY (ret < 0))
318324
return ret;
319325

src/libcrun/cgroup.c

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -379,7 +379,6 @@ int
379379
libcrun_cgroup_enter_finalize (struct libcrun_cgroup_args *args, struct libcrun_cgroup_status *cgroup_status arg_unused, libcrun_error_t *err)
380380
{
381381
cleanup_free char *target_cgroup = NULL;
382-
cleanup_free char *cgroup_path = NULL;
383382
cleanup_free char *content = NULL;
384383
const char *delegate_cgroup;
385384
cleanup_free char *dir = NULL;
@@ -398,8 +397,15 @@ libcrun_cgroup_enter_finalize (struct libcrun_cgroup_args *args, struct libcrun_
398397
if (cgroup_mode != CGROUP_MODE_UNIFIED)
399398
return crun_make_error (err, 0, "delegate-cgroup not supported on cgroup v1");
400399

401-
xasprintf (&cgroup_path, "/proc/%d/cgroup", args->pid);
402-
ret = read_all_file (cgroup_path, &content, NULL, err);
400+
cleanup_free char *proc_path = NULL;
401+
cleanup_close int fd = -1;
402+
403+
xasprintf (&proc_path, "%d/cgroup", args->pid);
404+
fd = libcrun_open_proc_file (args->container, proc_path, O_RDONLY, err);
405+
if (UNLIKELY (fd < 0))
406+
return fd;
407+
408+
ret = read_all_fd (fd, "cgroup path", &content, NULL, err);
403409
if (UNLIKELY (ret < 0))
404410
return ret;
405411

src/libcrun/cgroup.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@ struct libcrun_cgroup_args
5959
bool joined;
6060

6161
const char *state_root;
62+
libcrun_container_t *container;
6263
};
6364

6465
/* cgroup life-cycle management. */

src/libcrun/container.c

Lines changed: 33 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -562,6 +562,7 @@ make_container (runtime_spec_schema_config_schema *container_def, const char *pa
562562

563563
container->host_uid = geteuid ();
564564
container->host_gid = getegid ();
565+
container->proc_fd = -1;
565566

566567
container->annotations = make_string_map_from_json (container_def->annotations);
567568

@@ -616,6 +617,9 @@ libcrun_container_free (libcrun_container_t *ctr)
616617

617618
free_string_map (ctr->annotations);
618619

620+
if (ctr->proc_fd >= 0)
621+
close (ctr->proc_fd);
622+
619623
free (ctr->config_file_content);
620624
free (ctr->config_file);
621625
free (ctr);
@@ -659,11 +663,11 @@ unblock_signals (libcrun_error_t *err)
659663

660664
/* must be used on the host before pivot_root(2). */
661665
static int
662-
initialize_security (runtime_spec_schema_config_schema_process *proc, libcrun_error_t *err)
666+
initialize_security (libcrun_container_t *container, runtime_spec_schema_config_schema_process *proc, libcrun_error_t *err)
663667
{
664668
int ret;
665669

666-
ret = libcrun_init_caps (err);
670+
ret = libcrun_init_caps (container, err);
667671
if (UNLIKELY (ret < 0))
668672
return ret;
669673

@@ -677,7 +681,7 @@ initialize_security (runtime_spec_schema_config_schema_process *proc, libcrun_er
677681
return ret;
678682
}
679683

680-
ret = libcrun_initialize_selinux (err);
684+
ret = libcrun_initialize_selinux (container, err);
681685
if (UNLIKELY (ret < 0))
682686
return ret;
683687

@@ -1095,8 +1099,9 @@ libcrun_container_notify_handler (struct container_entrypoint_s *args,
10951099

10961100
/* Resolve and normalize the container rootfs path. */
10971101
static int
1098-
resolve_rootfs_path (runtime_spec_schema_config_schema *def, char **rootfs, libcrun_error_t *err)
1102+
resolve_rootfs_path (libcrun_container_t *container, char **rootfs, libcrun_error_t *err)
10991103
{
1104+
runtime_spec_schema_config_schema *def = container->container_def;
11001105
if (def->root && def->root->path)
11011106
{
11021107
*rootfs = realpath (def->root->path, NULL);
@@ -1107,8 +1112,14 @@ resolve_rootfs_path (runtime_spec_schema_config_schema *def, char **rootfs, libc
11071112
{
11081113
cleanup_free char *cwd = NULL;
11091114
ssize_t len;
1115+
int ret;
1116+
1117+
ret = libcrun_open_proc_file (container, "self/cwd", O_RDONLY, err);
1118+
if (UNLIKELY (ret < 0))
1119+
return ret;
11101120

1111-
len = safe_readlinkat (AT_FDCWD, "/proc/self/cwd", &cwd, 0, err);
1121+
len = safe_readlinkat (ret, "", &cwd, 0, err);
1122+
close (ret);
11121123
if (UNLIKELY (len < 0))
11131124
return len;
11141125

@@ -1295,15 +1306,15 @@ container_init_setup (void *args, pid_t own_pid, char *notify_socket,
12951306
runtime_spec_schema_config_schema *def = container->container_def;
12961307
cleanup_free char *rootfs = NULL;
12971308

1298-
ret = initialize_security (def->process, err);
1309+
ret = initialize_security (container, def->process, err);
12991310
if (UNLIKELY (ret < 0))
13001311
return ret;
13011312

13021313
ret = libcrun_configure_network (container, err);
13031314
if (UNLIKELY (ret < 0))
13041315
return ret;
13051316

1306-
ret = resolve_rootfs_path (def, &rootfs, err);
1317+
ret = resolve_rootfs_path (container, &rootfs, err);
13071318
if (UNLIKELY (ret < 0))
13081319
return ret;
13091320

@@ -1344,16 +1355,16 @@ container_init_setup (void *args, pid_t own_pid, char *notify_socket,
13441355

13451356
if (def->process)
13461357
{
1347-
ret = libcrun_set_selinux_label (def->process, false, err);
1358+
ret = libcrun_set_selinux_label (container, def->process, false, err);
13481359
if (UNLIKELY (ret < 0))
13491360
return ret;
13501361

1351-
ret = libcrun_set_apparmor_profile (def->process, false, err);
1362+
ret = libcrun_set_apparmor_profile (container, def->process, false, err);
13521363
if (UNLIKELY (ret < 0))
13531364
return ret;
13541365
}
13551366

1356-
ret = mark_or_close_fds_ge_than (entrypoint_args->context->preserve_fds + 3, false, err);
1367+
ret = mark_or_close_fds_ge_than (container, entrypoint_args->context->preserve_fds + 3, false, err);
13571368
if (UNLIKELY (ret < 0))
13581369
crun_error_write_warning_and_release (entrypoint_args->context->output_handler_arg, &err);
13591370

@@ -1651,7 +1662,7 @@ container_init (void *args, char *notify_socket, int sync_socket, libcrun_error_
16511662
This is a best effort operation, because the seccomp filter is already in place and it could
16521663
stop some syscalls used by mark_or_close_fds_ge_than.
16531664
*/
1654-
ret = mark_or_close_fds_ge_than (entrypoint_args->context->preserve_fds + 3, true, err);
1665+
ret = mark_or_close_fds_ge_than (entrypoint_args->container, entrypoint_args->context->preserve_fds + 3, true, err);
16551666
if (UNLIKELY (ret < 0))
16561667
crun_error_release (err);
16571668

@@ -1669,11 +1680,11 @@ container_init (void *args, char *notify_socket, int sync_socket, libcrun_error_
16691680
entrypoint_args->context = NULL;
16701681
}
16711682

1672-
ret = libcrun_set_selinux_label (def->process, true, err);
1683+
ret = libcrun_set_selinux_label (entrypoint_args->container, def->process, true, err);
16731684
if (UNLIKELY (ret < 0))
16741685
return ret;
16751686

1676-
ret = libcrun_set_apparmor_profile (def->process, true, err);
1687+
ret = libcrun_set_apparmor_profile (entrypoint_args->container, def->process, true, err);
16771688
if (UNLIKELY (ret < 0))
16781689
return ret;
16791690

@@ -1690,7 +1701,7 @@ container_init (void *args, char *notify_socket, int sync_socket, libcrun_error_
16901701
/* Attempt to close all the files that are not needed to prevent execv to have access to them.
16911702
This is a best effort operation since the seccomp profile is already in place now and might block
16921703
some of the syscalls needed by mark_or_close_fds_ge_than. */
1693-
ret = mark_or_close_fds_ge_than (entrypoint_args->context->preserve_fds + 3, true, err);
1704+
ret = mark_or_close_fds_ge_than (entrypoint_args->container, entrypoint_args->context->preserve_fds + 3, true, err);
16941705
if (UNLIKELY (ret < 0))
16951706
crun_error_release (err);
16961707

@@ -2516,7 +2527,7 @@ setup_container_keyring (libcrun_container_t *container, libcrun_context_t *cont
25162527
libcrun_debug ("Using SELinux process label: `%s`", label);
25172528
}
25182529

2519-
ret = libcrun_create_keyring (container->context->id, label, err);
2530+
ret = libcrun_create_keyring (container, container->context->id, label, err);
25202531
if (UNLIKELY (ret < 0))
25212532
return ret;
25222533
}
@@ -2635,6 +2646,7 @@ setup_cgroup_manager (libcrun_context_t *context, libcrun_container_t *container
26352646
cg->root_uid = root_uid;
26362647
cg->root_gid = root_gid;
26372648
cg->state_root = context->state_root;
2649+
cg->container = container;
26382650

26392651
ret = libcrun_cgroup_preenter (cg, cgroup_dirfd, err);
26402652
if (UNLIKELY (ret < 0))
@@ -3658,11 +3670,11 @@ exec_process_entrypoint (libcrun_context_t *context,
36583670
}
36593671
}
36603672

3661-
ret = libcrun_set_selinux_label (process, false, err);
3673+
ret = libcrun_set_selinux_label (container, process, false, err);
36623674
if (UNLIKELY (ret < 0))
36633675
return ret;
36643676

3665-
ret = libcrun_set_apparmor_profile (process, false, err);
3677+
ret = libcrun_set_apparmor_profile (container, process, false, err);
36663678
if (UNLIKELY (ret < 0))
36673679
return ret;
36683680

@@ -3692,7 +3704,7 @@ exec_process_entrypoint (libcrun_context_t *context,
36923704
return ret;
36933705
}
36943706

3695-
ret = mark_or_close_fds_ge_than (context->preserve_fds + 3, false, err);
3707+
ret = mark_or_close_fds_ge_than (container, context->preserve_fds + 3, false, err);
36963708
if (UNLIKELY (ret < 0))
36973709
return ret;
36983710

@@ -3802,7 +3814,7 @@ exec_process_entrypoint (libcrun_context_t *context,
38023814
This is a best effort operation, because the seccomp filter is already in place and it could
38033815
stop some syscalls used by mark_or_close_fds_ge_than.
38043816
*/
3805-
ret = mark_or_close_fds_ge_than (context->preserve_fds + 3, true, err);
3817+
ret = mark_or_close_fds_ge_than (container, context->preserve_fds + 3, true, err);
38063818
if (UNLIKELY (ret < 0))
38073819
crun_error_release (err);
38083820

@@ -3973,7 +3985,7 @@ libcrun_container_exec_with_options (libcrun_context_t *context, const char *id,
39733985
}
39743986
}
39753987

3976-
ret = initialize_security (process, err);
3988+
ret = initialize_security (container, process, err);
39773989
if (UNLIKELY (ret < 0))
39783990
return ret;
39793991

@@ -4637,6 +4649,7 @@ libcrun_container_restore (libcrun_context_t *context, const char *id, libcrun_c
46374649
.root_gid = root_gid,
46384650
.id = context->id,
46394651
.state_root = context->state_root,
4652+
.container = container,
46404653
};
46414654

46424655
/* The CRIU restore code uses bundle, rootfs and cgroup_path of status. The cgroup_path is set later. */

src/libcrun/container.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,8 @@ struct libcrun_container_s
9191

9292
string_map *annotations;
9393

94+
int proc_fd;
95+
9496
void *private_data;
9597
void (*cleanup_private_data) (void *private_data);
9698
struct libcrun_context_s *context;

0 commit comments

Comments
 (0)