[RFC 0/3] extend kexec_file_load system call

18 messages, 7 authors, 2016-08-05 · open the first message on its own page

[RFC 0/3] extend kexec_file_load system call

From: AKASHI Takahiro <hidden>
Date: 2016-07-12 01:37:09

Device tree blob must be passed to a second kernel on DTB-capable
archs, like powerpc and arm64, but the current kernel interface
lacks this support.
  
This patch extends kexec_file_load system call by adding an extra
argument to this syscall so that an arbitrary number of file descriptors
can be handed out from user space to the kernel.

See the background [1].

Please note that the new interface looks quite similar to the current
system call, but that it won't always mean that it provides the "binary
compatibility."

[1] http://lists.infradead.org/pipermail/kexec/2016-June/016276.html


AKASHI Takahiro (3):
  syscall: add kexec_file_load to generic unistd.h
  kexec: add dtb info to struct kimage
  kexec: extend kexec_file_load system call

 include/linux/fs.h                |  1 +
 include/linux/kexec.h             |  5 +++-
 include/linux/syscalls.h          |  4 ++-
 include/uapi/asm-generic/unistd.h |  8 ++++-
 include/uapi/linux/kexec.h        | 17 +++++++++++
 kernel/kexec_file.c               | 62 ++++++++++++++++++++++++++++++++++-----
 6 files changed, 87 insertions(+), 10 deletions(-)

-- 
2.9.0

[RFC 1/3] syscall: add kexec_file_load to generic unistd.h

From: AKASHI Takahiro <hidden>
Date: 2016-07-12 01:37:21

Currently kexec_file_load is supported only on x86, but it will be
supported on powerpc and arm64 in near future. Since both archs
use asm-generic/unistd.h, this patch adds the entry to this file.

Signed-off-by: AKASHI Takahiro <redacted>
---
 include/uapi/asm-generic/unistd.h | 8 +++++++-
 1 file changed, 7 insertions(+), 1 deletion(-)
diff --git a/include/uapi/asm-generic/unistd.h b/include/uapi/asm-generic/unistd.h
index a26415b..9ead10f 100644
--- a/include/uapi/asm-generic/unistd.h
+++ b/include/uapi/asm-generic/unistd.h
@@ -724,9 +724,15 @@ __SYSCALL(__NR_copy_file_range, sys_copy_file_range)
 __SC_COMP(__NR_preadv2, sys_preadv2, compat_sys_preadv2)
 #define __NR_pwritev2 287
 __SC_COMP(__NR_pwritev2, sys_pwritev2, compat_sys_pwritev2)
+#define __NR_kexec_file_load 288
+#ifdef CONFIG_KEXEC_FILE
+__SYSCALL(__NR_kexec_file_load, sys_kexec_file_load)
+#else
+__SYSCALL(__NR_kexec_file_load, sys_ni_syscall)
+#endif /* CONFIG_KEXEC_FILE */
 
 #undef __NR_syscalls
-#define __NR_syscalls 288
+#define __NR_syscalls 289
 
 /*
  * All syscalls below here should go away really,
-- 
2.9.0

[RFC 2/3] kexec: add dtb info to struct kimage

From: AKASHI Takahiro <hidden>
Date: 2016-07-12 01:37:36

Device tree blob must be passed to a second kernel on DTB-capable
archs, like powerpc and arm64, but the current kernel interface
lacks this support.

This patch adds dtb buffer information to struct kimage.
When users don't specify dtb explicitly and the one used for the current
kernel can be re-used, this change will be good enough for implementing
kexec_file_load feature.

Signed-off-by: AKASHI Takahiro <redacted>
---
 include/linux/kexec.h | 3 +++
 kernel/kexec_file.c   | 5 +++++
 2 files changed, 8 insertions(+)
diff --git a/include/linux/kexec.h b/include/linux/kexec.h
index e8acb2b..554c848 100644
--- a/include/linux/kexec.h
+++ b/include/linux/kexec.h
@@ -190,6 +190,9 @@ struct kimage {
 	char *cmdline_buf;
 	unsigned long cmdline_buf_len;
 
+	void *dtb_buf;
+	unsigned long dtb_buf_len;
+
 	/* File operations provided by image loader */
 	struct kexec_file_ops *fops;
 
diff --git a/kernel/kexec_file.c b/kernel/kexec_file.c
index 9891464..7278329 100644
--- a/kernel/kexec_file.c
+++ b/kernel/kexec_file.c
@@ -96,6 +96,11 @@ void kimage_file_post_load_cleanup(struct kimage *image)
 		image->initrd_buf = NULL;
 	}
 
+	if (image->dtb_buf) {
+		vfree(image->dtb_buf);
+		image->dtb_buf = NULL;
+	}
+
 	if (image->cmdline_buf) {
 		kfree(image->cmdline_buf);
 		image->cmdline_buf = NULL;
-- 
2.9.0

[RFC 3/3] kexec: extend kexec_file_load system call

From: AKASHI Takahiro <hidden>
Date: 2016-07-12 01:37:44

Device tree blob must be passed to a second kernel on DTB-capable
archs, like powerpc and arm64, but the current kernel interface
lacks this support.

This patch extends kexec_file_load system call by adding an extra
argument to this syscall so that an arbitrary number of file descriptors
can be handed out from user space to the kernel.

	long sys_kexec_file_load(int kernel_fd, int initrd_fd,
				 unsigned long cmdline_len,
				 const char __user *cmdline_ptr,
				 unsigned long flags,
				 const struct kexec_fdset __user *ufdset);

If KEXEC_FILE_EXTRA_FDS is set to the "flags" argument, the "ufdset"
argument points to the following struct buffer:

	struct kexec_fdset {
		int nr_fds;
		struct kexec_file_fd fds[0];
	}

Signed-off-by: AKASHI Takahiro <redacted>
---
 include/linux/fs.h         |  1 +
 include/linux/kexec.h      |  2 +-
 include/linux/syscalls.h   |  4 +++-
 include/uapi/linux/kexec.h | 17 ++++++++++++++
 kernel/kexec_file.c        | 57 ++++++++++++++++++++++++++++++++++++++++------
 5 files changed, 72 insertions(+), 9 deletions(-)
diff --git a/include/linux/fs.h b/include/linux/fs.h
index dd28814..6dd6fdf 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -2634,6 +2634,7 @@ extern int do_pipe_flags(int *, int);
 	id(MODULE, kernel-module)		\
 	id(KEXEC_IMAGE, kexec-image)		\
 	id(KEXEC_INITRAMFS, kexec-initramfs)	\
+	id(KEXEC_DTB, kexec-dtb)		\
 	id(POLICY, security-policy)		\
 	id(MAX_ID, )
 
diff --git a/include/linux/kexec.h b/include/linux/kexec.h
index 554c848..5f11bd5 100644
--- a/include/linux/kexec.h
+++ b/include/linux/kexec.h
@@ -277,7 +277,7 @@ extern int kexec_load_disabled;
 
 /* List of defined/legal kexec file flags */
 #define KEXEC_FILE_FLAGS	(KEXEC_FILE_UNLOAD | KEXEC_FILE_ON_CRASH | \
-				 KEXEC_FILE_NO_INITRAMFS)
+				 KEXEC_FILE_NO_INITRAMFS | KEXEC_FILE_EXTRA_FDS)
 
 #define VMCOREINFO_BYTES           (4096)
 #define VMCOREINFO_NOTE_NAME       "VMCOREINFO"
diff --git a/include/linux/syscalls.h b/include/linux/syscalls.h
index d022390..fc072bd 100644
--- a/include/linux/syscalls.h
+++ b/include/linux/syscalls.h
@@ -66,6 +66,7 @@ struct perf_event_attr;
 struct file_handle;
 struct sigaltstack;
 union bpf_attr;
+struct kexec_fdset;
 
 #include <linux/types.h>
 #include <linux/aio_abi.h>
@@ -321,7 +322,8 @@ asmlinkage long sys_kexec_load(unsigned long entry, unsigned long nr_segments,
 asmlinkage long sys_kexec_file_load(int kernel_fd, int initrd_fd,
 				    unsigned long cmdline_len,
 				    const char __user *cmdline_ptr,
-				    unsigned long flags);
+				    unsigned long flags,
+				    const struct kexec_fdset __user *ufdset);
 
 asmlinkage long sys_exit(int error_code);
 asmlinkage long sys_exit_group(int error_code);
diff --git a/include/uapi/linux/kexec.h b/include/uapi/linux/kexec.h
index aae5ebf..adf53b6 100644
--- a/include/uapi/linux/kexec.h
+++ b/include/uapi/linux/kexec.h
@@ -23,6 +23,23 @@
 #define KEXEC_FILE_UNLOAD	0x00000001
 #define KEXEC_FILE_ON_CRASH	0x00000002
 #define KEXEC_FILE_NO_INITRAMFS	0x00000004
+#define KEXEC_FILE_EXTRA_FDS	0x00000008
+
+enum kexec_file_type {
+	KEXEC_FILE_TYPE_KERNEL,
+	KEXEC_FILE_TYPE_INITRAMFS,
+	KEXEC_FILE_TYPE_DTB,
+};
+
+struct kexec_file_fd {
+	enum kexec_file_type type;
+	int fd;
+};
+
+struct kexec_fdset {
+	int nr_fds;
+	struct kexec_file_fd fds[0];
+};
 
 /* These values match the ELF architecture values.
  * Unless there is a good reason that should continue to be the case.
diff --git a/kernel/kexec_file.c b/kernel/kexec_file.c
index 7278329..451b4b0 100644
--- a/kernel/kexec_file.c
+++ b/kernel/kexec_file.c
@@ -137,11 +137,14 @@ void kimage_file_post_load_cleanup(struct kimage *image)
 static int
 kimage_file_prepare_segments(struct kimage *image, int kernel_fd, int initrd_fd,
 			     const char __user *cmdline_ptr,
-			     unsigned long cmdline_len, unsigned flags)
+			     unsigned long cmdline_len, unsigned long flags,
+			     const struct kexec_fdset __user *ufdset)
 {
-	int ret = 0;
+	int ret = 0, nr_fds, i;
 	void *ldata;
 	loff_t size;
+	struct kexec_fdset *fdset = NULL;
+	size_t fdset_size;
 
 	ret = kernel_read_file_from_fd(kernel_fd, &image->kernel_buf,
 				       &size, INT_MAX, READING_KEXEC_IMAGE);
@@ -174,6 +177,42 @@ kimage_file_prepare_segments(struct kimage *image, int kernel_fd, int initrd_fd,
 		image->initrd_buf_len = size;
 	}
 
+	if (flags & KEXEC_FILE_EXTRA_FDS) {
+		ret = copy_from_user(&nr_fds, ufdset, sizeof(int));
+		if (ret) {
+			ret = -EFAULT;
+			goto out;
+		}
+
+		fdset_size = sizeof(struct kexec_fdset)
+				+ nr_fds * sizeof(struct kexec_file_fd);
+		fdset = kmalloc(fdset_size, GFP_KERNEL);
+		if (!fdset) {
+			ret = -ENOMEM;
+			goto out;
+		}
+
+		ret = copy_from_user(fdset, ufdset, fdset_size);
+		if (ret) {
+			ret = -EFAULT;
+			goto out;
+		}
+
+		for (i = 0; i < fdset->nr_fds; i++) {
+			if (fdset->fds[i].type == KEXEC_FILE_TYPE_DTB) {
+				ret = kernel_read_file_from_fd(fdset->fds[i].fd,
+						&image->dtb_buf, &size, INT_MAX,
+						READING_KEXEC_DTB);
+				if (ret)
+					goto out;
+				image->dtb_buf_len = size;
+			} else {
+				pr_debug("unknown file type %d failed.\n",
+						fdset->fds[i].type);
+			}
+		}
+	}
+
 	if (cmdline_len) {
 		image->cmdline_buf = kzalloc(cmdline_len, GFP_KERNEL);
 		if (!image->cmdline_buf) {
@@ -208,6 +247,8 @@ kimage_file_prepare_segments(struct kimage *image, int kernel_fd, int initrd_fd,
 	image->image_loader_data = ldata;
 out:
 	/* In case of error, free up all allocated memory in this function */
+	kfree(fdset);
+
 	if (ret)
 		kimage_file_post_load_cleanup(image);
 	return ret;
@@ -216,7 +257,8 @@ out:
 static int
 kimage_file_alloc_init(struct kimage **rimage, int kernel_fd,
 		       int initrd_fd, const char __user *cmdline_ptr,
-		       unsigned long cmdline_len, unsigned long flags)
+		       unsigned long cmdline_len, unsigned long flags,
+		       const struct kexec_fdset __user *ufdset)
 {
 	int ret;
 	struct kimage *image;
@@ -235,7 +277,8 @@ kimage_file_alloc_init(struct kimage **rimage, int kernel_fd,
 	}
 
 	ret = kimage_file_prepare_segments(image, kernel_fd, initrd_fd,
-					   cmdline_ptr, cmdline_len, flags);
+					   cmdline_ptr, cmdline_len, flags,
+					   ufdset);
 	if (ret)
 		goto out_free_image;
 
@@ -270,9 +313,9 @@ out_free_image:
 	return ret;
 }
 
-SYSCALL_DEFINE5(kexec_file_load, int, kernel_fd, int, initrd_fd,
+SYSCALL_DEFINE6(kexec_file_load, int, kernel_fd, int, initrd_fd,
 		unsigned long, cmdline_len, const char __user *, cmdline_ptr,
-		unsigned long, flags)
+		unsigned long, flags, const struct kexec_fdset __user *, ufdset)
 {
 	int ret = 0, i;
 	struct kimage **dest_image, *image;
@@ -309,7 +352,7 @@ SYSCALL_DEFINE5(kexec_file_load, int, kernel_fd, int, initrd_fd,
 		kimage_free(xchg(&kexec_crash_image, NULL));
 
 	ret = kimage_file_alloc_init(&image, kernel_fd, initrd_fd, cmdline_ptr,
-				     cmdline_len, flags);
+				     cmdline_len, flags, ufdset);
 	if (ret)
 		goto out;
 
-- 
2.9.0

Re: [RFC 3/3] kexec: extend kexec_file_load system call

From: Vivek Goyal <vgoyal@redhat.com>
Date: 2016-07-15 13:10:48

On Tue, Jul 12, 2016 at 10:42:01AM +0900, AKASHI Takahiro wrote:

[..]
-SYSCALL_DEFINE5(kexec_file_load, int, kernel_fd, int, initrd_fd,
+SYSCALL_DEFINE6(kexec_file_load, int, kernel_fd, int, initrd_fd,
 		unsigned long, cmdline_len, const char __user *, cmdline_ptr,
-		unsigned long, flags)
+		unsigned long, flags, const struct kexec_fdset __user *, ufdset)
Can one add more parameters to existing syscall. Can it break existing
programs with new kernel? I was of the impression that one can't do that.
But may be I am missing something.

Vivek

Re: [RFC 3/3] kexec: extend kexec_file_load system call

From: Mark Rutland <mark.rutland@arm.com>
Date: 2016-07-15 13:20:08

On Fri, Jul 15, 2016 at 09:09:55AM -0400, Vivek Goyal wrote:
On Tue, Jul 12, 2016 at 10:42:01AM +0900, AKASHI Takahiro wrote:

[..]
quoted
-SYSCALL_DEFINE5(kexec_file_load, int, kernel_fd, int, initrd_fd,
+SYSCALL_DEFINE6(kexec_file_load, int, kernel_fd, int, initrd_fd,
 		unsigned long, cmdline_len, const char __user *, cmdline_ptr,
-		unsigned long, flags)
+		unsigned long, flags, const struct kexec_fdset __user *, ufdset)
Can one add more parameters to existing syscall. Can it break existing
programs with new kernel? I was of the impression that one can't do that.
But may be I am missing something.
I think the idea was that we would only look at the new params if a new
flags was set, and otherwise it would behave as the old syscall.

Regardless, I think it makes far more sense to add a kexec_file_load2
syscall if we're going to modify the prototype at all. It's a rather
different proposition to the existing syscall, and needs to be treated
as such.

Thanks,
Mark.

Re: [RFC 3/3] kexec: extend kexec_file_load system call

From: Dave Young <hidden>
Date: 2016-07-18 02:30:35

On 07/15/16 at 02:19pm, Mark Rutland wrote:
On Fri, Jul 15, 2016 at 09:09:55AM -0400, Vivek Goyal wrote:
quoted
On Tue, Jul 12, 2016 at 10:42:01AM +0900, AKASHI Takahiro wrote:

[..]
quoted
-SYSCALL_DEFINE5(kexec_file_load, int, kernel_fd, int, initrd_fd,
+SYSCALL_DEFINE6(kexec_file_load, int, kernel_fd, int, initrd_fd,
 		unsigned long, cmdline_len, const char __user *, cmdline_ptr,
-		unsigned long, flags)
+		unsigned long, flags, const struct kexec_fdset __user *, ufdset)
Can one add more parameters to existing syscall. Can it break existing
programs with new kernel? I was of the impression that one can't do that.
But may be I am missing something.
I think the idea was that we would only look at the new params if a new
flags was set, and otherwise it would behave as the old syscall.

Regardless, I think it makes far more sense to add a kexec_file_load2
syscall if we're going to modify the prototype at all. It's a rather
different proposition to the existing syscall, and needs to be treated
as such.
I do not think it is worth to add another syscall for extra fds.
We have open(2) as an example for different numbers of arguments
already.

Thanks
Dave

Re: [RFC 3/3] kexec: extend kexec_file_load system call

From: Dave Young <hidden>
Date: 2016-07-18 02:33:51

On 07/15/16 at 09:09am, Vivek Goyal wrote:
On Tue, Jul 12, 2016 at 10:42:01AM +0900, AKASHI Takahiro wrote:

[..]
quoted
-SYSCALL_DEFINE5(kexec_file_load, int, kernel_fd, int, initrd_fd,
+SYSCALL_DEFINE6(kexec_file_load, int, kernel_fd, int, initrd_fd,
 		unsigned long, cmdline_len, const char __user *, cmdline_ptr,
-		unsigned long, flags)
+		unsigned long, flags, const struct kexec_fdset __user *, ufdset)
Can one add more parameters to existing syscall. Can it break existing
programs with new kernel? I was of the impression that one can't do that.
But may be I am missing something.
It will not break existing programs because we can use the new param only
when the new flag is set.

But we have a case below, but I think it is fine?
Originally kexec_file_load with the new flags will fail, but now it will
succeed and will access the new argument.

Thanks
Dave

Re: [RFC 3/3] kexec: extend kexec_file_load system call

From: Mark Rutland <mark.rutland@arm.com>
Date: 2016-07-18 10:07:13

On Mon, Jul 18, 2016 at 10:30:24AM +0800, Dave Young wrote:
On 07/15/16 at 02:19pm, Mark Rutland wrote:
quoted
On Fri, Jul 15, 2016 at 09:09:55AM -0400, Vivek Goyal wrote:
quoted
On Tue, Jul 12, 2016 at 10:42:01AM +0900, AKASHI Takahiro wrote:

[..]
quoted
-SYSCALL_DEFINE5(kexec_file_load, int, kernel_fd, int, initrd_fd,
+SYSCALL_DEFINE6(kexec_file_load, int, kernel_fd, int, initrd_fd,
 		unsigned long, cmdline_len, const char __user *, cmdline_ptr,
-		unsigned long, flags)
+		unsigned long, flags, const struct kexec_fdset __user *, ufdset)
Can one add more parameters to existing syscall. Can it break existing
programs with new kernel? I was of the impression that one can't do that.
But may be I am missing something.
I think the idea was that we would only look at the new params if a new
flags was set, and otherwise it would behave as the old syscall.

Regardless, I think it makes far more sense to add a kexec_file_load2
syscall if we're going to modify the prototype at all. It's a rather
different proposition to the existing syscall, and needs to be treated
as such.
I do not think it is worth to add another syscall for extra fds.
We have open(2) as an example for different numbers of arguments
already.
Did we change the syscall interface for that?

I was under the impression that there was always one underlying syscall,
and the C library did the right thing to pass the expected information
to the underlying syscall.

That's rather different to changing the underlying syscall.

Regardless of how this is wrapped in userspace, I do not think modifying
the existing prototype is a good idea, and I think this kind of
extension needs to be a new syscall.

Thanks,
Mark.

Re: [RFC 3/3] kexec: extend kexec_file_load system call

From: Dave Young <hidden>
Date: 2016-07-19 00:56:09

On 07/18/16 at 11:07am, Mark Rutland wrote:
On Mon, Jul 18, 2016 at 10:30:24AM +0800, Dave Young wrote:
quoted
On 07/15/16 at 02:19pm, Mark Rutland wrote:
quoted
On Fri, Jul 15, 2016 at 09:09:55AM -0400, Vivek Goyal wrote:
quoted
On Tue, Jul 12, 2016 at 10:42:01AM +0900, AKASHI Takahiro wrote:

[..]
quoted
-SYSCALL_DEFINE5(kexec_file_load, int, kernel_fd, int, initrd_fd,
+SYSCALL_DEFINE6(kexec_file_load, int, kernel_fd, int, initrd_fd,
 		unsigned long, cmdline_len, const char __user *, cmdline_ptr,
-		unsigned long, flags)
+		unsigned long, flags, const struct kexec_fdset __user *, ufdset)
Can one add more parameters to existing syscall. Can it break existing
programs with new kernel? I was of the impression that one can't do that.
But may be I am missing something.
I think the idea was that we would only look at the new params if a new
flags was set, and otherwise it would behave as the old syscall.

Regardless, I think it makes far more sense to add a kexec_file_load2
syscall if we're going to modify the prototype at all. It's a rather
different proposition to the existing syscall, and needs to be treated
as such.
I do not think it is worth to add another syscall for extra fds.
We have open(2) as an example for different numbers of arguments
already.
Did we change the syscall interface for that?

I was under the impression that there was always one underlying syscall,
and the C library did the right thing to pass the expected information
to the underlying syscall.
I'm not sure kexec_load and kexec_file_load were included in glibc, we use
syscall directly in kexec-tools.

kexec_load man pages says there are no wrappers for both kexec_load and
kexec_file_load in glibc.
That's rather different to changing the underlying syscall.

Regardless of how this is wrapped in userspace, I do not think modifying
the existing prototype is a good idea, and I think this kind of
extension needs to be a new syscall.
Hmm, as I replied to Vivek, there is one case about the flags, previously
the new flag will be regarded as invalid, but not we extend it it will be
valid, this maybe the only potential bad case.

Thanks
Dave

Re: [RFC 3/3] kexec: extend kexec_file_load system call

From: Mark Rutland <mark.rutland@arm.com>
Date: 2016-07-19 10:52:09

On Tue, Jul 19, 2016 at 08:55:56AM +0800, Dave Young wrote:
On 07/18/16 at 11:07am, Mark Rutland wrote:
quoted
On Mon, Jul 18, 2016 at 10:30:24AM +0800, Dave Young wrote:
quoted
I do not think it is worth to add another syscall for extra fds.
We have open(2) as an example for different numbers of arguments
already.
Did we change the syscall interface for that?

I was under the impression that there was always one underlying syscall,
and the C library did the right thing to pass the expected information
to the underlying syscall.
I'm not sure kexec_load and kexec_file_load were included in glibc, we use
syscall directly in kexec-tools.

kexec_load man pages says there are no wrappers for both kexec_load and
kexec_file_load in glibc.
For the above, I was talking about how open() was handled.

If there are no userspace wrappers, then the two cases aren't comparable
in the first place...
quoted
That's rather different to changing the underlying syscall.

Regardless of how this is wrapped in userspace, I do not think modifying
the existing prototype is a good idea, and I think this kind of
extension needs to be a new syscall.
Hmm, as I replied to Vivek, there is one case about the flags, previously
the new flag will be regarded as invalid, but not we extend it it will be
valid, this maybe the only potential bad case.
It's true that adding suport for new flags will change the behaviour of
what used to be error cases. We generally expect real users to not be
making pointless calls for which they rely on an error being returned in
all cases.

Regardless, this extended syscall changes some underlying assumptions
made with the development of kexec_file_load, and I think treating this
as an extension is not a great idea. From a user's perspective there is
little difference between passing an additional flag or using a
different syscall number, so I don't think that we gain much by altering
the existing prototype relative to allocating a new syscall number.

Thus, I think that if this is necessary it should be treated as a new
syscall.

Thanks,
Mark.

Re: [RFC 3/3] kexec: extend kexec_file_load system call

From: Vivek Goyal <vgoyal@redhat.com>
Date: 2016-07-19 12:24:10

On Tue, Jul 19, 2016 at 11:52:00AM +0100, Mark Rutland wrote:
On Tue, Jul 19, 2016 at 08:55:56AM +0800, Dave Young wrote:
quoted
On 07/18/16 at 11:07am, Mark Rutland wrote:
quoted
On Mon, Jul 18, 2016 at 10:30:24AM +0800, Dave Young wrote:
quoted
I do not think it is worth to add another syscall for extra fds.
We have open(2) as an example for different numbers of arguments
already.
Did we change the syscall interface for that?

I was under the impression that there was always one underlying syscall,
and the C library did the right thing to pass the expected information
to the underlying syscall.
I'm not sure kexec_load and kexec_file_load were included in glibc, we use
syscall directly in kexec-tools.

kexec_load man pages says there are no wrappers for both kexec_load and
kexec_file_load in glibc.
For the above, I was talking about how open() was handled.

If there are no userspace wrappers, then the two cases aren't comparable
in the first place...
quoted
quoted
That's rather different to changing the underlying syscall.

Regardless of how this is wrapped in userspace, I do not think modifying
the existing prototype is a good idea, and I think this kind of
extension needs to be a new syscall.
Hmm, as I replied to Vivek, there is one case about the flags, previously
the new flag will be regarded as invalid, but not we extend it it will be
valid, this maybe the only potential bad case.
It's true that adding suport for new flags will change the behaviour of
what used to be error cases. We generally expect real users to not be
making pointless calls for which they rely on an error being returned in
all cases.

Regardless, this extended syscall changes some underlying assumptions
made with the development of kexec_file_load, and I think treating this
as an extension is not a great idea. From a user's perspective there is
little difference between passing an additional flag or using a
different syscall number, so I don't think that we gain much by altering
the existing prototype relative to allocating a new syscall number.
If we are providing/opening up additional flags, I can't think what will
it break. Same flag was invalid in old kernel but new kernel supports 
it and will accept it. So it sounds reasonable to me to add new flags.

If existing users are not broken, then I think it might be a good idea
to extend existing syscall. Otherwise userspace will have to be modified
to understand a 3rd syscall also and an additional option will show up
which asks users to specify which syscall to use. So extending existing
syscall might keep it little simple for users.

This is only if conclusion in the end is that DT needs to be passed in
from user space.

BTW, does kexec_load() needs to be modified too to handle DT?

Vivek

Re: [RFC 3/3] kexec: extend kexec_file_load system call

From: Mark Rutland <mark.rutland@arm.com>
Date: 2016-07-19 12:47:41

On Tue, Jul 19, 2016 at 08:24:06AM -0400, Vivek Goyal wrote:
On Tue, Jul 19, 2016 at 11:52:00AM +0100, Mark Rutland wrote:
quoted
Regardless, this extended syscall changes some underlying assumptions
made with the development of kexec_file_load, and I think treating this
as an extension is not a great idea. From a user's perspective there is
little difference between passing an additional flag or using a
different syscall number, so I don't think that we gain much by altering
the existing prototype relative to allocating a new syscall number.
If we are providing/opening up additional flags, I can't think what will
it break. Same flag was invalid in old kernel but new kernel supports 
it and will accept it. So it sounds reasonable to me to add new flags.

If existing users are not broken, then I think it might be a good idea
to extend existing syscall. Otherwise userspace will have to be modified
to understand a 3rd syscall also and an additional option will show up
which asks users to specify which syscall to use. So extending existing
syscall might keep it little simple for users.
I don't follow.

To use the new feature, you have to modify userspace anyway, as you
require userspace to pass information which it did not previously pass
(in the new arguments added to the syscall).

The presence of a new syscall does not imply the absence of the old
syscall, so you can always use that be default unless the user asks for
asomething only the new syscall provides. Regardless of the
syscall/flags difference, you still have to detect whether the new
functionality is present somehow.
BTW, does kexec_load() needs to be modified too to handle DT?
No, at least for arm64. In the kexec_load case userspace provides the
DTB as a raw segment, and the user-provided purgatory sets up registers
to pass that to the new kernel.

Thanks,
Mark.

Re: [RFC 3/3] kexec: extend kexec_file_load system call

From: Vivek Goyal <vgoyal@redhat.com>
Date: 2016-07-19 13:26:24

On Tue, Jul 19, 2016 at 01:47:28PM +0100, Mark Rutland wrote:
On Tue, Jul 19, 2016 at 08:24:06AM -0400, Vivek Goyal wrote:
quoted
On Tue, Jul 19, 2016 at 11:52:00AM +0100, Mark Rutland wrote:
quoted
Regardless, this extended syscall changes some underlying assumptions
made with the development of kexec_file_load, and I think treating this
as an extension is not a great idea. From a user's perspective there is
little difference between passing an additional flag or using a
different syscall number, so I don't think that we gain much by altering
the existing prototype relative to allocating a new syscall number.
If we are providing/opening up additional flags, I can't think what will
it break. Same flag was invalid in old kernel but new kernel supports 
it and will accept it. So it sounds reasonable to me to add new flags.

If existing users are not broken, then I think it might be a good idea
to extend existing syscall. Otherwise userspace will have to be modified
to understand a 3rd syscall also and an additional option will show up
which asks users to specify which syscall to use. So extending existing
syscall might keep it little simple for users.
I don't follow.

To use the new feature, you have to modify userspace anyway, as you
require userspace to pass information which it did not previously pass
(in the new arguments added to the syscall).

The presence of a new syscall does not imply the absence of the old
syscall, so you can always use that be default unless the user asks for
asomething only the new syscall provides. Regardless of the
syscall/flags difference, you still have to detect whether the new
functionality is present somehow.
Hmm., so current idea is that we have two syscalls() which are *ideally*
supposed to work for all arches. Difference between two is that first
one does not support kernel signature verification while second one does.

By default old syscall is used and user can force using new syscall using
option --kexec-file-load.

If a user DTB is present, I was hoping that it will continue to work the
same way. Both the sycalls can be used and can handle DTB. If we introduce
a 3rd syscall, that means only first and 3rd syscall can handle DTB and
we need to introduce one more option which tells whether to use
kexec_load() or use the 3rd new syscall. And that's what I am trying
to avoid.

Vivek
quoted
BTW, does kexec_load() needs to be modified too to handle DT?
No, at least for arm64. In the kexec_load case userspace provides the
DTB as a raw segment, and the user-provided purgatory sets up registers
to pass that to the new kernel.

Thanks,
Mark.

RE: [RFC 3/3] kexec: extend kexec_file_load system call

From: David Laight <hidden>
Date: 2016-07-20 11:43:31

RnJvbTogRGF2ZSBZb3VuZw0KPiBPbiAwNy8xNS8xNiBhdCAwMjoxOXBtLCBNYXJrIFJ1dGxhbmQg
d3JvdGU6DQo+ID4gT24gRnJpLCBKdWwgMTUsIDIwMTYgYXQgMDk6MDk6NTVBTSAtMDQwMCwgVml2
ZWsgR295YWwgd3JvdGU6DQo+ID4gPiBPbiBUdWUsIEp1bCAxMiwgMjAxNiBhdCAxMDo0MjowMUFN
ICswOTAwLCBBS0FTSEkgVGFrYWhpcm8gd3JvdGU6DQo+ID4gPg0KPiA+ID4gWy4uXQ0KPiA+ID4g
PiAtU1lTQ0FMTF9ERUZJTkU1KGtleGVjX2ZpbGVfbG9hZCwgaW50LCBrZXJuZWxfZmQsIGludCwg
aW5pdHJkX2ZkLA0KPiA+ID4gPiArU1lTQ0FMTF9ERUZJTkU2KGtleGVjX2ZpbGVfbG9hZCwgaW50
LCBrZXJuZWxfZmQsIGludCwgaW5pdHJkX2ZkLA0KPiA+ID4gPiAgCQl1bnNpZ25lZCBsb25nLCBj
bWRsaW5lX2xlbiwgY29uc3QgY2hhciBfX3VzZXIgKiwgY21kbGluZV9wdHIsDQo+ID4gPiA+IC0J
CXVuc2lnbmVkIGxvbmcsIGZsYWdzKQ0KPiA+ID4gPiArCQl1bnNpZ25lZCBsb25nLCBmbGFncywg
Y29uc3Qgc3RydWN0IGtleGVjX2Zkc2V0IF9fdXNlciAqLCB1ZmRzZXQpDQo+ID4gPg0KPiA+ID4g
Q2FuIG9uZSBhZGQgbW9yZSBwYXJhbWV0ZXJzIHRvIGV4aXN0aW5nIHN5c2NhbGwuIENhbiBpdCBi
cmVhayBleGlzdGluZw0KPiA+ID4gcHJvZ3JhbXMgd2l0aCBuZXcga2VybmVsPyBJIHdhcyBvZiB0
aGUgaW1wcmVzc2lvbiB0aGF0IG9uZSBjYW4ndCBkbyB0aGF0Lg0KPiA+ID4gQnV0IG1heSBiZSBJ
IGFtIG1pc3Npbmcgc29tZXRoaW5nLg0KPiA+DQo+ID4gSSB0aGluayB0aGUgaWRlYSB3YXMgdGhh
dCB3ZSB3b3VsZCBvbmx5IGxvb2sgYXQgdGhlIG5ldyBwYXJhbXMgaWYgYSBuZXcNCj4gPiBmbGFn
cyB3YXMgc2V0LCBhbmQgb3RoZXJ3aXNlIGl0IHdvdWxkIGJlaGF2ZSBhcyB0aGUgb2xkIHN5c2Nh
bGwuDQo+ID4NCj4gPiBSZWdhcmRsZXNzLCBJIHRoaW5rIGl0IG1ha2VzIGZhciBtb3JlIHNlbnNl
IHRvIGFkZCBhIGtleGVjX2ZpbGVfbG9hZDINCj4gPiBzeXNjYWxsIGlmIHdlJ3JlIGdvaW5nIHRv
IG1vZGlmeSB0aGUgcHJvdG90eXBlIGF0IGFsbC4gSXQncyBhIHJhdGhlcg0KPiA+IGRpZmZlcmVu
dCBwcm9wb3NpdGlvbiB0byB0aGUgZXhpc3Rpbmcgc3lzY2FsbCwgYW5kIG5lZWRzIHRvIGJlIHRy
ZWF0ZWQNCj4gPiBhcyBzdWNoLg0KPiANCj4gSSBkbyBub3QgdGhpbmsgaXQgaXMgd29ydGggdG8g
YWRkIGFub3RoZXIgc3lzY2FsbCBmb3IgZXh0cmEgZmRzLg0KPiBXZSBoYXZlIG9wZW4oMikgYXMg
YW4gZXhhbXBsZSBmb3IgZGlmZmVyZW50IG51bWJlcnMgb2YgYXJndW1lbnRzDQo+IGFscmVhZHku
DQoNClByb2JhYmx5IHdvcmtzICdieSBsdWNrJyBhbmQgbm8gb25lIGhhcyBhY3R1YWxseSB0aG91
Z2h0IGFib3V0IHdoeS4NClRoYXQgaW9jdGwoKSB3b3JrcyBpcyAocHJvYmFibHkpIGV2ZW4gbW9y
ZSBsdWNreS4NCg0KVGhlcmUgYXJlIEFCSSB0aGF0IHVzZSBkaWZmZXJlbnQgY2FsbGluZyBjb252
ZW50aW9ucyBmb3IgdmFyYWdzIGZ1bmN0aW9ucw0KKGVnIGFsd2F5cyBzdGFjayBhbGwgdGhlIGFy
Z3VtZW50cykuIEkgZ3Vlc3MgbGludXggZG9lc24ndCBydW4gb24gYW55IG9mIHRoZW0uDQoNCmlv
Y3RsKCkgaXMgYSBwYXJ0aWN1bGFyIHByb2JsZW0gYmVjYXVzZSB0aGUgJ2FyZycgbWlnaHQgYmUg
YW4gaW50ZWdlciBvciBhIHBvaW50ZXIuDQpGb3J0dW5hdGVseSBhbGwgdGhlIDY0Yml0IEFCSSBs
aW51eCB1c2VzIHBhc3MgdGhlIGFyZyBwYXJhbWV0ZXIgaW4gYSByZWdpc3Rlcg0KKGFuZCBkb24n
dCB1c2UgZGlmZmVyZW50IHJlZ2lzdGVycyBmb3IgcG9pbnRlciBhbmQgZGF0YSBhcmd1bWVudHMp
Lg0KDQpZb3UgY291bGQgaGF2ZSB0d28gJ2xpYmMnIGZ1bmN0aW9ucyB0aGF0IHJlZmVyIHRvIHRo
ZSBzYW1lIHN5c3RlbSBjYWxsIGVudHJ5Lg0KQ2VydGFpbmx5IHNhZmVyIHRoYW4gYSB2YXJhcmdz
IGZ1bmN0aW9uLg0KDQoJRGF2aWQNCg0K

Re: [RFC 3/3] kexec: extend kexec_file_load system call

From: Russell King - ARM Linux <linux@armlinux.org.uk>
Date: 2016-07-21 09:22:22

On Wed, Jul 20, 2016 at 11:41:35AM +0000, David Laight wrote:
From: Dave Young
quoted
I do not think it is worth to add another syscall for extra fds.
We have open(2) as an example for different numbers of arguments
already.
Probably works 'by luck' and no one has actually thought about why.
That ioctl() works is (probably) even more lucky.

There are ABI that use different calling conventions for varags functions
(eg always stack all the arguments). I guess linux doesn't run on any of them.

ioctl() is a particular problem because the 'arg' might be an integer or a pointer.
Fortunately all the 64bit ABI linux uses pass the arg parameter in a register
(and don't use different registers for pointer and data arguments).

You could have two 'libc' functions that refer to the same system call entry.
Certainly safer than a varargs function.
Don't forget that the syscall API is not a normal C function API - it's
special, because there's little point stacking arguments on the userspace
stack and then having the kernel function try and read them off the
kernelspace stack.

If an architecture does such a thing, then it needs special veneers to
handle that (reading off the userspace stack and placing them onto the
kernelspace stack, or the arch needs to define some other method of
handling the situation.)

So, really, the actual C APIs don't matter that much - what matters more
is the definition of a sane way to pass such arguments.  Given the
extensive historical nature of open() and ioctl(), it would be completely
silly not to create something which allows these calls to work.

-- 
RMK's Patch system: http://www.armlinux.org.uk/developer/patches/
FTTC broadband for 0.8mile line: currently at 9.6Mbps down 400kbps up
according to speedtest.net.

[PATCH v2 3/3] kexec: extend kexec_file_load system call

From: Thiago Jung Bauermann <hidden>
Date: 2016-07-27 00:25:10

Device tree blob must be passed to a second kernel on DTB-capable
archs, like powerpc and arm64, but the current kernel interface
lacks this support.

This patch extends kexec_file_load system call by adding an extra
argument to this syscall so that an arbitrary number of file descriptors
can be handed out from user space to the kernel.

	long sys_kexec_file_load(int kernel_fd, int initrd_fd,
				 unsigned long cmdline_len,
				 const char __user *cmdline_ptr,
				 unsigned long flags,
				 const struct kexec_fdset __user *ufdset);

If KEXEC_FILE_EXTRA_FDS is set to the "flags" argument, the "ufdset"
argument points to the following struct buffer:

	struct kexec_fdset {
		int nr_fds;
		struct kexec_file_fd fds[0];
	}

Signed-off-by: AKASHI Takahiro <redacted>
Signed-off-by: Thiago Jung Bauermann <redacted>
---

Notes:
    This is a new version of the last patch in this series which adds
    a function where each architecture can verify if the DTB is safe
    to load:
    
    int __weak arch_kexec_verify_buffer(enum kexec_file_type type,
                                        const void *buf,
                                        unsigned long size)
    {
            return -EINVAL;
    }
    
    I will then provide an implementation in my powerpc patch series
    which checks that the DTB only contains nodes and properties from a
    whitelist. arch_kexec_kernel_image_load will copy these properties
    to the device tree blob the kernel was booted with (and perform
    other changes such as setting /chosen/bootargs, of course).
    
    I made the following additional changes:
    - renamed KEXEC_FILE_TYPE_DTB to KEXEC_FILE_TYPE_PARTIAL_DTB,
    - limited max number of fds to KEXEC_SEGMENT_MAX,
    - changed to use fixed size buffer for fdset instead of allocating it,
    - changed to return -EINVAL if an unknown file type is found in fdset.

 include/linux/fs.h         |  1 +
 include/linux/kexec.h      |  7 ++--
 include/linux/syscalls.h   |  4 ++-
 include/uapi/linux/kexec.h | 22 ++++++++++++
 kernel/kexec_file.c        | 83 ++++++++++++++++++++++++++++++++++++++++++----
 5 files changed, 108 insertions(+), 9 deletions(-)
diff --git a/include/linux/fs.h b/include/linux/fs.h
index dd288148a6b1..5e0ee342b457 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -2634,6 +2634,7 @@ extern int do_pipe_flags(int *, int);
 	id(MODULE, kernel-module)		\
 	id(KEXEC_IMAGE, kexec-image)		\
 	id(KEXEC_INITRAMFS, kexec-initramfs)	\
+	id(KEXEC_PARTIAL_DTB, kexec-partial-dtb)		\
 	id(POLICY, security-policy)		\
 	id(MAX_ID, )
 
diff --git a/include/linux/kexec.h b/include/linux/kexec.h
index 554c8480dba3..b7eec336e935 100644
--- a/include/linux/kexec.h
+++ b/include/linux/kexec.h
@@ -146,7 +146,10 @@ struct kexec_file_ops {
 	kexec_verify_sig_t *verify_sig;
 #endif
 };
-#endif
+
+int __weak arch_kexec_verify_buffer(enum kexec_file_type type, const void *buf,
+				    unsigned long size);
+#endif /* CONFIG_KEXEC_FILE */
 
 struct kimage {
 	kimage_entry_t head;
@@ -277,7 +280,7 @@ extern int kexec_load_disabled;
 
 /* List of defined/legal kexec file flags */
 #define KEXEC_FILE_FLAGS	(KEXEC_FILE_UNLOAD | KEXEC_FILE_ON_CRASH | \
-				 KEXEC_FILE_NO_INITRAMFS)
+				 KEXEC_FILE_NO_INITRAMFS | KEXEC_FILE_EXTRA_FDS)
 
 #define VMCOREINFO_BYTES           (4096)
 #define VMCOREINFO_NOTE_NAME       "VMCOREINFO"
diff --git a/include/linux/syscalls.h b/include/linux/syscalls.h
index d02239022bd0..fc072bdb74e3 100644
--- a/include/linux/syscalls.h
+++ b/include/linux/syscalls.h
@@ -66,6 +66,7 @@ struct perf_event_attr;
 struct file_handle;
 struct sigaltstack;
 union bpf_attr;
+struct kexec_fdset;
 
 #include <linux/types.h>
 #include <linux/aio_abi.h>
@@ -321,7 +322,8 @@ asmlinkage long sys_kexec_load(unsigned long entry, unsigned long nr_segments,
 asmlinkage long sys_kexec_file_load(int kernel_fd, int initrd_fd,
 				    unsigned long cmdline_len,
 				    const char __user *cmdline_ptr,
-				    unsigned long flags);
+				    unsigned long flags,
+				    const struct kexec_fdset __user *ufdset);
 
 asmlinkage long sys_exit(int error_code);
 asmlinkage long sys_exit_group(int error_code);
diff --git a/include/uapi/linux/kexec.h b/include/uapi/linux/kexec.h
index 99048e501b88..32e0cefe2000 100644
--- a/include/uapi/linux/kexec.h
+++ b/include/uapi/linux/kexec.h
@@ -23,6 +23,28 @@
 #define KEXEC_FILE_UNLOAD	0x00000001
 #define KEXEC_FILE_ON_CRASH	0x00000002
 #define KEXEC_FILE_NO_INITRAMFS	0x00000004
+#define KEXEC_FILE_EXTRA_FDS	0x00000008
+
+enum kexec_file_type {
+	KEXEC_FILE_TYPE_KERNEL,
+	KEXEC_FILE_TYPE_INITRAMFS,
+
+	/*
+	 * Device Tree Blob containing just the nodes and properties that
+	 * the kexec_file_load caller wants to add or modify.
+	 */
+	KEXEC_FILE_TYPE_PARTIAL_DTB,
+};
+
+struct kexec_file_fd {
+	enum kexec_file_type type;
+	int fd;
+};
+
+struct kexec_fdset {
+	int nr_fds;
+	struct kexec_file_fd fds[0];
+};
 
 /* These values match the ELF architecture values.
  * Unless there is a good reason that should continue to be the case.
diff --git a/kernel/kexec_file.c b/kernel/kexec_file.c
index 113af2f219b9..d6803dd884e2 100644
--- a/kernel/kexec_file.c
+++ b/kernel/kexec_file.c
@@ -25,6 +25,9 @@
 #include <linux/vmalloc.h>
 #include "kexec_internal.h"
 
+#define MAX_FDSET_SIZE	(sizeof(struct kexec_fdset) + \
+				KEXEC_SEGMENT_MAX * sizeof(struct kexec_file_fd))
+
 /*
  * Declare these symbols weak so that if architecture provides a purgatory,
  * these will be overridden.
@@ -116,6 +119,22 @@ void kimage_file_post_load_cleanup(struct kimage *image)
 	image->image_loader_data = NULL;
 }
 
+/**
+ * arch_kexec_verify_buffer() - check that the given kexec file is valid
+ *
+ * Device trees in particular can contain properties that may make the kernel
+ * execute code that it wasn't supposed to (e.g., use the wrong entry point
+ * when calling firmware functions). Because of this, the kernel needs to
+ * verify that it is safe to use the device tree blob passed from userspace.
+ *
+ * Return: 0 on success, negative errno on error.
+ */
+int __weak arch_kexec_verify_buffer(enum kexec_file_type type, const void *buf,
+				    unsigned long size)
+{
+	return -EINVAL;
+}
+
 /*
  * In file mode list of segments is prepared by kernel. Copy relevant
  * data from user space, do error checking, prepare segment list
@@ -123,7 +142,8 @@ void kimage_file_post_load_cleanup(struct kimage *image)
 static int
 kimage_file_prepare_segments(struct kimage *image, int kernel_fd, int initrd_fd,
 			     const char __user *cmdline_ptr,
-			     unsigned long cmdline_len, unsigned flags)
+			     unsigned long cmdline_len, unsigned long flags,
+			     const struct kexec_fdset __user *ufdset)
 {
 	int ret = 0;
 	void *ldata;
@@ -160,6 +180,55 @@ kimage_file_prepare_segments(struct kimage *image, int kernel_fd, int initrd_fd,
 		image->initrd_buf_len = size;
 	}
 
+	if (flags & KEXEC_FILE_EXTRA_FDS) {
+		int nr_fds, i;
+		size_t fdset_size;
+		char fdset_buf[MAX_FDSET_SIZE];
+		struct kexec_fdset *fdset = (struct kexec_fdset *) fdset_buf;
+
+		ret = copy_from_user(&nr_fds, ufdset, sizeof(int));
+		if (ret) {
+			ret = -EFAULT;
+			goto out;
+		}
+
+		if (nr_fds > KEXEC_SEGMENT_MAX) {
+			ret = -E2BIG;
+			goto out;
+		}
+
+		fdset_size = sizeof(struct kexec_fdset)
+				+ nr_fds * sizeof(struct kexec_file_fd);
+
+		ret = copy_from_user(fdset, ufdset, fdset_size);
+		if (ret) {
+			ret = -EFAULT;
+			goto out;
+		}
+
+		for (i = 0; i < fdset->nr_fds; i++) {
+			if (fdset->fds[i].type == KEXEC_FILE_TYPE_PARTIAL_DTB) {
+				ret = kernel_read_file_from_fd(fdset->fds[i].fd,
+						&image->dtb_buf, &size, INT_MAX,
+						READING_KEXEC_PARTIAL_DTB);
+				if (ret)
+					goto out;
+				image->dtb_buf_len = size;
+
+				ret = arch_kexec_verify_buffer(KEXEC_FILE_TYPE_PARTIAL_DTB,
+							       image->dtb_buf,
+							       image->dtb_buf_len);
+				if (ret)
+					goto out;
+			} else {
+				pr_debug("unknown file type %d failed.\n",
+						fdset->fds[i].type);
+				ret = -EINVAL;
+				goto out;
+			}
+		}
+	}
+
 	if (cmdline_len) {
 		image->cmdline_buf = kzalloc(cmdline_len, GFP_KERNEL);
 		if (!image->cmdline_buf) {
@@ -202,7 +271,8 @@ out:
 static int
 kimage_file_alloc_init(struct kimage **rimage, int kernel_fd,
 		       int initrd_fd, const char __user *cmdline_ptr,
-		       unsigned long cmdline_len, unsigned long flags)
+		       unsigned long cmdline_len, unsigned long flags,
+		       const struct kexec_fdset __user *ufdset)
 {
 	int ret;
 	struct kimage *image;
@@ -221,7 +291,8 @@ kimage_file_alloc_init(struct kimage **rimage, int kernel_fd,
 	}
 
 	ret = kimage_file_prepare_segments(image, kernel_fd, initrd_fd,
-					   cmdline_ptr, cmdline_len, flags);
+					   cmdline_ptr, cmdline_len, flags,
+					   ufdset);
 	if (ret)
 		goto out_free_image;
 
@@ -256,9 +327,9 @@ out_free_image:
 	return ret;
 }
 
-SYSCALL_DEFINE5(kexec_file_load, int, kernel_fd, int, initrd_fd,
+SYSCALL_DEFINE6(kexec_file_load, int, kernel_fd, int, initrd_fd,
 		unsigned long, cmdline_len, const char __user *, cmdline_ptr,
-		unsigned long, flags)
+		unsigned long, flags, const struct kexec_fdset __user *, ufdset)
 {
 	int ret = 0, i;
 	struct kimage **dest_image, *image;
@@ -295,7 +366,7 @@ SYSCALL_DEFINE5(kexec_file_load, int, kernel_fd, int, initrd_fd,
 		kimage_free(xchg(&kexec_crash_image, NULL));
 
 	ret = kimage_file_alloc_init(&image, kernel_fd, initrd_fd, cmdline_ptr,
-				     cmdline_len, flags);
+				     cmdline_len, flags, ufdset);
 	if (ret)
 		goto out;
 
-- 
1.9.1

Re: [PATCH v2 3/3] kexec: extend kexec_file_load system call

From: Thiago Jung Bauermann <hidden>
Date: 2016-08-05 20:47:00

Hi,

Am Dienstag, 26 Juli 2016, 21:24:29 schrieb Thiago Jung Bauermann:
Notes:
    This is a new version of the last patch in this series which adds
    a function where each architecture can verify if the DTB is safe
    to load:

    int __weak arch_kexec_verify_buffer(enum kexec_file_type type,
                                        const void *buf,
                                        unsigned long size)
    {
            return -EINVAL;
    }

    I will then provide an implementation in my powerpc patch series
    which checks that the DTB only contains nodes and properties from a
    whitelist. arch_kexec_kernel_image_load will copy these properties
    to the device tree blob the kernel was booted with (and perform
    other changes such as setting /chosen/bootargs, of course).
Is this approach ok? If so, I'll post a patch next week adding an 
arch_kexec_verify_buffer hook for powerpc to enforce the whitelist, and also 
a new version of the patches implementing kexec_file_load for powerpc on top 
of this series.

Eric, does this address your concerns?

-- 
[]'s
Thiago Jung Bauermann
IBM Linux Technology Center
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help