Skip to content

Commit 11701f4

Browse files
committed
criu: fix missing umount() in error path
Fix possible error leak. Closes: containers#2020 Signed-off-by: Erik Sjölund <erik.sjolund@gmail.com>
1 parent 94fda0b commit 11701f4

File tree

1 file changed

+64
-17
lines changed

1 file changed

+64
-17
lines changed

src/libcrun/criu.c

Lines changed: 64 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1087,66 +1087,100 @@ libcrun_container_restore_linux_criu (libcrun_container_status_t *status, libcru
10871087
const int open_flags_for_inherit = O_RDONLY; /* Cannot be O_CLOEXEC as it is passed to the child process. */
10881088
int value = libcrun_find_namespace (def->linux->namespaces[i]->type);
10891089
if (UNLIKELY (value < 0))
1090-
return crun_make_error (err, 0, "invalid namespace type: `%s`", def->linux->namespaces[i]->type);
1090+
{
1091+
ret = crun_make_error (err, 0, "invalid namespace type: `%s`", def->linux->namespaces[i]->type);
1092+
goto out_umount;
1093+
}
10911094

10921095
if (value == CLONE_NEWNET && def->linux->namespaces[i]->path != NULL)
10931096
{
10941097
inherit_new_net_fd = open (def->linux->namespaces[i]->path, open_flags_for_inherit);
10951098
if (UNLIKELY (inherit_new_net_fd < 0))
1096-
return crun_make_error (err, errno, "unable to open(): `%s`", def->linux->namespaces[i]->path);
1099+
{
1100+
ret = crun_make_error (err, errno, "unable to open(): `%s`", def->linux->namespaces[i]->path);
1101+
goto out_umount;
1102+
}
10971103

10981104
ret = libcriu_wrapper->criu_add_inherit_fd (inherit_new_net_fd, CRIU_EXT_NETNS);
10991105
if (UNLIKELY (ret < 0))
1100-
return crun_make_error (err, -ret, "CRIU: failed adding fd");
1106+
{
1107+
ret = crun_make_error (err, -ret, "CRIU: failed adding fd");
1108+
goto out_umount;
1109+
}
11011110
}
11021111

11031112
if (value == CLONE_NEWPID && def->linux->namespaces[i]->path != NULL)
11041113
{
11051114
inherit_new_pid_fd = open (def->linux->namespaces[i]->path, open_flags_for_inherit);
11061115
if (UNLIKELY (inherit_new_pid_fd < 0))
1107-
return crun_make_error (err, errno, "unable to open(): `%s`", def->linux->namespaces[i]->path);
1116+
{
1117+
ret = crun_make_error (err, errno, "unable to open(): `%s`", def->linux->namespaces[i]->path);
1118+
goto out_umount;
1119+
}
11081120

11091121
ret = libcriu_wrapper->criu_add_inherit_fd (inherit_new_pid_fd, CRIU_EXT_PIDNS);
11101122
if (UNLIKELY (ret < 0))
1111-
return crun_make_error (err, -ret, "CRIU: failed adding fd");
1123+
{
1124+
ret = crun_make_error (err, -ret, "CRIU: failed adding fd");
1125+
goto out_umount;
1126+
}
11121127
}
11131128

11141129
# ifdef CRIU_JOIN_NS_SUPPORT
11151130
if (value == CLONE_NEWTIME && def->linux->namespaces[i]->path != NULL)
11161131
{
11171132
if (libcriu_wrapper->criu_join_ns_add == NULL)
1118-
return crun_make_error (err, 0, "shared time namespace restore is supported in CRIU >= 3.16.1");
1133+
{
1134+
ret = crun_make_error (err, 0, "shared time namespace restore is supported in CRIU >= 3.16.1");
1135+
goto out_umount;
1136+
}
11191137

11201138
ret = libcriu_wrapper->criu_join_ns_add ("time", def->linux->namespaces[i]->path, NULL);
11211139
if (UNLIKELY (ret < 0))
1122-
return crun_make_error (err, -ret, "CRIU: failed adding external namespace `%s`", def->linux->namespaces[i]->path);
1140+
{
1141+
ret = crun_make_error (err, -ret, "CRIU: failed adding external namespace `%s`", def->linux->namespaces[i]->path);
1142+
goto out_umount;
1143+
}
11231144
}
11241145

11251146
if (value == CLONE_NEWIPC && def->linux->namespaces[i]->path != NULL)
11261147
{
11271148
if (libcriu_wrapper->criu_join_ns_add == NULL)
1128-
return crun_make_error (err, 0, "shared ipc namespace restore is supported in CRIU >= 3.16.1");
1149+
{
1150+
ret = crun_make_error (err, 0, "shared ipc namespace restore is supported in CRIU >= 3.16.1");
1151+
goto out_umount;
1152+
}
11291153

11301154
ret = libcriu_wrapper->criu_join_ns_add ("ipc", def->linux->namespaces[i]->path, NULL);
11311155
if (UNLIKELY (ret < 0))
1132-
return crun_make_error (err, -ret, "CRIU: failed adding external namespace `%s`", def->linux->namespaces[i]->path);
1156+
{
1157+
ret = crun_make_error (err, -ret, "CRIU: failed adding external namespace `%s`", def->linux->namespaces[i]->path);
1158+
goto out_umount;
1159+
}
11331160
}
11341161

11351162
if (value == CLONE_NEWUTS && def->linux->namespaces[i]->path != NULL)
11361163
{
11371164
if (libcriu_wrapper->criu_join_ns_add == NULL)
1138-
return crun_make_error (err, 0, "shared uts namespace restore is supported in CRIU >= 3.16.1");
1165+
{
1166+
ret = crun_make_error (err, 0, "shared uts namespace restore is supported in CRIU >= 3.16.1");
1167+
goto out_umount;
1168+
}
11391169

11401170
ret = libcriu_wrapper->criu_join_ns_add ("uts", def->linux->namespaces[i]->path, NULL);
11411171
if (UNLIKELY (ret < 0))
1142-
return crun_make_error (err, -ret, "CRIU: failed adding external namespace `%s`", def->linux->namespaces[i]->path);
1172+
{
1173+
ret = crun_make_error (err, -ret, "CRIU: failed adding external namespace `%s`", def->linux->namespaces[i]->path);
1174+
goto out_umount;
1175+
}
11431176
}
11441177
# endif
11451178
}
11461179

11471180
/* Set up CRIU config file */
1148-
if (UNLIKELY (handle_criu_config_file (container, err)))
1149-
return -1;
1181+
ret = handle_criu_config_file (container, err);
1182+
if (UNLIKELY (ret < 0))
1183+
goto out_umount;
11501184

11511185
/* Tell CRIU if cgroup v1 needs to be handled. */
11521186
ret = restore_cgroup_v1_mount (def, err);
@@ -1168,7 +1202,10 @@ libcrun_container_restore_linux_criu (libcrun_container_status_t *status, libcru
11681202
{
11691203
ret = libcriu_wrapper->criu_add_cg_root (NULL, status->cgroup_path);
11701204
if (UNLIKELY (ret != 0))
1171-
return crun_make_error (err, 0, "error setting CRIU cgroup root to `%s`", status->cgroup_path);
1205+
{
1206+
ret = crun_make_error (err, 0, "error setting CRIU cgroup root to `%s`", status->cgroup_path);
1207+
goto out_umount;
1208+
}
11721209
}
11731210

11741211
if (cr_options->manage_cgroups_mode == -1)
@@ -1182,13 +1219,19 @@ libcrun_container_restore_linux_criu (libcrun_container_status_t *status, libcru
11821219
{
11831220
ret = libcriu_wrapper->criu_set_network_lock (cr_options->network_lock_method);
11841221
if (UNLIKELY (ret < 0))
1185-
return crun_make_error (err, 0, "CRIU: failed setting network lock");
1222+
{
1223+
ret = crun_make_error (err, 0, "CRIU: failed setting network lock");
1224+
goto out_umount;
1225+
}
11861226
}
11871227

11881228
libcriu_wrapper->criu_set_log_level (4);
11891229
ret = libcriu_wrapper->criu_set_log_file (CRIU_RESTORE_LOG_FILE);
11901230
if (UNLIKELY (ret < 0))
1191-
return crun_make_error (err, -ret, "error setting CRIU log file to `%s`", CRIU_RESTORE_LOG_FILE);
1231+
{
1232+
ret = crun_make_error (err, -ret, "error setting CRIU log file to `%s`", CRIU_RESTORE_LOG_FILE);
1233+
goto out_umount;
1234+
}
11921235

11931236
/* criu_restore() returns the PID of the process of the restored process
11941237
* tree. This PID will not be the same as status->pid if the container is
@@ -1212,8 +1255,12 @@ libcrun_container_restore_linux_criu (libcrun_container_status_t *status, libcru
12121255
ret_out = umount (root);
12131256
if (UNLIKELY (ret_out == -1))
12141257
{
1258+
int saved_errno = errno;
12151259
rmdir (root);
1216-
return crun_make_error (err, errno, "error unmounting restore directory `%s`", root);
1260+
if (ret < 0)
1261+
return crun_error_wrap (err, "error unmounting restore directory `%s`", root);
1262+
else
1263+
return crun_make_error (err, saved_errno, "error unmounting restore directory `%s`", root);
12171264
}
12181265
out:
12191266
ret_out = rmdir (root);

0 commit comments

Comments
 (0)