linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH] firmware_loader: load files from the mount namespace of init
@ 2020-01-17 18:36 Topi Miettinen
  2020-01-17 21:14 ` Greg Kroah-Hartman
  2020-01-18 12:32 ` kbuild test robot
  0 siblings, 2 replies; 4+ messages in thread
From: Topi Miettinen @ 2020-01-17 18:36 UTC (permalink / raw)
  To: Luis Chamberlain, Greg Kroah-Hartman, linux-kernel

[-- Attachment #1: Type: text/plain, Size: 1312 bytes --]

Hi,

I have an experimental setup where almost every possible system service 
(even early startup ones) runs in separate namespace, using a dedicated, 
minimal file system. In process of minimizing the contents of the file 
systems with regards to modules and firmware files, I noticed that in my 
system, the firmware files are loaded from three different mount 
namespaces, those of systemd-udevd, init and systemd-networkd. The logic 
of the source namespace is not very clear, it seems to depend on the 
driver, but the namespace of the current process is used.

So, this patch tries to make things a bit clearer and changes the 
loading of firmware files only from the mount namespace of init. This 
may also improve security, though I think that using firmware files as 
attack vector could be too impractical anyway.

Later, it might make sense to make the mount namespace configurable, for 
example with a new file in
/proc/sys/kernel/firmware_config/. That would allow a dedicated file 
system only for firmware files and those need not be present anywhere 
else. This configurability would make more sense if made also for kernel 
modules and /sbin/modprobe. Modules are already loaded from init 
namespace (usermodehelper uses kthreadd namespace) except when directly 
loaded by systemd-udevd.

-Topi

[-- Attachment #2: 0001-firmware_loader-load-files-from-the-mount-namespace-.patch --]
[-- Type: text/x-diff, Size: 2929 bytes --]

From 8adbf10d6b5a5e011b83fcf952e5dd4b4f2b749e Mon Sep 17 00:00:00 2001
From: Topi Miettinen <toiwoton@gmail.com>
Date: Fri, 17 Jan 2020 19:56:45 +0200
Subject: [PATCH] firmware_loader: load files from the mount namespace of init

Instead of using the mount namespace of the current process to load
firmware files, use the mount namespace of init process.

Signed-off-by: Topi Miettinen <toiwoton@gmail.com>
---
 drivers/base/firmware_loader/main.c |  6 ++++--
 fs/exec.c                           | 25 +++++++++++++++++++++++++
 include/linux/fs.h                  |  2 ++
 3 files changed, 31 insertions(+), 2 deletions(-)

diff --git a/drivers/base/firmware_loader/main.c b/drivers/base/firmware_loader/main.c
index 249add8c5e05..01f5315fae53 100644
--- a/drivers/base/firmware_loader/main.c
+++ b/drivers/base/firmware_loader/main.c
@@ -493,8 +493,10 @@ fw_get_filesystem_firmware(struct device *device, struct fw_priv *fw_priv,
 		}
 
 		fw_priv->size = 0;
-		rc = kernel_read_file_from_path(path, &buffer, &size,
-						msize, id);
+
+		/* load firmware files from the mount namespace of init */
+		rc = kernel_read_file_from_path_initns(path, &buffer,
+						       &size, msize, id);
 		if (rc) {
 			if (rc != -ENOENT)
 				dev_warn(device, "loading %s failed with error %d\n",
diff --git a/fs/exec.c b/fs/exec.c
index 74d88dab98dd..fda1364dc142 100644
--- a/fs/exec.c
+++ b/fs/exec.c
@@ -981,6 +981,31 @@ int kernel_read_file_from_path(const char *path, void **buf, loff_t *size,
 }
 EXPORT_SYMBOL_GPL(kernel_read_file_from_path);
 
+int kernel_read_file_from_path_initns(const char *path, void **buf,
+				      loff_t *size, loff_t max_size,
+				      enum kernel_read_file_id id)
+{
+	struct file *file;
+	struct path root;
+	int ret;
+
+	if (!path || !*path)
+		return -EINVAL;
+
+	task_lock(&init_task);
+	get_fs_root(init_task.fs, &root);
+	task_unlock(&init_task);
+
+	file = file_open_root(root.dentry, root.mnt, path, O_RDONLY, 0);
+	path_put(&root);
+	if (IS_ERR(file))
+		return PTR_ERR(file);
+
+	ret = kernel_read_file(file, buf, size, max_size, id);
+	fput(file);
+	return ret;
+}
+
 int kernel_read_file_from_fd(int fd, void **buf, loff_t *size, loff_t max_size,
 			     enum kernel_read_file_id id)
 {
diff --git a/include/linux/fs.h b/include/linux/fs.h
index 98e0349adb52..616a64871b2e 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -2994,6 +2994,8 @@ extern int kernel_read_file(struct file *, void **, loff_t *, loff_t,
 			    enum kernel_read_file_id);
 extern int kernel_read_file_from_path(const char *, void **, loff_t *, loff_t,
 				      enum kernel_read_file_id);
+extern int kernel_read_file_from_path_initns(const char *, void **, loff_t *, loff_t,
+					     enum kernel_read_file_id);
 extern int kernel_read_file_from_fd(int, void **, loff_t *, loff_t,
 				    enum kernel_read_file_id);
 extern ssize_t kernel_read(struct file *, void *, size_t, loff_t *);
-- 
2.24.1


^ permalink raw reply related	[flat|nested] 4+ messages in thread

* Re: [PATCH] firmware_loader: load files from the mount namespace of init
  2020-01-17 18:36 [PATCH] firmware_loader: load files from the mount namespace of init Topi Miettinen
@ 2020-01-17 21:14 ` Greg Kroah-Hartman
  2020-01-18 16:38   ` Topi Miettinen
  2020-01-18 12:32 ` kbuild test robot
  1 sibling, 1 reply; 4+ messages in thread
From: Greg Kroah-Hartman @ 2020-01-17 21:14 UTC (permalink / raw)
  To: Topi Miettinen; +Cc: Luis Chamberlain, linux-kernel

On Fri, Jan 17, 2020 at 08:36:13PM +0200, Topi Miettinen wrote:
> Hi,
> 
> I have an experimental setup where almost every possible system service
> (even early startup ones) runs in separate namespace, using a dedicated,
> minimal file system. In process of minimizing the contents of the file
> systems with regards to modules and firmware files, I noticed that in my
> system, the firmware files are loaded from three different mount namespaces,
> those of systemd-udevd, init and systemd-networkd. The logic of the source
> namespace is not very clear, it seems to depend on the driver, but the
> namespace of the current process is used.
> 
> So, this patch tries to make things a bit clearer and changes the loading of
> firmware files only from the mount namespace of init. This may also improve
> security, though I think that using firmware files as attack vector could be
> too impractical anyway.

I like this, but:

> Later, it might make sense to make the mount namespace configurable, for
> example with a new file in
> /proc/sys/kernel/firmware_config/. That would allow a dedicated file system
> only for firmware files and those need not be present anywhere else. This
> configurability would make more sense if made also for kernel modules and
> /sbin/modprobe. Modules are already loaded from init namespace
> (usermodehelper uses kthreadd namespace) except when directly loaded by
> systemd-udevd.

I think you answered your question of why firmware is loaded from the
namespace of systemd-udevd at times, it happens due to a module being
asked to be loaded which then called out and asked for firmware as part
of its probe process.

Now saying that the firmware load namespace is going to be tied always
to the modprobe namespace is problematic, as we can't guarantee that
will always happen for all bus and driver types.

So resetting this all back to the init namespace seems to make sense to
me, and odds are it will not break anything.

But, as you are adding a new firmware feature, any chance you can write
an additional test to the firmware self-tests so that we can verify that
this really is working the way you are saying it does, so we can trust
it and verify it doesn't break in the future?

thanks,

greg k-h

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [PATCH] firmware_loader: load files from the mount namespace of init
  2020-01-17 18:36 [PATCH] firmware_loader: load files from the mount namespace of init Topi Miettinen
  2020-01-17 21:14 ` Greg Kroah-Hartman
@ 2020-01-18 12:32 ` kbuild test robot
  1 sibling, 0 replies; 4+ messages in thread
From: kbuild test robot @ 2020-01-18 12:32 UTC (permalink / raw)
  To: Topi Miettinen
  Cc: kbuild-all, Luis Chamberlain, Greg Kroah-Hartman, linux-kernel

[-- Attachment #1: Type: text/plain, Size: 1432 bytes --]

Hi Topi,

Thank you for the patch! Yet something to improve:

[auto build test ERROR on driver-core/driver-core-testing]
[also build test ERROR on linux/master linus/master v5.5-rc6]
[if your patch is applied to the wrong git tree, please drop us a note to help
improve the system. BTW, we also suggest to use '--base' option to specify the
base tree in git format-patch, please see https://stackoverflow.com/a/37406982]

url:    https://github.com/0day-ci/linux/commits/Topi-Miettinen/firmware_loader-load-files-from-the-mount-namespace-of-init/20200118-100042
base:   https://git.kernel.org/pub/scm/linux/kernel/git/gregkh/driver-core.git a37f4958f7b63d2b3cd17a76151fdfc29ce1da5f
config: mips-markeins_defconfig (attached as .config)
compiler: mips-linux-gcc (GCC) 7.5.0
reproduce:
        wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # save the attached .config to linux build tree
        GCC_VERSION=7.5.0 make.cross ARCH=mips 

If you fix the issue, kindly add following tag
Reported-by: kbuild test robot <lkp@intel.com>

All errors (new ones prefixed by >>):

>> ERROR: "kernel_read_file_from_path_initns" [drivers/base/firmware_loader/firmware_class.ko] undefined!

---
0-DAY kernel test infrastructure                 Open Source Technology Center
https://lists.01.org/hyperkitty/list/kbuild-all@lists.01.org Intel Corporation

[-- Attachment #2: .config.gz --]
[-- Type: application/gzip, Size: 16302 bytes --]

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [PATCH] firmware_loader: load files from the mount namespace of init
  2020-01-17 21:14 ` Greg Kroah-Hartman
@ 2020-01-18 16:38   ` Topi Miettinen
  0 siblings, 0 replies; 4+ messages in thread
From: Topi Miettinen @ 2020-01-18 16:38 UTC (permalink / raw)
  To: Greg Kroah-Hartman; +Cc: Luis Chamberlain, linux-kernel

On 17.1.2020 23.14, Greg Kroah-Hartman wrote:
> On Fri, Jan 17, 2020 at 08:36:13PM +0200, Topi Miettinen wrote:
>> Hi,
>>
>> I have an experimental setup where almost every possible system service
>> (even early startup ones) runs in separate namespace, using a dedicated,
>> minimal file system. In process of minimizing the contents of the file
>> systems with regards to modules and firmware files, I noticed that in my
>> system, the firmware files are loaded from three different mount namespaces,
>> those of systemd-udevd, init and systemd-networkd. The logic of the source
>> namespace is not very clear, it seems to depend on the driver, but the
>> namespace of the current process is used.
>>
>> So, this patch tries to make things a bit clearer and changes the loading of
>> firmware files only from the mount namespace of init. This may also improve
>> security, though I think that using firmware files as attack vector could be
>> too impractical anyway.
> 
> I like this, but:
> 
>> Later, it might make sense to make the mount namespace configurable, for
>> example with a new file in
>> /proc/sys/kernel/firmware_config/. That would allow a dedicated file system
>> only for firmware files and those need not be present anywhere else. This
>> configurability would make more sense if made also for kernel modules and
>> /sbin/modprobe. Modules are already loaded from init namespace
>> (usermodehelper uses kthreadd namespace) except when directly loaded by
>> systemd-udevd.
> 
> I think you answered your question of why firmware is loaded from the
> namespace of systemd-udevd at times, it happens due to a module being
> asked to be loaded which then called out and asked for firmware as part
> of its probe process.

r8169 requests firmware only when opening the device, so the firmware is 
loaded from systemd-networkd namespace.

> Now saying that the firmware load namespace is going to be tied always
> to the modprobe namespace is problematic, as we can't guarantee that
> will always happen for all bus and driver types.
> 
> So resetting this all back to the init namespace seems to make sense to
> me, and odds are it will not break anything.
> 
> But, as you are adding a new firmware feature, any chance you can write
> an additional test to the firmware self-tests so that we can verify that
> this really is working the way you are saying it does, so we can trust
> it and verify it doesn't break in the future?

OK, sent v2 of the patch with the tests. They assume a writable 
/lib/firmware, is that OK? Maybe I should change that to overmount it 
temporarily with a writable tmpfs instead.

-Topi

^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2020-01-18 16:38 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-01-17 18:36 [PATCH] firmware_loader: load files from the mount namespace of init Topi Miettinen
2020-01-17 21:14 ` Greg Kroah-Hartman
2020-01-18 16:38   ` Topi Miettinen
2020-01-18 12:32 ` kbuild test robot

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).