2
0
mirror of https://github.com/checkpoint-restore/criu synced 2025-08-31 22:35:33 +00:00

uffd: use userns_call() to execute ioctl(UFFDIO_API)

In the recent kernels the userfaultfd support for FORK events is limited to
CAP_SYS_PTRACE. That causes the followong error when the ioctl(UFFDIO_API)
is executed from non-privilieged userns:

Error (criu/uffd.c:273): uffd: Failed to get uffd API: Operation not permitted

Wrapping the call to ioctl(UFFDIO_API) in userns_call() resolves the issue.

Fixes: #964
Signed-off-by: Mike Rapoport <rppt@linux.ibm.com>
This commit is contained in:
Mike Rapoport
2020-02-26 12:25:37 +02:00
committed by Andrei Vagin
parent 38793699e7
commit cdd08cdff8

View File

@@ -40,6 +40,7 @@
#include "tls.h"
#include "fdstore.h"
#include "util.h"
#include "namespaces.h"
#undef LOG_PREFIX
#define LOG_PREFIX "uffd: "
@@ -254,6 +255,13 @@ bool uffd_noncooperative(void)
return (kdat.uffd_features & features) == features;
}
static int uffd_api_ioctl(void *arg, int fd, pid_t pid)
{
struct uffdio_api *uffdio_api = arg;
return ioctl(fd, UFFDIO_API, uffdio_api);
}
int uffd_open(int flags, unsigned long *features)
{
struct uffdio_api uffdio_api = { 0 };
@@ -269,7 +277,8 @@ int uffd_open(int flags, unsigned long *features)
if (features)
uffdio_api.features = *features;
if (ioctl(uffd, UFFDIO_API, &uffdio_api)) {
if (userns_call(uffd_api_ioctl, 0, &uffdio_api, sizeof(uffdio_api),
uffd)) {
pr_perror("Failed to get uffd API");
goto err;
}