Skip to content
This repository was archived by the owner on Feb 8, 2021. It is now read-only.

Commit fa120fe

Browse files
committed
create file volume mountpoint in chroot jail
For both device and fsmap based file volumes, the mountpoints need to be in chroot jail as well. Signed-off-by: Peng Tao <bergwolf@gmail.com>
1 parent 0282d55 commit fa120fe

File tree

3 files changed

+61
-70
lines changed

3 files changed

+61
-70
lines changed

src/container.c

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -160,8 +160,7 @@ static int container_setup_volume(struct hyper_container *container)
160160
return -1;
161161
}
162162
} else {
163-
hyper_filize(mountpoint);
164-
if (hyper_create_file(mountpoint) < 0) {
163+
if (hyper_create_file_at(".", mountpoint, sizeof(mountpoint)) < 0) {
165164
perror("create volume file failed");
166165
return -1;
167166
}
@@ -216,12 +215,10 @@ static int container_setup_volume(struct hyper_container *container)
216215
}
217216
}
218217
} else {
219-
int fd = open(mountpoint, O_CREAT|O_WRONLY, 0755);
220-
if (fd < 0) {
221-
perror("create map file failed");
218+
if (hyper_create_file_at(".", mountpoint, sizeof(mountpoint)) < 0) {
219+
perror("create volume file failed");
222220
return -1;
223221
}
224-
close(fd);
225222
}
226223

227224
if (mount(src, mountpoint, NULL, MS_BIND, NULL) < 0) {

src/util.c

Lines changed: 57 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -260,47 +260,6 @@ void hyper_filize(char *hyper_path)
260260
}
261261
}
262262

263-
static int hyper_create_parent_dir(const char *hyper_path)
264-
{
265-
char *p, *path = strdup(hyper_path);
266-
int ret = 0;
267-
268-
if (path == NULL)
269-
return -1;
270-
p = strrchr(path, '/');
271-
if (p != NULL && p != path) {
272-
*p = '\0';
273-
ret = hyper_mkdir(path, 0777);
274-
}
275-
free(path);
276-
277-
return ret;
278-
}
279-
280-
/* hyper_path must point to a file rather than a directory, e.g., having trailing '/' */
281-
int hyper_create_file(const char *hyper_path)
282-
{
283-
int fd;
284-
struct stat stbuf;
285-
286-
if (stat(hyper_path, &stbuf) >= 0) {
287-
if (S_ISREG(stbuf.st_mode))
288-
return 0;
289-
errno = S_ISDIR(stbuf.st_mode) ? EISDIR : EINVAL;
290-
return -1;
291-
}
292-
293-
if (hyper_create_parent_dir(hyper_path) < 0)
294-
return -1;
295-
296-
fd = open(hyper_path, O_CREAT|O_WRONLY, 0666);
297-
if (fd < 0)
298-
return -1;
299-
close(fd);
300-
fprintf(stdout, "created file %s\n", hyper_path);
301-
return 0;
302-
}
303-
304263
static char *hyper_resolve_link(char *path)
305264
{
306265
char buf[512];
@@ -327,16 +286,17 @@ static char *hyper_resolve_link(char *path)
327286
* @root: chroot jail path.
328287
* @path: target directory. It is always relative to @root even if it starts with /.
329288
* @parent: what's already created to the target directory.
330-
* @mode: directory mode.
331289
* @link_max: max number of symlinks to follow.
290+
* @create_file: create last component of @path as a normal file
332291
*
333292
* Upon success, @parent is changed to point to resolved path name.
334293
*/
335294
static int hyper_mkdir_follow_link(const char *root, const char *path, char *parent,
336-
mode_t mode, int *link_max)
295+
int *link_max, bool create_file)
337296
{
338-
char *comp, *prev, *link, *dummy, *npath, *delim = "/";
297+
char *comp, *next, *prev, *last, *link, *dummy, *npath, *delim = "/";
339298
struct stat st;
299+
int fd;
340300

341301
if (strncmp(root, parent, strlen(root)) != 0) {
342302
errno = EINVAL;
@@ -352,6 +312,9 @@ static int hyper_mkdir_follow_link(const char *root, const char *path, char *par
352312
goto out;
353313

354314
do {
315+
last = comp;
316+
next = strtok_r(NULL, delim, &dummy);
317+
355318
if (!strcmp(comp, "."))
356319
continue;
357320

@@ -381,7 +344,8 @@ static int hyper_mkdir_follow_link(const char *root, const char *path, char *par
381344
strcat(parent, comp);
382345

383346
if (lstat(parent, &st) >= 0) {
384-
if (S_ISDIR(st.st_mode)) {
347+
if ((S_ISDIR(st.st_mode) && (next != NULL || !create_file)) ||
348+
(S_ISREG(st.st_mode) && next == NULL && create_file)) {
385349
continue;
386350
} else if (S_ISLNK(st.st_mode)) {
387351
if (--(*link_max) <= 0) {
@@ -396,7 +360,7 @@ static int hyper_mkdir_follow_link(const char *root, const char *path, char *par
396360
} else {
397361
*prev = '\0'; /* drop current comp */
398362
}
399-
if (hyper_mkdir_follow_link(root, link, parent, mode, link_max) < 0) {
363+
if (hyper_mkdir_follow_link(root, link, parent, link_max, next == NULL && create_file) < 0) {
400364
free(link);
401365
goto out;
402366
}
@@ -408,35 +372,38 @@ static int hyper_mkdir_follow_link(const char *root, const char *path, char *par
408372
}
409373
}
410374

411-
fprintf(stdout, "create directory %s\n", parent);
412-
if (mkdir(parent, mode) < 0 && errno != EEXIST) {
413-
perror("failed to create directory");
414-
goto out;
375+
if (next == NULL && create_file) {
376+
fprintf(stdout, "create file %s\n", parent);
377+
fd = open(parent, O_CREAT|O_WRONLY, 0666);
378+
if (fd < 0)
379+
goto out;
380+
close(fd);
381+
} else {
382+
fprintf(stdout, "create directory %s\n", parent);
383+
if (mkdir(parent, 0755) < 0 && errno != EEXIST) {
384+
perror("failed to create directory");
385+
goto out;
386+
}
415387
}
416-
} while((comp = strtok_r(NULL, delim, &dummy)) != NULL);
388+
} while((comp = next) != NULL);
417389

418-
/* reset errno to mark success */
419-
errno = 0;
390+
if (create_file && (!strcmp(last, ".") || !strcmp(last, "..")))
391+
errno = ENOTDIR;
392+
else
393+
/* reset errno to mark success */
394+
errno = 0;
420395
out:
421396
free(npath);
422397
return errno ? -1 : 0;
423398
}
424399

425-
/*
426-
* hyper_mkdir_at() is similar to hyper_mkdir() with the exception that
427-
* when there are symlinks in the path components, it acts as if we created
428-
* directories in a chroot jail. @hyper_path is always considered relative
429-
* to root even if it starts with a leading stash ('/').
430-
*
431-
* Upon success, @hyper_path is modified to save resolved path in chroot jail.
432-
*/
433-
int hyper_mkdir_at(const char *root, char *hyper_path, int size)
400+
static int hyper_create_target_at(const char *root, char *hyper_path, int size, bool create_file)
434401
{
435402
char result[512];
436403
int max_link = 40;
437404

438405
sprintf(result, "%s", root);
439-
if (hyper_mkdir_follow_link(root, hyper_path, result, 0755, &max_link) < 0)
406+
if (hyper_mkdir_follow_link(root, hyper_path, result, &max_link, create_file) < 0)
440407
return -1;
441408

442409
if (strlen(result) + 1 > size) {
@@ -447,6 +414,33 @@ int hyper_mkdir_at(const char *root, char *hyper_path, int size)
447414
return 0;
448415
}
449416

417+
/*
418+
* hyper_mkdir_at() is similar to hyper_mkdir() with the exception that
419+
* when there are symlinks in the path components, it acts as if we created
420+
* directories in a chroot jail. @hyper_path is always considered relative
421+
* to root even if it starts with a leading stash ('/').
422+
*
423+
* Upon success, @hyper_path is modified to save resolved path in chroot jail.
424+
*/
425+
int hyper_mkdir_at(const char *root, char *hyper_path, int size)
426+
{
427+
return hyper_create_target_at(root, hyper_path, size, false);
428+
}
429+
430+
/**
431+
* hyper_create_file_at - create a file in @root chroot jail.
432+
*
433+
* @root: chroot jail path.
434+
* @hyper_path: must point to a file rather than a directory, e.g., having trailing '/'
435+
* @size: size of @hyper_path storage.
436+
*
437+
* Upon success, @hyper_path is modified to point to the path resolved in chroot jail.
438+
*/
439+
int hyper_create_file_at(const char* root, char *hyper_path, int size)
440+
{
441+
return hyper_create_target_at(root, hyper_path, size, true);
442+
}
443+
450444
int hyper_mkdir(char *path, mode_t mode)
451445
{
452446
struct stat st;

src/util.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ void hyper_sync_time_hctosys();
2626
void online_cpu(void);
2727
void online_memory(void);
2828
int hyper_cmd(char *cmd);
29-
int hyper_create_file(const char *hyper_path);
29+
int hyper_create_file_at(const char *root, char *hyper_path, int size);
3030
void hyper_filize(char *hyper_path);
3131
int hyper_mkdir(char *path, mode_t mode);
3232
int hyper_mkdir_at(const char *root, char *path, int size);

0 commit comments

Comments
 (0)