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
26077e91
Unverified
Commit
26077e91
authored
Jul 09, 2019
by
Christian Brauner
Committed by
GitHub
Jul 09, 2019
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #3080 from Blub/seccomp-notify-api
Seccomp notify api update
parents
cfc3b342
b9dab9ef
Hide whitespace changes
Inline
Side-by-side
Showing
9 changed files
with
253 additions
and
60 deletions
+253
-60
configure.ac
configure.ac
+1
-0
lxc.container.conf.sgml.in
doc/lxc.container.conf.sgml.in
+13
-2
af_unix.c
src/lxc/af_unix.c
+38
-20
af_unix.h
src/lxc/af_unix.h
+4
-0
confile.c
src/lxc/confile.c
+34
-0
file_utils.c
src/lxc/file_utils.c
+18
-0
file_utils.h
src/lxc/file_utils.h
+3
-0
lxcseccomp.h
src/lxc/lxcseccomp.h
+14
-3
seccomp.c
src/lxc/seccomp.c
+128
-35
No files found.
configure.ac
View file @
26077e91
...
@@ -367,6 +367,7 @@ OLD_CFLAGS="$CFLAGS"
...
@@ -367,6 +367,7 @@ OLD_CFLAGS="$CFLAGS"
CFLAGS="$CFLAGS $SECCOMP_CFLAGS"
CFLAGS="$CFLAGS $SECCOMP_CFLAGS"
AC_CHECK_TYPES([scmp_filter_ctx], [], [], [[#include <seccomp.h>]])
AC_CHECK_TYPES([scmp_filter_ctx], [], [], [[#include <seccomp.h>]])
AC_CHECK_DECLS([seccomp_notify_fd], [], [], [[#include <seccomp.h>]])
AC_CHECK_DECLS([seccomp_notify_fd], [], [], [[#include <seccomp.h>]])
AC_CHECK_TYPES([struct seccomp_notif_sizes], [], [], [[#include <seccomp.h>]])
AC_CHECK_DECLS([seccomp_syscall_resolve_name_arch], [], [], [[#include <seccomp.h>]])
AC_CHECK_DECLS([seccomp_syscall_resolve_name_arch], [], [], [[#include <seccomp.h>]])
CFLAGS="$OLD_CFLAGS"
CFLAGS="$OLD_CFLAGS"
...
...
doc/lxc.container.conf.sgml.in
View file @
26077e91
...
@@ -1997,11 +1997,22 @@ dev/null proc/kcore none bind,relative 0 0
...
@@ -1997,11 +1997,22 @@ dev/null proc/kcore none bind,relative 0 0
<listitem>
<listitem>
<para>
<para>
Specify a unix socket to which LXC will connect and forward
Specify a unix socket to which LXC will connect and forward
seccomp events to. The path must b
y
in the form
seccomp events to. The path must b
e
in the form
unix:/path/to/socket or unix:@socket. The former specifies a
unix:/path/to/socket or unix:@socket. The former specifies a
path-bound unix domain socket while the latter specifies an
path-bound unix domain socket while the latter specifies an
abstract unix domain socket.
abstract unix domain socket.
</para>
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>
<option>lxc.seccomp.notify.cookie</option>
</term>
<listitem>
<para>
An additional string sent along with proxied seccomp notification
requests.
</para>
</listitem>
</listitem>
</varlistentry>
</varlistentry>
</variablelist>
</variablelist>
...
...
src/lxc/af_unix.c
View file @
26077e91
...
@@ -153,19 +153,16 @@ int lxc_abstract_unix_connect(const char *path)
...
@@ -153,19 +153,16 @@ int lxc_abstract_unix_connect(const char *path)
return
fd
;
return
fd
;
}
}
int
lxc_abstract_unix_send_fds
(
int
fd
,
int
*
sendfds
,
int
num_sendfds
,
int
lxc_abstract_unix_send_fds
_iov
(
int
fd
,
int
*
sendfds
,
int
num_sendfds
,
void
*
data
,
size_t
size
)
struct
iovec
*
iov
,
size_t
iovlen
)
{
{
__do_free
char
*
cmsgbuf
=
NULL
;
__do_free
char
*
cmsgbuf
=
NULL
;
int
ret
;
int
ret
;
struct
msghdr
msg
;
struct
msghdr
msg
;
struct
iovec
iov
;
struct
cmsghdr
*
cmsg
=
NULL
;
struct
cmsghdr
*
cmsg
=
NULL
;
char
buf
[
1
]
=
{
0
};
size_t
cmsgbufsize
=
CMSG_SPACE
(
num_sendfds
*
sizeof
(
int
));
size_t
cmsgbufsize
=
CMSG_SPACE
(
num_sendfds
*
sizeof
(
int
));
memset
(
&
msg
,
0
,
sizeof
(
msg
));
memset
(
&
msg
,
0
,
sizeof
(
msg
));
memset
(
&
iov
,
0
,
sizeof
(
iov
));
cmsgbuf
=
malloc
(
cmsgbufsize
);
cmsgbuf
=
malloc
(
cmsgbufsize
);
if
(
!
cmsgbuf
)
{
if
(
!
cmsgbuf
)
{
...
@@ -185,10 +182,8 @@ int lxc_abstract_unix_send_fds(int fd, int *sendfds, int num_sendfds,
...
@@ -185,10 +182,8 @@ int lxc_abstract_unix_send_fds(int fd, int *sendfds, int num_sendfds,
memcpy
(
CMSG_DATA
(
cmsg
),
sendfds
,
num_sendfds
*
sizeof
(
int
));
memcpy
(
CMSG_DATA
(
cmsg
),
sendfds
,
num_sendfds
*
sizeof
(
int
));
iov
.
iov_base
=
data
?
data
:
buf
;
msg
.
msg_iov
=
iov
;
iov
.
iov_len
=
data
?
size
:
sizeof
(
buf
);
msg
.
msg_iovlen
=
iovlen
;
msg
.
msg_iov
=
&
iov
;
msg
.
msg_iovlen
=
1
;
again:
again:
ret
=
sendmsg
(
fd
,
&
msg
,
MSG_NOSIGNAL
);
ret
=
sendmsg
(
fd
,
&
msg
,
MSG_NOSIGNAL
);
...
@@ -199,26 +194,35 @@ again:
...
@@ -199,26 +194,35 @@ again:
return
ret
;
return
ret
;
}
}
int
lxc_abstract_unix_send_fds
(
int
fd
,
int
*
sendfds
,
int
num_sendfds
,
void
*
data
,
size_t
size
)
{
char
buf
[
1
]
=
{
0
};
struct
iovec
iov
=
{
.
iov_base
=
data
?
data
:
buf
,
.
iov_len
=
data
?
size
:
sizeof
(
buf
),
};
return
lxc_abstract_unix_send_fds_iov
(
fd
,
sendfds
,
num_sendfds
,
&
iov
,
1
);
}
int
lxc_unix_send_fds
(
int
fd
,
int
*
sendfds
,
int
num_sendfds
,
void
*
data
,
int
lxc_unix_send_fds
(
int
fd
,
int
*
sendfds
,
int
num_sendfds
,
void
*
data
,
size_t
size
)
size_t
size
)
{
{
return
lxc_abstract_unix_send_fds
(
fd
,
sendfds
,
num_sendfds
,
data
,
size
);
return
lxc_abstract_unix_send_fds
(
fd
,
sendfds
,
num_sendfds
,
data
,
size
);
}
}
int
lxc_abstract_unix_recv_fds
(
int
fd
,
int
*
recvfds
,
int
num_recvfds
,
static
int
lxc_abstract_unix_recv_fds_iov
(
int
fd
,
int
*
recvfds
,
int
num_recvfds
,
void
*
data
,
size_t
size
)
struct
iovec
*
iov
,
size_t
iovlen
)
{
{
__do_free
char
*
cmsgbuf
=
NULL
;
__do_free
char
*
cmsgbuf
=
NULL
;
int
ret
;
int
ret
;
struct
msghdr
msg
;
struct
msghdr
msg
;
struct
iovec
iov
;
struct
cmsghdr
*
cmsg
=
NULL
;
struct
cmsghdr
*
cmsg
=
NULL
;
char
buf
[
1
]
=
{
0
};
size_t
cmsgbufsize
=
CMSG_SPACE
(
sizeof
(
struct
ucred
))
+
size_t
cmsgbufsize
=
CMSG_SPACE
(
sizeof
(
struct
ucred
))
+
CMSG_SPACE
(
num_recvfds
*
sizeof
(
int
));
CMSG_SPACE
(
num_recvfds
*
sizeof
(
int
));
memset
(
&
msg
,
0
,
sizeof
(
msg
));
memset
(
&
msg
,
0
,
sizeof
(
msg
));
memset
(
&
iov
,
0
,
sizeof
(
iov
));
cmsgbuf
=
malloc
(
cmsgbufsize
);
cmsgbuf
=
malloc
(
cmsgbufsize
);
if
(
!
cmsgbuf
)
{
if
(
!
cmsgbuf
)
{
...
@@ -229,10 +233,8 @@ int lxc_abstract_unix_recv_fds(int fd, int *recvfds, int num_recvfds,
...
@@ -229,10 +233,8 @@ int lxc_abstract_unix_recv_fds(int fd, int *recvfds, int num_recvfds,
msg
.
msg_control
=
cmsgbuf
;
msg
.
msg_control
=
cmsgbuf
;
msg
.
msg_controllen
=
cmsgbufsize
;
msg
.
msg_controllen
=
cmsgbufsize
;
iov
.
iov_base
=
data
?
data
:
buf
;
msg
.
msg_iov
=
iov
;
iov
.
iov_len
=
data
?
size
:
sizeof
(
buf
);
msg
.
msg_iovlen
=
iovlen
;
msg
.
msg_iov
=
&
iov
;
msg
.
msg_iovlen
=
1
;
again:
again:
ret
=
recvmsg
(
fd
,
&
msg
,
0
);
ret
=
recvmsg
(
fd
,
&
msg
,
0
);
...
@@ -264,6 +266,17 @@ out:
...
@@ -264,6 +266,17 @@ out:
return
ret
;
return
ret
;
}
}
int
lxc_abstract_unix_recv_fds
(
int
fd
,
int
*
recvfds
,
int
num_recvfds
,
void
*
data
,
size_t
size
)
{
char
buf
[
1
]
=
{
0
};
struct
iovec
iov
=
{
.
iov_base
=
data
?
data
:
buf
,
.
iov_len
=
data
?
size
:
sizeof
(
buf
),
};
return
lxc_abstract_unix_recv_fds_iov
(
fd
,
recvfds
,
num_recvfds
,
&
iov
,
1
);
}
int
lxc_abstract_unix_send_credential
(
int
fd
,
void
*
data
,
size_t
size
)
int
lxc_abstract_unix_send_credential
(
int
fd
,
void
*
data
,
size_t
size
)
{
{
struct
msghdr
msg
=
{
0
};
struct
msghdr
msg
=
{
0
};
...
@@ -365,13 +378,13 @@ int lxc_unix_sockaddr(struct sockaddr_un *ret, const char *path)
...
@@ -365,13 +378,13 @@ int lxc_unix_sockaddr(struct sockaddr_un *ret, const char *path)
return
(
int
)(
offsetof
(
struct
sockaddr_un
,
sun_path
)
+
len
+
1
);
return
(
int
)(
offsetof
(
struct
sockaddr_un
,
sun_path
)
+
len
+
1
);
}
}
int
lxc_unix_connect
(
struct
sockaddr_un
*
addr
)
int
lxc_unix_connect
_type
(
struct
sockaddr_un
*
addr
,
int
type
)
{
{
__do_close_prot_errno
int
fd
=
-
EBADF
;
__do_close_prot_errno
int
fd
=
-
EBADF
;
int
ret
;
int
ret
;
ssize_t
len
;
ssize_t
len
;
fd
=
socket
(
AF_UNIX
,
SOCK_STREAM
|
SOCK_CLOEXEC
,
0
);
fd
=
socket
(
AF_UNIX
,
type
|
SOCK_CLOEXEC
,
0
);
if
(
fd
<
0
)
{
if
(
fd
<
0
)
{
SYSERROR
(
"Failed to open new AF_UNIX socket"
);
SYSERROR
(
"Failed to open new AF_UNIX socket"
);
return
-
1
;
return
-
1
;
...
@@ -392,6 +405,11 @@ int lxc_unix_connect(struct sockaddr_un *addr)
...
@@ -392,6 +405,11 @@ int lxc_unix_connect(struct sockaddr_un *addr)
return
move_fd
(
fd
);
return
move_fd
(
fd
);
}
}
int
lxc_unix_connect
(
struct
sockaddr_un
*
addr
,
int
type
)
{
return
lxc_unix_connect_type
(
addr
,
SOCK_STREAM
);
}
int
lxc_socket_set_timeout
(
int
fd
,
int
rcv_timeout
,
int
snd_timeout
)
int
lxc_socket_set_timeout
(
int
fd
,
int
rcv_timeout
,
int
snd_timeout
)
{
{
struct
timeval
out
=
{
0
};
struct
timeval
out
=
{
0
};
...
...
src/lxc/af_unix.h
View file @
26077e91
...
@@ -35,6 +35,9 @@ extern void lxc_abstract_unix_close(int fd);
...
@@ -35,6 +35,9 @@ extern void lxc_abstract_unix_close(int fd);
extern
int
lxc_abstract_unix_connect
(
const
char
*
path
);
extern
int
lxc_abstract_unix_connect
(
const
char
*
path
);
extern
int
lxc_abstract_unix_send_fds
(
int
fd
,
int
*
sendfds
,
int
num_sendfds
,
extern
int
lxc_abstract_unix_send_fds
(
int
fd
,
int
*
sendfds
,
int
num_sendfds
,
void
*
data
,
size_t
size
);
void
*
data
,
size_t
size
);
extern
int
lxc_abstract_unix_send_fds_iov
(
int
fd
,
int
*
sendfds
,
int
num_sendfds
,
struct
iovec
*
iov
,
size_t
iovlen
);
extern
int
lxc_unix_send_fds
(
int
fd
,
int
*
sendfds
,
int
num_sendfds
,
void
*
data
,
extern
int
lxc_unix_send_fds
(
int
fd
,
int
*
sendfds
,
int
num_sendfds
,
void
*
data
,
size_t
size
);
size_t
size
);
extern
int
lxc_abstract_unix_recv_fds
(
int
fd
,
int
*
recvfds
,
int
num_recvfds
,
extern
int
lxc_abstract_unix_recv_fds
(
int
fd
,
int
*
recvfds
,
int
num_recvfds
,
...
@@ -43,6 +46,7 @@ extern int lxc_abstract_unix_send_credential(int fd, void *data, size_t size);
...
@@ -43,6 +46,7 @@ extern int lxc_abstract_unix_send_credential(int fd, void *data, size_t size);
extern
int
lxc_abstract_unix_rcv_credential
(
int
fd
,
void
*
data
,
size_t
size
);
extern
int
lxc_abstract_unix_rcv_credential
(
int
fd
,
void
*
data
,
size_t
size
);
extern
int
lxc_unix_sockaddr
(
struct
sockaddr_un
*
ret
,
const
char
*
path
);
extern
int
lxc_unix_sockaddr
(
struct
sockaddr_un
*
ret
,
const
char
*
path
);
extern
int
lxc_unix_connect
(
struct
sockaddr_un
*
addr
);
extern
int
lxc_unix_connect
(
struct
sockaddr_un
*
addr
);
extern
int
lxc_unix_connect_type
(
struct
sockaddr_un
*
addr
,
int
type
);
extern
int
lxc_socket_set_timeout
(
int
fd
,
int
rcv_timeout
,
int
snd_timeout
);
extern
int
lxc_socket_set_timeout
(
int
fd
,
int
rcv_timeout
,
int
snd_timeout
);
#endif
/* __LXC_AF_UNIX_H */
#endif
/* __LXC_AF_UNIX_H */
src/lxc/confile.c
View file @
26077e91
...
@@ -153,6 +153,7 @@ lxc_config_define(rootfs_options);
...
@@ -153,6 +153,7 @@ lxc_config_define(rootfs_options);
lxc_config_define
(
rootfs_path
);
lxc_config_define
(
rootfs_path
);
lxc_config_define
(
seccomp_profile
);
lxc_config_define
(
seccomp_profile
);
lxc_config_define
(
seccomp_allow_nesting
);
lxc_config_define
(
seccomp_allow_nesting
);
lxc_config_define
(
seccomp_notify_cookie
);
lxc_config_define
(
seccomp_notify_proxy
);
lxc_config_define
(
seccomp_notify_proxy
);
lxc_config_define
(
selinux_context
);
lxc_config_define
(
selinux_context
);
lxc_config_define
(
signal_halt
);
lxc_config_define
(
signal_halt
);
...
@@ -246,6 +247,7 @@ static struct lxc_config_t config_jump_table[] = {
...
@@ -246,6 +247,7 @@ static struct lxc_config_t config_jump_table[] = {
{
"lxc.rootfs.options"
,
set_config_rootfs_options
,
get_config_rootfs_options
,
clr_config_rootfs_options
,
},
{
"lxc.rootfs.options"
,
set_config_rootfs_options
,
get_config_rootfs_options
,
clr_config_rootfs_options
,
},
{
"lxc.rootfs.path"
,
set_config_rootfs_path
,
get_config_rootfs_path
,
clr_config_rootfs_path
,
},
{
"lxc.rootfs.path"
,
set_config_rootfs_path
,
get_config_rootfs_path
,
clr_config_rootfs_path
,
},
{
"lxc.seccomp.allow_nesting"
,
set_config_seccomp_allow_nesting
,
get_config_seccomp_allow_nesting
,
clr_config_seccomp_allow_nesting
,
},
{
"lxc.seccomp.allow_nesting"
,
set_config_seccomp_allow_nesting
,
get_config_seccomp_allow_nesting
,
clr_config_seccomp_allow_nesting
,
},
{
"lxc.seccomp.notify.cookie"
,
set_config_seccomp_notify_cookie
,
get_config_seccomp_notify_cookie
,
clr_config_seccomp_notify_cookie
,
},
{
"lxc.seccomp.notify.proxy"
,
set_config_seccomp_notify_proxy
,
get_config_seccomp_notify_proxy
,
clr_config_seccomp_notify_proxy
,
},
{
"lxc.seccomp.notify.proxy"
,
set_config_seccomp_notify_proxy
,
get_config_seccomp_notify_proxy
,
clr_config_seccomp_notify_proxy
,
},
{
"lxc.seccomp.profile"
,
set_config_seccomp_profile
,
get_config_seccomp_profile
,
clr_config_seccomp_profile
,
},
{
"lxc.seccomp.profile"
,
set_config_seccomp_profile
,
get_config_seccomp_profile
,
clr_config_seccomp_profile
,
},
{
"lxc.selinux.context"
,
set_config_selinux_context
,
get_config_selinux_context
,
clr_config_selinux_context
,
},
{
"lxc.selinux.context"
,
set_config_selinux_context
,
get_config_selinux_context
,
clr_config_selinux_context
,
},
...
@@ -1013,6 +1015,16 @@ static int set_config_seccomp_allow_nesting(const char *key, const char *value,
...
@@ -1013,6 +1015,16 @@ static int set_config_seccomp_allow_nesting(const char *key, const char *value,
#endif
#endif
}
}
static
int
set_config_seccomp_notify_cookie
(
const
char
*
key
,
const
char
*
value
,
struct
lxc_conf
*
lxc_conf
,
void
*
data
)
{
#ifdef HAVE_SECCOMP_NOTIFY
return
set_config_string_item
(
&
lxc_conf
->
seccomp
.
notifier
.
cookie
,
value
);
#else
return
minus_one_set_errno
(
ENOSYS
);
#endif
}
static
int
set_config_seccomp_notify_proxy
(
const
char
*
key
,
const
char
*
value
,
static
int
set_config_seccomp_notify_proxy
(
const
char
*
key
,
const
char
*
value
,
struct
lxc_conf
*
lxc_conf
,
void
*
data
)
struct
lxc_conf
*
lxc_conf
,
void
*
data
)
{
{
...
@@ -3955,6 +3967,16 @@ static int get_config_seccomp_allow_nesting(const char *key, char *retv,
...
@@ -3955,6 +3967,16 @@ static int get_config_seccomp_allow_nesting(const char *key, char *retv,
#endif
#endif
}
}
static
int
get_config_seccomp_notify_cookie
(
const
char
*
key
,
char
*
retv
,
int
inlen
,
struct
lxc_conf
*
c
,
void
*
data
)
{
#ifdef HAVE_SECCOMP_NOTIFY
return
lxc_get_conf_str
(
retv
,
inlen
,
c
->
seccomp
.
notifier
.
cookie
);
#else
return
minus_one_set_errno
(
ENOSYS
);
#endif
}
static
int
get_config_seccomp_notify_proxy
(
const
char
*
key
,
char
*
retv
,
int
inlen
,
static
int
get_config_seccomp_notify_proxy
(
const
char
*
key
,
char
*
retv
,
int
inlen
,
struct
lxc_conf
*
c
,
void
*
data
)
struct
lxc_conf
*
c
,
void
*
data
)
{
{
...
@@ -4563,6 +4585,18 @@ static inline int clr_config_seccomp_allow_nesting(const char *key,
...
@@ -4563,6 +4585,18 @@ static inline int clr_config_seccomp_allow_nesting(const char *key,
#endif
#endif
}
}
static
inline
int
clr_config_seccomp_notify_cookie
(
const
char
*
key
,
struct
lxc_conf
*
c
,
void
*
data
)
{
#ifdef HAVE_SECCOMP_NOTIFY
free
(
c
->
seccomp
.
notifier
.
cookie
);
c
->
seccomp
.
notifier
.
cookie
=
NULL
;
return
0
;
#else
return
minus_one_set_errno
(
ENOSYS
);
#endif
}
static
inline
int
clr_config_seccomp_notify_proxy
(
const
char
*
key
,
static
inline
int
clr_config_seccomp_notify_proxy
(
const
char
*
key
,
struct
lxc_conf
*
c
,
void
*
data
)
struct
lxc_conf
*
c
,
void
*
data
)
{
{
...
...
src/lxc/file_utils.c
View file @
26077e91
...
@@ -142,6 +142,24 @@ again:
...
@@ -142,6 +142,24 @@ again:
return
ret
;
return
ret
;
}
}
ssize_t
lxc_recvmsg_nointr_iov
(
int
sockfd
,
struct
iovec
*
iov
,
size_t
iovlen
,
int
flags
)
{
ssize_t
ret
;
struct
msghdr
msg
;
memset
(
&
msg
,
0
,
sizeof
(
msg
));
msg
.
msg_iov
=
iov
;
msg
.
msg_iovlen
=
iovlen
;
again:
ret
=
recvmsg
(
sockfd
,
&
msg
,
flags
);
if
(
ret
<
0
&&
errno
==
EINTR
)
goto
again
;
return
ret
;
}
ssize_t
lxc_read_nointr_expect
(
int
fd
,
void
*
buf
,
size_t
count
,
const
void
*
expected_buf
)
ssize_t
lxc_read_nointr_expect
(
int
fd
,
void
*
buf
,
size_t
count
,
const
void
*
expected_buf
)
{
{
ssize_t
ret
;
ssize_t
ret
;
...
...
src/lxc/file_utils.h
View file @
26077e91
...
@@ -26,6 +26,7 @@
...
@@ -26,6 +26,7 @@
#include <stdio.h>
#include <stdio.h>
#include <sys/stat.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/types.h>
#include <sys/uio.h>
#include <sys/vfs.h>
#include <sys/vfs.h>
#include <unistd.h>
#include <unistd.h>
...
@@ -43,6 +44,8 @@ extern ssize_t lxc_read_nointr_expect(int fd, void *buf, size_t count,
...
@@ -43,6 +44,8 @@ extern ssize_t lxc_read_nointr_expect(int fd, void *buf, size_t count,
extern
ssize_t
lxc_read_file_expect
(
const
char
*
path
,
void
*
buf
,
size_t
count
,
extern
ssize_t
lxc_read_file_expect
(
const
char
*
path
,
void
*
buf
,
size_t
count
,
const
void
*
expected_buf
);
const
void
*
expected_buf
);
extern
ssize_t
lxc_recv_nointr
(
int
sockfd
,
void
*
buf
,
size_t
len
,
int
flags
);
extern
ssize_t
lxc_recv_nointr
(
int
sockfd
,
void
*
buf
,
size_t
len
,
int
flags
);
ssize_t
lxc_recvmsg_nointr_iov
(
int
sockfd
,
struct
iovec
*
iov
,
size_t
iovlen
,
int
flags
);
extern
bool
file_exists
(
const
char
*
f
);
extern
bool
file_exists
(
const
char
*
f
);
extern
int
print_to_file
(
const
char
*
file
,
const
char
*
content
);
extern
int
print_to_file
(
const
char
*
file
,
const
char
*
content
);
...
...
src/lxc/lxcseccomp.h
View file @
26077e91
...
@@ -54,12 +54,21 @@ struct lxc_handler;
...
@@ -54,12 +54,21 @@ struct lxc_handler;
#if HAVE_DECL_SECCOMP_NOTIFY_FD
#if HAVE_DECL_SECCOMP_NOTIFY_FD
#if !HAVE_STRUCT_SECCOMP_NOTIF_SIZES
struct
seccomp_notif_sizes
{
__u16
seccomp_notif
;
__u16
seccomp_notif_resp
;
__u16
seccomp_data
;
};
#endif
struct
seccomp_notify_proxy_msg
{
struct
seccomp_notify_proxy_msg
{
uint32_t
version
;
uint64_t
__reserved
;
struct
seccomp_notif
req
;
struct
seccomp_notif_resp
resp
;
pid_t
monitor_pid
;
pid_t
monitor_pid
;
pid_t
init_pid
;
pid_t
init_pid
;
struct
seccomp_notif_sizes
sizes
;
uint64_t
cookie_len
;
/* followed by: seccomp_notif, seccomp_notif_resp, cookie */
};
};
struct
seccomp_notify
{
struct
seccomp_notify
{
...
@@ -67,8 +76,10 @@ struct seccomp_notify {
...
@@ -67,8 +76,10 @@ struct seccomp_notify {
int
notify_fd
;
int
notify_fd
;
int
proxy_fd
;
int
proxy_fd
;
struct
sockaddr_un
proxy_addr
;
struct
sockaddr_un
proxy_addr
;
struct
seccomp_notif_sizes
sizes
;
struct
seccomp_notif
*
req_buf
;
struct
seccomp_notif
*
req_buf
;
struct
seccomp_notif_resp
*
rsp_buf
;
struct
seccomp_notif_resp
*
rsp_buf
;
char
*
cookie
;
};
};
#define HAVE_SECCOMP_NOTIFY 1
#define HAVE_SECCOMP_NOTIFY 1
...
...
src/lxc/seccomp.c
View file @
26077e91
...
@@ -49,8 +49,25 @@
...
@@ -49,8 +49,25 @@
#define MIPS_ARCH_N64 lxc_seccomp_arch_mips64
#define MIPS_ARCH_N64 lxc_seccomp_arch_mips64
#endif
#endif
#ifndef SECCOMP_GET_NOTIF_SIZES
#define SECCOMP_GET_NOTIF_SIZES 3
#endif
lxc_log_define
(
seccomp
,
lxc
);
lxc_log_define
(
seccomp
,
lxc
);
#if HAVE_DECL_SECCOMP_NOTIFY_FD
static
inline
int
__seccomp
(
unsigned
int
operation
,
unsigned
int
flags
,
void
*
args
)
{
#ifdef __NR_seccomp
return
syscall
(
__NR_seccomp
,
operation
,
flags
,
args
);
#else
errno
=
ENOSYS
;
return
-
1
;
#endif
}
#endif
static
int
parse_config_v1
(
FILE
*
f
,
char
*
line
,
size_t
*
line_bufsz
,
struct
lxc_conf
*
conf
)
static
int
parse_config_v1
(
FILE
*
f
,
char
*
line
,
size_t
*
line_bufsz
,
struct
lxc_conf
*
conf
)
{
{
int
ret
=
0
;
int
ret
=
0
;
...
@@ -1294,7 +1311,8 @@ static int seccomp_notify_reconnect(struct lxc_handler *handler)
...
@@ -1294,7 +1311,8 @@ static int seccomp_notify_reconnect(struct lxc_handler *handler)
close_prot_errno_disarm
(
handler
->
conf
->
seccomp
.
notifier
.
proxy_fd
);
close_prot_errno_disarm
(
handler
->
conf
->
seccomp
.
notifier
.
proxy_fd
);
notify_fd
=
lxc_unix_connect
(
&
handler
->
conf
->
seccomp
.
notifier
.
proxy_addr
);
notify_fd
=
lxc_unix_connect_type
(
&
handler
->
conf
->
seccomp
.
notifier
.
proxy_addr
,
SOCK_SEQPACKET
);
if
(
notify_fd
<
0
)
{
if
(
notify_fd
<
0
)
{
SYSERROR
(
"Failed to reconnect to seccomp proxy"
);
SYSERROR
(
"Failed to reconnect to seccomp proxy"
);
return
-
1
;
return
-
1
;
...
@@ -1311,17 +1329,15 @@ static int seccomp_notify_reconnect(struct lxc_handler *handler)
...
@@ -1311,17 +1329,15 @@ static int seccomp_notify_reconnect(struct lxc_handler *handler)
#endif
#endif
#if HAVE_DECL_SECCOMP_NOTIFY_FD
#if HAVE_DECL_SECCOMP_NOTIFY_FD
static
int
seccomp_notify_default_answer
(
int
fd
,
struct
seccomp_notif
*
req
,
static
void
seccomp_notify_default_answer
(
int
fd
,
struct
seccomp_notif
*
req
,
struct
seccomp_notif_resp
*
resp
,
struct
seccomp_notif_resp
*
resp
,
struct
lxc_handler
*
handler
)
struct
lxc_handler
*
handler
)
{
{
resp
->
id
=
req
->
id
;
resp
->
id
=
req
->
id
;
resp
->
error
=
-
ENOSYS
;
resp
->
error
=
-
ENOSYS
;
if
(
seccomp_notify_respond
(
fd
,
resp
))
if
(
seccomp_notify_respond
(
fd
,
resp
))
SYSERROR
(
"Failed to send default message to seccomp"
);
SYSERROR
(
"Failed to send default message to seccomp"
);
return
seccomp_notify_reconnect
(
handler
);
}
}
#endif
#endif
...
@@ -1330,24 +1346,26 @@ int seccomp_notify_handler(int fd, uint32_t events, void *data,
...
@@ -1330,24 +1346,26 @@ int seccomp_notify_handler(int fd, uint32_t events, void *data,
{
{
#if HAVE_DECL_SECCOMP_NOTIFY_FD
#if HAVE_DECL_SECCOMP_NOTIFY_FD
__do_close_prot_errno
int
fd_pid
=
-
EBADF
;
__do_close_prot_errno
int
fd_mem
=
-
EBADF
;
__do_close_prot_errno
int
fd_mem
=
-
EBADF
;
int
re
connect_count
,
re
t
;
int
ret
;
ssize_t
bytes
;
ssize_t
bytes
;
int
send_fd_list
[
2
];
struct
iovec
iov
[
4
];
size_t
iov_len
,
msg_base_size
,
msg_full_size
;
char
mem_path
[
6
/* /proc/ */
char
mem_path
[
6
/* /proc/ */
+
INTTYPE_TO_STRLEN
(
int64_t
)
+
INTTYPE_TO_STRLEN
(
int64_t
)
+
3
/* mem */
+
3
/* mem */
+
1
/* \0 */
];
+
1
/* \0 */
];
bool
reconnected
=
false
;
struct
lxc_handler
*
hdlr
=
data
;
struct
lxc_handler
*
hdlr
=
data
;
struct
lxc_conf
*
conf
=
hdlr
->
conf
;
struct
lxc_conf
*
conf
=
hdlr
->
conf
;
struct
seccomp_notif
*
req
=
conf
->
seccomp
.
notifier
.
req_buf
;
struct
seccomp_notif
*
req
=
conf
->
seccomp
.
notifier
.
req_buf
;
struct
seccomp_notif_resp
*
resp
=
conf
->
seccomp
.
notifier
.
rsp_buf
;
struct
seccomp_notif_resp
*
resp
=
conf
->
seccomp
.
notifier
.
rsp_buf
;
int
listener_proxy_fd
=
conf
->
seccomp
.
notifier
.
proxy_fd
;
int
listener_proxy_fd
=
conf
->
seccomp
.
notifier
.
proxy_fd
;
struct
seccomp_notify_proxy_msg
msg
=
{
0
};
struct
seccomp_notify_proxy_msg
msg
=
{
0
};
char
*
cookie
=
conf
->
seccomp
.
notifier
.
cookie
;
if
(
listener_proxy_fd
<
0
)
{
uint64_t
req_id
;
ERROR
(
"No seccomp proxy registered"
);
return
minus_one_set_errno
(
EINVAL
);
}
ret
=
seccomp_notify_receive
(
fd
,
req
);
ret
=
seccomp_notify_receive
(
fd
,
req
);
if
(
ret
)
{
if
(
ret
)
{
...
@@ -1355,10 +1373,36 @@ int seccomp_notify_handler(int fd, uint32_t events, void *data,
...
@@ -1355,10 +1373,36 @@ int seccomp_notify_handler(int fd, uint32_t events, void *data,
goto
out
;
goto
out
;
}
}
if
(
listener_proxy_fd
<
0
)
{
ret
=
-
1
;
/* Same condition as for the initial setup_proxy() */
if
(
conf
->
seccomp
.
notifier
.
wants_supervision
&&
conf
->
seccomp
.
notifier
.
proxy_addr
.
sun_path
[
1
]
!=
'\0'
)
{
ret
=
seccomp_notify_reconnect
(
hdlr
);
}
if
(
ret
)
{
ERROR
(
"No seccomp proxy registered"
);
seccomp_notify_default_answer
(
fd
,
req
,
resp
,
hdlr
);
goto
out
;
}
listener_proxy_fd
=
conf
->
seccomp
.
notifier
.
proxy_fd
;
}
/* remember the ID in case we receive garbage from the proxy */
resp
->
id
=
req_id
=
req
->
id
;
snprintf
(
mem_path
,
sizeof
(
mem_path
),
"/proc/%d"
,
req
->
pid
);
fd_pid
=
open
(
mem_path
,
O_RDONLY
|
O_DIRECTORY
|
O_CLOEXEC
);
if
(
fd_pid
<
0
)
{
seccomp_notify_default_answer
(
fd
,
req
,
resp
,
hdlr
);
SYSERROR
(
"Failed to open process pidfd for seccomp notify request"
);
goto
out
;
}
snprintf
(
mem_path
,
sizeof
(
mem_path
),
"/proc/%d/mem"
,
req
->
pid
);
snprintf
(
mem_path
,
sizeof
(
mem_path
),
"/proc/%d/mem"
,
req
->
pid
);
fd_mem
=
open
(
mem_path
,
O_RDONLY
|
O_CLOEXEC
);
fd_mem
=
open
(
mem_path
,
O_RDONLY
|
O_CLOEXEC
);
if
(
fd_mem
<
0
)
{
if
(
fd_mem
<
0
)
{
(
void
)
seccomp_notify_default_answer
(
fd
,
req
,
resp
,
hdlr
);
seccomp_notify_default_answer
(
fd
,
req
,
resp
,
hdlr
);
SYSERROR
(
"Failed to open process memory for seccomp notify request"
);
SYSERROR
(
"Failed to open process memory for seccomp notify request"
);
goto
out
;
goto
out
;
}
}
...
@@ -1369,39 +1413,80 @@ int seccomp_notify_handler(int fd, uint32_t events, void *data,
...
@@ -1369,39 +1413,80 @@ int seccomp_notify_handler(int fd, uint32_t events, void *data,
*/
*/
ret
=
seccomp_notify_id_valid
(
fd
,
req
->
id
);
ret
=
seccomp_notify_id_valid
(
fd
,
req
->
id
);
if
(
ret
<
0
)
{
if
(
ret
<
0
)
{
(
void
)
seccomp_notify_default_answer
(
fd
,
req
,
resp
,
hdlr
);
seccomp_notify_default_answer
(
fd
,
req
,
resp
,
hdlr
);
SYSERROR
(
"Invalid seccomp notify request id"
);
SYSERROR
(
"Invalid seccomp notify request id"
);
goto
out
;
goto
out
;
}
}
memcpy
(
&
msg
.
req
,
req
,
sizeof
(
msg
.
req
));
msg
.
monitor_pid
=
hdlr
->
monitor_pid
;
msg
.
monitor_pid
=
hdlr
->
monitor_pid
;
msg
.
init_pid
=
hdlr
->
pid
;
msg
.
init_pid
=
hdlr
->
pid
;
memcpy
(
&
msg
.
sizes
,
&
conf
->
seccomp
.
notifier
.
sizes
,
sizeof
(
msg
.
sizes
));
msg_base_size
=
0
;
iov
[
0
].
iov_base
=
&
msg
;
msg_base_size
+=
(
iov
[
0
].
iov_len
=
sizeof
(
msg
));
iov
[
1
].
iov_base
=
req
;
msg_base_size
+=
(
iov
[
1
].
iov_len
=
msg
.
sizes
.
seccomp_notif
);
iov
[
2
].
iov_base
=
resp
;
msg_base_size
+=
(
iov
[
2
].
iov_len
=
msg
.
sizes
.
seccomp_notif_resp
);
msg_full_size
=
msg_base_size
;
if
(
cookie
)
{
size_t
len
=
strlen
(
cookie
);
msg
.
cookie_len
=
(
uint64_t
)
len
;
reconnect_count
=
0
;
iov
[
3
].
iov_base
=
cookie
;
do
{
msg_full_size
+=
(
iov
[
3
].
iov_len
=
len
);
bytes
=
lxc_unix_send_fds
(
listener_proxy_fd
,
&
fd_mem
,
1
,
&
msg
,
sizeof
(
msg
));
iov_len
=
4
;
if
(
bytes
!=
(
ssize_t
)
sizeof
(
msg
))
{
}
else
{
SYSERROR
(
"Failed to forward message to seccomp proxy"
);
iov_len
=
3
;
if
(
seccomp_notify_default_answer
(
fd
,
req
,
resp
,
hdlr
))
}
goto
out
;
send_fd_list
[
0
]
=
fd_pid
;
send_fd_list
[
1
]
=
fd_mem
;
retry:
bytes
=
lxc_abstract_unix_send_fds_iov
(
listener_proxy_fd
,
send_fd_list
,
2
,
iov
,
iov_len
);
if
(
bytes
!=
(
ssize_t
)
msg_full_size
)
{
SYSERROR
(
"Failed to forward message to seccomp proxy"
);
if
(
!
reconnected
)
{
ret
=
seccomp_notify_reconnect
(
hdlr
);
if
(
ret
==
0
)
{
reconnected
=
true
;
goto
retry
;
}
}
}
}
while
(
reconnect_count
++
);
seccomp_notify_default_answer
(
fd
,
req
,
resp
,
hdlr
);
goto
out
;
}
close_prot_errno_disarm
(
fd_mem
);
close_prot_errno_disarm
(
fd_mem
);
reconnect_count
=
0
;
if
(
msg
.
__reserved
!=
0
)
{
do
{
ERROR
(
"Proxy filled reserved data in response"
);
bytes
=
lxc_recv_nointr
(
listener_proxy_fd
,
&
msg
,
sizeof
(
msg
),
0
);
seccomp_notify_default_answer
(
fd
,
req
,
resp
,
hdlr
);
if
(
bytes
!=
(
ssize_t
)
sizeof
(
msg
))
{
goto
out
;
SYSERROR
(
"Failed to receive message from seccomp proxy"
);
}
if
(
seccomp_notify_default_answer
(
fd
,
req
,
resp
,
hdlr
))
goto
out
;
if
(
resp
->
id
!=
req_id
)
{
}
resp
->
id
=
req_id
;
}
while
(
reconnect_count
++
);
ERROR
(
"Proxy returned response with illegal id"
);
seccomp_notify_default_answer
(
fd
,
req
,
resp
,
hdlr
);
goto
out
;
}
bytes
=
lxc_recvmsg_nointr_iov
(
listener_proxy_fd
,
iov
,
iov_len
,
MSG_TRUNC
);
if
(
bytes
!=
(
ssize_t
)
msg_base_size
)
{
SYSERROR
(
"Failed to receive message from seccomp proxy"
);
seccomp_notify_default_answer
(
fd
,
req
,
resp
,
hdlr
);
goto
out
;
}
memcpy
(
resp
,
&
msg
.
resp
,
sizeof
(
*
resp
));
ret
=
seccomp_notify_respond
(
fd
,
resp
);
ret
=
seccomp_notify_respond
(
fd
,
resp
);
if
(
ret
)
if
(
ret
)
SYSERROR
(
"Failed to send seccomp notification"
);
SYSERROR
(
"Failed to send seccomp notification"
);
...
@@ -1441,7 +1526,8 @@ int lxc_seccomp_setup_proxy(struct lxc_seccomp *seccomp,
...
@@ -1441,7 +1526,8 @@ int lxc_seccomp_setup_proxy(struct lxc_seccomp *seccomp,
__do_close_prot_errno
int
notify_fd
=
-
EBADF
;
__do_close_prot_errno
int
notify_fd
=
-
EBADF
;
int
ret
;
int
ret
;
notify_fd
=
lxc_unix_connect
(
&
seccomp
->
notifier
.
proxy_addr
);
notify_fd
=
lxc_unix_connect_type
(
&
seccomp
->
notifier
.
proxy_addr
,
SOCK_SEQPACKET
);
if
(
notify_fd
<
0
)
{
if
(
notify_fd
<
0
)
{
SYSERROR
(
"Failed to connect to seccomp proxy"
);
SYSERROR
(
"Failed to connect to seccomp proxy"
);
return
-
1
;
return
-
1
;
...
@@ -1454,6 +1540,13 @@ int lxc_seccomp_setup_proxy(struct lxc_seccomp *seccomp,
...
@@ -1454,6 +1540,13 @@ int lxc_seccomp_setup_proxy(struct lxc_seccomp *seccomp,
return
-
1
;
return
-
1
;
}
}
ret
=
__seccomp
(
SECCOMP_GET_NOTIF_SIZES
,
0
,
&
seccomp
->
notifier
.
sizes
);
if
(
ret
)
{
SYSERROR
(
"Failed to query seccomp notify struct sizes"
);
return
-
1
;
}
ret
=
seccomp_notify_alloc
(
&
seccomp
->
notifier
.
req_buf
,
ret
=
seccomp_notify_alloc
(
&
seccomp
->
notifier
.
req_buf
,
&
seccomp
->
notifier
.
rsp_buf
);
&
seccomp
->
notifier
.
rsp_buf
);
if
(
ret
)
{
if
(
ret
)
{
...
...
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