Re: [PATCH] x86: Lock down MSR writing in secure boot

2013-02-08 Thread Kees Cook
On Fri, Feb 8, 2013 at 11:42 AM, H. Peter Anvin h...@zytor.com wrote:
 On 02/08/2013 11:18 AM, Kees Cook wrote:

 No. CAP_RAWIO is for reading. Writing needs a much stronger check.

 If so, I suspect we need to do this for *all* raw I/O... but I keep
 wondering how much more sensitive writing really is than reading.

Well, I think there's a reasonable distinction between systems that
expect to strictly enforce user-space/kernel-space separation
(CAP_COMPROMISE_KERNEL) and things that are fiddling with hardware
(CAP_SYS_RAWIO).

For example, even things like /dev/mem already have this separation
(although it is stronger). You can't open /dev/mem without
CAP_SYS_RAWIO, but if you do, you still can't write to RAM in
/dev/mem. This might be one of the earliest examples of this
distinction, actually.

I think it's likely that after a while, we can convert some of these
proposed CAP_COMPROMISE_KERNEL checks in always-deny once we figure
out how to deal with those areas more safely.

-Kees

--
Kees Cook
Chrome OS Security
--
To unsubscribe from this list: send the line unsubscribe linux-efi in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH] x86: Lock down MSR writing in secure boot

2013-02-08 Thread H. Peter Anvin
Analogy fail.  The /dev/mem lockout applies to system RAM, not MMIO.

I fear COMPROMISE_KERNEL is becoming the new SYS_ADMIN, which in turn is the 
new root.  Why?  Because it is inhebtly about a usage model, not about a 
specific resource.

Kees Cook keesc...@chromium.org wrote:

On Fri, Feb 8, 2013 at 11:42 AM, H. Peter Anvin h...@zytor.com wrote:
 On 02/08/2013 11:18 AM, Kees Cook wrote:

 No. CAP_RAWIO is for reading. Writing needs a much stronger check.

 If so, I suspect we need to do this for *all* raw I/O... but I keep
 wondering how much more sensitive writing really is than reading.

Well, I think there's a reasonable distinction between systems that
expect to strictly enforce user-space/kernel-space separation
(CAP_COMPROMISE_KERNEL) and things that are fiddling with hardware
(CAP_SYS_RAWIO).

For example, even things like /dev/mem already have this separation
(although it is stronger). You can't open /dev/mem without
CAP_SYS_RAWIO, but if you do, you still can't write to RAM in
/dev/mem. This might be one of the earliest examples of this
distinction, actually.

I think it's likely that after a while, we can convert some of these
proposed CAP_COMPROMISE_KERNEL checks in always-deny once we figure
out how to deal with those areas more safely.

-Kees

--
Kees Cook
Chrome OS Security

-- 
Sent from my mobile phone. Please excuse brevity and lack of formatting.
--
To unsubscribe from this list: send the line unsubscribe linux-efi in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[RFC][PATCH 0/7] Chainsaw efivars.c

2013-02-08 Thread Matt Fleming
From: Matt Fleming matt.flem...@intel.com

drivers/firmware/efivars.c has grown pretty large and is ~2K lines.

Inside efivars.c there's currently,

  o code for handling EFI variables at the firmware-level
  o sysfs code for exposing EFI variables
  o a new EFI variable filesystem
  o a persistent storage backend

all intertwined and smushed together. This situation is only going to
get worse as new EFI support is added.

We need an interface that hides the EFI variable operations in use so
code isn't tempted to access them directly, e.g. efivarfs currently
uses '__efivars' which means it doesn't work for CONFIG_GOOGLE_SMI as
that uses different variable ops. With this interface in place, we can
start moving independent code out into separate files, allowing users
to only turn on the functionality that they want.

This patch series introduces the new efivar_entry API, and splits out
the major parts of efivars.c into new files. There's more work TODO,
but this is at least a start.

The series is also available on the 'chainsaw' branch at,

  git://git.kernel.org/pub/scm/linux/kernel/git/mfleming/linux.git

Comments welcome.

Matt Fleming (7):
  efivars: Keep a private global pointer to efivars
  efi: Move utf16_strlen() to efi.h
  efivars: New efivar_entry API
  drivers/firmware: Create a new EFI drivers directory
  efivars: Move pstore code out of efivars.c
  efi: Add generic variable operations
  efivarfs: Move to fs/efivarfs

 MAINTAINERS|   12 +-
 drivers/firmware/Kconfig   |   18 +-
 drivers/firmware/Makefile  |1 +
 drivers/firmware/efi/Kconfig   |   56 +
 drivers/firmware/efi/Makefile  |6 +
 drivers/firmware/efi/generic-ops.c |   52 +
 drivers/firmware/efi/pstore.c  |  239 +
 drivers/firmware/efi/sysfs.c   |  549 ++
 drivers/firmware/efivars.c | 2068 +---
 drivers/firmware/google/Kconfig|6 +-
 drivers/firmware/google/gsmi.c |   30 +-
 fs/Kconfig |1 +
 fs/Makefile|1 +
 fs/efivarfs/Kconfig|   12 +
 fs/efivarfs/Makefile   |7 +
 fs/efivarfs/file.c |  130 +++
 fs/efivarfs/inode.c|  179 
 fs/efivarfs/internal.h |   18 +
 fs/efivarfs/super.c|  233 
 include/linux/efi.h|  120 ++-
 20 files changed, 2120 insertions(+), 1618 deletions(-)
 create mode 100644 drivers/firmware/efi/Kconfig
 create mode 100644 drivers/firmware/efi/Makefile
 create mode 100644 drivers/firmware/efi/generic-ops.c
 create mode 100644 drivers/firmware/efi/pstore.c
 create mode 100644 drivers/firmware/efi/sysfs.c
 create mode 100644 fs/efivarfs/Kconfig
 create mode 100644 fs/efivarfs/Makefile
 create mode 100644 fs/efivarfs/file.c
 create mode 100644 fs/efivarfs/inode.c
 create mode 100644 fs/efivarfs/internal.h
 create mode 100644 fs/efivarfs/super.c

-- 
1.7.11.7

--
To unsubscribe from this list: send the line unsubscribe linux-efi in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[RFC][PATCH 1/7] efivars: Keep a private global pointer to efivars

2013-02-08 Thread Matt Fleming
From: Matt Fleming matt.flem...@intel.com

This may seem like a step backwards in terms of modularity, but we
don't need to track more than one 'struct efivars' at one time. There
is no synchronisation done between multiple EFI variable operations,
and according to Mike no one is using both the generic EFI var ops and
CONFIG_GOOGLE_SMI.

Make this explicit by returning -EBUSY if someone has already called
register_efivars().

Cc: Mike Waychison mi...@google.com
Signed-off-by: Matt Fleming matt.flem...@intel.com
---
 drivers/firmware/efivars.c | 31 ---
 1 file changed, 20 insertions(+), 11 deletions(-)

diff --git a/drivers/firmware/efivars.c b/drivers/firmware/efivars.c
index 5eafa22..24585c3 100644
--- a/drivers/firmware/efivars.c
+++ b/drivers/firmware/efivars.c
@@ -132,8 +132,11 @@ struct efivar_attribute {
ssize_t (*store)(struct efivar_entry *entry, const char *buf, size_t 
count);
 };
 
-static struct efivars __efivars;
-static struct efivar_operations ops;
+static struct efivars generic_efivars;
+static struct efivar_operations generic_ops;
+
+/* Private pointer to registered efivars */
+static struct efivars *__efivars;
 
 #define PSTORE_EFI_ATTRIBUTES \
(EFI_VARIABLE_NON_VOLATILE | \
@@ -974,7 +977,7 @@ static int efivarfs_create(struct inode *dir, struct dentry 
*dentry,
  umode_t mode, bool excl)
 {
struct inode *inode;
-   struct efivars *efivars = __efivars;
+   struct efivars *efivars = __efivars;
struct efivar_entry *var;
int namelen, i = 0, err = 0;
 
@@ -1140,7 +1143,7 @@ static int efivarfs_fill_super(struct super_block *sb, 
void *data, int silent)
struct inode *inode = NULL;
struct dentry *root;
struct efivar_entry *entry, *n;
-   struct efivars *efivars = __efivars;
+   struct efivars *efivars = __efivars;
char *name;
 
efivarfs_sb = sb;
@@ -1835,6 +1838,12 @@ int register_efivars(struct efivars *efivars,
unsigned long variable_name_size = 1024;
int error = 0;
 
+   if (__efivars) {
+   return -EBUSY;
+   }
+
+   __efivars = efivars;
+
variable_name = kzalloc(variable_name_size, GFP_KERNEL);
if (!variable_name) {
printk(KERN_ERR efivars: Memory allocation failed.\n);
@@ -1937,12 +1946,12 @@ efivars_init(void)
return -ENOMEM;
}
 
-   ops.get_variable = efi.get_variable;
-   ops.set_variable = efi.set_variable;
-   ops.get_next_variable = efi.get_next_variable;
-   ops.query_variable_info = efi.query_variable_info;
+   generic_ops.get_variable = efi.get_variable;
+   generic_ops.set_variable = efi.set_variable;
+   generic_ops.get_next_variable = efi.get_next_variable;
+   generic_ops.query_variable_info = efi.query_variable_info;
 
-   error = register_efivars(__efivars, ops, efi_kobj);
+   error = register_efivars(generic_efivars, generic_ops, efi_kobj);
if (error)
goto err_put;
 
@@ -1958,7 +1967,7 @@ efivars_init(void)
return 0;
 
 err_unregister:
-   unregister_efivars(__efivars);
+   unregister_efivars(generic_efivars);
 err_put:
kobject_put(efi_kobj);
return error;
@@ -1968,7 +1977,7 @@ static void __exit
 efivars_exit(void)
 {
if (efi_enabled(EFI_RUNTIME_SERVICES)) {
-   unregister_efivars(__efivars);
+   unregister_efivars(generic_efivars);
kobject_put(efi_kobj);
}
 }
-- 
1.7.11.7

--
To unsubscribe from this list: send the line unsubscribe linux-efi in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[RFC][PATCH 4/7] drivers/firmware: Create a new EFI drivers directory

2013-02-08 Thread Matt Fleming
From: Matt Fleming matt.flem...@intel.com

efivars.c has grown far too large and needs to be divided up.

Move the sysfs support code for EFI variables into efi/ so that it is
more self-contained. This also allows enabling the efivarfs code
without requiring that the sysfs code be enabled. Having EFI variables
accessible to userland via two different methods is just confusing,
especially given that no synchronisation is done between them.

Cc: Seiji Aguchi seiji.agu...@hds.com
Cc: Matthew Garrett mj...@srcf.ucam.org
Cc: Jeremy Kerr jeremy.k...@canonical.com
Cc: Tony Luck tony.l...@intel.com
Cc: Mike Waychison mi...@google.com
Signed-off-by: Matt Fleming matt.flem...@intel.com
---
 MAINTAINERS   |   1 +
 drivers/firmware/Kconfig  |  18 +-
 drivers/firmware/Makefile |   1 +
 drivers/firmware/efi/Kconfig  |  32 +++
 drivers/firmware/efi/Makefile |   4 +
 drivers/firmware/efi/sysfs.c  | 549 ++
 drivers/firmware/efivars.c| 530 +---
 include/linux/efi.h   |   4 +-
 8 files changed, 594 insertions(+), 545 deletions(-)
 create mode 100644 drivers/firmware/efi/Kconfig
 create mode 100644 drivers/firmware/efi/Makefile
 create mode 100644 drivers/firmware/efi/sysfs.c

diff --git a/MAINTAINERS b/MAINTAINERS
index 212c255..e37219d 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -2892,6 +2892,7 @@ F:arch/x86/boot/compressed/eboot.[ch]
 F: arch/x86/include/asm/efi.h
 F: arch/x86/platform/efi/*
 F: drivers/firmware/efivars.c
+F: drivers/firmware/efi/*
 F: include/linux/efi*.h
 
 EFIFB FRAMEBUFFER DRIVER
diff --git a/drivers/firmware/Kconfig b/drivers/firmware/Kconfig
index 9b00072..9387630 100644
--- a/drivers/firmware/Kconfig
+++ b/drivers/firmware/Kconfig
@@ -36,23 +36,6 @@ config FIRMWARE_MEMMAP
 
   See also Documentation/ABI/testing/sysfs-firmware-memmap.
 
-config EFI_VARS
-   tristate EFI Variable Support via sysfs
-   depends on EFI
-   default n
-   help
- If you say Y here, you are able to get EFI (Extensible Firmware
- Interface) variable information via sysfs.  You may read,
- write, create, and destroy EFI variables through this interface.
-
- Note that using this driver in concert with efibootmgr requires
- at least test release version 0.5.0-test3 or later, which is
- available from Matt Domsch's website located at:
- 
http://linux.dell.com/efibootmgr/testing/efibootmgr-0.5.0-test3.tar.gz
-
- Subsequent efibootmgr releases may be found at:
- http://linux.dell.com/efibootmgr
-
 config EFI_PCDP
bool Console device selection via EFI PCDP or HCDP table
depends on ACPI  EFI  IA64
@@ -146,5 +129,6 @@ config ISCSI_IBFT
  Otherwise, say N.
 
 source drivers/firmware/google/Kconfig
+source drivers/firmware/efi/Kconfig
 
 endmenu
diff --git a/drivers/firmware/Makefile b/drivers/firmware/Makefile
index 5a7e273..31bf68c 100644
--- a/drivers/firmware/Makefile
+++ b/drivers/firmware/Makefile
@@ -14,3 +14,4 @@ obj-$(CONFIG_ISCSI_IBFT)  += iscsi_ibft.o
 obj-$(CONFIG_FIRMWARE_MEMMAP)  += memmap.o
 
 obj-$(CONFIG_GOOGLE_FIRMWARE)  += google/
+obj-$(CONFIG_EFI)  += efi/
diff --git a/drivers/firmware/efi/Kconfig b/drivers/firmware/efi/Kconfig
new file mode 100644
index 000..a4f213c
--- /dev/null
+++ b/drivers/firmware/efi/Kconfig
@@ -0,0 +1,32 @@
+menu EFI (Extensible Firmware Interface) Support
+   depends on EFI
+
+config EFI_VARS
+   bool EFI Variable Support
+   depends on EFI
+   default n
+   help
+ This option enables the EFI variable support code.
+
+ This is required for all EFI variable drivers.
+
+ If unsure, say N.
+
+config EFI_VARS_SYSFS
+   tristate EFI Variable Support via sysfs
+   depends on EFI_VARS
+   default n
+   help
+ If you say Y here, you are able to get EFI (Extensible Firmware
+ Interface) variable information via sysfs.  You may read,
+ write, create, and destroy EFI variables through this interface.
+
+ Note that using this driver in concert with efibootmgr requires
+ at least test release version 0.5.0-test3 or later, which is
+ available from Matt Domsch's website located at:
+ 
http://linux.dell.com/efibootmgr/testing/efibootmgr-0.5.0-test3.tar.gz
+
+ Subsequent efibootmgr releases may be found at:
+ http://linux.dell.com/efibootmgr
+
+endmenu
diff --git a/drivers/firmware/efi/Makefile b/drivers/firmware/efi/Makefile
new file mode 100644
index 000..73ec68b
--- /dev/null
+++ b/drivers/firmware/efi/Makefile
@@ -0,0 +1,4 @@
+#
+# Makefile for linux kernel
+#
+obj-$(CONFIG_EFI_VARS_SYSFS)   += sysfs.o
diff --git a/drivers/firmware/efi/sysfs.c b/drivers/firmware/efi/sysfs.c
new file mode 100644
index 000..d066eb5
--- /dev/null
+++ b/drivers/firmware/efi/sysfs.c
@@ -0,0 +1,549 @@
+/*

[RFC][PATCH 5/7] efivars: Move pstore code out of efivars.c

2013-02-08 Thread Matt Fleming
From: Matt Fleming matt.flem...@intel.com

Move the persistence storage code to efi/pstore.c now that it uses the
new efivar API, helping us to reduce the size of efivars.c. This move
also allows us to delete the code that was previously necessary when
CONFIG_PSTORE was disabled.

Cc: Anton Vorontsov cbouatmai...@gmail.com
Cc: Colin Cross ccr...@android.com
Cc: Kees Cook keesc...@chromium.org
Cc: Matthew Garrett mj...@srcf.ucam.org
Cc: Tony Luck tony.l...@intel.com
Signed-off-by: Matt Fleming matt.flem...@intel.com
---

Folks, I haven't put a copyright notice at the top of pstore.c. Please
suggest one and I'll incorporate it.

 MAINTAINERS   |   2 +-
 drivers/firmware/efi/Kconfig  |  12 ++
 drivers/firmware/efi/Makefile |   1 +
 drivers/firmware/efi/pstore.c | 239 +++
 drivers/firmware/efivars.c| 287 --
 include/linux/efi.h   |  28 +
 6 files changed, 281 insertions(+), 288 deletions(-)
 create mode 100644 drivers/firmware/efi/pstore.c

diff --git a/MAINTAINERS b/MAINTAINERS
index e37219d..c31e5a4 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -6091,7 +6091,7 @@ S:Maintained
 T: git git://git.infradead.org/users/cbou/linux-pstore.git
 F: fs/pstore/
 F: include/linux/pstore*
-F: drivers/firmware/efivars.c
+F: drivers/firmware/efi/pstore.c
 F: drivers/acpi/apei/erst.c
 
 PTP HARDWARE CLOCK SUPPORT
diff --git a/drivers/firmware/efi/Kconfig b/drivers/firmware/efi/Kconfig
index a4f213c..f664de2 100644
--- a/drivers/firmware/efi/Kconfig
+++ b/drivers/firmware/efi/Kconfig
@@ -29,4 +29,16 @@ config EFI_VARS_SYSFS
  Subsequent efibootmgr releases may be found at:
  http://linux.dell.com/efibootmgr
 
+config EFI_VARS_PSTORE
+   tristate EFI Variable Persistent Storage
+   depends on PSTORE
+   depends on EFI_VARS_SYSFS
+   default n
+   help
+ This option enables panic and oops messages to be stored in
+ EFI variables, which allows them to be examined after the
+ machine has been rebooted.
+
+ If unsure, say N.
+
 endmenu
diff --git a/drivers/firmware/efi/Makefile b/drivers/firmware/efi/Makefile
index 73ec68b..0b8d7e0 100644
--- a/drivers/firmware/efi/Makefile
+++ b/drivers/firmware/efi/Makefile
@@ -2,3 +2,4 @@
 # Makefile for linux kernel
 #
 obj-$(CONFIG_EFI_VARS_SYSFS)   += sysfs.o
+obj-$(CONFIG_EFI_VARS_PSTORE)  += pstore.o
diff --git a/drivers/firmware/efi/pstore.c b/drivers/firmware/efi/pstore.c
new file mode 100644
index 000..8924f29
--- /dev/null
+++ b/drivers/firmware/efi/pstore.c
@@ -0,0 +1,239 @@
+#include linux/efi.h
+#include linux/module.h
+#include linux/pstore.h
+
+#define DUMP_NAME_LEN 52
+
+#define PSTORE_EFI_ATTRIBUTES \
+   (EFI_VARIABLE_NON_VOLATILE | \
+EFI_VARIABLE_BOOTSERVICE_ACCESS | \
+EFI_VARIABLE_RUNTIME_ACCESS)
+
+static int efi_pstore_open(struct pstore_info *psi)
+{
+   efivar_entry_iter_begin();
+   psi-data = NULL;
+   return 0;
+}
+
+static int efi_pstore_close(struct pstore_info *psi)
+{
+   efivar_entry_iter_end();
+   psi-data = NULL;
+   return 0;
+}
+
+struct pstore_read_data {
+   u64 *id;
+   enum pstore_type_id *type;
+   int *count;
+   struct timespec *timespec;
+   char **buf;
+};
+
+static int efi_pstore_read_func(struct efivar_entry *entry, void *data)
+{
+   struct pstore_read_data *cb_data = data;
+   char name[DUMP_NAME_LEN];
+   int i;
+   int cnt;
+   unsigned int part;
+   unsigned long time, size;
+   efi_guid_t vendor = LINUX_EFI_CRASH_GUID;
+
+   if (efi_guidcmp(entry-var.VendorGuid, vendor))
+   return 0;
+
+   for (i = 0; i  DUMP_NAME_LEN; i++)
+   name[i] = entry-var.VariableName[i];
+
+   if (sscanf(name, dump-type%u-%u-%d-%lu,
+  cb_data-type, part, cnt, time) == 4) {
+   *cb_data-id = part;
+   *cb_data-count = cnt;
+   cb_data-timespec-tv_sec = time;
+   cb_data-timespec-tv_nsec = 0;
+   } else if (sscanf(name, dump-type%u-%u-%lu,
+ cb_data-type, part, time) == 3) {
+   /*
+* Check if an old format,
+* which doesn't support holding
+* multiple logs, remains.
+*/
+   *cb_data-id = part;
+   *cb_data-count = 0;
+   cb_data-timespec-tv_sec = time;
+   cb_data-timespec-tv_nsec = 0;
+   } else
+   return 0;
+
+   efivar_entry_size(entry, size);
+   *cb_data-buf = kmalloc(size, GFP_KERNEL);
+   if (*cb_data-buf == NULL)
+   return -ENOMEM;
+   memcpy(*cb_data-buf, entry-var.Data, size);
+   return size;
+}
+
+static ssize_t efi_pstore_read(u64 *id, enum pstore_type_id *type,
+  int *count, struct timespec *timespec,
+

[RFC][PATCH 6/7] efi: Add generic variable operations

2013-02-08 Thread Matt Fleming
From: Matt Fleming matt.flem...@intel.com

Some machines have an EFI variable interface that does not conform to
the UEFI specification, e.g. CONFIG_GOOGLE_SMI. Add the necessary code
and Kconfig glue so that it's only possible to choose one set of EFI
variable operations.

Cc: Mike Waychison mi...@google.com
Signed-off-by: Matt Fleming matt.flem...@intel.com
---
 drivers/firmware/efi/Kconfig   | 12 +
 drivers/firmware/efi/Makefile  |  1 +
 drivers/firmware/efi/generic-ops.c | 52 ++
 drivers/firmware/efivars.c | 19 +-
 drivers/firmware/google/Kconfig|  6 ++---
 5 files changed, 69 insertions(+), 21 deletions(-)
 create mode 100644 drivers/firmware/efi/generic-ops.c

diff --git a/drivers/firmware/efi/Kconfig b/drivers/firmware/efi/Kconfig
index f664de2..e83ef8f 100644
--- a/drivers/firmware/efi/Kconfig
+++ b/drivers/firmware/efi/Kconfig
@@ -12,9 +12,21 @@ config EFI_VARS
 
  If unsure, say N.
 
+config EFI_VARS_GENERIC_OPS
+   bool Generic EFI Variable Operations
+   depends on EFI_VARS
+   default y
+   help
+ This option enables the use of the generic EFI variable
+ operations, those that are compliant with the UEFI
+ specification.
+
+ If unsure, say Y.
+
 config EFI_VARS_SYSFS
tristate EFI Variable Support via sysfs
depends on EFI_VARS
+   depends on EFI_VARS_GENERIC_OPS || GOOGLE_SMI
default n
help
  If you say Y here, you are able to get EFI (Extensible Firmware
diff --git a/drivers/firmware/efi/Makefile b/drivers/firmware/efi/Makefile
index 0b8d7e0..ef5066f 100644
--- a/drivers/firmware/efi/Makefile
+++ b/drivers/firmware/efi/Makefile
@@ -3,3 +3,4 @@
 #
 obj-$(CONFIG_EFI_VARS_SYSFS)   += sysfs.o
 obj-$(CONFIG_EFI_VARS_PSTORE)  += pstore.o
+obj-$(CONFIG_EFI_VARS_GENERIC_OPS) += generic-ops.o
diff --git a/drivers/firmware/efi/generic-ops.c 
b/drivers/firmware/efi/generic-ops.c
new file mode 100644
index 000..b474800
--- /dev/null
+++ b/drivers/firmware/efi/generic-ops.c
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2013 Intel Corporation matt.flem...@intel.com
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#include linux/efi.h
+#include linux/kconfig.h
+
+extern struct kobject *efi_kobj;
+
+static struct efivars generic_efivars;
+static struct efivar_operations generic_ops;
+
+int generic_register(void)
+{
+   int error;
+
+   generic_ops.get_variable = efi.get_variable;
+   generic_ops.set_variable = efi.set_variable;
+   generic_ops.get_next_variable = efi.get_next_variable;
+   generic_ops.query_variable_info = efi.query_variable_info;
+
+   error = efivars_register(generic_efivars, generic_ops);
+   if (error)
+   return error;
+
+#if defined(CONFIG_EFI_VARS_SYSFS) || defined(CONFIG_EFI_VARS_SYSFS_MODULE)
+   efivars_sysfs_init(efi_kobj);
+#endif
+   return 0;
+}
+
+void generic_unregister(void)
+{
+   efivars_unregister(generic_efivars);
+}
+
+module_init(generic_register);
+module_exit(generic_unregister);
diff --git a/drivers/firmware/efivars.c b/drivers/firmware/efivars.c
index eaaddae..c2275b8 100644
--- a/drivers/firmware/efivars.c
+++ b/drivers/firmware/efivars.c
@@ -40,9 +40,6 @@
 
 #include asm/uaccess.h
 
-static struct efivars generic_efivars;
-static struct efivar_operations generic_ops;
-
 /* Private pointer to registered efivars */
 static struct efivars *__efivars;
 
@@ -791,7 +788,7 @@ static struct attribute_group efi_subsys_attr_group = {
.attrs = efi_subsys_attrs,
 };
 
-static struct kobject *efi_kobj;
+struct kobject *efi_kobj;
 
 /**
  * efivar_init - build the initial list of EFI variables
@@ -1358,19 +1355,6 @@ efivars_init(void)
return -ENOMEM;
}
 
-   generic_ops.get_variable = efi.get_variable;
-   generic_ops.set_variable = efi.set_variable;
-   generic_ops.get_next_variable = efi.get_next_variable;
-   generic_ops.query_variable_info = efi.query_variable_info;
-
-   error = efivars_register(generic_efivars, generic_ops);
-   if (error)
-   return error;
-
-#if defined(CONFIG_EFI_VARS_SYSFS) || defined(CONFIG_EFI_VARS_SYSFS_MODULE)
-   efivars_sysfs_init(efi_kobj);

[RFC][PATCH 7/7] efivarfs: Move to fs/efivarfs

2013-02-08 Thread Matt Fleming
From: Matt Fleming matt.flem...@intel.com

Now that efivarfs uses the efivar API, move it out of efivars.c and
into fs/efivarfs where it belongs. This move allows us to turn on
other EFI varible code, like CONFIG_EFI_VARS_SYSFS without requiring
that the efivarfs code also be built, and vice versa.

Cc: Matthew Garrett matthew.garr...@nebula.com
Cc: Jeremy Kerr jeremy.k...@canonical.com
Signed-off-by: Matt Fleming matt.flem...@intel.com
---
 MAINTAINERS|   9 +
 drivers/firmware/efivars.c | 487 -
 fs/Kconfig |   1 +
 fs/Makefile|   1 +
 fs/efivarfs/Kconfig|  12 ++
 fs/efivarfs/Makefile   |   7 +
 fs/efivarfs/file.c | 130 
 fs/efivarfs/inode.c| 179 +
 fs/efivarfs/internal.h |  18 ++
 fs/efivarfs/super.c| 233 ++
 10 files changed, 590 insertions(+), 487 deletions(-)
 create mode 100644 fs/efivarfs/Kconfig
 create mode 100644 fs/efivarfs/Makefile
 create mode 100644 fs/efivarfs/file.c
 create mode 100644 fs/efivarfs/inode.c
 create mode 100644 fs/efivarfs/internal.h
 create mode 100644 fs/efivarfs/super.c

diff --git a/MAINTAINERS b/MAINTAINERS
index c31e5a4..d2b3b29 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -2895,6 +2895,15 @@ F:   drivers/firmware/efivars.c
 F: drivers/firmware/efi/*
 F: include/linux/efi*.h
 
+EFI VARIABLE FILESYSTEM
+M: Matthew Garrett matthew.garr...@nebula.com
+M: Jeremy Kerr jeremy.k...@canonical.com
+M: Matt Fleming matt.flem...@intel.com
+T: git git://git.kernel.org/pub/scm/linux/kernel/git/mfleming/efi.git
+L: linux-efi@vger.kernel.org
+S: Maintained
+F: fs/efivarfs/
+
 EFIFB FRAMEBUFFER DRIVER
 L: linux-fb...@vger.kernel.org
 M: Peter Jones pjo...@redhat.com
diff --git a/drivers/firmware/efivars.c b/drivers/firmware/efivars.c
index c2275b8..3445334 100644
--- a/drivers/firmware/efivars.c
+++ b/drivers/firmware/efivars.c
@@ -228,12 +228,6 @@ efivar_validate(struct efi_variable *var, u8 *data, 
unsigned long len)
 }
 EXPORT_SYMBOL_GPL(efivar_validate);
 
-static int efivarfs_file_open(struct inode *inode, struct file *file)
-{
-   file-private_data = inode-i_private;
-   return 0;
-}
-
 static int efi_status_to_err(efi_status_t status)
 {
int err;
@@ -267,485 +261,6 @@ static int efi_status_to_err(efi_status_t status)
return err;
 }
 
-static ssize_t efivarfs_file_write(struct file *file,
-   const char __user *userbuf, size_t count, loff_t *ppos)
-{
-   struct efivar_entry *var = file-private_data;
-   void *data;
-   u32 attributes;
-   struct inode *inode = file-f_mapping-host;
-   unsigned long datasize = count - sizeof(attributes);
-   u64 storage_size, remaining_size, max_size;
-   ssize_t bytes = 0;
-   bool set = false;
-   int err;
-
-   if (count  sizeof(attributes))
-   return -EINVAL;
-
-   if (copy_from_user(attributes, userbuf, sizeof(attributes)))
-   return -EFAULT;
-
-   if (attributes  ~(EFI_VARIABLE_MASK))
-   return -EINVAL;
-
-   /*
-* Ensure that the user can't allocate arbitrarily large
-* amounts of memory. Pick a default size of 64K if
-* QueryVariableInfo() isn't supported by the firmware.
-*/
-   err = efivar_query_info(attributes, storage_size,
-  remaining_size, max_size);
-   if (err) {
-   if (err != -ENOSYS)
-   return err;
-
-   remaining_size = 65536;
-   }
-
-   if (datasize  remaining_size)
-   return -ENOSPC;
-
-   data = kmalloc(datasize, GFP_KERNEL);
-   if (!data)
-   return -ENOMEM;
-
-   if (copy_from_user(data, userbuf + sizeof(attributes), datasize)) {
-   bytes = -EFAULT;
-   goto out;
-   }
-
-   bytes = efivar_entry_set_get_size(var, attributes, datasize,
- data, set);
-   if (!set  bytes)
-   goto out;
-
-   if (bytes == -ENOENT) {
-   drop_nlink(inode);
-   d_delete(file-f_dentry);
-   dput(file-f_dentry);
-   } else {
-   mutex_lock(inode-i_mutex);
-   i_size_write(inode, datasize + sizeof(attributes));
-   mutex_unlock(inode-i_mutex);
-   }
-
-   bytes = count;
-
-out:
-   kfree(data);
-
-   return bytes;
-}
-
-static ssize_t efivarfs_file_read(struct file *file, char __user *userbuf,
-   size_t count, loff_t *ppos)
-{
-   struct efivar_entry *var = file-private_data;
-   unsigned long datasize = 0;
-   u32 attributes;
-   void *data;
-   ssize_t size = 0;
-   int err;
-
-   err = efivar_entry_size(var, datasize);
-   if (err)
-   return err;
-
-   data = kmalloc(datasize + 

Re: [PATCH] x86: Lock down MSR writing in secure boot

2013-02-08 Thread Matthew Garrett
On Fri, 2013-02-08 at 13:02 -0800, Kees Cook wrote:

 I don't find it unreasonable to drop all caps and lose access to
 sensitive things. :) That's sort of the point, really. I think a cap
 is the best match. It seems like it should either be a cap or a
 namespace flag, but the latter seems messy.

Yeah, I think it's an expected outcome, but it means that if (say) qemu
drops privileges, qemu can no longer access PCI resources - even on
non-secure boot systems. That breaks existing userspace.


Re: [PATCH] x86: Lock down MSR writing in secure boot

2013-02-08 Thread Josh Boyer
On Fri, Feb 8, 2013 at 4:07 PM, Matthew Garrett
matthew.garr...@nebula.com wrote:
 On Fri, 2013-02-08 at 13:02 -0800, Kees Cook wrote:

 I don't find it unreasonable to drop all caps and lose access to
 sensitive things. :) That's sort of the point, really. I think a cap
 is the best match. It seems like it should either be a cap or a
 namespace flag, but the latter seems messy.

 Yeah, I think it's an expected outcome, but it means that if (say) qemu
 drops privileges, qemu can no longer access PCI resources - even on
 non-secure boot systems. That breaks existing userspace.

Right.  We've had a few reports in Fedora of things breaking on non-SB
systems because of this.  The qemu one is the latest, but the general
problem is people think dropping all caps blindly is making their apps
safer.  Then they find they can't do things they could do before the new
cap was added.  It's messy.

I've thought of treating CAP_COMPROMISE_KERNEL as a hidden cap, where
only the kernel can grant or drop it.  Peter Jones suggested it might
work to allow it to be dropped iff it is the only cap being changed.
Either way, it's a special cap and I have no idea how acceptable
something like that would be.

Really though, the main issue is that you cannot introduce new caps to
enforce finer grained access without breaking something.

josh
--
To unsubscribe from this list: send the line unsubscribe linux-efi in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


RE: [RFC][PATCH 3/7] efivars: New efivar_entry API

2013-02-08 Thread Seiji Aguchi
 Matt,

 There isn't really a formalised interface for dealing with EFI
 variables or struct efivar_entry. This has led to the efivarfs code
 directly accessing '__efivars'.

I agree with you.

I have some comment on a pstore part.

 @@ -1363,86 +1195,90 @@ static int efi_pstore_write(enum pstore_type_id type,
   for (i = 0; i  DUMP_NAME_LEN; i++)
   efi_name[i] = name[i];
 
 - efivars-ops-set_variable(efi_name, vendor, PSTORE_EFI_ATTRIBUTES,
 -size, psi-buf);
 + entry = kzalloc(sizeof(*entry), GFP_KERNEL);
 + if (!entry)
 + return -ENOMEM;

Please don't allocate memory dynamically in the efi_pstore_write() because 
efi_pstore_write() is 
called in an interrupt context like oops and panic.

Also, a whole process of query_info() + entry_set() should be protected by a 
single spin lock()
Because if efi_pstore_write() runs concurrently, a result of query_info() may 
be meaningless...

So, how about introducing query_info_nolock and entry_set_nolock()?

spin_lock()
query_info_nolock()
entry_set_nolock()
spin_unlock()

IMO, efivarfs_file_write() should be fixed as above.

As for efi_pstore_erase() and efi_pstore_read(), it will take some time to 
fully understand your change.

Seiji


--
To unsubscribe from this list: send the line unsubscribe linux-efi in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH] x86: Lock down MSR writing in secure boot

2013-02-08 Thread H. Peter Anvin
On 02/08/2013 01:02 PM, Kees Cook wrote:
 On Fri, Feb 8, 2013 at 12:34 PM, Matthew Garrett
 matthew.garr...@nebula.com wrote:
 On Fri, 2013-02-08 at 12:28 -0800, Kees Cook wrote:

 Maybe a capability isn't the right way to go, I'm not sure. I'll leave
 that to Matthew. Whatever the flag, it should be an immutable state of
 the boot. Though, it probably makes sense as a cap just so that
 non-secure-boot systems can still remove it from containers, etc.

 There was interest in ensuring that this wasn't something special-cased
 to UEFI Secure Boot, so using a capability seemed like the most
 straightforward way - it's fundamentally a restriction on what an
 otherwise privileged user is able to do, so it seemed like it fit the
 model. But I'm not wed to it in the slightest, and in fact it causes
 problems for some userspace (anything that drops all capabilities
 suddenly finds itself unable to do something that it expects to be able
 to do), so if anyone has any suggestions for a better approach…
 
 I don't find it unreasonable to drop all caps and lose access to
 sensitive things. :) That's sort of the point, really. I think a cap
 is the best match. It seems like it should either be a cap or a
 namespace flag, but the latter seems messy.
 

Caps are fine; the problem is the putting it all under one cap.  The
semi-problem here is that to preserve backwards compatibility we really
should have a way to have hierarchical caps in Linux (which we currently
don't), but it is not really an issue for this.

Also, keep in mind that there is a very simple way to deny MSR access
completely, which is to not include the driver in your kernel (and not
allow module loading, but if you can load modules you can just load a
module to muck with whatever MSR you want.)

I am still wondering if there are any legitimate uses of CAP_RAWIO 
~CAP_COMPROMISE_KERNEL that can't be used to subvert the latter.  I am
not sure there are.

-hpa

--
To unsubscribe from this list: send the line unsubscribe linux-efi in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v5 -next 0/2] make efivars/efi_pstore interrupt-safe

2013-02-08 Thread Matt Fleming
On Fri, 2013-02-08 at 22:31 +, Seiji Aguchi wrote:
 Matt,
 
 Can you please take a look at this patchset which removes
 create_sysfs_entries() from efi_pstore_write()?
 
 It has been updated in accordance with Mike's comment and fixes an
 actual bug.
 http://comments.gmane.org/gmane.linux.kernel.efi/406

OK, I'll find some time to review these.

--
To unsubscribe from this list: send the line unsubscribe linux-efi in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH] x86: Lock down MSR writing in secure boot

2013-02-08 Thread Borislav Petkov
On Fri, Feb 08, 2013 at 02:30:52PM -0800, H. Peter Anvin wrote:
 Also, keep in mind that there is a very simple way to deny MSR access
 completely, which is to not include the driver in your kernel (and not
 allow module loading, but if you can load modules you can just load a
 module to muck with whatever MSR you want.)

I was contemplating that too. What is the use case of having
msr.ko in a secure boot environment? Isn't that an all-no-tools,
you-can't-do-sh*t-except-what-you're-explicitly-allowed-to environment which
simply doesn't need to write MSRs in the first place?

-- 
Regards/Gruss,
Boris.

Sent from a fat crate under my desk. Formatting is fine.
--
--
To unsubscribe from this list: send the line unsubscribe linux-efi in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH] x86: Lock down MSR writing in secure boot

2013-02-08 Thread Andy Lutomirski
On 02/08/2013 01:14 PM, Josh Boyer wrote:
 On Fri, Feb 8, 2013 at 4:07 PM, Matthew Garrett
 matthew.garrett-05XSO3Yj/jvqt0dzr+a...@public.gmane.org wrote:
 On Fri, 2013-02-08 at 13:02 -0800, Kees Cook wrote:

 I don't find it unreasonable to drop all caps and lose access to
 sensitive things. :) That's sort of the point, really. I think a cap
 is the best match. It seems like it should either be a cap or a
 namespace flag, but the latter seems messy.

 Yeah, I think it's an expected outcome, but it means that if (say) qemu
 drops privileges, qemu can no longer access PCI resources - even on
 non-secure boot systems. That breaks existing userspace.
 
 Right.  We've had a few reports in Fedora of things breaking on non-SB
 systems because of this.  The qemu one is the latest, but the general
 problem is people think dropping all caps blindly is making their apps
 safer.  Then they find they can't do things they could do before the new
 cap was added.  It's messy.

Why not require CAP_COMPROMISE_KERNEL to open (with O_RDWR or O_WRONLY)
/dev/msr?  After all, sudo /dev/null /dev/msr will cause a privileged
write() call on the fd as long as the capability is in your bounding set.

--Andy
--
To unsubscribe from this list: send the line unsubscribe linux-efi in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


RE: [RFC][PATCH 3/7] efivars: New efivar_entry API

2013-02-08 Thread Seiji Aguchi
 
 It's probably still possible to have a CPU creating an EFI variable via the 
 sysfs files while another CPU is in the pstore write path, but I'm
 not convinced making the query_variable_info() and set_variable() atomic is 
 something that we need to worry about.


When I talked about query_variable_info() with Tony, 
Matthew commented as follows.

http://marc.info/?l=linux-kernelm=134305325801789w=2

snip
Running out of space in EFI isn't a well-tested scenario, and I wouldn't 
expect all firmware to handle it gracefully. This is made worse by EFI 1 
not providing any information about available storage.
snip

I'm just concerned that set_variable() may run in the  out of space situation 
if query_variable_info() and set_variable() are not atomic.

Seiji


 
 --
 Matt Fleming, Intel Open Source Technology Center

N�r��yb�X��ǧv�^�)޺{.n�+{�y^n�r���z���h����G���h�(�階�ݢj���m��z�ޖ���f���h���~�m�

Re: [PATCH] x86: Lock down MSR writing in secure boot

2013-02-08 Thread Matthew Garrett
On Sat, 2013-02-09 at 00:06 +0100, Borislav Petkov wrote:
 On Fri, Feb 08, 2013 at 02:30:52PM -0800, H. Peter Anvin wrote:
  Also, keep in mind that there is a very simple way to deny MSR access
  completely, which is to not include the driver in your kernel (and not
  allow module loading, but if you can load modules you can just load a
  module to muck with whatever MSR you want.)
 
 I was contemplating that too. What is the use case of having
 msr.ko in a secure boot environment? Isn't that an all-no-tools,
 you-can't-do-sh*t-except-what-you're-explicitly-allowed-to environment which
 simply doesn't need to write MSRs in the first place?

Well, sure, distributions could build every kernel twice. That seems a
little excessive, though.


Re: [PATCH] x86: Lock down MSR writing in secure boot

2013-02-08 Thread Matthew Garrett
On Fri, 2013-02-08 at 17:22 -0800, H. Peter Anvin wrote:

 You don't have to build the kernel twice to exclude a loadable module.

I guess you could just strip the signatures off any modules you don't
want to support under Secure Boot, but that breaks some other use cases.



Re: [PATCH] x86: Lock down MSR writing in secure boot

2013-02-08 Thread Kees Cook
On Fri, Feb 8, 2013 at 5:29 PM, Matthew Garrett
matthew.garr...@nebula.com wrote:
 On Fri, 2013-02-08 at 17:22 -0800, H. Peter Anvin wrote:

 You don't have to build the kernel twice to exclude a loadable module.

 I guess you could just strip the signatures off any modules you don't
 want to support under Secure Boot, but that breaks some other use cases.

Also, _reading_ MSRs from userspace arguably has utility that doesn't
compromise ring-0. So excluding the driver entirely seems like
overkill.

-Kees

--
Kees Cook
Chrome OS Security
--
To unsubscribe from this list: send the line unsubscribe linux-efi in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html