nsenter: cloned_binary: detect and handle short copies
For a variety of reasons, sendfile(2) can end up doing a short-copy so we need to just loop until we hit the binary size. Since /proc/self/exe is tautologically our own binary, there's no chance someone is going to modify it underneath us (or changing the size). Signed-off-by: Aleksa Sarai <asarai@suse.de>
This commit is contained in:
parent
f79e211b1d
commit
5b775bf297
|
@ -64,7 +64,6 @@ int memfd_create(const char *name, unsigned int flags)
|
||||||
# define F_SEAL_WRITE 0x0008 /* prevent writes */
|
# define F_SEAL_WRITE 0x0008 /* prevent writes */
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define RUNC_SENDFILE_MAX 0x7FFFF000 /* sendfile(2) is limited to 2GB. */
|
|
||||||
#ifdef HAVE_MEMFD_CREATE
|
#ifdef HAVE_MEMFD_CREATE
|
||||||
# define RUNC_MEMFD_COMMENT "runc_cloned:/proc/self/exe"
|
# define RUNC_MEMFD_COMMENT "runc_cloned:/proc/self/exe"
|
||||||
# define RUNC_MEMFD_SEALS \
|
# define RUNC_MEMFD_SEALS \
|
||||||
|
@ -195,7 +194,8 @@ error:
|
||||||
static int clone_binary(void)
|
static int clone_binary(void)
|
||||||
{
|
{
|
||||||
int binfd, memfd;
|
int binfd, memfd;
|
||||||
ssize_t sent = 0;
|
struct stat statbuf = {};
|
||||||
|
size_t sent = 0;
|
||||||
|
|
||||||
#ifdef HAVE_MEMFD_CREATE
|
#ifdef HAVE_MEMFD_CREATE
|
||||||
memfd = memfd_create(RUNC_MEMFD_COMMENT, MFD_CLOEXEC | MFD_ALLOW_SEALING);
|
memfd = memfd_create(RUNC_MEMFD_COMMENT, MFD_CLOEXEC | MFD_ALLOW_SEALING);
|
||||||
|
@ -209,9 +209,17 @@ static int clone_binary(void)
|
||||||
if (binfd < 0)
|
if (binfd < 0)
|
||||||
goto error;
|
goto error;
|
||||||
|
|
||||||
sent = sendfile(memfd, binfd, NULL, RUNC_SENDFILE_MAX);
|
if (fstat(binfd, &statbuf) < 0)
|
||||||
|
goto error_binfd;
|
||||||
|
|
||||||
|
while (sent < statbuf.st_size) {
|
||||||
|
int n = sendfile(memfd, binfd, NULL, statbuf.st_size - sent);
|
||||||
|
if (n < 0)
|
||||||
|
goto error_binfd;
|
||||||
|
sent += n;
|
||||||
|
}
|
||||||
close(binfd);
|
close(binfd);
|
||||||
if (sent < 0)
|
if (sent != statbuf.st_size)
|
||||||
goto error;
|
goto error;
|
||||||
|
|
||||||
#ifdef HAVE_MEMFD_CREATE
|
#ifdef HAVE_MEMFD_CREATE
|
||||||
|
@ -235,6 +243,8 @@ static int clone_binary(void)
|
||||||
#endif
|
#endif
|
||||||
return memfd;
|
return memfd;
|
||||||
|
|
||||||
|
error_binfd:
|
||||||
|
close(binfd);
|
||||||
error:
|
error:
|
||||||
close(memfd);
|
close(memfd);
|
||||||
return -EIO;
|
return -EIO;
|
||||||
|
|
Loading…
Reference in New Issue