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
4aa90f60
Unverified
Commit
4aa90f60
authored
Feb 18, 2019
by
Christian Brauner
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
[V2] rexec: handle legacy kernels
Signed-off-by:
Christian Brauner
<
christian.brauner@ubuntu.com
>
parent
fed8112d
Show whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
114 additions
and
20 deletions
+114
-20
file_utils.c
src/lxc/file_utils.c
+40
-6
file_utils.h
src/lxc/file_utils.h
+1
-0
memory_utils.h
src/lxc/memory_utils.h
+11
-5
rexec.c
src/lxc/rexec.c
+62
-9
No files found.
src/lxc/file_utils.c
View file @
4aa90f60
...
@@ -31,7 +31,9 @@
...
@@ -31,7 +31,9 @@
#include "config.h"
#include "config.h"
#include "file_utils.h"
#include "file_utils.h"
#include "macro.h"
#include "macro.h"
#include "memory_utils.h"
#include "string_utils.h"
#include "string_utils.h"
#include "utils.h"
int
lxc_write_to_file
(
const
char
*
filename
,
const
void
*
buf
,
size_t
count
,
int
lxc_write_to_file
(
const
char
*
filename
,
const
void
*
buf
,
size_t
count
,
bool
add_newline
,
mode_t
mode
)
bool
add_newline
,
mode_t
mode
)
...
@@ -218,7 +220,8 @@ int lxc_count_file_lines(const char *fn)
...
@@ -218,7 +220,8 @@ int lxc_count_file_lines(const char *fn)
int
lxc_make_tmpfile
(
char
*
template
,
bool
rm
)
int
lxc_make_tmpfile
(
char
*
template
,
bool
rm
)
{
{
int
fd
,
ret
;
__do_close_prot_errno
int
fd
=
-
EBADF
;
int
ret
;
mode_t
msk
;
mode_t
msk
;
msk
=
umask
(
0022
);
msk
=
umask
(
0022
);
...
@@ -227,16 +230,17 @@ int lxc_make_tmpfile(char *template, bool rm)
...
@@ -227,16 +230,17 @@ int lxc_make_tmpfile(char *template, bool rm)
if
(
fd
<
0
)
if
(
fd
<
0
)
return
-
1
;
return
-
1
;
if
(
lxc_set_cloexec
(
fd
))
return
-
1
;
if
(
!
rm
)
if
(
!
rm
)
return
fd
;
return
steal_fd
(
fd
)
;
ret
=
unlink
(
template
);
ret
=
unlink
(
template
);
if
(
ret
<
0
)
{
if
(
ret
<
0
)
close
(
fd
);
return
-
1
;
return
-
1
;
}
return
fd
;
return
steal_fd
(
fd
)
;
}
}
bool
is_fs_type
(
const
struct
statfs
*
fs
,
fs_type_magic
magic_val
)
bool
is_fs_type
(
const
struct
statfs
*
fs
,
fs_type_magic
magic_val
)
...
@@ -366,3 +370,33 @@ on_error:
...
@@ -366,3 +370,33 @@ on_error:
return
NULL
;
return
NULL
;
}
}
int
fd_to_fd
(
int
from
,
int
to
)
{
for
(;;)
{
uint8_t
buf
[
PATH_MAX
];
uint8_t
*
p
=
buf
;
ssize_t
bytes_to_write
;
ssize_t
bytes_read
;
bytes_read
=
lxc_read_nointr
(
from
,
buf
,
sizeof
buf
);
if
(
bytes_read
<
0
)
return
-
1
;
if
(
bytes_read
==
0
)
break
;
bytes_to_write
=
(
size_t
)
bytes_read
;
do
{
ssize_t
bytes_written
;
bytes_written
=
lxc_write_nointr
(
to
,
p
,
bytes_to_write
);
if
(
bytes_written
<
0
)
return
-
1
;
bytes_to_write
-=
bytes_written
;
p
+=
bytes_written
;
}
while
(
bytes_to_write
>
0
);
}
return
0
;
}
src/lxc/file_utils.h
View file @
4aa90f60
...
@@ -57,5 +57,6 @@ extern FILE *fopen_cloexec(const char *path, const char *mode);
...
@@ -57,5 +57,6 @@ extern FILE *fopen_cloexec(const char *path, const char *mode);
extern
ssize_t
lxc_sendfile_nointr
(
int
out_fd
,
int
in_fd
,
off_t
*
offset
,
extern
ssize_t
lxc_sendfile_nointr
(
int
out_fd
,
int
in_fd
,
off_t
*
offset
,
size_t
count
);
size_t
count
);
extern
char
*
file_to_buf
(
char
*
path
,
size_t
*
length
);
extern
char
*
file_to_buf
(
char
*
path
,
size_t
*
length
);
extern
int
fd_to_fd
(
int
from
,
int
to
);
#endif
/* __LXC_FILE_UTILS_H */
#endif
/* __LXC_FILE_UTILS_H */
src/lxc/memory_utils.h
View file @
4aa90f60
...
@@ -28,6 +28,8 @@
...
@@ -28,6 +28,8 @@
#include <sys/types.h>
#include <sys/types.h>
#include <unistd.h>
#include <unistd.h>
#include "macro.h"
static
inline
void
__auto_free__
(
void
*
p
)
static
inline
void
__auto_free__
(
void
*
p
)
{
{
free
(
*
(
void
**
)
p
);
free
(
*
(
void
**
)
p
);
...
@@ -45,13 +47,17 @@ static inline void __auto_closedir__(DIR **d)
...
@@ -45,13 +47,17 @@ static inline void __auto_closedir__(DIR **d)
closedir
(
*
d
);
closedir
(
*
d
);
}
}
#define close_prot_errno_disarm(fd) \
if (fd >= 0) { \
int _e_ = errno; \
close(fd); \
errno = _e_; \
fd = -EBADF; \
}
static
inline
void
__auto_close__
(
int
*
fd
)
static
inline
void
__auto_close__
(
int
*
fd
)
{
{
if
(
*
fd
>=
0
)
{
close_prot_errno_disarm
(
*
fd
);
int
e
=
errno
;
close
(
*
fd
);
errno
=
e
;
}
}
}
#define __do_close_prot_errno __attribute__((__cleanup__(__auto_close__)))
#define __do_close_prot_errno __attribute__((__cleanup__(__auto_close__)))
...
...
src/lxc/rexec.c
View file @
4aa90f60
...
@@ -84,42 +84,95 @@ static int parse_argv(char ***argv)
...
@@ -84,42 +84,95 @@ static int parse_argv(char ***argv)
static
int
is_memfd
(
void
)
static
int
is_memfd
(
void
)
{
{
__do_close_prot_errno
int
fd
=
-
EBADF
;
__do_close_prot_errno
int
fd
=
-
EBADF
;
int
s
aved_errno
,
s
eals
;
int
seals
;
fd
=
open
(
"/proc/self/exe"
,
O_RDONLY
|
O_CLOEXEC
);
fd
=
open
(
"/proc/self/exe"
,
O_RDONLY
|
O_CLOEXEC
);
if
(
fd
<
0
)
if
(
fd
<
0
)
return
-
ENOTRECOVERABLE
;
return
-
ENOTRECOVERABLE
;
seals
=
fcntl
(
fd
,
F_GET_SEALS
);
seals
=
fcntl
(
fd
,
F_GET_SEALS
);
if
(
seals
<
0
)
if
(
seals
<
0
)
{
struct
stat
s
=
{
0
};
if
(
fstat
(
fd
,
&
s
)
==
0
)
return
(
s
.
st_nlink
==
0
);
return
-
EINVAL
;
return
-
EINVAL
;
}
return
seals
==
LXC_MEMFD_REXEC_SEALS
;
return
seals
==
LXC_MEMFD_REXEC_SEALS
;
}
}
static
void
lxc_rexec_as_memfd
(
char
**
argv
,
char
**
envp
,
const
char
*
memfd_name
)
static
void
lxc_rexec_as_memfd
(
char
**
argv
,
char
**
envp
,
const
char
*
memfd_name
)
{
{
__do_close_prot_errno
int
fd
=
-
EBADF
,
memfd
=
-
EBADF
;
__do_close_prot_errno
int
fd
=
-
EBADF
,
memfd
=
-
EBADF
,
tmpfd
=
-
EBADF
;
int
saved_errno
;
int
ret
;
ssize_t
bytes_sent
;
memfd
=
memfd_create
(
memfd_name
,
MFD_ALLOW_SEALING
|
MFD_CLOEXEC
);
memfd
=
memfd_create
(
memfd_name
,
MFD_ALLOW_SEALING
|
MFD_CLOEXEC
);
if
(
memfd
<
0
)
if
(
memfd
<
0
)
{
char
template
[
PATH_MAX
];
ret
=
snprintf
(
template
,
sizeof
(
template
),
P_tmpdir
"/.%s_XXXXXX"
,
memfd_name
);
if
(
ret
<
0
||
(
size_t
)
ret
>=
sizeof
(
template
))
return
;
tmpfd
=
lxc_make_tmpfile
(
template
,
true
);
if
(
tmpfd
<
0
)
return
;
ret
=
fchmod
(
tmpfd
,
0700
);
if
(
ret
)
return
;
return
;
}
fd
=
open
(
"/proc/self/exe"
,
O_RDONLY
|
O_CLOEXEC
);
fd
=
open
(
"/proc/self/exe"
,
O_RDONLY
|
O_CLOEXEC
);
if
(
fd
<
0
)
if
(
fd
<
0
)
return
;
return
;
/* sendfile() handles up to 2GB. */
/* sendfile() handles up to 2GB. */
bytes_sent
=
lxc_sendfile_nointr
(
memfd
,
fd
,
NULL
,
LXC_SENDFILE_MAX
);
if
(
memfd
>=
0
)
{
if
(
bytes_sent
<
0
)
ssize_t
bytes_sent
=
0
;
struct
stat
st
=
{
0
};
ret
=
fstat
(
fd
,
&
st
);
if
(
ret
)
return
;
return
;
if
(
fcntl
(
memfd
,
F_ADD_SEALS
,
LXC_MEMFD_REXEC_SEALS
))
while
(
bytes_sent
<
st
.
st_size
)
{
ssize_t
sent
;
sent
=
lxc_sendfile_nointr
(
memfd
,
fd
,
NULL
,
st
.
st_size
-
bytes_sent
);
if
(
sent
<
0
)
return
;
return
;
bytes_sent
+=
sent
;
}
}
else
if
(
fd_to_fd
(
fd
,
tmpfd
))
{
return
;
}
close_prot_errno_disarm
(
fd
);
if
(
memfd
>=
0
&&
fcntl
(
memfd
,
F_ADD_SEALS
,
LXC_MEMFD_REXEC_SEALS
))
return
;
if
(
memfd
>=
0
)
{
fexecve
(
memfd
,
argv
,
envp
);
fexecve
(
memfd
,
argv
,
envp
);
}
else
{
__do_close_prot_errno
int
execfd
=
-
EBADF
;
char
procfd
[
LXC_PROC_PID_FD_LEN
];
ret
=
snprintf
(
procfd
,
sizeof
(
procfd
),
"/proc/self/fd/%d"
,
tmpfd
);
if
(
ret
<
0
||
(
size_t
)
ret
>=
sizeof
(
procfd
))
return
;
execfd
=
open
(
procfd
,
O_PATH
|
O_CLOEXEC
);
close_prot_errno_disarm
(
tmpfd
);
if
(
execfd
<
0
)
return
;
fexecve
(
execfd
,
argv
,
envp
);
}
}
}
/*
/*
...
...
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