Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
L
lxc
Project
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Chen Yisong
lxc
Commits
c0886b82
Unverified
Commit
c0886b82
authored
Feb 11, 2021
by
Christian Brauner
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
conf: introduce lxc_bind_mount_console()
Signed-off-by:
Christian Brauner
<
christian.brauner@ubuntu.com
>
parent
1e08aa8f
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
81 additions
and
68 deletions
+81
-68
conf.c
src/lxc/conf.c
+81
-68
No files found.
src/lxc/conf.c
View file @
c0886b82
...
@@ -1643,16 +1643,51 @@ static inline bool wants_console(const struct lxc_terminal *terminal)
...
@@ -1643,16 +1643,51 @@ static inline bool wants_console(const struct lxc_terminal *terminal)
return
!
terminal
->
path
||
strcmp
(
terminal
->
path
,
"none"
);
return
!
terminal
->
path
||
strcmp
(
terminal
->
path
,
"none"
);
}
}
static
int
lxc_bind_mount_console
(
const
struct
lxc_terminal
*
console
,
int
dfd_to
,
const
char
*
path_to
)
{
__do_close
int
fd_pty
=
-
EBADF
;
if
(
is_empty_string
(
console
->
name
))
return
ret_errno
(
EINVAL
);
/*
* When the pty fd stashed in console->pty has been retrieved via the
* TIOCGPTPEER ioctl() to avoid dangerous path-based lookups when
* allocating new pty devices we can't reopen it through openat2() or
* created a detached mount through open_tree() from it. This means we
* would need to mount using the path stased in console->name which is
* unsafe. We could be mounting a device that isn't identical to the
* one we've already safely opened and stashed in console->pty.
* So, what we do is we open an O_PATH file descriptor for
* console->name and verify that the opened fd and the fd we stashed in
* console->pty refer to the same device. If they do we can go on and
* created a detached mount based on the newly opened O_PATH file
* descriptor and then safely mount.
*/
fd_pty
=
open_at
(
-
EBADF
,
console
->
name
,
PROTECT_OPATH_FILE
,
PROTECT_LOOKUP_ABSOLUTE_XDEV
,
0
);
if
(
fd_pty
<
0
)
return
log_error_errno
(
-
errno
,
errno
,
"Failed to open
\"
%s
\"
"
,
console
->
name
);
if
(
!
same_file_lax
(
console
->
pty
,
fd_pty
))
return
log_error_errno
(
-
EINVAL
,
EINVAL
,
"Console file descriptor changed"
);
/*
* Note, there are intentionally no open or lookup restrictions since
* we're operating directly on the fd.
*/
return
fd_bind_mount
(
fd_pty
,
""
,
0
,
0
,
dfd_to
,
path_to
,
PROTECT_OPATH_FILE
,
PROTECT_LOOKUP_BENEATH
,
0
,
false
);
}
static
int
lxc_setup_dev_console
(
struct
lxc_rootfs
*
rootfs
,
static
int
lxc_setup_dev_console
(
struct
lxc_rootfs
*
rootfs
,
const
struct
lxc_terminal
*
console
,
const
struct
lxc_terminal
*
console
)
int
pty_mnt_fd
)
{
{
int
ret
;
int
ret
;
char
*
rootfs_path
=
rootfs
->
path
?
rootfs
->
mount
:
""
;
char
*
rootfs_path
=
rootfs
->
path
?
rootfs
->
mount
:
""
;
if
(
!
wants_console
(
console
))
return
0
;
/*
/*
* When we are asked to setup a console we remove any previous
* When we are asked to setup a console we remove any previous
* /dev/console bind-mounts.
* /dev/console bind-mounts.
...
@@ -1681,47 +1716,30 @@ static int lxc_setup_dev_console(struct lxc_rootfs *rootfs,
...
@@ -1681,47 +1716,30 @@ static int lxc_setup_dev_console(struct lxc_rootfs *rootfs,
if
(
ret
<
0
)
if
(
ret
<
0
)
return
log_error_errno
(
-
errno
,
errno
,
"Failed to set mode
\"
0%o
\"
to
\"
%s
\"
"
,
S_IXUSR
|
S_IXGRP
,
console
->
name
);
return
log_error_errno
(
-
errno
,
errno
,
"Failed to set mode
\"
0%o
\"
to
\"
%s
\"
"
,
S_IXUSR
|
S_IXGRP
,
console
->
name
);
if
(
pty_mnt_fd
>=
0
)
{
if
(
new_mount_api
())
{
ret
=
move_mount
(
pty_mnt_fd
,
""
,
rootfs
->
dfd_dev
,
"console"
,
MOVE_MOUNT_F_EMPTY_PATH
);
ret
=
lxc_bind_mount_console
(
console
,
rootfs
->
dfd_dev
,
"console"
);
if
(
!
ret
)
{
}
else
{
DEBUG
(
"Moved mount
\"
%s
\"
onto %d(console)"
,
console
->
name
,
rootfs
->
dfd_dev
);
ret
=
strnprintf
(
rootfs
->
buf
,
sizeof
(
rootfs
->
buf
),
"%s/dev/console"
,
rootfs_path
);
return
0
;
if
(
ret
<
0
)
}
return
ret
;
if
(
ret
&&
errno
!=
ENOSYS
)
return
log_error_errno
(
-
1
,
errno
,
"Failed to mount %d(%s) on %d(console)"
,
pty_mnt_fd
,
console
->
name
,
rootfs
->
dfd_dev
);
}
ret
=
safe_mount_beneath_at
(
rootfs
->
dfd_dev
,
console
->
name
,
"console"
,
NULL
,
MS_BIND
,
NULL
);
if
(
ret
<
0
)
{
if
(
errno
==
ENOSYS
)
{
ret
=
strnprintf
(
rootfs
->
buf
,
sizeof
(
rootfs
->
buf
),
"%s/dev/console"
,
rootfs_path
);
if
(
ret
<
0
)
return
-
1
;
ret
=
safe_mount
(
console
->
name
,
rootfs
->
buf
,
"none"
,
MS_BIND
,
NULL
,
rootfs_path
);
ret
=
safe_mount
(
console
->
name
,
rootfs
->
buf
,
"none"
,
MS_BIND
,
NULL
,
rootfs_path
);
if
(
ret
<
0
)
return
log_error_errno
(
-
1
,
errno
,
"Failed to mount %d(%s) on
\"
%s
\"
"
,
pty_mnt_fd
,
console
->
name
,
rootfs
->
buf
);
}
}
}
if
(
ret
<
0
)
return
log_error_errno
(
ret
,
errno
,
"Failed to mount %d(%s) on
\"
%s
\"
"
,
console
->
pty
,
console
->
name
,
rootfs
->
buf
);
DEBUG
(
"Mounted pty device %d(%s) onto
\"
%s
\"
"
,
pty_mnt_fd
,
console
->
name
,
rootfs
->
buf
);
DEBUG
(
"Mounted pty device %d(%s) onto
\"
%s
\"
"
,
console
->
pty
,
console
->
name
,
rootfs
->
buf
);
return
0
;
return
0
;
}
}
static
int
lxc_setup_ttydir_console
(
const
struct
lxc_rootfs
*
rootfs
,
static
int
lxc_setup_ttydir_console
(
struct
lxc_rootfs
*
rootfs
,
const
struct
lxc_terminal
*
console
,
const
struct
lxc_terminal
*
console
,
char
*
ttydir
,
int
pty_mnt_fd
)
char
*
ttydir
)
{
{
int
ret
;
int
ret
;
char
path
[
PATH_MAX
],
lxcpath
[
PATH_MAX
];
char
path
[
PATH_MAX
],
lxcpath
[
PATH_MAX
];
char
*
rootfs_path
=
rootfs
->
path
?
rootfs
->
mount
:
""
;
char
*
rootfs_path
=
rootfs
->
path
?
rootfs
->
mount
:
""
;
if
(
!
wants_console
(
console
))
return
0
;
/* create rootfs/dev/<ttydir> directory */
/* create rootfs/dev/<ttydir> directory */
ret
=
strnprintf
(
path
,
sizeof
(
path
),
"%s/dev/%s"
,
rootfs_path
,
ttydir
);
ret
=
strnprintf
(
path
,
sizeof
(
path
),
"%s/dev/%s"
,
rootfs_path
,
ttydir
);
if
(
ret
<
0
)
if
(
ret
<
0
)
...
@@ -1761,44 +1779,51 @@ static int lxc_setup_ttydir_console(const struct lxc_rootfs *rootfs,
...
@@ -1761,44 +1779,51 @@ static int lxc_setup_ttydir_console(const struct lxc_rootfs *rootfs,
return
log_error_errno
(
-
errno
,
errno
,
"Failed to set mode
\"
0%o
\"
to
\"
%s
\"
"
,
S_IXUSR
|
S_IXGRP
,
console
->
name
);
return
log_error_errno
(
-
errno
,
errno
,
"Failed to set mode
\"
0%o
\"
to
\"
%s
\"
"
,
S_IXUSR
|
S_IXGRP
,
console
->
name
);
/* bind mount console->name to '/dev/<ttydir>/console' */
/* bind mount console->name to '/dev/<ttydir>/console' */
if
(
pty_mnt_fd
>=
0
)
{
if
(
new_mount_api
())
{
ret
=
move_mount
(
pty_mnt_fd
,
""
,
-
EBADF
,
lxcpath
,
MOVE_MOUNT_F_EMPTY_PATH
);
ret
=
strnprintf
(
rootfs
->
buf
,
sizeof
(
rootfs
->
buf
),
"%s/console"
,
ttydir
);
if
(
!
ret
)
{
if
(
ret
<
0
)
DEBUG
(
"Moved mount
\"
%s
\"
onto
\"
%s
\"
"
,
console
->
name
,
lxcpath
);
return
ret
;
goto
finish
;
}
if
(
ret
&&
errno
!=
ENOSYS
)
ret
=
lxc_bind_mount_console
(
console
,
rootfs
->
dfd_dev
,
rootfs
->
buf
);
return
log_error_errno
(
-
1
,
errno
,
}
else
{
"Failed to mount %d(%s) on
\"
%s
\"
"
,
ret
=
safe_mount
(
console
->
name
,
lxcpath
,
"none"
,
MS_BIND
,
0
,
rootfs_path
);
pty_mnt_fd
,
console
->
name
,
lxcpath
);
}
}
ret
=
safe_mount
(
console
->
name
,
lxcpath
,
"none"
,
MS_BIND
,
0
,
rootfs_path
);
if
(
ret
<
0
)
if
(
ret
<
0
)
return
log_error_errno
(
-
1
,
errno
,
"Failed to mount %d(%s) on
\"
%s
\"
"
,
pty_mnt_fd
,
console
->
name
,
lxcpath
);
return
log_error_errno
(
ret
,
errno
,
"Failed to mount %d(%s) on
\"
%s
\"
"
,
console
->
pty
,
console
->
name
,
lxcpath
);
DEBUG
(
"Mounted
\"
%s
\"
onto
\"
%s
\"
"
,
console
->
name
,
lxcpath
);
DEBUG
(
"Mounted
\"
%s
\"
onto
\"
%s
\"
"
,
console
->
name
,
lxcpath
);
finish:
/* bind mount '/dev/<ttydir>/console' to '/dev/console' */
/* bind mount '/dev/<ttydir>/console' to '/dev/console' */
ret
=
safe_mount
(
lxcpath
,
path
,
"none"
,
MS_BIND
,
0
,
rootfs_path
);
if
(
new_mount_api
())
{
ret
=
fd_bind_mount
(
rootfs
->
dfd_dev
,
rootfs
->
buf
,
PROTECT_OPATH_FILE
,
PROTECT_LOOKUP_BENEATH_XDEV
,
rootfs
->
dfd_dev
,
"console"
,
PROTECT_OPATH_FILE
,
PROTECT_LOOKUP_BENEATH
,
0
,
false
);
}
else
{
ret
=
safe_mount
(
lxcpath
,
path
,
"none"
,
MS_BIND
,
0
,
rootfs_path
);
}
if
(
ret
<
0
)
if
(
ret
<
0
)
return
log_error_errno
(
-
1
,
errno
,
"Failed to mount
\"
%s
\"
on
\"
%s
\"
"
,
console
->
name
,
lxcpath
);
return
log_error_errno
(
-
1
,
errno
,
"Failed to mount
\"
%s
\"
on
\"
%s
\"
"
,
console
->
name
,
lxcpath
);
DEBUG
(
"Mounted
\"
%s
\"
onto
\"
%s
\"
"
,
console
->
name
,
lxc
path
);
DEBUG
(
"Mounted
\"
%s
\"
onto
\"
%s
\"
"
,
lxcpath
,
path
);
DEBUG
(
"Console has been setup under
\"
%s
\"
and mounted to
\"
%s
\"
"
,
lxcpath
,
path
);
DEBUG
(
"Console has been setup under
\"
%s
\"
and mounted to
\"
%s
\"
"
,
lxcpath
,
path
);
return
0
;
return
0
;
}
}
static
int
lxc_setup_console
(
struct
lxc_rootfs
*
rootfs
,
static
int
lxc_setup_console
(
struct
lxc_rootfs
*
rootfs
,
const
struct
lxc_terminal
*
console
,
char
*
ttydir
,
struct
lxc_terminal
*
console
,
char
*
ttydir
)
int
pty_mnt_fd
)
{
{
int
ret
;
if
(
!
ttydir
)
if
(
!
wants_console
(
console
)
)
return
l
xc_setup_dev_console
(
rootfs
,
console
,
pty_mnt_fd
);
return
l
og_trace
(
0
,
"Skipping console setup"
);
return
lxc_setup_ttydir_console
(
rootfs
,
console
,
ttydir
,
pty_mnt_fd
);
if
(
ttydir
)
ret
=
lxc_setup_ttydir_console
(
rootfs
,
console
,
ttydir
);
else
ret
=
lxc_setup_dev_console
(
rootfs
,
console
);
close_prot_errno_disarm
(
console
->
pty
);
return
ret
;
}
}
static
int
parse_mntopt
(
char
*
opt
,
unsigned
long
*
flags
,
char
**
data
,
size_t
size
)
static
int
parse_mntopt
(
char
*
opt
,
unsigned
long
*
flags
,
char
**
data
,
size_t
size
)
...
@@ -3360,7 +3385,6 @@ static int lxc_setup_keyring(struct lsm_ops *lsm_ops, const struct lxc_conf *con
...
@@ -3360,7 +3385,6 @@ static int lxc_setup_keyring(struct lsm_ops *lsm_ops, const struct lxc_conf *con
int
lxc_setup
(
struct
lxc_handler
*
handler
)
int
lxc_setup
(
struct
lxc_handler
*
handler
)
{
{
__do_close
int
pty_mnt_fd
=
-
EBADF
;
int
ret
;
int
ret
;
const
char
*
lxcpath
=
handler
->
lxcpath
,
*
name
=
handler
->
name
;
const
char
*
lxcpath
=
handler
->
lxcpath
,
*
name
=
handler
->
name
;
struct
lxc_conf
*
lxc_conf
=
handler
->
conf
;
struct
lxc_conf
*
lxc_conf
=
handler
->
conf
;
...
@@ -3392,17 +3416,6 @@ int lxc_setup(struct lxc_handler *handler)
...
@@ -3392,17 +3416,6 @@ int lxc_setup(struct lxc_handler *handler)
return
log_error
(
-
1
,
"Failed to send network device names and ifindices to parent"
);
return
log_error
(
-
1
,
"Failed to send network device names and ifindices to parent"
);
}
}
if
(
wants_console
(
&
lxc_conf
->
console
))
{
pty_mnt_fd
=
open_tree
(
-
EBADF
,
lxc_conf
->
console
.
name
,
OPEN_TREE_CLONE
|
OPEN_TREE_CLOEXEC
|
AT_EMPTY_PATH
);
if
(
pty_mnt_fd
<
0
)
SYSTRACE
(
"Failed to create detached mount for container's console
\"
%s
\"
"
,
lxc_conf
->
console
.
name
);
else
TRACE
(
"Created detached mount for container's console
\"
%s
\"
"
,
lxc_conf
->
console
.
name
);
}
if
(
lxc_conf
->
autodev
>
0
)
{
if
(
lxc_conf
->
autodev
>
0
)
{
ret
=
mount_autodev
(
name
,
&
lxc_conf
->
rootfs
,
lxc_conf
->
autodevtmpfssize
,
lxcpath
);
ret
=
mount_autodev
(
name
,
&
lxc_conf
->
rootfs
,
lxc_conf
->
autodevtmpfssize
,
lxcpath
);
if
(
ret
<
0
)
if
(
ret
<
0
)
...
@@ -3486,7 +3499,7 @@ int lxc_setup(struct lxc_handler *handler)
...
@@ -3486,7 +3499,7 @@ int lxc_setup(struct lxc_handler *handler)
return
log_error
(
-
1
,
"Failed to
\"
/proc
\"
LSMs"
);
return
log_error
(
-
1
,
"Failed to
\"
/proc
\"
LSMs"
);
ret
=
lxc_setup_console
(
&
lxc_conf
->
rootfs
,
&
lxc_conf
->
console
,
ret
=
lxc_setup_console
(
&
lxc_conf
->
rootfs
,
&
lxc_conf
->
console
,
lxc_conf
->
ttys
.
dir
,
pty_mnt_fd
);
lxc_conf
->
ttys
.
dir
);
if
(
ret
<
0
)
if
(
ret
<
0
)
return
log_error
(
-
1
,
"Failed to setup console"
);
return
log_error
(
-
1
,
"Failed to setup console"
);
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment