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
25c659d5
Unverified
Commit
25c659d5
authored
Jan 29, 2021
by
Christian Brauner
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
attach: move to file descriptor only namespace interactions
Signed-off-by:
Christian Brauner
<
christian.brauner@ubuntu.com
>
parent
c538837d
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
43 additions
and
41 deletions
+43
-41
attach.c
src/lxc/attach.c
+34
-33
namespace.c
src/lxc/namespace.c
+8
-8
namespace.h
src/lxc/namespace.h
+1
-0
No files found.
src/lxc/attach.c
View file @
25c659d5
...
@@ -58,7 +58,8 @@ static lxc_attach_options_t attach_static_default_options = LXC_ATTACH_OPTIONS_D
...
@@ -58,7 +58,8 @@ static lxc_attach_options_t attach_static_default_options = LXC_ATTACH_OPTIONS_D
struct
attach_context
{
struct
attach_context
{
int
init_pid
;
int
init_pid
;
int
dfd_pid
;
int
dfd_init_pid
;
int
dfd_self_pid
;
char
*
lsm_label
;
char
*
lsm_label
;
struct
lxc_container
*
container
;
struct
lxc_container
*
container
;
signed
long
personality
;
signed
long
personality
;
...
@@ -116,7 +117,7 @@ static int get_personality(const char *name, const char *lxcpath,
...
@@ -116,7 +117,7 @@ static int get_personality(const char *name, const char *lxcpath,
static
int
get_attach_context
(
struct
attach_context
*
ctx
,
static
int
get_attach_context
(
struct
attach_context
*
ctx
,
struct
lxc_container
*
container
)
struct
lxc_container
*
container
)
{
{
__do_close
int
fd_status
=
-
EBADF
;
__do_close
int
dfd_self_pid
=
-
EBADF
,
dfd_init_pid
=
-
EBADF
,
fd_status
=
-
EBADF
;
__do_free
char
*
line
=
NULL
;
__do_free
char
*
line
=
NULL
;
__do_fclose
FILE
*
f_status
=
NULL
;
__do_fclose
FILE
*
f_status
=
NULL
;
int
ret
;
int
ret
;
...
@@ -130,15 +131,23 @@ static int get_attach_context(struct attach_context *ctx,
...
@@ -130,15 +131,23 @@ static int get_attach_context(struct attach_context *ctx,
if
(
ctx
->
init_pid
<
0
)
if
(
ctx
->
init_pid
<
0
)
return
log_error
(
-
1
,
"Failed to get init pid"
);
return
log_error
(
-
1
,
"Failed to get init pid"
);
ret
=
snprintf
(
path
,
sizeof
(
path
),
"/proc/%d"
,
lxc_raw_getpid
());
if
(
ret
<
0
||
ret
>=
sizeof
(
path
))
return
ret_errno
(
EIO
);
dfd_self_pid
=
openat
(
-
EBADF
,
path
,
O_CLOEXEC
|
O_NOCTTY
|
O_NOFOLLOW
|
O_PATH
|
O_DIRECTORY
);
if
(
dfd_self_pid
<
0
)
return
-
errno
;
ret
=
snprintf
(
path
,
sizeof
(
path
),
"/proc/%d"
,
ctx
->
init_pid
);
ret
=
snprintf
(
path
,
sizeof
(
path
),
"/proc/%d"
,
ctx
->
init_pid
);
if
(
ret
<
0
||
ret
>=
sizeof
(
path
))
if
(
ret
<
0
||
ret
>=
sizeof
(
path
))
return
ret_errno
(
EIO
);
return
ret_errno
(
EIO
);
ctx
->
dfd
_pid
=
openat
(
-
EBADF
,
path
,
O_CLOEXEC
|
O_NOCTTY
|
O_NOFOLLOW
|
O_PATH
|
O_DIRECTORY
);
dfd_init
_pid
=
openat
(
-
EBADF
,
path
,
O_CLOEXEC
|
O_NOCTTY
|
O_NOFOLLOW
|
O_PATH
|
O_DIRECTORY
);
if
(
ctx
->
dfd
_pid
<
0
)
if
(
dfd_init
_pid
<
0
)
return
-
errno
;
return
-
errno
;
fd_status
=
openat
(
ctx
->
dfd
_pid
,
"status"
,
O_CLOEXEC
|
O_NOCTTY
|
O_NOFOLLOW
|
O_RDONLY
);
fd_status
=
openat
(
dfd_init
_pid
,
"status"
,
O_CLOEXEC
|
O_NOCTTY
|
O_NOFOLLOW
|
O_RDONLY
);
if
(
fd_status
<
0
)
if
(
fd_status
<
0
)
return
-
errno
;
return
-
errno
;
...
@@ -162,6 +171,7 @@ static int get_attach_context(struct attach_context *ctx,
...
@@ -162,6 +171,7 @@ static int get_attach_context(struct attach_context *ctx,
ctx
->
lsm_ops
=
lsm_init_static
();
ctx
->
lsm_ops
=
lsm_init_static
();
/* Move to file descriptor-only lsm label retrieval. */
ctx
->
lsm_label
=
ctx
->
lsm_ops
->
process_label_get
(
ctx
->
lsm_ops
,
ctx
->
init_pid
);
ctx
->
lsm_label
=
ctx
->
lsm_ops
->
process_label_get
(
ctx
->
lsm_ops
,
ctx
->
init_pid
);
ctx
->
ns_inherited
=
0
;
ctx
->
ns_inherited
=
0
;
for
(
int
i
=
0
;
i
<
LXC_NS_MAX
;
i
++
)
for
(
int
i
=
0
;
i
<
LXC_NS_MAX
;
i
++
)
...
@@ -177,38 +187,27 @@ static int get_attach_context(struct attach_context *ctx,
...
@@ -177,38 +187,27 @@ static int get_attach_context(struct attach_context *ctx,
return
log_error_errno
(
-
ENOMEM
,
ENOMEM
,
"Failed to allocate new lxc config"
);
return
log_error_errno
(
-
ENOMEM
,
ENOMEM
,
"Failed to allocate new lxc config"
);
}
}
ctx
->
dfd_init_pid
=
move_fd
(
dfd_init_pid
);
ctx
->
dfd_self_pid
=
move_fd
(
dfd_self_pid
);
return
0
;
return
0
;
}
}
/**
static
int
in_same_namespace
(
int
ns_fd_pid1
,
int
ns_fd_pid2
,
const
char
*
ns_path
)
* in_same_namespace - Check whether two processes are in the same namespace.
* @pid1 - PID of the first process.
* @pid2 - PID of the second process.
* @ns - Name of the namespace to check. Must correspond to one of the names
* for the namespaces as shown in /proc/<pid/ns/
*
* If the two processes are not in the same namespace returns an fd to the
* namespace of the second process identified by @pid2. If the two processes are
* in the same namespace returns -EINVAL, -1 if an error occurred.
*/
static
int
in_same_namespace
(
pid_t
pid1
,
pid_t
pid2
,
const
char
*
ns
)
{
{
__do_close
int
ns_fd1
=
-
EBADF
,
ns_fd2
=
-
EBADF
;
__do_close
int
ns_fd1
=
-
EBADF
,
ns_fd2
=
-
EBADF
;
int
ret
=
-
1
;
int
ret
=
-
1
;
struct
stat
ns_st1
,
ns_st2
;
struct
stat
ns_st1
,
ns_st2
;
ns_fd1
=
lxc_preserve_ns
(
pid1
,
ns
);
ns_fd1
=
openat
(
ns_fd_pid1
,
ns_path
,
O_CLOEXEC
|
O_NOCTTY
|
O_RDONLY
);
if
(
ns_fd1
<
0
)
{
if
(
ns_fd1
<
0
)
{
/* The kernel does not support this namespace. This is not an
/* The kernel does not support this namespace. This is not an error. */
* error.
*/
if
(
errno
==
ENOENT
)
if
(
errno
==
ENOENT
)
return
-
EINVAL
;
return
-
EINVAL
;
return
-
1
;
return
-
1
;
}
}
ns_fd2
=
lxc_preserve_ns
(
pid2
,
ns
);
ns_fd2
=
openat
(
ns_fd_pid2
,
ns_path
,
O_CLOEXEC
|
O_NOCTTY
|
O_RDONLY
);
if
(
ns_fd2
<
0
)
if
(
ns_fd2
<
0
)
return
-
1
;
return
-
1
;
...
@@ -221,7 +220,8 @@ static int in_same_namespace(pid_t pid1, pid_t pid2, const char *ns)
...
@@ -221,7 +220,8 @@ static int in_same_namespace(pid_t pid1, pid_t pid2, const char *ns)
return
-
1
;
return
-
1
;
/* processes are in the same namespace */
/* processes are in the same namespace */
if
((
ns_st1
.
st_dev
==
ns_st2
.
st_dev
)
&&
(
ns_st1
.
st_ino
==
ns_st2
.
st_ino
))
if
((
ns_st1
.
st_dev
==
ns_st2
.
st_dev
)
&&
(
ns_st1
.
st_ino
==
ns_st2
.
st_ino
))
return
-
EINVAL
;
return
-
EINVAL
;
/* processes are in different namespaces */
/* processes are in different namespaces */
...
@@ -231,16 +231,13 @@ static int in_same_namespace(pid_t pid1, pid_t pid2, const char *ns)
...
@@ -231,16 +231,13 @@ static int in_same_namespace(pid_t pid1, pid_t pid2, const char *ns)
static
int
get_attach_context_nsfds
(
struct
attach_context
*
ctx
,
static
int
get_attach_context_nsfds
(
struct
attach_context
*
ctx
,
lxc_attach_options_t
*
options
)
lxc_attach_options_t
*
options
)
{
{
pid_t
pid_self
=
lxc_raw_getpid
();
for
(
int
i
=
0
;
i
<
LXC_NS_MAX
;
i
++
)
{
for
(
int
i
=
0
;
i
<
LXC_NS_MAX
;
i
++
)
{
int
j
;
int
j
;
if
(
options
->
namespaces
&
ns_info
[
i
].
clone_flag
)
if
(
options
->
namespaces
&
ns_info
[
i
].
clone_flag
)
ctx
->
ns_fd
[
i
]
=
lxc_preserve_ns
(
ctx
->
init_pid
,
ns_info
[
i
].
proc_name
);
ctx
->
ns_fd
[
i
]
=
openat
(
ctx
->
dfd_init_pid
,
ns_info
[
i
].
proc_path
,
O_CLOEXEC
|
O_NOCTTY
|
O_RDONLY
);
else
if
(
ctx
->
ns_inherited
&
ns_info
[
i
].
clone_flag
)
else
if
(
ctx
->
ns_inherited
&
ns_info
[
i
].
clone_flag
)
ctx
->
ns_fd
[
i
]
=
in_same_namespace
(
pid_self
,
ctx
->
init_pid
,
ns_info
[
i
].
proc_name
);
ctx
->
ns_fd
[
i
]
=
in_same_namespace
(
ctx
->
dfd_self_pid
,
ctx
->
dfd_init_pid
,
ns_info
[
i
].
proc_path
);
else
else
continue
;
continue
;
...
@@ -248,13 +245,13 @@ static int get_attach_context_nsfds(struct attach_context *ctx,
...
@@ -248,13 +245,13 @@ static int get_attach_context_nsfds(struct attach_context *ctx,
continue
;
continue
;
if
(
ctx
->
ns_fd
[
i
]
==
-
EINVAL
)
{
if
(
ctx
->
ns_fd
[
i
]
==
-
EINVAL
)
{
DEBUG
(
"Inheriting %s namespace
from %d"
,
ns_info
[
i
].
proc_name
,
pid_self
);
DEBUG
(
"Inheriting %s namespace
"
,
ns_info
[
i
].
proc_name
);
ctx
->
ns_inherited
&=
~
ns_info
[
i
].
clone_flag
;
ctx
->
ns_inherited
&=
~
ns_info
[
i
].
clone_flag
;
continue
;
continue
;
}
}
/* We failed to preserve the namespace. */
/* We failed to preserve the namespace. */
SYSERROR
(
"Failed to
attach to %s namespace of %d"
,
ns_info
[
i
].
proc_name
,
pid_self
);
SYSERROR
(
"Failed to
preserve %s namespace of %d"
,
ns_info
[
i
].
proc_name
,
ctx
->
init_pid
);
/* Close all already opened file descriptors before we return an
/* Close all already opened file descriptors before we return an
* error, so we don't leak them.
* error, so we don't leak them.
...
@@ -278,7 +275,7 @@ static void put_attach_context(struct attach_context *ctx)
...
@@ -278,7 +275,7 @@ static void put_attach_context(struct attach_context *ctx)
{
{
if
(
ctx
)
{
if
(
ctx
)
{
free_disarm
(
ctx
->
lsm_label
);
free_disarm
(
ctx
->
lsm_label
);
close_prot_errno_disarm
(
ctx
->
dfd_pid
);
close_prot_errno_disarm
(
ctx
->
dfd_
init_
pid
);
if
(
ctx
->
container
)
{
if
(
ctx
->
container
)
{
lxc_container_put
(
ctx
->
container
);
lxc_container_put
(
ctx
->
container
);
...
@@ -318,9 +315,13 @@ static int attach_context_container(struct attach_context *ctx)
...
@@ -318,9 +315,13 @@ static int attach_context_container(struct attach_context *ctx)
static
bool
attach_context_security_barrier
(
struct
attach_context
*
ctx
)
static
bool
attach_context_security_barrier
(
struct
attach_context
*
ctx
)
{
{
if
(
ctx
)
{
if
(
ctx
)
{
if
(
close
(
ctx
->
dfd_pid
))
if
(
close
(
ctx
->
dfd_self_pid
))
return
false
;
ctx
->
dfd_self_pid
=
-
EBADF
;
if
(
close
(
ctx
->
dfd_init_pid
))
return
false
;
return
false
;
ctx
->
dfd_pid
=
-
EBADF
;
ctx
->
dfd_
init_
pid
=
-
EBADF
;
}
}
return
true
;
return
true
;
...
...
src/lxc/namespace.c
View file @
25c659d5
...
@@ -38,14 +38,14 @@ lxc_log_define(namespace, lxc);
...
@@ -38,14 +38,14 @@ lxc_log_define(namespace, lxc);
* linux/fs/namespace.c:mntns_install().
* linux/fs/namespace.c:mntns_install().
*/
*/
const
struct
ns_info
ns_info
[
LXC_NS_MAX
]
=
{
const
struct
ns_info
ns_info
[
LXC_NS_MAX
]
=
{
[
LXC_NS_USER
]
=
{
"user"
,
CLONE_NEWUSER
,
"CLONE_NEWUSER"
,
"LXC_USER_NS"
},
[
LXC_NS_USER
]
=
{
"user"
,
"ns/user"
,
CLONE_NEWUSER
,
"CLONE_NEWUSER"
,
"LXC_USER_NS"
},
[
LXC_NS_MNT
]
=
{
"mnt"
,
CLONE_NEWNS
,
"CLONE_NEWNS"
,
"LXC_MNT_NS"
},
[
LXC_NS_MNT
]
=
{
"mnt"
,
"ns/mnt"
,
CLONE_NEWNS
,
"CLONE_NEWNS"
,
"LXC_MNT_NS"
},
[
LXC_NS_PID
]
=
{
"pid"
,
CLONE_NEWPID
,
"CLONE_NEWPID"
,
"LXC_PID_NS"
},
[
LXC_NS_PID
]
=
{
"pid"
,
"ns/pid"
,
CLONE_NEWPID
,
"CLONE_NEWPID"
,
"LXC_PID_NS"
},
[
LXC_NS_UTS
]
=
{
"uts"
,
CLONE_NEWUTS
,
"CLONE_NEWUTS"
,
"LXC_UTS_NS"
},
[
LXC_NS_UTS
]
=
{
"uts"
,
"ns/uts"
,
CLONE_NEWUTS
,
"CLONE_NEWUTS"
,
"LXC_UTS_NS"
},
[
LXC_NS_IPC
]
=
{
"ipc"
,
CLONE_NEWIPC
,
"CLONE_NEWIPC"
,
"LXC_IPC_NS"
},
[
LXC_NS_IPC
]
=
{
"ipc"
,
"ns/ipc"
,
CLONE_NEWIPC
,
"CLONE_NEWIPC"
,
"LXC_IPC_NS"
},
[
LXC_NS_NET
]
=
{
"net"
,
CLONE_NEWNET
,
"CLONE_NEWNET"
,
"LXC_NET_NS"
},
[
LXC_NS_NET
]
=
{
"net"
,
"ns/net"
,
CLONE_NEWNET
,
"CLONE_NEWNET"
,
"LXC_NET_NS"
},
[
LXC_NS_CGROUP
]
=
{
"cgroup"
,
CLONE_NEWCGROUP
,
"CLONE_NEWCGROUP"
,
"LXC_CGROUP_NS"
},
[
LXC_NS_CGROUP
]
=
{
"cgroup"
,
"ns/cgroup"
,
CLONE_NEWCGROUP
,
"CLONE_NEWCGROUP"
,
"LXC_CGROUP_NS"
},
[
LXC_NS_TIME
]
=
{
"time"
,
CLONE_NEWTIME
,
"CLONE_NEWTIME"
,
"LXC_TIME_NS"
},
[
LXC_NS_TIME
]
=
{
"time"
,
"ns/time"
,
CLONE_NEWTIME
,
"CLONE_NEWTIME"
,
"LXC_TIME_NS"
},
};
};
int
lxc_namespace_2_cloneflag
(
const
char
*
namespace
)
int
lxc_namespace_2_cloneflag
(
const
char
*
namespace
)
...
...
src/lxc/namespace.h
View file @
25c659d5
...
@@ -23,6 +23,7 @@ enum {
...
@@ -23,6 +23,7 @@ enum {
__hidden
extern
const
struct
ns_info
{
__hidden
extern
const
struct
ns_info
{
const
char
*
proc_name
;
const
char
*
proc_name
;
const
char
*
proc_path
;
int
clone_flag
;
int
clone_flag
;
const
char
*
flag_name
;
const
char
*
flag_name
;
const
char
*
env_name
;
const
char
*
env_name
;
...
...
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