Commit Graph

68 Commits

Author SHA1 Message Date
Nicolas Iooss 4599981389 Use copy_from_kernel_nofault when reading physical memory
Currently Linux driver uses `memcpy` when reading physical memory. This
causes a kernel panic on some systems when trying to access "forbidden"
physical memory. The Linux kernel provides function
`copy_from_kernel_nofault` (previously named `probe_kernel_read`) to read
memory without crashing (and this function is used by the implementation
of `/dev/mem`).

Replace `memcpy` with `copy_from_kernel_nofault`, providing a simple
wrapper for older kernels.

While at it:
- Move the allocation of a bounce buffer outside of the while loop. As
  memory is always read one page at a time, a `PAGE_SIZE` buffer is
  enough.
- Use `size_t` as the type of `sz` instead of the signed type `ssize_t`.
- Replace calls to `min_t` with `if` statements which are easier to read.
- Name the number of written bytes `written` instead of `read`, in
  `write_mem`.
- Remove stray spaces in various places.

By the way, the `write_mem` function was not updated to use
`copy_to_kernel_nofault`, as this function has no longer been exported
since Linux 5.8.

Fixes: https://github.com/chipsec/chipsec/issues/1094
Signed-off-by: Nicolas Iooss <nicolas.iooss_git@polytechnique.org>
2022-01-10 15:04:33 -08:00
brentholtsclaw e3de327631 Update version
Signed-off-by: brentholtsclaw <brent.holtsclaw@intel.com>
2021-12-02 16:18:44 -08:00
Nathaniel Mitchell da9d2a1493 Update to 1.7.2
Signed-off-by: Nathaniel Mitchell <nathaniel.p.mitchell@intel.com>
2021-10-11 16:26:41 -07:00
Nathaniel Mitchell f6dbffe100 Update to 1.7.1
Signed-off-by: Nathaniel Mitchell <nathaniel.p.mitchell@intel.com>
2021-08-31 16:35:56 -07:00
Nathaniel Mitchell 888cee2981 Updating to 1.7.0
Signed-off-by: Nathaniel Mitchell <nathaniel.p.mitchell@intel.com>
2021-07-29 16:18:27 -07:00
Sae86 85e4cde375 Update to 1.6.4
Signed-off-by: Sae86 <sara.batllori@intel.com>
2021-06-25 20:11:11 -07:00
Mathias Krause 6b974e9e29 drivers/linux: fix getting physical address of GDT
Since kernel version 4.12 the GDT as seen by SGDT is only an r/o alias
mapping located at a fixed address not backed by a dedicated kernel
memory allocation. Later kernels moved it further to the "cpu entry
area", yet another alias mapping. All, just to mitigate all too easy
kernel address leaking in the name of KASLR. Anyhow, the fact that these
virtual addresses have no 'struct page' attached prevents us from using
virt_to_phys() to resolve its physical address. A full software page
table walk is required instead.

Luckily, slow_virt_to_phys() does just that. It was introduced in kernel
v3.9 so covers all affected kernels.

This fixes github issue #608.

While at it, extend the switch block to reject invalid descriptor code
arguments to not operate on uninitialized descriptor.

Signed-off-by: Mathias Krause <minipli@grsecurity.net>
2021-06-21 16:24:21 -07:00
Mathias Krause 2ae4d4391d drivers/linux: make my_[un]xlate_dev_mem_ptr() static
Reduce the visibility of my_[un]xlate_dev_mem_ptr() by making them
static, allowing the compiler to optimize their use.

Signed-off-by: Mathias Krause <minipli@grsecurity.net>
2021-06-21 16:23:57 -07:00
Mathias Krause 9c08b4aa7e drivers/linux: simplify my_xlate_dev_mem_ptr() slightly
Simplify my_xlate_dev_mem_ptr() by doing the address masking only once.

Signed-off-by: Mathias Krause <minipli@grsecurity.net>
2021-06-21 16:23:57 -07:00
Mathias Krause a149d3a126 drivers/linux: fix memory leak in IOCTL_GET_EFIVAR ioctl
If the user provides an invalid size for the EFI variable name, we leak
the buffer used for the usercopy operation.

Fix that!

Signed-off-by: Mathias Krause <minipli@grsecurity.net>
2021-06-21 16:23:57 -07:00
Mathias Krause e3ba438a54 drivers/linux: fix ioctl() error codes
d_ioctl() makes excessive use of '-EFAULT' as an error code. This error
should be used for invalid userland addresses only, as otherwise
userland might be confused what the real error might be.

Use appropriate error codes instead:
- memory allocation failed: -ENOMEM
- unsupported feature: -EOPNOTSUPP
- invalid argument: -EINVAL

Signed-off-by: Mathias Krause <minipli@grsecurity.net>
2021-06-21 16:23:57 -07:00
Mathias Krause d7041d1985 drivers/linux: use appropriate error code on module init errors
If the symbol lookup via find_symbols() fails, init_module() returns
with -1 as an error code. This is unfortunate, however, as that value
will be passed up to userland as an error code, so should rather be a
symbolic one that can be grep'ed for (-1 would be -EPERM which doesn't
seem fitting).

Use -EOPNOTSUPP instead.

Signed-off-by: Mathias Krause <minipli@grsecurity.net>
2021-06-21 16:23:57 -07:00
Mathias Krause 6c04344b8b drivers/linux: always ensure required symbols are non-null
For kernels <= 2.6.33 we rely on module parameters to get the addresses
of 'page_is_ram' and 'phys_mem_access_prot'. However, if a user loads
the module without providing these arguments they will be left at zero
and lead to a NULL function pointer dereference on use.

Prevent that by always testing they're non-null.

Signed-off-by: Mathias Krause <minipli@grsecurity.net>
2021-06-21 16:23:57 -07:00
Mathias Krause 53c0b1773b drivers/linux: sprint_symbol() based fallback for symbol resolving
On kernels >= 5.10 that have CONFIG_KPROBES disabled the kprobes based
approach to get the address of kallsyms_lookup_name() won't work. While
it should still be the preferred option (as it gets us a precise
address), add another method that makes use of "code scanning" within
kernel/kallsyms.o to find the address with the help of sprint_symbol().

We scan backwards, starting at '&sprint_symbol' itself to find
kallsyms_lookup_name() by getting a symbolic representation of the
current address via sprint_symbol(). We lower the address with the
offset+1 sprint_symbol() provides us as long as we haven't found our
target function.

As kallsyms_lookup_name() is preceding sprint_symbol(), this search
should succeed. Still, to account for future code refactoring, limit the
search to 32kB at most to not run out of kernel text.

Signed-off-by: Mathias Krause <minipli@grsecurity.net>
2021-06-21 16:23:57 -07:00
Mathias Krause 397b1b8d8b drivers/linux: simplify and fix symbol resolving for kernels >= 5.10
There's no need to have a 'return 0' stub for the static calls. Simply
make them call an initialization function that will do the necessary
lookup and static call updates. This avoids the need for callers to do
the update themselves prior to making use of the functions, as the first
user will now do it for us implicitly.

Right now we would be doing it ahead of time for 'page_is_ram' users and
*always* for users of chipsec_lookup_name(). The latter is clearly
unintentional.

For kernels that have CONFIG_KPROBES disabled the kprobe based method to
get the address of kallsyms_lookup_name() will fail with '-ENOSYS'.
Returning this error code in chipsec_lookup_name() isn't appropriate as
users will wrongly use it as a function pointer as they expect only NULL
as a possible error value.

On top of fixing that, remove the ugly #ifdef'ery for 'page_is_ram'
users by providing a helper function that does "The Right Thing"
depending on the kernel version -- either use the static call or a
direct function pointer dereference.

Fix a few adjacent whitespace errors while touching the code. Also
reduce the visibility of the related symbols by making them static.

Last but not least lower the printk level to DEBUG when we fail to
register the kprobe. It's not important enough to warrant an "alert".
The already existing follow up handling of the failing symbol resolving
will provide meaningful messages already.

Signed-off-by: Mathias Krause <minipli@grsecurity.net>
2021-06-21 16:23:57 -07:00
Mathias Krause a25b6e85fe drivers/linux: drop _GNU_SOURCE define
While defining _GNU_SOURCE for userland code might have a legitimation,
it does nothing for kernel code. Just drop it, it's misleading.

Signed-off-by: Mathias Krause <minipli@grsecurity.net>
2021-06-21 16:23:57 -07:00
Nathaniel Mitchell b7590fa420 Updating to 1.6.3
Signed-off-by: Nathaniel Mitchell <nathaniel.p.mitchell@intel.com>
2021-06-02 19:46:34 -07:00
brentholtsclaw 3fbf973072 Fixup linux swsmi assembly
Signed-off-by: brentholtsclaw <brent.holtsclaw@intel.com>
2021-06-02 13:27:06 -07:00
Nicolas Iooss 4f6ed29c84 Simplify the Makefile used by Linux kernel module
Several improvements

* Drop the detection of EFI through kallsyms. This detection is no
  longer useful since commit 2c0c4c9fd1 ("Using CONFIG_EFI instead of
  user defined HAS_EFI (#1036)") replaced `HAS_EFI` with `CONFIG_EFI`.

* Use `...-objs-y` and `...-objs-$(CONFIG_...)` logic to choose which
  `cpu.asm` file is being built. This is something that other modules do
  in Linux kernel source.

* Introduce `quiet_cmd_...` and `cmd_...` definition in order to use the
  build system of the kernel to compile `cpu.asm` with NASM. This should
  prevent issues like the one mentioned in 2210002bab ("Fixed build
  error on latest Ubuntu") from happening again. Moreover this makes the
  custom clean command `rm -f ${asm-path}/cpu.o` no longer necessary.

* Remove variables which become unused after these changes. Now, all
  that `Makefile` needs is a kernel directory, specified with `KSRC`.

This change has been tested on a test system running Ubuntu 20.10 and on
GitHub Actions workers running Ubuntu 16.04, 18.04 and 20.04 on Linux
5.4.0-1040-azure. It has also been compile-tested on many other Linux
distributions using a work-in-progress GitHub Actions configuration
(https://github.com/fishilico/chipsec/actions/runs/661200380).
2021-05-27 16:01:25 -07:00
Nicolas Iooss 9547b609b9 Simplify parsing /proc/kallsyms in Linux kernel module
While debugging issues on Linux systems using clang CFI (Control Flow
Integrity, `CONFIG_CFI_CLANG`), it appeared to me that
`chipsec_lookup_name` could be simplified.

- Instead of using `set_fs(KERNEL_DS);` to invoke read operations,
  `kernel_read` can directly be used. This function existed since at
  least Linux 2.4.0
  (https://elixir.bootlin.com/linux/2.4.0/source/fs/exec.c#L368) so
  there should not be compatibility issues.

- Instead of allocating a 128-byte buffer with `kmalloc`, use a stack
  buffer. While at it, fix a buffer overflow issue on systems with large
  symbol names such as ones using clang's CFI: some lines were 142
  characters long.

- Instead of matching anything on the line of `/proc/kallsyms` with
  `strstr`, only do prefix-matching on the start of the symbol name.
  This involves counting spaces in the line, in order to extract the
  name as the 3rd item.

- Last but not least, show a clear error message if the symbol is not
  found in /proc/kallsyms. This helps debugging issues.

While at it, add a comment which explains why reading `/proc/kallsyms`
does not work with Linux 5.10.
2021-05-27 10:26:38 -07:00
Sae86 4a917f0d43 Update to 1.6.2
Signed-off-by: Sae86 <sara.batllori@intel.com>
2021-05-07 15:22:42 -07:00
Sae86 8d40e6ae8f Updating to 1.6.1
Signed-off-by: Sae86 <sae.batllori@intel.com>
2021-04-05 15:48:54 -07:00
Sae86 15d94d76ff Updating to 1.6.0
Removing underscore in hal/uefi_common for Python2 compatibility
Signed-off-by: Sae86 <sae.batllori@intel.com>
2021-03-31 20:44:47 -07:00
Nicolas Iooss 8502e29f65 Override KSRC instead of KERNELDIR in dkms.conf
As `drivers/linux/Makefile` uses `KSRC` to define the kernel source
directory, override this variable in DKMS configuration directly.

This fixes building the Linux kernel module with dkms on Ubuntu 20.04.
2021-03-31 11:47:08 -07:00
Nicolas Iooss c0f0592058 Update chipsec version in dkms.conf
The version in `drivers/linux/dkms.conf` needs to be the same as the one
in `chipsec/VERSION` to make LinuxHelper able to find the built driver.
2021-03-31 11:47:08 -07:00
Yves-Alexis Perez fbf45bd56c Support overriding Linux source path
It was previously possible to build Chipsec kernel module for a different Linux
kernel than the running one, and ff4a273 broke that possibility.

Bring that back just by giving a way to override the KSRC variable when calling
the Makefile.

Fix issue #1122
2021-03-25 10:16:05 -07:00
net-wayfarer ff4a27367b Fix Makefile to work with DKMS
drivers/linux/Makefile:
* Replaced KERNEL_SRC_DIR variable with KSRC.
* Added KSRC variable which should enable successful DKMS compilation,
  as opposed to bailing out with "Unable to find the Linux source tree."

This patch has been tested on Black Arch.
2021-02-24 14:47:36 -08:00
Shawn C 9a2536c611 Fix two memory leak bugs
These are caught by PaX AUTOSLAB plugin.

Signed-off-by: Shawn C <citypw@hardenedlinux.org>
2021-02-17 15:44:19 -08:00
Shawn C 84f33831ea Workaround for function pointer complaints
* Some function pointers misuse caught by PaX RAP. These workaround fix would be useful
to the vanilla kernel since the recent TigerLake support Intel CET which might have
the same complaints if the implementation can achieve the current level as PaX RAP.

* Static call is a hack to make the function pointer writable. Please keep in mind that
this hack is only for the firmware audit reason. Be cautions if you intend to do the similar
things in production.

Thanks to Spender and PaX team points out the way to fix.

Signed-off-by: Shawn C <citypw@hardenedlinux.org>
2021-02-17 15:32:24 -08:00
Shawn C 9a1cead82c Fix #1086: Linux kernel v5.10 removed the old good syscalls get_fs/set_fs
in name of security reasons. The current workaround is get the kallsyms_lookup_name()
via kprobe if the kernel >= v5.10.

Signed-off-by: Shawn C <citypw@hardenedlinux.org>
2021-02-17 15:32:24 -08:00
gibarrasch 2c0c4c9fd1 Using CONFIG_EFI instead of user defined HAS_EFI (#1036)
Co-authored-by: Nathaniel Mitchell <nathaniel.p.mitchell@intel.com>
2021-02-17 15:31:12 -08:00
Shawn C f2f1ab2d4f Expand the conditional compilation based on d02624b to support more PaX/GRsec kernel
Signed-off-by: Shawn C <citypw@hardenedlinux.org>
2021-01-27 08:16:28 -08:00
Nathaniel Mitchell 2210002bab Fixed build error on latest Ubuntu
Signed-off-by: Nathaniel Mitchell <nathaniel.p.mitchell@intel.com>
2021-01-26 16:04:06 -08:00
Shawn C d746954e64 Add the support for access the kernel symbols by reading /proc/kallsyms directly
since kallsyms_lookup_name() and kallsyms_on_each_symbol() are no longer exported:

https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=0bd476e6c67190b5eb7b6e105c8db8ff61103281

Signed-off-by: Shawn C <citypw@hardenedlinux.org>
2020-12-17 11:08:20 -08:00
gibarrasch 787e556b97 Fixed compilation in kernels >= 5.6 (#911) 2020-05-20 15:57:24 -07:00
brentholtsclaw 54860e3d45 Update IOCTL_LOAD_UCODE_PATCH in linux driver
Signed-off-by: brentholtsclaw <brent.holtsclaw@intel.com>
2020-05-01 08:23:23 -07:00
brentholtsclaw acace8ec2c Modify rdmsr/wrmsr for linux driver
Signed-off-by: brentholtsclaw <brent.holtsclaw@intel.com>
2020-05-01 08:22:28 -07:00
Cr4sh 6d491162bf linux helper HAS_EFI bugfix 2020-04-28 16:07:53 -07:00
RageLtMan d02624bbaf valid_mmap_phys_addr_range conflicts with upstream
PaX implements valid_mmap_phys_addr_range in the kernel, and the
(return 1) hack in chipsec_km.c has a name collision with it.

Add another conditional for exposing the definition predicated on
whether __HAVE_ARCH_PAX_OPEN_USERLAND is defined in the kernel
headers. If it is, dont redefine the original function.
2019-11-06 20:26:22 -08:00
Barry Rountree 8ad2ffcb53 Trivial README patch for module loading/unloading. 2019-09-03 11:09:26 -07:00
Barry Rountree bc66115d7f Explanation of Kbuild warning. 2019-09-03 11:09:14 -07:00
BrentHoltsclaw c29769d81a Fix Warning #535 2019-03-01 15:19:44 -08:00
BrentHoltsclaw 509bb0ba20 Fix Linux build error #535 2019-03-01 15:19:44 -08:00
BrentHoltsclaw e2d2442b08 Add #define to make future changes easier 2019-01-17 11:30:20 -08:00
BrentHoltsclaw 3a515e9cfb Address issue #249
changed drivers/linux/include/chipsec.h to start from 'C'
added logic to compute ioctl base based upon changes to chipsec.h above
2019-01-17 11:30:20 -08:00
BrentHoltsclaw e3c050b920 Fix 32bit linux cpuid assembly
Found that cpuid was causing a kernel error in 32bit linux
2019-01-14 09:57:16 -08:00
BrentHoltsclaw 0b685ff5fb Linux driver support for legacy BIOS and UEFI-compatibility mode
Issue #186
2019-01-14 09:54:26 -08:00
BrentHoltsclaw 10d6d1ea81 Fix for Issue #498
thanks @afoodu2
2019-01-04 11:39:14 -08:00
Erik Bjorge 02df863cdd Reverting to previous memory access method.
More debug is required before switching to this updated method for memory access.

Signed-off-by: Erik Bjorge <erik.c.bjorge@intel.com>
2018-10-01 10:32:20 -07:00
BrentHoltsclaw cf47af320c Forgot to change void * to char * and increment copyright 2018-05-21 13:12:35 -07:00