License cleanup: add SPDX GPL-2.0 license identifier to files with no license
Many source files in the tree are missing licensing information, which
makes it harder for compliance tools to determine the correct license.
By default all files without license information are under the default
license of the kernel, which is GPL version 2.
Update the files which contain no license information with the 'GPL-2.0'
SPDX license identifier. The SPDX identifier is a legally binding
shorthand, which can be used instead of the full boiler plate text.
This patch is based on work done by Thomas Gleixner and Kate Stewart and
Philippe Ombredanne.
How this work was done:
Patches were generated and checked against linux-4.14-rc6 for a subset of
the use cases:
- file had no licensing information it it.
- file was a */uapi/* one with no licensing information in it,
- file was a */uapi/* one with existing licensing information,
Further patches will be generated in subsequent months to fix up cases
where non-standard license headers were used, and references to license
had to be inferred by heuristics based on keywords.
The analysis to determine which SPDX License Identifier to be applied to
a file was done in a spreadsheet of side by side results from of the
output of two independent scanners (ScanCode & Windriver) producing SPDX
tag:value files created by Philippe Ombredanne. Philippe prepared the
base worksheet, and did an initial spot review of a few 1000 files.
The 4.13 kernel was the starting point of the analysis with 60,537 files
assessed. Kate Stewart did a file by file comparison of the scanner
results in the spreadsheet to determine which SPDX license identifier(s)
to be applied to the file. She confirmed any determination that was not
immediately clear with lawyers working with the Linux Foundation.
Criteria used to select files for SPDX license identifier tagging was:
- Files considered eligible had to be source code files.
- Make and config files were included as candidates if they contained >5
lines of source
- File already had some variant of a license header in it (even if <5
lines).
All documentation files were explicitly excluded.
The following heuristics were used to determine which SPDX license
identifiers to apply.
- when both scanners couldn't find any license traces, file was
considered to have no license information in it, and the top level
COPYING file license applied.
For non */uapi/* files that summary was:
SPDX license identifier # files
---------------------------------------------------|-------
GPL-2.0 11139
and resulted in the first patch in this series.
If that file was a */uapi/* path one, it was "GPL-2.0 WITH
Linux-syscall-note" otherwise it was "GPL-2.0". Results of that was:
SPDX license identifier # files
---------------------------------------------------|-------
GPL-2.0 WITH Linux-syscall-note 930
and resulted in the second patch in this series.
- if a file had some form of licensing information in it, and was one
of the */uapi/* ones, it was denoted with the Linux-syscall-note if
any GPL family license was found in the file or had no licensing in
it (per prior point). Results summary:
SPDX license identifier # files
---------------------------------------------------|------
GPL-2.0 WITH Linux-syscall-note 270
GPL-2.0+ WITH Linux-syscall-note 169
((GPL-2.0 WITH Linux-syscall-note) OR BSD-2-Clause) 21
((GPL-2.0 WITH Linux-syscall-note) OR BSD-3-Clause) 17
LGPL-2.1+ WITH Linux-syscall-note 15
GPL-1.0+ WITH Linux-syscall-note 14
((GPL-2.0+ WITH Linux-syscall-note) OR BSD-3-Clause) 5
LGPL-2.0+ WITH Linux-syscall-note 4
LGPL-2.1 WITH Linux-syscall-note 3
((GPL-2.0 WITH Linux-syscall-note) OR MIT) 3
((GPL-2.0 WITH Linux-syscall-note) AND MIT) 1
and that resulted in the third patch in this series.
- when the two scanners agreed on the detected license(s), that became
the concluded license(s).
- when there was disagreement between the two scanners (one detected a
license but the other didn't, or they both detected different
licenses) a manual inspection of the file occurred.
- In most cases a manual inspection of the information in the file
resulted in a clear resolution of the license that should apply (and
which scanner probably needed to revisit its heuristics).
- When it was not immediately clear, the license identifier was
confirmed with lawyers working with the Linux Foundation.
- If there was any question as to the appropriate license identifier,
the file was flagged for further research and to be revisited later
in time.
In total, over 70 hours of logged manual review was done on the
spreadsheet to determine the SPDX license identifiers to apply to the
source files by Kate, Philippe, Thomas and, in some cases, confirmation
by lawyers working with the Linux Foundation.
Kate also obtained a third independent scan of the 4.13 code base from
FOSSology, and compared selected files where the other two scanners
disagreed against that SPDX file, to see if there was new insights. The
Windriver scanner is based on an older version of FOSSology in part, so
they are related.
Thomas did random spot checks in about 500 files from the spreadsheets
for the uapi headers and agreed with SPDX license identifier in the
files he inspected. For the non-uapi files Thomas did random spot checks
in about 15000 files.
In initial set of patches against 4.14-rc6, 3 files were found to have
copy/paste license identifier errors, and have been fixed to reflect the
correct identifier.
Additionally Philippe spent 10 hours this week doing a detailed manual
inspection and review of the 12,461 patched files from the initial patch
version early this week with:
- a full scancode scan run, collecting the matched texts, detected
license ids and scores
- reviewing anything where there was a license detected (about 500+
files) to ensure that the applied SPDX license was correct
- reviewing anything where there was no detection but the patch license
was not GPL-2.0 WITH Linux-syscall-note to ensure that the applied
SPDX license was correct
This produced a worksheet with 20 files needing minor correction. This
worksheet was then exported into 3 different .csv files for the
different types of files to be modified.
These .csv files were then reviewed by Greg. Thomas wrote a script to
parse the csv files and add the proper SPDX tag to the file, in the
format that the file expected. This script was further refined by Greg
based on the output to detect more types of files automatically and to
distinguish between header and source .c files (which need different
comment types.) Finally Greg ran the script using the .csv files to
generate the patches.
Reviewed-by: Kate Stewart <kstewart@linuxfoundation.org>
Reviewed-by: Philippe Ombredanne <pombredanne@nexb.com>
Reviewed-by: Thomas Gleixner <tglx@linutronix.de>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2017-11-01 22:07:57 +08:00
|
|
|
# SPDX-License-Identifier: GPL-2.0
|
2007-10-16 04:25:06 +08:00
|
|
|
# Backward compatibility
|
|
|
|
asflags-y += $(EXTRA_AFLAGS)
|
|
|
|
ccflags-y += $(EXTRA_CFLAGS)
|
|
|
|
cppflags-y += $(EXTRA_CPPFLAGS)
|
|
|
|
ldflags-y += $(EXTRA_LDFLAGS)
|
|
|
|
|
2017-10-09 11:49:11 +08:00
|
|
|
# flags that take effect in current and sub directories
|
2017-10-10 19:43:21 +08:00
|
|
|
KBUILD_AFLAGS += $(subdir-asflags-y)
|
|
|
|
KBUILD_CFLAGS += $(subdir-ccflags-y)
|
2021-07-03 22:42:57 +08:00
|
|
|
KBUILD_RUSTFLAGS += $(subdir-rustflags-y)
|
2009-04-19 17:04:26 +08:00
|
|
|
|
2005-04-17 06:20:36 +08:00
|
|
|
# Figure out what we need to build from the various variables
|
|
|
|
# ===========================================================================
|
|
|
|
|
|
|
|
# When an object is listed to be built compiled-in and modular,
|
|
|
|
# only build the compiled-in version
|
|
|
|
obj-m := $(filter-out $(obj-y),$(obj-m))
|
|
|
|
|
|
|
|
# Libraries are always collected in one lib file.
|
|
|
|
# Filter out objects already built-in
|
|
|
|
lib-y := $(filter-out $(obj-y), $(sort $(lib-y) $(lib-m)))
|
|
|
|
|
2020-06-01 13:56:55 +08:00
|
|
|
# Subdirectories we need to descend into
|
|
|
|
subdir-ym := $(sort $(subdir-y) $(subdir-m) \
|
|
|
|
$(patsubst %/,%, $(filter %/, $(obj-y) $(obj-m))))
|
|
|
|
|
2020-06-01 13:57:00 +08:00
|
|
|
# Handle objects in subdirs:
|
|
|
|
# - If we encounter foo/ in $(obj-y), replace it by foo/built-in.a and
|
|
|
|
# foo/modules.order
|
|
|
|
# - If we encounter foo/ in $(obj-m), replace it by foo/modules.order
|
|
|
|
#
|
|
|
|
# Generate modules.order to determine modorder. Unfortunately, we don't have
|
|
|
|
# information about ordering between -y and -m subdirs. Just put -y's first.
|
|
|
|
|
|
|
|
ifdef need-modorder
|
|
|
|
obj-m := $(patsubst %/,%/modules.order, $(filter %/, $(obj-y)) $(obj-m))
|
|
|
|
else
|
|
|
|
obj-m := $(filter-out %/, $(obj-m))
|
|
|
|
endif
|
|
|
|
|
2019-12-19 00:04:28 +08:00
|
|
|
ifdef need-builtin
|
2018-02-10 22:25:04 +08:00
|
|
|
obj-y := $(patsubst %/, %/built-in.a, $(obj-y))
|
2019-12-19 00:04:28 +08:00
|
|
|
else
|
|
|
|
obj-y := $(filter-out %/, $(obj-y))
|
|
|
|
endif
|
2005-04-17 06:20:36 +08:00
|
|
|
|
2021-05-03 02:09:55 +08:00
|
|
|
# Expand $(foo-objs) $(foo-y) etc. by replacing their individuals
|
|
|
|
suffix-search = $(strip $(foreach s, $3, $($(1:%$(strip $2)=%$s))))
|
|
|
|
# List composite targets that are constructed by combining other targets
|
|
|
|
multi-search = $(sort $(foreach m, $1, $(if $(call suffix-search, $m, $2, $3 -), $m)))
|
|
|
|
# List primitive targets that are compiled from source files
|
|
|
|
real-search = $(foreach m, $1, $(if $(call suffix-search, $m, $2, $3 -), $(call suffix-search, $m, $2, $3), $m))
|
|
|
|
|
2019-08-06 14:39:19 +08:00
|
|
|
# If $(foo-objs), $(foo-y), $(foo-m), or $(foo-) exists, foo.o is a composite object
|
2021-05-03 02:09:55 +08:00
|
|
|
multi-obj-y := $(call multi-search, $(obj-y), .o, -objs -y)
|
|
|
|
multi-obj-m := $(call multi-search, $(obj-m), .o, -objs -y -m)
|
2021-03-06 14:11:20 +08:00
|
|
|
multi-obj-ym := $(multi-obj-y) $(multi-obj-m)
|
2005-04-17 06:20:36 +08:00
|
|
|
|
kbuild: link $(real-obj-y) instead of $(obj-y) into built-in.a
In Kbuild, Makefiles can add the same object to obj-y multiple
times. So,
obj-y += foo.o
obj-y += foo.o
is fine.
However, this is not true when the same object is added multiple
times via composite objects. For example,
obj-y += foo.o bar.o
foo-objs := foo-bar-common.o foo-only.o
bar-objs := foo-bar-common.o bar-only.o
causes build error because two instances of foo-bar-common.o are
linked into the vmlinux.
Makefiles tend to invent ugly work-around, for example
- lib/zstd/Makefile
- drivers/net/ethernet/cavium/liquidio/Makefile
The technique used in Kbuild to avoid the multiple definition error
is to use $(filter $(obj-y), $^). Here, $^ lists the names of all
the prerequisites with duplicated names removed.
By replacing it with $(filter $(real-obj-y), $^) we can do likewise
for composite objects. For built-in objects, we do not need to keep
the composite object structure. We can simply expand them, and link
$(real-obj-y) to built-in.a.
Signed-off-by: Masahiro Yamada <yamada.masahiro@socionext.com>
2018-03-19 19:26:08 +08:00
|
|
|
# Replace multi-part objects by their individual parts,
|
|
|
|
# including built-in.a from subdirectories
|
2021-05-03 02:09:55 +08:00
|
|
|
real-obj-y := $(call real-search, $(obj-y), .o, -objs -y)
|
|
|
|
real-obj-m := $(call real-search, $(obj-m), .o, -objs -y -m)
|
2005-04-17 06:20:36 +08:00
|
|
|
|
2020-02-02 00:49:24 +08:00
|
|
|
always-y += $(always-m)
|
|
|
|
|
2020-08-01 20:27:18 +08:00
|
|
|
# hostprogs-always-y += foo
|
|
|
|
# ... is a shorthand for
|
|
|
|
# hostprogs += foo
|
|
|
|
# always-y += foo
|
|
|
|
hostprogs += $(hostprogs-always-y) $(hostprogs-always-m)
|
|
|
|
always-y += $(hostprogs-always-y) $(hostprogs-always-m)
|
|
|
|
|
|
|
|
# userprogs-always-y is likewise.
|
|
|
|
userprogs += $(userprogs-always-y) $(userprogs-always-m)
|
|
|
|
always-y += $(userprogs-always-y) $(userprogs-always-m)
|
|
|
|
|
2005-04-17 06:20:36 +08:00
|
|
|
# Add subdir path
|
|
|
|
|
2022-09-25 02:19:10 +08:00
|
|
|
ifneq ($(obj),.)
|
2005-04-17 06:20:36 +08:00
|
|
|
extra-y := $(addprefix $(obj)/,$(extra-y))
|
2020-02-02 00:49:24 +08:00
|
|
|
always-y := $(addprefix $(obj)/,$(always-y))
|
2005-04-17 06:20:36 +08:00
|
|
|
targets := $(addprefix $(obj)/,$(targets))
|
|
|
|
obj-m := $(addprefix $(obj)/,$(obj-m))
|
|
|
|
lib-y := $(addprefix $(obj)/,$(lib-y))
|
2018-03-19 19:26:07 +08:00
|
|
|
real-obj-y := $(addprefix $(obj)/,$(real-obj-y))
|
|
|
|
real-obj-m := $(addprefix $(obj)/,$(real-obj-m))
|
2021-03-06 14:11:20 +08:00
|
|
|
multi-obj-m := $(addprefix $(obj)/, $(multi-obj-m))
|
2005-04-17 06:20:36 +08:00
|
|
|
subdir-ym := $(addprefix $(obj)/,$(subdir-ym))
|
2022-09-25 02:19:10 +08:00
|
|
|
endif
|
2005-04-17 06:20:36 +08:00
|
|
|
|
2018-03-19 17:01:27 +08:00
|
|
|
# Finds the multi-part object the current object will be linked into.
|
2019-12-19 16:33:28 +08:00
|
|
|
# If the object belongs to two or more multi-part objects, list them all.
|
2021-03-06 14:11:20 +08:00
|
|
|
modname-multi = $(sort $(foreach m,$(multi-obj-ym),\
|
2021-05-03 02:09:57 +08:00
|
|
|
$(if $(filter $*.o, $(call suffix-search, $m, .o, -objs -y -m)),$(m:.o=))))
|
2018-03-19 17:01:27 +08:00
|
|
|
|
kbuild: replace $(if A,A,B) with $(or A,B)
$(or ...) is available since GNU Make 3.81, and useful to shorten the
code in some places.
Covert as follows:
$(if A,A,B) --> $(or A,B)
This patch also converts:
$(if A, A, B) --> $(or A, B)
Strictly speaking, the latter is not an equivalent conversion because
GNU Make keeps spaces after commas; if A is not empty, $(if A, A, B)
expands to " A", while $(or A, B) expands to "A".
Anyway, preceding spaces are not significant in the code hunks I touched.
Signed-off-by: Masahiro Yamada <masahiroy@kernel.org>
Reviewed-by: Nicolas Schier <nicolas@fjasle.eu>
2022-02-11 13:14:11 +08:00
|
|
|
__modname = $(or $(modname-multi),$(basetarget))
|
2019-12-19 16:33:28 +08:00
|
|
|
|
|
|
|
modname = $(subst $(space),:,$(__modname))
|
|
|
|
modfile = $(addprefix $(obj)/,$(__modname))
|
2018-03-19 17:01:27 +08:00
|
|
|
|
kbuild: change *FLAGS_<basetarget>.o to take the path relative to $(obj)
Kbuild provides per-file compiler flag addition/removal:
CFLAGS_<basetarget>.o
CFLAGS_REMOVE_<basetarget>.o
AFLAGS_<basetarget>.o
AFLAGS_REMOVE_<basetarget>.o
CPPFLAGS_<basetarget>.lds
HOSTCFLAGS_<basetarget>.o
HOSTCXXFLAGS_<basetarget>.o
The <basetarget> is the filename of the target with its directory and
suffix stripped.
This syntax comes into a trouble when two files with the same basename
appear in one Makefile, for example:
obj-y += foo.o
obj-y += dir/foo.o
CFLAGS_foo.o := <some-flags>
Here, the <some-flags> applies to both foo.o and dir/foo.o
The real world problem is:
scripts/kconfig/util.c
scripts/kconfig/lxdialog/util.c
Both files are compiled into scripts/kconfig/mconf, but only the
latter should be given with the ncurses flags.
It is more sensible to use the relative path to the Makefile, like this:
obj-y += foo.o
CFLAGS_foo.o := <some-flags>
obj-y += dir/foo.o
CFLAGS_dir/foo.o := <other-flags>
At first, I attempted to replace $(basetarget) with $*. The $* variable
is replaced with the stem ('%') part in a pattern rule. This works with
most of cases, but does not for explicit rules.
For example, arch/ia64/lib/Makefile reuses rule_as_o_S in its own
explicit rules, so $* will be empty, resulting in ignoring the per-file
AFLAGS.
I introduced a new variable, target-stem, which can be used also from
explicit rules.
Signed-off-by: Masahiro Yamada <yamada.masahiro@socionext.com>
Acked-by: Marc Zyngier <maz@kernel.org>
2019-08-30 12:34:01 +08:00
|
|
|
# target with $(obj)/ and its suffix stripped
|
|
|
|
target-stem = $(basename $(patsubst $(obj)/%,%,$@))
|
|
|
|
|
2005-04-17 06:20:36 +08:00
|
|
|
# These flags are needed for modversions and compiling, so we define them here
|
2017-10-09 11:49:11 +08:00
|
|
|
# $(modname_flags) defines KBUILD_MODNAME as the name of the module it will
|
2005-04-17 06:20:36 +08:00
|
|
|
# end up in (or would, if it gets compiled in)
|
2020-12-12 02:46:24 +08:00
|
|
|
name-fix-token = $(subst $(comma),_,$(subst -,_,$1))
|
|
|
|
name-fix = $(call stringify,$(call name-fix-token,$1))
|
2016-03-17 23:32:14 +08:00
|
|
|
basename_flags = -DKBUILD_BASENAME=$(call name-fix,$(basetarget))
|
2020-12-12 02:46:24 +08:00
|
|
|
modname_flags = -DKBUILD_MODNAME=$(call name-fix,$(modname)) \
|
|
|
|
-D__KBUILD_MODNAME=kmod_$(call name-fix-token,$(modname))
|
2019-12-19 16:33:28 +08:00
|
|
|
modfile_flags = -DKBUILD_MODFILE=$(call stringify,$(modfile))
|
2005-04-17 06:20:36 +08:00
|
|
|
|
2020-07-07 17:21:16 +08:00
|
|
|
_c_flags = $(filter-out $(CFLAGS_REMOVE_$(target-stem).o), \
|
|
|
|
$(filter-out $(ccflags-remove-y), \
|
|
|
|
$(KBUILD_CPPFLAGS) $(KBUILD_CFLAGS) $(ccflags-y)) \
|
|
|
|
$(CFLAGS_$(target-stem).o))
|
2021-07-03 22:42:57 +08:00
|
|
|
_rust_flags = $(filter-out $(RUSTFLAGS_REMOVE_$(target-stem).o), \
|
|
|
|
$(filter-out $(rustflags-remove-y), \
|
|
|
|
$(KBUILD_RUSTFLAGS) $(rustflags-y)) \
|
|
|
|
$(RUSTFLAGS_$(target-stem).o))
|
2020-07-07 17:21:16 +08:00
|
|
|
_a_flags = $(filter-out $(AFLAGS_REMOVE_$(target-stem).o), \
|
|
|
|
$(filter-out $(asflags-remove-y), \
|
|
|
|
$(KBUILD_CPPFLAGS) $(KBUILD_AFLAGS) $(asflags-y)) \
|
|
|
|
$(AFLAGS_$(target-stem).o))
|
kbuild: change *FLAGS_<basetarget>.o to take the path relative to $(obj)
Kbuild provides per-file compiler flag addition/removal:
CFLAGS_<basetarget>.o
CFLAGS_REMOVE_<basetarget>.o
AFLAGS_<basetarget>.o
AFLAGS_REMOVE_<basetarget>.o
CPPFLAGS_<basetarget>.lds
HOSTCFLAGS_<basetarget>.o
HOSTCXXFLAGS_<basetarget>.o
The <basetarget> is the filename of the target with its directory and
suffix stripped.
This syntax comes into a trouble when two files with the same basename
appear in one Makefile, for example:
obj-y += foo.o
obj-y += dir/foo.o
CFLAGS_foo.o := <some-flags>
Here, the <some-flags> applies to both foo.o and dir/foo.o
The real world problem is:
scripts/kconfig/util.c
scripts/kconfig/lxdialog/util.c
Both files are compiled into scripts/kconfig/mconf, but only the
latter should be given with the ncurses flags.
It is more sensible to use the relative path to the Makefile, like this:
obj-y += foo.o
CFLAGS_foo.o := <some-flags>
obj-y += dir/foo.o
CFLAGS_dir/foo.o := <other-flags>
At first, I attempted to replace $(basetarget) with $*. The $* variable
is replaced with the stem ('%') part in a pattern rule. This works with
most of cases, but does not for explicit rules.
For example, arch/ia64/lib/Makefile reuses rule_as_o_S in its own
explicit rules, so $* will be empty, resulting in ignoring the per-file
AFLAGS.
I introduced a new variable, target-stem, which can be used also from
explicit rules.
Signed-off-by: Masahiro Yamada <yamada.masahiro@socionext.com>
Acked-by: Marc Zyngier <maz@kernel.org>
2019-08-30 12:34:01 +08:00
|
|
|
_cpp_flags = $(KBUILD_CPPFLAGS) $(cppflags-y) $(CPPFLAGS_$(target-stem).lds)
|
2005-04-17 06:20:36 +08:00
|
|
|
|
2009-06-18 07:28:08 +08:00
|
|
|
#
|
|
|
|
# Enable gcov profiling flags for a file, directory or for all files depending
|
|
|
|
# on variables GCOV_PROFILE_obj.o, GCOV_PROFILE and CONFIG_GCOV_PROFILE_ALL
|
|
|
|
# (in this order)
|
|
|
|
#
|
|
|
|
ifeq ($(CONFIG_GCOV_KERNEL),y)
|
|
|
|
_c_flags += $(if $(patsubst n%,, \
|
kbuild: provide reasonable defaults for tool coverage
The objtool, sanitizers (KASAN, UBSAN, etc.), and profilers (GCOV, etc.)
are intended only for kernel space objects.
For instance, the following are not kernel objects, and therefore should
opt out of coverage:
- vDSO
- purgatory
- bootloader (arch/*/boot/)
However, to exclude these from coverage, you need to explicitly set
OBJECT_FILES_NON_STNDARD=y, KASAN_SANITIZE=n, etc.
Kbuild can achieve this without relying on such variables because
objects not directly linked to vmlinux or modules are considered
"non-standard objects".
Detecting standard objects is straightforward:
- objects added to obj-y or lib-y are linked to vmlinux
- objects added to obj-m are linked to modules
There are some exceptional Makefiles (e.g., arch/s390/boot/Makefile,
arch/xtensa/boot/lib/Makefile) that use obj-y or lib-y for non-kernel
space objects, but they can be fixed later if necessary.
Going forward, objects that are not listed in obj-y, lib-y, or obj-m
will opt out of objtool, sanitizers, and profilers by default.
You can still override the Kbuild decision by explicitly specifying
OBJECT_FILES_NON_STANDARD, KASAN_SANITIZE, etc. but most of such Make
variables can be removed.
The next commit will clean up redundant variables.
Note:
This commit changes the coverage for some objects:
- exclude .vmlinux.export.o from UBSAN, KCOV
- exclude arch/csky/kernel/vdso/vgettimeofday.o from UBSAN
- exclude arch/parisc/kernel/vdso32/vdso32.so from UBSAN
- exclude arch/parisc/kernel/vdso64/vdso64.so from UBSAN
- exclude arch/x86/um/vdso/um_vdso.o from UBSAN
- exclude drivers/misc/lkdtm/rodata.o from UBSAN, KCOV
- exclude init/version-timestamp.o from UBSAN, KCOV
- exclude lib/test_fortify/*.o from all santizers and profilers
I believe these are positive effects.
Signed-off-by: Masahiro Yamada <masahiroy@kernel.org>
Reviewed-by: Kees Cook <keescook@chromium.org>
Tested-by: Roberto Sassu <roberto.sassu@huawei.com>
2024-05-06 21:35:42 +08:00
|
|
|
$(GCOV_PROFILE_$(target-stem).o)$(GCOV_PROFILE)$(if $(is-kernel-object),$(CONFIG_GCOV_PROFILE_ALL))), \
|
2009-06-18 07:28:08 +08:00
|
|
|
$(CFLAGS_GCOV))
|
|
|
|
endif
|
|
|
|
|
kasan: add kernel address sanitizer infrastructure
Kernel Address sanitizer (KASan) is a dynamic memory error detector. It
provides fast and comprehensive solution for finding use-after-free and
out-of-bounds bugs.
KASAN uses compile-time instrumentation for checking every memory access,
therefore GCC > v4.9.2 required. v4.9.2 almost works, but has issues with
putting symbol aliases into the wrong section, which breaks kasan
instrumentation of globals.
This patch only adds infrastructure for kernel address sanitizer. It's
not available for use yet. The idea and some code was borrowed from [1].
Basic idea:
The main idea of KASAN is to use shadow memory to record whether each byte
of memory is safe to access or not, and use compiler's instrumentation to
check the shadow memory on each memory access.
Address sanitizer uses 1/8 of the memory addressable in kernel for shadow
memory and uses direct mapping with a scale and offset to translate a
memory address to its corresponding shadow address.
Here is function to translate address to corresponding shadow address:
unsigned long kasan_mem_to_shadow(unsigned long addr)
{
return (addr >> KASAN_SHADOW_SCALE_SHIFT) + KASAN_SHADOW_OFFSET;
}
where KASAN_SHADOW_SCALE_SHIFT = 3.
So for every 8 bytes there is one corresponding byte of shadow memory.
The following encoding used for each shadow byte: 0 means that all 8 bytes
of the corresponding memory region are valid for access; k (1 <= k <= 7)
means that the first k bytes are valid for access, and other (8 - k) bytes
are not; Any negative value indicates that the entire 8-bytes are
inaccessible. Different negative values used to distinguish between
different kinds of inaccessible memory (redzones, freed memory) (see
mm/kasan/kasan.h).
To be able to detect accesses to bad memory we need a special compiler.
Such compiler inserts a specific function calls (__asan_load*(addr),
__asan_store*(addr)) before each memory access of size 1, 2, 4, 8 or 16.
These functions check whether memory region is valid to access or not by
checking corresponding shadow memory. If access is not valid an error
printed.
Historical background of the address sanitizer from Dmitry Vyukov:
"We've developed the set of tools, AddressSanitizer (Asan),
ThreadSanitizer and MemorySanitizer, for user space. We actively use
them for testing inside of Google (continuous testing, fuzzing,
running prod services). To date the tools have found more than 10'000
scary bugs in Chromium, Google internal codebase and various
open-source projects (Firefox, OpenSSL, gcc, clang, ffmpeg, MySQL and
lots of others): [2] [3] [4].
The tools are part of both gcc and clang compilers.
We have not yet done massive testing under the Kernel AddressSanitizer
(it's kind of chicken and egg problem, you need it to be upstream to
start applying it extensively). To date it has found about 50 bugs.
Bugs that we've found in upstream kernel are listed in [5].
We've also found ~20 bugs in out internal version of the kernel. Also
people from Samsung and Oracle have found some.
[...]
As others noted, the main feature of AddressSanitizer is its
performance due to inline compiler instrumentation and simple linear
shadow memory. User-space Asan has ~2x slowdown on computational
programs and ~2x memory consumption increase. Taking into account that
kernel usually consumes only small fraction of CPU and memory when
running real user-space programs, I would expect that kernel Asan will
have ~10-30% slowdown and similar memory consumption increase (when we
finish all tuning).
I agree that Asan can well replace kmemcheck. We have plans to start
working on Kernel MemorySanitizer that finds uses of unitialized
memory. Asan+Msan will provide feature-parity with kmemcheck. As
others noted, Asan will unlikely replace debug slab and pagealloc that
can be enabled at runtime. Asan uses compiler instrumentation, so even
if it is disabled, it still incurs visible overheads.
Asan technology is easily portable to other architectures. Compiler
instrumentation is fully portable. Runtime has some arch-dependent
parts like shadow mapping and atomic operation interception. They are
relatively easy to port."
Comparison with other debugging features:
========================================
KMEMCHECK:
- KASan can do almost everything that kmemcheck can. KASan uses
compile-time instrumentation, which makes it significantly faster than
kmemcheck. The only advantage of kmemcheck over KASan is detection of
uninitialized memory reads.
Some brief performance testing showed that kasan could be
x500-x600 times faster than kmemcheck:
$ netperf -l 30
MIGRATED TCP STREAM TEST from 0.0.0.0 (0.0.0.0) port 0 AF_INET to localhost (127.0.0.1) port 0 AF_INET
Recv Send Send
Socket Socket Message Elapsed
Size Size Size Time Throughput
bytes bytes bytes secs. 10^6bits/sec
no debug: 87380 16384 16384 30.00 41624.72
kasan inline: 87380 16384 16384 30.00 12870.54
kasan outline: 87380 16384 16384 30.00 10586.39
kmemcheck: 87380 16384 16384 30.03 20.23
- Also kmemcheck couldn't work on several CPUs. It always sets
number of CPUs to 1. KASan doesn't have such limitation.
DEBUG_PAGEALLOC:
- KASan is slower than DEBUG_PAGEALLOC, but KASan works on sub-page
granularity level, so it able to find more bugs.
SLUB_DEBUG (poisoning, redzones):
- SLUB_DEBUG has lower overhead than KASan.
- SLUB_DEBUG in most cases are not able to detect bad reads,
KASan able to detect both reads and writes.
- In some cases (e.g. redzone overwritten) SLUB_DEBUG detect
bugs only on allocation/freeing of object. KASan catch
bugs right before it will happen, so we always know exact
place of first bad read/write.
[1] https://code.google.com/p/address-sanitizer/wiki/AddressSanitizerForKernel
[2] https://code.google.com/p/address-sanitizer/wiki/FoundBugs
[3] https://code.google.com/p/thread-sanitizer/wiki/FoundBugs
[4] https://code.google.com/p/memory-sanitizer/wiki/FoundBugs
[5] https://code.google.com/p/address-sanitizer/wiki/AddressSanitizerForKernel#Trophies
Based on work by Andrey Konovalov.
Signed-off-by: Andrey Ryabinin <a.ryabinin@samsung.com>
Acked-by: Michal Marek <mmarek@suse.cz>
Signed-off-by: Andrey Konovalov <adech.fo@gmail.com>
Cc: Dmitry Vyukov <dvyukov@google.com>
Cc: Konstantin Serebryany <kcc@google.com>
Cc: Dmitry Chernenkov <dmitryc@google.com>
Cc: Yuri Gribov <tetra2005@gmail.com>
Cc: Konstantin Khlebnikov <koct9i@gmail.com>
Cc: Sasha Levin <sasha.levin@oracle.com>
Cc: Christoph Lameter <cl@linux.com>
Cc: Joonsoo Kim <iamjoonsoo.kim@lge.com>
Cc: Dave Hansen <dave.hansen@intel.com>
Cc: Andi Kleen <andi@firstfloor.org>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: "H. Peter Anvin" <hpa@zytor.com>
Cc: Christoph Lameter <cl@linux.com>
Cc: Pekka Enberg <penberg@kernel.org>
Cc: David Rientjes <rientjes@google.com>
Cc: Stephen Rothwell <sfr@canb.auug.org.au>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
2015-02-14 06:39:17 +08:00
|
|
|
#
|
|
|
|
# Enable address sanitizer flags for kernel except some files or directories
|
|
|
|
# we don't want to check (depends on variables KASAN_SANITIZE_obj.o, KASAN_SANITIZE)
|
|
|
|
#
|
|
|
|
ifeq ($(CONFIG_KASAN),y)
|
2020-12-23 04:02:06 +08:00
|
|
|
ifneq ($(CONFIG_KASAN_HW_TAGS),y)
|
kasan: add kernel address sanitizer infrastructure
Kernel Address sanitizer (KASan) is a dynamic memory error detector. It
provides fast and comprehensive solution for finding use-after-free and
out-of-bounds bugs.
KASAN uses compile-time instrumentation for checking every memory access,
therefore GCC > v4.9.2 required. v4.9.2 almost works, but has issues with
putting symbol aliases into the wrong section, which breaks kasan
instrumentation of globals.
This patch only adds infrastructure for kernel address sanitizer. It's
not available for use yet. The idea and some code was borrowed from [1].
Basic idea:
The main idea of KASAN is to use shadow memory to record whether each byte
of memory is safe to access or not, and use compiler's instrumentation to
check the shadow memory on each memory access.
Address sanitizer uses 1/8 of the memory addressable in kernel for shadow
memory and uses direct mapping with a scale and offset to translate a
memory address to its corresponding shadow address.
Here is function to translate address to corresponding shadow address:
unsigned long kasan_mem_to_shadow(unsigned long addr)
{
return (addr >> KASAN_SHADOW_SCALE_SHIFT) + KASAN_SHADOW_OFFSET;
}
where KASAN_SHADOW_SCALE_SHIFT = 3.
So for every 8 bytes there is one corresponding byte of shadow memory.
The following encoding used for each shadow byte: 0 means that all 8 bytes
of the corresponding memory region are valid for access; k (1 <= k <= 7)
means that the first k bytes are valid for access, and other (8 - k) bytes
are not; Any negative value indicates that the entire 8-bytes are
inaccessible. Different negative values used to distinguish between
different kinds of inaccessible memory (redzones, freed memory) (see
mm/kasan/kasan.h).
To be able to detect accesses to bad memory we need a special compiler.
Such compiler inserts a specific function calls (__asan_load*(addr),
__asan_store*(addr)) before each memory access of size 1, 2, 4, 8 or 16.
These functions check whether memory region is valid to access or not by
checking corresponding shadow memory. If access is not valid an error
printed.
Historical background of the address sanitizer from Dmitry Vyukov:
"We've developed the set of tools, AddressSanitizer (Asan),
ThreadSanitizer and MemorySanitizer, for user space. We actively use
them for testing inside of Google (continuous testing, fuzzing,
running prod services). To date the tools have found more than 10'000
scary bugs in Chromium, Google internal codebase and various
open-source projects (Firefox, OpenSSL, gcc, clang, ffmpeg, MySQL and
lots of others): [2] [3] [4].
The tools are part of both gcc and clang compilers.
We have not yet done massive testing under the Kernel AddressSanitizer
(it's kind of chicken and egg problem, you need it to be upstream to
start applying it extensively). To date it has found about 50 bugs.
Bugs that we've found in upstream kernel are listed in [5].
We've also found ~20 bugs in out internal version of the kernel. Also
people from Samsung and Oracle have found some.
[...]
As others noted, the main feature of AddressSanitizer is its
performance due to inline compiler instrumentation and simple linear
shadow memory. User-space Asan has ~2x slowdown on computational
programs and ~2x memory consumption increase. Taking into account that
kernel usually consumes only small fraction of CPU and memory when
running real user-space programs, I would expect that kernel Asan will
have ~10-30% slowdown and similar memory consumption increase (when we
finish all tuning).
I agree that Asan can well replace kmemcheck. We have plans to start
working on Kernel MemorySanitizer that finds uses of unitialized
memory. Asan+Msan will provide feature-parity with kmemcheck. As
others noted, Asan will unlikely replace debug slab and pagealloc that
can be enabled at runtime. Asan uses compiler instrumentation, so even
if it is disabled, it still incurs visible overheads.
Asan technology is easily portable to other architectures. Compiler
instrumentation is fully portable. Runtime has some arch-dependent
parts like shadow mapping and atomic operation interception. They are
relatively easy to port."
Comparison with other debugging features:
========================================
KMEMCHECK:
- KASan can do almost everything that kmemcheck can. KASan uses
compile-time instrumentation, which makes it significantly faster than
kmemcheck. The only advantage of kmemcheck over KASan is detection of
uninitialized memory reads.
Some brief performance testing showed that kasan could be
x500-x600 times faster than kmemcheck:
$ netperf -l 30
MIGRATED TCP STREAM TEST from 0.0.0.0 (0.0.0.0) port 0 AF_INET to localhost (127.0.0.1) port 0 AF_INET
Recv Send Send
Socket Socket Message Elapsed
Size Size Size Time Throughput
bytes bytes bytes secs. 10^6bits/sec
no debug: 87380 16384 16384 30.00 41624.72
kasan inline: 87380 16384 16384 30.00 12870.54
kasan outline: 87380 16384 16384 30.00 10586.39
kmemcheck: 87380 16384 16384 30.03 20.23
- Also kmemcheck couldn't work on several CPUs. It always sets
number of CPUs to 1. KASan doesn't have such limitation.
DEBUG_PAGEALLOC:
- KASan is slower than DEBUG_PAGEALLOC, but KASan works on sub-page
granularity level, so it able to find more bugs.
SLUB_DEBUG (poisoning, redzones):
- SLUB_DEBUG has lower overhead than KASan.
- SLUB_DEBUG in most cases are not able to detect bad reads,
KASan able to detect both reads and writes.
- In some cases (e.g. redzone overwritten) SLUB_DEBUG detect
bugs only on allocation/freeing of object. KASan catch
bugs right before it will happen, so we always know exact
place of first bad read/write.
[1] https://code.google.com/p/address-sanitizer/wiki/AddressSanitizerForKernel
[2] https://code.google.com/p/address-sanitizer/wiki/FoundBugs
[3] https://code.google.com/p/thread-sanitizer/wiki/FoundBugs
[4] https://code.google.com/p/memory-sanitizer/wiki/FoundBugs
[5] https://code.google.com/p/address-sanitizer/wiki/AddressSanitizerForKernel#Trophies
Based on work by Andrey Konovalov.
Signed-off-by: Andrey Ryabinin <a.ryabinin@samsung.com>
Acked-by: Michal Marek <mmarek@suse.cz>
Signed-off-by: Andrey Konovalov <adech.fo@gmail.com>
Cc: Dmitry Vyukov <dvyukov@google.com>
Cc: Konstantin Serebryany <kcc@google.com>
Cc: Dmitry Chernenkov <dmitryc@google.com>
Cc: Yuri Gribov <tetra2005@gmail.com>
Cc: Konstantin Khlebnikov <koct9i@gmail.com>
Cc: Sasha Levin <sasha.levin@oracle.com>
Cc: Christoph Lameter <cl@linux.com>
Cc: Joonsoo Kim <iamjoonsoo.kim@lge.com>
Cc: Dave Hansen <dave.hansen@intel.com>
Cc: Andi Kleen <andi@firstfloor.org>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: "H. Peter Anvin" <hpa@zytor.com>
Cc: Christoph Lameter <cl@linux.com>
Cc: Pekka Enberg <penberg@kernel.org>
Cc: David Rientjes <rientjes@google.com>
Cc: Stephen Rothwell <sfr@canb.auug.org.au>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
2015-02-14 06:39:17 +08:00
|
|
|
_c_flags += $(if $(patsubst n%,, \
|
kbuild: provide reasonable defaults for tool coverage
The objtool, sanitizers (KASAN, UBSAN, etc.), and profilers (GCOV, etc.)
are intended only for kernel space objects.
For instance, the following are not kernel objects, and therefore should
opt out of coverage:
- vDSO
- purgatory
- bootloader (arch/*/boot/)
However, to exclude these from coverage, you need to explicitly set
OBJECT_FILES_NON_STNDARD=y, KASAN_SANITIZE=n, etc.
Kbuild can achieve this without relying on such variables because
objects not directly linked to vmlinux or modules are considered
"non-standard objects".
Detecting standard objects is straightforward:
- objects added to obj-y or lib-y are linked to vmlinux
- objects added to obj-m are linked to modules
There are some exceptional Makefiles (e.g., arch/s390/boot/Makefile,
arch/xtensa/boot/lib/Makefile) that use obj-y or lib-y for non-kernel
space objects, but they can be fixed later if necessary.
Going forward, objects that are not listed in obj-y, lib-y, or obj-m
will opt out of objtool, sanitizers, and profilers by default.
You can still override the Kbuild decision by explicitly specifying
OBJECT_FILES_NON_STANDARD, KASAN_SANITIZE, etc. but most of such Make
variables can be removed.
The next commit will clean up redundant variables.
Note:
This commit changes the coverage for some objects:
- exclude .vmlinux.export.o from UBSAN, KCOV
- exclude arch/csky/kernel/vdso/vgettimeofday.o from UBSAN
- exclude arch/parisc/kernel/vdso32/vdso32.so from UBSAN
- exclude arch/parisc/kernel/vdso64/vdso64.so from UBSAN
- exclude arch/x86/um/vdso/um_vdso.o from UBSAN
- exclude drivers/misc/lkdtm/rodata.o from UBSAN, KCOV
- exclude init/version-timestamp.o from UBSAN, KCOV
- exclude lib/test_fortify/*.o from all santizers and profilers
I believe these are positive effects.
Signed-off-by: Masahiro Yamada <masahiroy@kernel.org>
Reviewed-by: Kees Cook <keescook@chromium.org>
Tested-by: Roberto Sassu <roberto.sassu@huawei.com>
2024-05-06 21:35:42 +08:00
|
|
|
$(KASAN_SANITIZE_$(target-stem).o)$(KASAN_SANITIZE)$(is-kernel-object)), \
|
2018-02-07 07:36:00 +08:00
|
|
|
$(CFLAGS_KASAN), $(CFLAGS_KASAN_NOSANITIZE))
|
2024-08-21 03:48:58 +08:00
|
|
|
_rust_flags += $(if $(patsubst n%,, \
|
|
|
|
$(KASAN_SANITIZE_$(target-stem).o)$(KASAN_SANITIZE)$(is-kernel-object)), \
|
|
|
|
$(RUSTFLAGS_KASAN))
|
kasan: add kernel address sanitizer infrastructure
Kernel Address sanitizer (KASan) is a dynamic memory error detector. It
provides fast and comprehensive solution for finding use-after-free and
out-of-bounds bugs.
KASAN uses compile-time instrumentation for checking every memory access,
therefore GCC > v4.9.2 required. v4.9.2 almost works, but has issues with
putting symbol aliases into the wrong section, which breaks kasan
instrumentation of globals.
This patch only adds infrastructure for kernel address sanitizer. It's
not available for use yet. The idea and some code was borrowed from [1].
Basic idea:
The main idea of KASAN is to use shadow memory to record whether each byte
of memory is safe to access or not, and use compiler's instrumentation to
check the shadow memory on each memory access.
Address sanitizer uses 1/8 of the memory addressable in kernel for shadow
memory and uses direct mapping with a scale and offset to translate a
memory address to its corresponding shadow address.
Here is function to translate address to corresponding shadow address:
unsigned long kasan_mem_to_shadow(unsigned long addr)
{
return (addr >> KASAN_SHADOW_SCALE_SHIFT) + KASAN_SHADOW_OFFSET;
}
where KASAN_SHADOW_SCALE_SHIFT = 3.
So for every 8 bytes there is one corresponding byte of shadow memory.
The following encoding used for each shadow byte: 0 means that all 8 bytes
of the corresponding memory region are valid for access; k (1 <= k <= 7)
means that the first k bytes are valid for access, and other (8 - k) bytes
are not; Any negative value indicates that the entire 8-bytes are
inaccessible. Different negative values used to distinguish between
different kinds of inaccessible memory (redzones, freed memory) (see
mm/kasan/kasan.h).
To be able to detect accesses to bad memory we need a special compiler.
Such compiler inserts a specific function calls (__asan_load*(addr),
__asan_store*(addr)) before each memory access of size 1, 2, 4, 8 or 16.
These functions check whether memory region is valid to access or not by
checking corresponding shadow memory. If access is not valid an error
printed.
Historical background of the address sanitizer from Dmitry Vyukov:
"We've developed the set of tools, AddressSanitizer (Asan),
ThreadSanitizer and MemorySanitizer, for user space. We actively use
them for testing inside of Google (continuous testing, fuzzing,
running prod services). To date the tools have found more than 10'000
scary bugs in Chromium, Google internal codebase and various
open-source projects (Firefox, OpenSSL, gcc, clang, ffmpeg, MySQL and
lots of others): [2] [3] [4].
The tools are part of both gcc and clang compilers.
We have not yet done massive testing under the Kernel AddressSanitizer
(it's kind of chicken and egg problem, you need it to be upstream to
start applying it extensively). To date it has found about 50 bugs.
Bugs that we've found in upstream kernel are listed in [5].
We've also found ~20 bugs in out internal version of the kernel. Also
people from Samsung and Oracle have found some.
[...]
As others noted, the main feature of AddressSanitizer is its
performance due to inline compiler instrumentation and simple linear
shadow memory. User-space Asan has ~2x slowdown on computational
programs and ~2x memory consumption increase. Taking into account that
kernel usually consumes only small fraction of CPU and memory when
running real user-space programs, I would expect that kernel Asan will
have ~10-30% slowdown and similar memory consumption increase (when we
finish all tuning).
I agree that Asan can well replace kmemcheck. We have plans to start
working on Kernel MemorySanitizer that finds uses of unitialized
memory. Asan+Msan will provide feature-parity with kmemcheck. As
others noted, Asan will unlikely replace debug slab and pagealloc that
can be enabled at runtime. Asan uses compiler instrumentation, so even
if it is disabled, it still incurs visible overheads.
Asan technology is easily portable to other architectures. Compiler
instrumentation is fully portable. Runtime has some arch-dependent
parts like shadow mapping and atomic operation interception. They are
relatively easy to port."
Comparison with other debugging features:
========================================
KMEMCHECK:
- KASan can do almost everything that kmemcheck can. KASan uses
compile-time instrumentation, which makes it significantly faster than
kmemcheck. The only advantage of kmemcheck over KASan is detection of
uninitialized memory reads.
Some brief performance testing showed that kasan could be
x500-x600 times faster than kmemcheck:
$ netperf -l 30
MIGRATED TCP STREAM TEST from 0.0.0.0 (0.0.0.0) port 0 AF_INET to localhost (127.0.0.1) port 0 AF_INET
Recv Send Send
Socket Socket Message Elapsed
Size Size Size Time Throughput
bytes bytes bytes secs. 10^6bits/sec
no debug: 87380 16384 16384 30.00 41624.72
kasan inline: 87380 16384 16384 30.00 12870.54
kasan outline: 87380 16384 16384 30.00 10586.39
kmemcheck: 87380 16384 16384 30.03 20.23
- Also kmemcheck couldn't work on several CPUs. It always sets
number of CPUs to 1. KASan doesn't have such limitation.
DEBUG_PAGEALLOC:
- KASan is slower than DEBUG_PAGEALLOC, but KASan works on sub-page
granularity level, so it able to find more bugs.
SLUB_DEBUG (poisoning, redzones):
- SLUB_DEBUG has lower overhead than KASan.
- SLUB_DEBUG in most cases are not able to detect bad reads,
KASan able to detect both reads and writes.
- In some cases (e.g. redzone overwritten) SLUB_DEBUG detect
bugs only on allocation/freeing of object. KASan catch
bugs right before it will happen, so we always know exact
place of first bad read/write.
[1] https://code.google.com/p/address-sanitizer/wiki/AddressSanitizerForKernel
[2] https://code.google.com/p/address-sanitizer/wiki/FoundBugs
[3] https://code.google.com/p/thread-sanitizer/wiki/FoundBugs
[4] https://code.google.com/p/memory-sanitizer/wiki/FoundBugs
[5] https://code.google.com/p/address-sanitizer/wiki/AddressSanitizerForKernel#Trophies
Based on work by Andrey Konovalov.
Signed-off-by: Andrey Ryabinin <a.ryabinin@samsung.com>
Acked-by: Michal Marek <mmarek@suse.cz>
Signed-off-by: Andrey Konovalov <adech.fo@gmail.com>
Cc: Dmitry Vyukov <dvyukov@google.com>
Cc: Konstantin Serebryany <kcc@google.com>
Cc: Dmitry Chernenkov <dmitryc@google.com>
Cc: Yuri Gribov <tetra2005@gmail.com>
Cc: Konstantin Khlebnikov <koct9i@gmail.com>
Cc: Sasha Levin <sasha.levin@oracle.com>
Cc: Christoph Lameter <cl@linux.com>
Cc: Joonsoo Kim <iamjoonsoo.kim@lge.com>
Cc: Dave Hansen <dave.hansen@intel.com>
Cc: Andi Kleen <andi@firstfloor.org>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: "H. Peter Anvin" <hpa@zytor.com>
Cc: Christoph Lameter <cl@linux.com>
Cc: Pekka Enberg <penberg@kernel.org>
Cc: David Rientjes <rientjes@google.com>
Cc: Stephen Rothwell <sfr@canb.auug.org.au>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
2015-02-14 06:39:17 +08:00
|
|
|
endif
|
2020-12-23 04:02:06 +08:00
|
|
|
endif
|
kasan: add kernel address sanitizer infrastructure
Kernel Address sanitizer (KASan) is a dynamic memory error detector. It
provides fast and comprehensive solution for finding use-after-free and
out-of-bounds bugs.
KASAN uses compile-time instrumentation for checking every memory access,
therefore GCC > v4.9.2 required. v4.9.2 almost works, but has issues with
putting symbol aliases into the wrong section, which breaks kasan
instrumentation of globals.
This patch only adds infrastructure for kernel address sanitizer. It's
not available for use yet. The idea and some code was borrowed from [1].
Basic idea:
The main idea of KASAN is to use shadow memory to record whether each byte
of memory is safe to access or not, and use compiler's instrumentation to
check the shadow memory on each memory access.
Address sanitizer uses 1/8 of the memory addressable in kernel for shadow
memory and uses direct mapping with a scale and offset to translate a
memory address to its corresponding shadow address.
Here is function to translate address to corresponding shadow address:
unsigned long kasan_mem_to_shadow(unsigned long addr)
{
return (addr >> KASAN_SHADOW_SCALE_SHIFT) + KASAN_SHADOW_OFFSET;
}
where KASAN_SHADOW_SCALE_SHIFT = 3.
So for every 8 bytes there is one corresponding byte of shadow memory.
The following encoding used for each shadow byte: 0 means that all 8 bytes
of the corresponding memory region are valid for access; k (1 <= k <= 7)
means that the first k bytes are valid for access, and other (8 - k) bytes
are not; Any negative value indicates that the entire 8-bytes are
inaccessible. Different negative values used to distinguish between
different kinds of inaccessible memory (redzones, freed memory) (see
mm/kasan/kasan.h).
To be able to detect accesses to bad memory we need a special compiler.
Such compiler inserts a specific function calls (__asan_load*(addr),
__asan_store*(addr)) before each memory access of size 1, 2, 4, 8 or 16.
These functions check whether memory region is valid to access or not by
checking corresponding shadow memory. If access is not valid an error
printed.
Historical background of the address sanitizer from Dmitry Vyukov:
"We've developed the set of tools, AddressSanitizer (Asan),
ThreadSanitizer and MemorySanitizer, for user space. We actively use
them for testing inside of Google (continuous testing, fuzzing,
running prod services). To date the tools have found more than 10'000
scary bugs in Chromium, Google internal codebase and various
open-source projects (Firefox, OpenSSL, gcc, clang, ffmpeg, MySQL and
lots of others): [2] [3] [4].
The tools are part of both gcc and clang compilers.
We have not yet done massive testing under the Kernel AddressSanitizer
(it's kind of chicken and egg problem, you need it to be upstream to
start applying it extensively). To date it has found about 50 bugs.
Bugs that we've found in upstream kernel are listed in [5].
We've also found ~20 bugs in out internal version of the kernel. Also
people from Samsung and Oracle have found some.
[...]
As others noted, the main feature of AddressSanitizer is its
performance due to inline compiler instrumentation and simple linear
shadow memory. User-space Asan has ~2x slowdown on computational
programs and ~2x memory consumption increase. Taking into account that
kernel usually consumes only small fraction of CPU and memory when
running real user-space programs, I would expect that kernel Asan will
have ~10-30% slowdown and similar memory consumption increase (when we
finish all tuning).
I agree that Asan can well replace kmemcheck. We have plans to start
working on Kernel MemorySanitizer that finds uses of unitialized
memory. Asan+Msan will provide feature-parity with kmemcheck. As
others noted, Asan will unlikely replace debug slab and pagealloc that
can be enabled at runtime. Asan uses compiler instrumentation, so even
if it is disabled, it still incurs visible overheads.
Asan technology is easily portable to other architectures. Compiler
instrumentation is fully portable. Runtime has some arch-dependent
parts like shadow mapping and atomic operation interception. They are
relatively easy to port."
Comparison with other debugging features:
========================================
KMEMCHECK:
- KASan can do almost everything that kmemcheck can. KASan uses
compile-time instrumentation, which makes it significantly faster than
kmemcheck. The only advantage of kmemcheck over KASan is detection of
uninitialized memory reads.
Some brief performance testing showed that kasan could be
x500-x600 times faster than kmemcheck:
$ netperf -l 30
MIGRATED TCP STREAM TEST from 0.0.0.0 (0.0.0.0) port 0 AF_INET to localhost (127.0.0.1) port 0 AF_INET
Recv Send Send
Socket Socket Message Elapsed
Size Size Size Time Throughput
bytes bytes bytes secs. 10^6bits/sec
no debug: 87380 16384 16384 30.00 41624.72
kasan inline: 87380 16384 16384 30.00 12870.54
kasan outline: 87380 16384 16384 30.00 10586.39
kmemcheck: 87380 16384 16384 30.03 20.23
- Also kmemcheck couldn't work on several CPUs. It always sets
number of CPUs to 1. KASan doesn't have such limitation.
DEBUG_PAGEALLOC:
- KASan is slower than DEBUG_PAGEALLOC, but KASan works on sub-page
granularity level, so it able to find more bugs.
SLUB_DEBUG (poisoning, redzones):
- SLUB_DEBUG has lower overhead than KASan.
- SLUB_DEBUG in most cases are not able to detect bad reads,
KASan able to detect both reads and writes.
- In some cases (e.g. redzone overwritten) SLUB_DEBUG detect
bugs only on allocation/freeing of object. KASan catch
bugs right before it will happen, so we always know exact
place of first bad read/write.
[1] https://code.google.com/p/address-sanitizer/wiki/AddressSanitizerForKernel
[2] https://code.google.com/p/address-sanitizer/wiki/FoundBugs
[3] https://code.google.com/p/thread-sanitizer/wiki/FoundBugs
[4] https://code.google.com/p/memory-sanitizer/wiki/FoundBugs
[5] https://code.google.com/p/address-sanitizer/wiki/AddressSanitizerForKernel#Trophies
Based on work by Andrey Konovalov.
Signed-off-by: Andrey Ryabinin <a.ryabinin@samsung.com>
Acked-by: Michal Marek <mmarek@suse.cz>
Signed-off-by: Andrey Konovalov <adech.fo@gmail.com>
Cc: Dmitry Vyukov <dvyukov@google.com>
Cc: Konstantin Serebryany <kcc@google.com>
Cc: Dmitry Chernenkov <dmitryc@google.com>
Cc: Yuri Gribov <tetra2005@gmail.com>
Cc: Konstantin Khlebnikov <koct9i@gmail.com>
Cc: Sasha Levin <sasha.levin@oracle.com>
Cc: Christoph Lameter <cl@linux.com>
Cc: Joonsoo Kim <iamjoonsoo.kim@lge.com>
Cc: Dave Hansen <dave.hansen@intel.com>
Cc: Andi Kleen <andi@firstfloor.org>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: "H. Peter Anvin" <hpa@zytor.com>
Cc: Christoph Lameter <cl@linux.com>
Cc: Pekka Enberg <penberg@kernel.org>
Cc: David Rientjes <rientjes@google.com>
Cc: Stephen Rothwell <sfr@canb.auug.org.au>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
2015-02-14 06:39:17 +08:00
|
|
|
|
2022-09-15 23:03:45 +08:00
|
|
|
ifeq ($(CONFIG_KMSAN),y)
|
|
|
|
_c_flags += $(if $(patsubst n%,, \
|
kbuild: provide reasonable defaults for tool coverage
The objtool, sanitizers (KASAN, UBSAN, etc.), and profilers (GCOV, etc.)
are intended only for kernel space objects.
For instance, the following are not kernel objects, and therefore should
opt out of coverage:
- vDSO
- purgatory
- bootloader (arch/*/boot/)
However, to exclude these from coverage, you need to explicitly set
OBJECT_FILES_NON_STNDARD=y, KASAN_SANITIZE=n, etc.
Kbuild can achieve this without relying on such variables because
objects not directly linked to vmlinux or modules are considered
"non-standard objects".
Detecting standard objects is straightforward:
- objects added to obj-y or lib-y are linked to vmlinux
- objects added to obj-m are linked to modules
There are some exceptional Makefiles (e.g., arch/s390/boot/Makefile,
arch/xtensa/boot/lib/Makefile) that use obj-y or lib-y for non-kernel
space objects, but they can be fixed later if necessary.
Going forward, objects that are not listed in obj-y, lib-y, or obj-m
will opt out of objtool, sanitizers, and profilers by default.
You can still override the Kbuild decision by explicitly specifying
OBJECT_FILES_NON_STANDARD, KASAN_SANITIZE, etc. but most of such Make
variables can be removed.
The next commit will clean up redundant variables.
Note:
This commit changes the coverage for some objects:
- exclude .vmlinux.export.o from UBSAN, KCOV
- exclude arch/csky/kernel/vdso/vgettimeofday.o from UBSAN
- exclude arch/parisc/kernel/vdso32/vdso32.so from UBSAN
- exclude arch/parisc/kernel/vdso64/vdso64.so from UBSAN
- exclude arch/x86/um/vdso/um_vdso.o from UBSAN
- exclude drivers/misc/lkdtm/rodata.o from UBSAN, KCOV
- exclude init/version-timestamp.o from UBSAN, KCOV
- exclude lib/test_fortify/*.o from all santizers and profilers
I believe these are positive effects.
Signed-off-by: Masahiro Yamada <masahiroy@kernel.org>
Reviewed-by: Kees Cook <keescook@chromium.org>
Tested-by: Roberto Sassu <roberto.sassu@huawei.com>
2024-05-06 21:35:42 +08:00
|
|
|
$(KMSAN_SANITIZE_$(target-stem).o)$(KMSAN_SANITIZE)$(is-kernel-object)), \
|
2022-09-15 23:03:45 +08:00
|
|
|
$(CFLAGS_KMSAN))
|
|
|
|
_c_flags += $(if $(patsubst n%,, \
|
kbuild: provide reasonable defaults for tool coverage
The objtool, sanitizers (KASAN, UBSAN, etc.), and profilers (GCOV, etc.)
are intended only for kernel space objects.
For instance, the following are not kernel objects, and therefore should
opt out of coverage:
- vDSO
- purgatory
- bootloader (arch/*/boot/)
However, to exclude these from coverage, you need to explicitly set
OBJECT_FILES_NON_STNDARD=y, KASAN_SANITIZE=n, etc.
Kbuild can achieve this without relying on such variables because
objects not directly linked to vmlinux or modules are considered
"non-standard objects".
Detecting standard objects is straightforward:
- objects added to obj-y or lib-y are linked to vmlinux
- objects added to obj-m are linked to modules
There are some exceptional Makefiles (e.g., arch/s390/boot/Makefile,
arch/xtensa/boot/lib/Makefile) that use obj-y or lib-y for non-kernel
space objects, but they can be fixed later if necessary.
Going forward, objects that are not listed in obj-y, lib-y, or obj-m
will opt out of objtool, sanitizers, and profilers by default.
You can still override the Kbuild decision by explicitly specifying
OBJECT_FILES_NON_STANDARD, KASAN_SANITIZE, etc. but most of such Make
variables can be removed.
The next commit will clean up redundant variables.
Note:
This commit changes the coverage for some objects:
- exclude .vmlinux.export.o from UBSAN, KCOV
- exclude arch/csky/kernel/vdso/vgettimeofday.o from UBSAN
- exclude arch/parisc/kernel/vdso32/vdso32.so from UBSAN
- exclude arch/parisc/kernel/vdso64/vdso64.so from UBSAN
- exclude arch/x86/um/vdso/um_vdso.o from UBSAN
- exclude drivers/misc/lkdtm/rodata.o from UBSAN, KCOV
- exclude init/version-timestamp.o from UBSAN, KCOV
- exclude lib/test_fortify/*.o from all santizers and profilers
I believe these are positive effects.
Signed-off-by: Masahiro Yamada <masahiroy@kernel.org>
Reviewed-by: Kees Cook <keescook@chromium.org>
Tested-by: Roberto Sassu <roberto.sassu@huawei.com>
2024-05-06 21:35:42 +08:00
|
|
|
$(KMSAN_ENABLE_CHECKS_$(target-stem).o)$(KMSAN_ENABLE_CHECKS)$(is-kernel-object)), \
|
2022-09-15 23:03:45 +08:00
|
|
|
, -mllvm -msan-disable-checks=1)
|
|
|
|
endif
|
|
|
|
|
2016-01-21 07:00:55 +08:00
|
|
|
ifeq ($(CONFIG_UBSAN),y)
|
|
|
|
_c_flags += $(if $(patsubst n%,, \
|
kbuild: provide reasonable defaults for tool coverage
The objtool, sanitizers (KASAN, UBSAN, etc.), and profilers (GCOV, etc.)
are intended only for kernel space objects.
For instance, the following are not kernel objects, and therefore should
opt out of coverage:
- vDSO
- purgatory
- bootloader (arch/*/boot/)
However, to exclude these from coverage, you need to explicitly set
OBJECT_FILES_NON_STNDARD=y, KASAN_SANITIZE=n, etc.
Kbuild can achieve this without relying on such variables because
objects not directly linked to vmlinux or modules are considered
"non-standard objects".
Detecting standard objects is straightforward:
- objects added to obj-y or lib-y are linked to vmlinux
- objects added to obj-m are linked to modules
There are some exceptional Makefiles (e.g., arch/s390/boot/Makefile,
arch/xtensa/boot/lib/Makefile) that use obj-y or lib-y for non-kernel
space objects, but they can be fixed later if necessary.
Going forward, objects that are not listed in obj-y, lib-y, or obj-m
will opt out of objtool, sanitizers, and profilers by default.
You can still override the Kbuild decision by explicitly specifying
OBJECT_FILES_NON_STANDARD, KASAN_SANITIZE, etc. but most of such Make
variables can be removed.
The next commit will clean up redundant variables.
Note:
This commit changes the coverage for some objects:
- exclude .vmlinux.export.o from UBSAN, KCOV
- exclude arch/csky/kernel/vdso/vgettimeofday.o from UBSAN
- exclude arch/parisc/kernel/vdso32/vdso32.so from UBSAN
- exclude arch/parisc/kernel/vdso64/vdso64.so from UBSAN
- exclude arch/x86/um/vdso/um_vdso.o from UBSAN
- exclude drivers/misc/lkdtm/rodata.o from UBSAN, KCOV
- exclude init/version-timestamp.o from UBSAN, KCOV
- exclude lib/test_fortify/*.o from all santizers and profilers
I believe these are positive effects.
Signed-off-by: Masahiro Yamada <masahiroy@kernel.org>
Reviewed-by: Kees Cook <keescook@chromium.org>
Tested-by: Roberto Sassu <roberto.sassu@huawei.com>
2024-05-06 21:35:42 +08:00
|
|
|
$(UBSAN_SANITIZE_$(target-stem).o)$(UBSAN_SANITIZE)$(is-kernel-object)), \
|
2016-01-21 07:00:55 +08:00
|
|
|
$(CFLAGS_UBSAN))
|
2024-01-19 07:06:05 +08:00
|
|
|
_c_flags += $(if $(patsubst n%,, \
|
kbuild: provide reasonable defaults for tool coverage
The objtool, sanitizers (KASAN, UBSAN, etc.), and profilers (GCOV, etc.)
are intended only for kernel space objects.
For instance, the following are not kernel objects, and therefore should
opt out of coverage:
- vDSO
- purgatory
- bootloader (arch/*/boot/)
However, to exclude these from coverage, you need to explicitly set
OBJECT_FILES_NON_STNDARD=y, KASAN_SANITIZE=n, etc.
Kbuild can achieve this without relying on such variables because
objects not directly linked to vmlinux or modules are considered
"non-standard objects".
Detecting standard objects is straightforward:
- objects added to obj-y or lib-y are linked to vmlinux
- objects added to obj-m are linked to modules
There are some exceptional Makefiles (e.g., arch/s390/boot/Makefile,
arch/xtensa/boot/lib/Makefile) that use obj-y or lib-y for non-kernel
space objects, but they can be fixed later if necessary.
Going forward, objects that are not listed in obj-y, lib-y, or obj-m
will opt out of objtool, sanitizers, and profilers by default.
You can still override the Kbuild decision by explicitly specifying
OBJECT_FILES_NON_STANDARD, KASAN_SANITIZE, etc. but most of such Make
variables can be removed.
The next commit will clean up redundant variables.
Note:
This commit changes the coverage for some objects:
- exclude .vmlinux.export.o from UBSAN, KCOV
- exclude arch/csky/kernel/vdso/vgettimeofday.o from UBSAN
- exclude arch/parisc/kernel/vdso32/vdso32.so from UBSAN
- exclude arch/parisc/kernel/vdso64/vdso64.so from UBSAN
- exclude arch/x86/um/vdso/um_vdso.o from UBSAN
- exclude drivers/misc/lkdtm/rodata.o from UBSAN, KCOV
- exclude init/version-timestamp.o from UBSAN, KCOV
- exclude lib/test_fortify/*.o from all santizers and profilers
I believe these are positive effects.
Signed-off-by: Masahiro Yamada <masahiroy@kernel.org>
Reviewed-by: Kees Cook <keescook@chromium.org>
Tested-by: Roberto Sassu <roberto.sassu@huawei.com>
2024-05-06 21:35:42 +08:00
|
|
|
$(UBSAN_SIGNED_WRAP_$(target-stem).o)$(UBSAN_SANITIZE_$(target-stem).o)$(UBSAN_SIGNED_WRAP)$(UBSAN_SANITIZE)$(is-kernel-object)), \
|
2024-01-19 07:06:05 +08:00
|
|
|
$(CFLAGS_UBSAN_SIGNED_WRAP))
|
2016-01-21 07:00:55 +08:00
|
|
|
endif
|
|
|
|
|
kernel: add kcov code coverage
kcov provides code coverage collection for coverage-guided fuzzing
(randomized testing). Coverage-guided fuzzing is a testing technique
that uses coverage feedback to determine new interesting inputs to a
system. A notable user-space example is AFL
(http://lcamtuf.coredump.cx/afl/). However, this technique is not
widely used for kernel testing due to missing compiler and kernel
support.
kcov does not aim to collect as much coverage as possible. It aims to
collect more or less stable coverage that is function of syscall inputs.
To achieve this goal it does not collect coverage in soft/hard
interrupts and instrumentation of some inherently non-deterministic or
non-interesting parts of kernel is disbled (e.g. scheduler, locking).
Currently there is a single coverage collection mode (tracing), but the
API anticipates additional collection modes. Initially I also
implemented a second mode which exposes coverage in a fixed-size hash
table of counters (what Quentin used in his original patch). I've
dropped the second mode for simplicity.
This patch adds the necessary support on kernel side. The complimentary
compiler support was added in gcc revision 231296.
We've used this support to build syzkaller system call fuzzer, which has
found 90 kernel bugs in just 2 months:
https://github.com/google/syzkaller/wiki/Found-Bugs
We've also found 30+ bugs in our internal systems with syzkaller.
Another (yet unexplored) direction where kcov coverage would greatly
help is more traditional "blob mutation". For example, mounting a
random blob as a filesystem, or receiving a random blob over wire.
Why not gcov. Typical fuzzing loop looks as follows: (1) reset
coverage, (2) execute a bit of code, (3) collect coverage, repeat. A
typical coverage can be just a dozen of basic blocks (e.g. an invalid
input). In such context gcov becomes prohibitively expensive as
reset/collect coverage steps depend on total number of basic
blocks/edges in program (in case of kernel it is about 2M). Cost of
kcov depends only on number of executed basic blocks/edges. On top of
that, kernel requires per-thread coverage because there are always
background threads and unrelated processes that also produce coverage.
With inlined gcov instrumentation per-thread coverage is not possible.
kcov exposes kernel PCs and control flow to user-space which is
insecure. But debugfs should not be mapped as user accessible.
Based on a patch by Quentin Casasnovas.
[akpm@linux-foundation.org: make task_struct.kcov_mode have type `enum kcov_mode']
[akpm@linux-foundation.org: unbreak allmodconfig]
[akpm@linux-foundation.org: follow x86 Makefile layout standards]
Signed-off-by: Dmitry Vyukov <dvyukov@google.com>
Reviewed-by: Kees Cook <keescook@chromium.org>
Cc: syzkaller <syzkaller@googlegroups.com>
Cc: Vegard Nossum <vegard.nossum@oracle.com>
Cc: Catalin Marinas <catalin.marinas@arm.com>
Cc: Tavis Ormandy <taviso@google.com>
Cc: Will Deacon <will.deacon@arm.com>
Cc: Quentin Casasnovas <quentin.casasnovas@oracle.com>
Cc: Kostya Serebryany <kcc@google.com>
Cc: Eric Dumazet <edumazet@google.com>
Cc: Alexander Potapenko <glider@google.com>
Cc: Kees Cook <keescook@google.com>
Cc: Bjorn Helgaas <bhelgaas@google.com>
Cc: Sasha Levin <sasha.levin@oracle.com>
Cc: David Drysdale <drysdale@google.com>
Cc: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Cc: Andrey Ryabinin <ryabinin.a.a@gmail.com>
Cc: Kirill A. Shutemov <kirill@shutemov.name>
Cc: Jiri Slaby <jslaby@suse.cz>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: "H. Peter Anvin" <hpa@zytor.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
2016-03-23 05:27:30 +08:00
|
|
|
ifeq ($(CONFIG_KCOV),y)
|
|
|
|
_c_flags += $(if $(patsubst n%,, \
|
kbuild: provide reasonable defaults for tool coverage
The objtool, sanitizers (KASAN, UBSAN, etc.), and profilers (GCOV, etc.)
are intended only for kernel space objects.
For instance, the following are not kernel objects, and therefore should
opt out of coverage:
- vDSO
- purgatory
- bootloader (arch/*/boot/)
However, to exclude these from coverage, you need to explicitly set
OBJECT_FILES_NON_STNDARD=y, KASAN_SANITIZE=n, etc.
Kbuild can achieve this without relying on such variables because
objects not directly linked to vmlinux or modules are considered
"non-standard objects".
Detecting standard objects is straightforward:
- objects added to obj-y or lib-y are linked to vmlinux
- objects added to obj-m are linked to modules
There are some exceptional Makefiles (e.g., arch/s390/boot/Makefile,
arch/xtensa/boot/lib/Makefile) that use obj-y or lib-y for non-kernel
space objects, but they can be fixed later if necessary.
Going forward, objects that are not listed in obj-y, lib-y, or obj-m
will opt out of objtool, sanitizers, and profilers by default.
You can still override the Kbuild decision by explicitly specifying
OBJECT_FILES_NON_STANDARD, KASAN_SANITIZE, etc. but most of such Make
variables can be removed.
The next commit will clean up redundant variables.
Note:
This commit changes the coverage for some objects:
- exclude .vmlinux.export.o from UBSAN, KCOV
- exclude arch/csky/kernel/vdso/vgettimeofday.o from UBSAN
- exclude arch/parisc/kernel/vdso32/vdso32.so from UBSAN
- exclude arch/parisc/kernel/vdso64/vdso64.so from UBSAN
- exclude arch/x86/um/vdso/um_vdso.o from UBSAN
- exclude drivers/misc/lkdtm/rodata.o from UBSAN, KCOV
- exclude init/version-timestamp.o from UBSAN, KCOV
- exclude lib/test_fortify/*.o from all santizers and profilers
I believe these are positive effects.
Signed-off-by: Masahiro Yamada <masahiroy@kernel.org>
Reviewed-by: Kees Cook <keescook@chromium.org>
Tested-by: Roberto Sassu <roberto.sassu@huawei.com>
2024-05-06 21:35:42 +08:00
|
|
|
$(KCOV_INSTRUMENT_$(target-stem).o)$(KCOV_INSTRUMENT)$(if $(is-kernel-object),$(CONFIG_KCOV_INSTRUMENT_ALL))), \
|
kernel: add kcov code coverage
kcov provides code coverage collection for coverage-guided fuzzing
(randomized testing). Coverage-guided fuzzing is a testing technique
that uses coverage feedback to determine new interesting inputs to a
system. A notable user-space example is AFL
(http://lcamtuf.coredump.cx/afl/). However, this technique is not
widely used for kernel testing due to missing compiler and kernel
support.
kcov does not aim to collect as much coverage as possible. It aims to
collect more or less stable coverage that is function of syscall inputs.
To achieve this goal it does not collect coverage in soft/hard
interrupts and instrumentation of some inherently non-deterministic or
non-interesting parts of kernel is disbled (e.g. scheduler, locking).
Currently there is a single coverage collection mode (tracing), but the
API anticipates additional collection modes. Initially I also
implemented a second mode which exposes coverage in a fixed-size hash
table of counters (what Quentin used in his original patch). I've
dropped the second mode for simplicity.
This patch adds the necessary support on kernel side. The complimentary
compiler support was added in gcc revision 231296.
We've used this support to build syzkaller system call fuzzer, which has
found 90 kernel bugs in just 2 months:
https://github.com/google/syzkaller/wiki/Found-Bugs
We've also found 30+ bugs in our internal systems with syzkaller.
Another (yet unexplored) direction where kcov coverage would greatly
help is more traditional "blob mutation". For example, mounting a
random blob as a filesystem, or receiving a random blob over wire.
Why not gcov. Typical fuzzing loop looks as follows: (1) reset
coverage, (2) execute a bit of code, (3) collect coverage, repeat. A
typical coverage can be just a dozen of basic blocks (e.g. an invalid
input). In such context gcov becomes prohibitively expensive as
reset/collect coverage steps depend on total number of basic
blocks/edges in program (in case of kernel it is about 2M). Cost of
kcov depends only on number of executed basic blocks/edges. On top of
that, kernel requires per-thread coverage because there are always
background threads and unrelated processes that also produce coverage.
With inlined gcov instrumentation per-thread coverage is not possible.
kcov exposes kernel PCs and control flow to user-space which is
insecure. But debugfs should not be mapped as user accessible.
Based on a patch by Quentin Casasnovas.
[akpm@linux-foundation.org: make task_struct.kcov_mode have type `enum kcov_mode']
[akpm@linux-foundation.org: unbreak allmodconfig]
[akpm@linux-foundation.org: follow x86 Makefile layout standards]
Signed-off-by: Dmitry Vyukov <dvyukov@google.com>
Reviewed-by: Kees Cook <keescook@chromium.org>
Cc: syzkaller <syzkaller@googlegroups.com>
Cc: Vegard Nossum <vegard.nossum@oracle.com>
Cc: Catalin Marinas <catalin.marinas@arm.com>
Cc: Tavis Ormandy <taviso@google.com>
Cc: Will Deacon <will.deacon@arm.com>
Cc: Quentin Casasnovas <quentin.casasnovas@oracle.com>
Cc: Kostya Serebryany <kcc@google.com>
Cc: Eric Dumazet <edumazet@google.com>
Cc: Alexander Potapenko <glider@google.com>
Cc: Kees Cook <keescook@google.com>
Cc: Bjorn Helgaas <bhelgaas@google.com>
Cc: Sasha Levin <sasha.levin@oracle.com>
Cc: David Drysdale <drysdale@google.com>
Cc: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Cc: Andrey Ryabinin <ryabinin.a.a@gmail.com>
Cc: Kirill A. Shutemov <kirill@shutemov.name>
Cc: Jiri Slaby <jslaby@suse.cz>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: "H. Peter Anvin" <hpa@zytor.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
2016-03-23 05:27:30 +08:00
|
|
|
$(CFLAGS_KCOV))
|
|
|
|
endif
|
|
|
|
|
2019-11-15 02:02:54 +08:00
|
|
|
#
|
|
|
|
# Enable KCSAN flags except some files or directories we don't want to check
|
|
|
|
# (depends on variables KCSAN_SANITIZE_obj.o, KCSAN_SANITIZE)
|
|
|
|
#
|
|
|
|
ifeq ($(CONFIG_KCSAN),y)
|
|
|
|
_c_flags += $(if $(patsubst n%,, \
|
kbuild: provide reasonable defaults for tool coverage
The objtool, sanitizers (KASAN, UBSAN, etc.), and profilers (GCOV, etc.)
are intended only for kernel space objects.
For instance, the following are not kernel objects, and therefore should
opt out of coverage:
- vDSO
- purgatory
- bootloader (arch/*/boot/)
However, to exclude these from coverage, you need to explicitly set
OBJECT_FILES_NON_STNDARD=y, KASAN_SANITIZE=n, etc.
Kbuild can achieve this without relying on such variables because
objects not directly linked to vmlinux or modules are considered
"non-standard objects".
Detecting standard objects is straightforward:
- objects added to obj-y or lib-y are linked to vmlinux
- objects added to obj-m are linked to modules
There are some exceptional Makefiles (e.g., arch/s390/boot/Makefile,
arch/xtensa/boot/lib/Makefile) that use obj-y or lib-y for non-kernel
space objects, but they can be fixed later if necessary.
Going forward, objects that are not listed in obj-y, lib-y, or obj-m
will opt out of objtool, sanitizers, and profilers by default.
You can still override the Kbuild decision by explicitly specifying
OBJECT_FILES_NON_STANDARD, KASAN_SANITIZE, etc. but most of such Make
variables can be removed.
The next commit will clean up redundant variables.
Note:
This commit changes the coverage for some objects:
- exclude .vmlinux.export.o from UBSAN, KCOV
- exclude arch/csky/kernel/vdso/vgettimeofday.o from UBSAN
- exclude arch/parisc/kernel/vdso32/vdso32.so from UBSAN
- exclude arch/parisc/kernel/vdso64/vdso64.so from UBSAN
- exclude arch/x86/um/vdso/um_vdso.o from UBSAN
- exclude drivers/misc/lkdtm/rodata.o from UBSAN, KCOV
- exclude init/version-timestamp.o from UBSAN, KCOV
- exclude lib/test_fortify/*.o from all santizers and profilers
I believe these are positive effects.
Signed-off-by: Masahiro Yamada <masahiroy@kernel.org>
Reviewed-by: Kees Cook <keescook@chromium.org>
Tested-by: Roberto Sassu <roberto.sassu@huawei.com>
2024-05-06 21:35:42 +08:00
|
|
|
$(KCSAN_SANITIZE_$(target-stem).o)$(KCSAN_SANITIZE)$(is-kernel-object)), \
|
2019-11-15 02:02:54 +08:00
|
|
|
$(CFLAGS_KCSAN))
|
2021-11-30 19:44:14 +08:00
|
|
|
# Some uninstrumented files provide implied barriers required to avoid false
|
|
|
|
# positives: set KCSAN_INSTRUMENT_BARRIERS for barrier instrumentation only.
|
|
|
|
_c_flags += $(if $(patsubst n%,, \
|
2024-02-17 13:55:03 +08:00
|
|
|
$(KCSAN_INSTRUMENT_BARRIERS_$(target-stem).o)$(KCSAN_INSTRUMENT_BARRIERS)n), \
|
2021-11-30 19:44:14 +08:00
|
|
|
-D__KCSAN_INSTRUMENT_BARRIERS__)
|
2019-11-15 02:02:54 +08:00
|
|
|
endif
|
kernel: add kcov code coverage
kcov provides code coverage collection for coverage-guided fuzzing
(randomized testing). Coverage-guided fuzzing is a testing technique
that uses coverage feedback to determine new interesting inputs to a
system. A notable user-space example is AFL
(http://lcamtuf.coredump.cx/afl/). However, this technique is not
widely used for kernel testing due to missing compiler and kernel
support.
kcov does not aim to collect as much coverage as possible. It aims to
collect more or less stable coverage that is function of syscall inputs.
To achieve this goal it does not collect coverage in soft/hard
interrupts and instrumentation of some inherently non-deterministic or
non-interesting parts of kernel is disbled (e.g. scheduler, locking).
Currently there is a single coverage collection mode (tracing), but the
API anticipates additional collection modes. Initially I also
implemented a second mode which exposes coverage in a fixed-size hash
table of counters (what Quentin used in his original patch). I've
dropped the second mode for simplicity.
This patch adds the necessary support on kernel side. The complimentary
compiler support was added in gcc revision 231296.
We've used this support to build syzkaller system call fuzzer, which has
found 90 kernel bugs in just 2 months:
https://github.com/google/syzkaller/wiki/Found-Bugs
We've also found 30+ bugs in our internal systems with syzkaller.
Another (yet unexplored) direction where kcov coverage would greatly
help is more traditional "blob mutation". For example, mounting a
random blob as a filesystem, or receiving a random blob over wire.
Why not gcov. Typical fuzzing loop looks as follows: (1) reset
coverage, (2) execute a bit of code, (3) collect coverage, repeat. A
typical coverage can be just a dozen of basic blocks (e.g. an invalid
input). In such context gcov becomes prohibitively expensive as
reset/collect coverage steps depend on total number of basic
blocks/edges in program (in case of kernel it is about 2M). Cost of
kcov depends only on number of executed basic blocks/edges. On top of
that, kernel requires per-thread coverage because there are always
background threads and unrelated processes that also produce coverage.
With inlined gcov instrumentation per-thread coverage is not possible.
kcov exposes kernel PCs and control flow to user-space which is
insecure. But debugfs should not be mapped as user accessible.
Based on a patch by Quentin Casasnovas.
[akpm@linux-foundation.org: make task_struct.kcov_mode have type `enum kcov_mode']
[akpm@linux-foundation.org: unbreak allmodconfig]
[akpm@linux-foundation.org: follow x86 Makefile layout standards]
Signed-off-by: Dmitry Vyukov <dvyukov@google.com>
Reviewed-by: Kees Cook <keescook@chromium.org>
Cc: syzkaller <syzkaller@googlegroups.com>
Cc: Vegard Nossum <vegard.nossum@oracle.com>
Cc: Catalin Marinas <catalin.marinas@arm.com>
Cc: Tavis Ormandy <taviso@google.com>
Cc: Will Deacon <will.deacon@arm.com>
Cc: Quentin Casasnovas <quentin.casasnovas@oracle.com>
Cc: Kostya Serebryany <kcc@google.com>
Cc: Eric Dumazet <edumazet@google.com>
Cc: Alexander Potapenko <glider@google.com>
Cc: Kees Cook <keescook@google.com>
Cc: Bjorn Helgaas <bhelgaas@google.com>
Cc: Sasha Levin <sasha.levin@oracle.com>
Cc: David Drysdale <drysdale@google.com>
Cc: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Cc: Andrey Ryabinin <ryabinin.a.a@gmail.com>
Cc: Kirill A. Shutemov <kirill@shutemov.name>
Cc: Jiri Slaby <jslaby@suse.cz>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: "H. Peter Anvin" <hpa@zytor.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
2016-03-23 05:27:30 +08:00
|
|
|
|
kbuild: use $(src) instead of $(srctree)/$(src) for source directory
Kbuild conventionally uses $(obj)/ for generated files, and $(src)/ for
checked-in source files. It is merely a convention without any functional
difference. In fact, $(obj) and $(src) are exactly the same, as defined
in scripts/Makefile.build:
src := $(obj)
When the kernel is built in a separate output directory, $(src) does
not accurately reflect the source directory location. While Kbuild
resolves this discrepancy by specifying VPATH=$(srctree) to search for
source files, it does not cover all cases. For example, when adding a
header search path for local headers, -I$(srctree)/$(src) is typically
passed to the compiler.
This introduces inconsistency between upstream and downstream Makefiles
because $(src) is used instead of $(srctree)/$(src) for the latter.
To address this inconsistency, this commit changes the semantics of
$(src) so that it always points to the directory in the source tree.
Going forward, the variables used in Makefiles will have the following
meanings:
$(obj) - directory in the object tree
$(src) - directory in the source tree (changed by this commit)
$(objtree) - the top of the kernel object tree
$(srctree) - the top of the kernel source tree
Consequently, $(srctree)/$(src) in upstream Makefiles need to be replaced
with $(src).
Signed-off-by: Masahiro Yamada <masahiroy@kernel.org>
Reviewed-by: Nicolas Schier <nicolas@fjasle.eu>
2024-04-27 22:55:02 +08:00
|
|
|
# $(src) for including checkin headers from generated source files
|
|
|
|
# $(obj) for including generated headers from checkin source files
|
2019-01-16 10:56:40 +08:00
|
|
|
ifeq ($(KBUILD_EXTMOD),)
|
2019-07-06 11:07:12 +08:00
|
|
|
ifdef building_out_of_srctree
|
kbuild: use $(src) instead of $(srctree)/$(src) for source directory
Kbuild conventionally uses $(obj)/ for generated files, and $(src)/ for
checked-in source files. It is merely a convention without any functional
difference. In fact, $(obj) and $(src) are exactly the same, as defined
in scripts/Makefile.build:
src := $(obj)
When the kernel is built in a separate output directory, $(src) does
not accurately reflect the source directory location. While Kbuild
resolves this discrepancy by specifying VPATH=$(srctree) to search for
source files, it does not cover all cases. For example, when adding a
header search path for local headers, -I$(srctree)/$(src) is typically
passed to the compiler.
This introduces inconsistency between upstream and downstream Makefiles
because $(src) is used instead of $(srctree)/$(src) for the latter.
To address this inconsistency, this commit changes the semantics of
$(src) so that it always points to the directory in the source tree.
Going forward, the variables used in Makefiles will have the following
meanings:
$(obj) - directory in the object tree
$(src) - directory in the source tree (changed by this commit)
$(objtree) - the top of the kernel object tree
$(srctree) - the top of the kernel source tree
Consequently, $(srctree)/$(src) in upstream Makefiles need to be replaced
with $(src).
Signed-off-by: Masahiro Yamada <masahiroy@kernel.org>
Reviewed-by: Nicolas Schier <nicolas@fjasle.eu>
2024-04-27 22:55:02 +08:00
|
|
|
_c_flags += $(addprefix -I, $(src) $(obj))
|
|
|
|
_a_flags += $(addprefix -I, $(src) $(obj))
|
|
|
|
_cpp_flags += $(addprefix -I, $(src) $(obj))
|
2005-04-17 06:20:36 +08:00
|
|
|
endif
|
2019-01-16 10:56:40 +08:00
|
|
|
endif
|
2005-04-17 06:20:36 +08:00
|
|
|
|
kbuild: provide reasonable defaults for tool coverage
The objtool, sanitizers (KASAN, UBSAN, etc.), and profilers (GCOV, etc.)
are intended only for kernel space objects.
For instance, the following are not kernel objects, and therefore should
opt out of coverage:
- vDSO
- purgatory
- bootloader (arch/*/boot/)
However, to exclude these from coverage, you need to explicitly set
OBJECT_FILES_NON_STNDARD=y, KASAN_SANITIZE=n, etc.
Kbuild can achieve this without relying on such variables because
objects not directly linked to vmlinux or modules are considered
"non-standard objects".
Detecting standard objects is straightforward:
- objects added to obj-y or lib-y are linked to vmlinux
- objects added to obj-m are linked to modules
There are some exceptional Makefiles (e.g., arch/s390/boot/Makefile,
arch/xtensa/boot/lib/Makefile) that use obj-y or lib-y for non-kernel
space objects, but they can be fixed later if necessary.
Going forward, objects that are not listed in obj-y, lib-y, or obj-m
will opt out of objtool, sanitizers, and profilers by default.
You can still override the Kbuild decision by explicitly specifying
OBJECT_FILES_NON_STANDARD, KASAN_SANITIZE, etc. but most of such Make
variables can be removed.
The next commit will clean up redundant variables.
Note:
This commit changes the coverage for some objects:
- exclude .vmlinux.export.o from UBSAN, KCOV
- exclude arch/csky/kernel/vdso/vgettimeofday.o from UBSAN
- exclude arch/parisc/kernel/vdso32/vdso32.so from UBSAN
- exclude arch/parisc/kernel/vdso64/vdso64.so from UBSAN
- exclude arch/x86/um/vdso/um_vdso.o from UBSAN
- exclude drivers/misc/lkdtm/rodata.o from UBSAN, KCOV
- exclude init/version-timestamp.o from UBSAN, KCOV
- exclude lib/test_fortify/*.o from all santizers and profilers
I believe these are positive effects.
Signed-off-by: Masahiro Yamada <masahiroy@kernel.org>
Reviewed-by: Kees Cook <keescook@chromium.org>
Tested-by: Roberto Sassu <roberto.sassu@huawei.com>
2024-05-06 21:35:42 +08:00
|
|
|
# If $(is-kernel-object) is 'y', this object will be linked to vmlinux or modules
|
|
|
|
is-kernel-object = $(or $(part-of-builtin),$(part-of-module))
|
|
|
|
|
|
|
|
part-of-builtin = $(if $(filter $(basename $@).o, $(real-obj-y) $(lib-y)),y)
|
2019-08-19 16:58:43 +08:00
|
|
|
part-of-module = $(if $(filter $(basename $@).o, $(real-obj-m)),y)
|
|
|
|
quiet_modtag = $(if $(part-of-module),[M], )
|
|
|
|
|
|
|
|
modkern_cflags = \
|
|
|
|
$(if $(part-of-module), \
|
|
|
|
$(KBUILD_CFLAGS_MODULE) $(CFLAGS_MODULE), \
|
2019-12-19 16:33:28 +08:00
|
|
|
$(KBUILD_CFLAGS_KERNEL) $(CFLAGS_KERNEL) $(modfile_flags))
|
2019-08-19 16:58:43 +08:00
|
|
|
|
2021-07-03 22:42:57 +08:00
|
|
|
modkern_rustflags = \
|
|
|
|
$(if $(part-of-module), \
|
|
|
|
$(KBUILD_RUSTFLAGS_MODULE) $(RUSTFLAGS_MODULE), \
|
|
|
|
$(KBUILD_RUSTFLAGS_KERNEL) $(RUSTFLAGS_KERNEL))
|
|
|
|
|
2019-08-19 16:58:43 +08:00
|
|
|
modkern_aflags = $(if $(part-of-module), \
|
|
|
|
$(KBUILD_AFLAGS_MODULE) $(AFLAGS_MODULE), \
|
2024-09-06 22:45:02 +08:00
|
|
|
$(KBUILD_AFLAGS_KERNEL) $(AFLAGS_KERNEL) $(modfile_flags))
|
2019-08-19 16:58:43 +08:00
|
|
|
|
2020-04-23 22:23:53 +08:00
|
|
|
c_flags = -Wp,-MMD,$(depfile) $(NOSTDINC_FLAGS) $(LINUXINCLUDE) \
|
2018-03-27 20:52:50 +08:00
|
|
|
-include $(srctree)/include/linux/compiler_types.h \
|
2019-05-13 14:22:17 +08:00
|
|
|
$(_c_flags) $(modkern_cflags) \
|
2016-03-17 23:32:14 +08:00
|
|
|
$(basename_flags) $(modname_flags)
|
2005-04-17 06:20:36 +08:00
|
|
|
|
2021-07-03 22:42:57 +08:00
|
|
|
rust_flags = $(_rust_flags) $(modkern_rustflags) @$(objtree)/include/generated/rustc_cfg
|
|
|
|
|
2020-04-23 22:23:53 +08:00
|
|
|
a_flags = -Wp,-MMD,$(depfile) $(NOSTDINC_FLAGS) $(LINUXINCLUDE) \
|
2024-09-06 22:45:02 +08:00
|
|
|
$(_a_flags) $(modkern_aflags) $(modname_flags)
|
2005-04-17 06:20:36 +08:00
|
|
|
|
2020-04-23 22:23:53 +08:00
|
|
|
cpp_flags = -Wp,-MMD,$(depfile) $(NOSTDINC_FLAGS) $(LINUXINCLUDE) \
|
2019-05-13 14:22:17 +08:00
|
|
|
$(_cpp_flags)
|
2005-04-17 06:20:36 +08:00
|
|
|
|
2018-08-24 07:20:39 +08:00
|
|
|
ld_flags = $(KBUILD_LDFLAGS) $(ldflags-y) $(LDFLAGS_$(@F))
|
2005-04-17 06:20:36 +08:00
|
|
|
|
2022-05-28 23:47:04 +08:00
|
|
|
ifdef CONFIG_OBJTOOL
|
|
|
|
|
|
|
|
objtool := $(objtree)/tools/objtool/objtool
|
|
|
|
|
2022-09-07 02:49:35 +08:00
|
|
|
objtool-args-$(CONFIG_HAVE_JUMP_LABEL_HACK) += --hacks=jump_label
|
|
|
|
objtool-args-$(CONFIG_HAVE_NOINSTR_HACK) += --hacks=noinstr
|
2023-11-22 00:07:30 +08:00
|
|
|
objtool-args-$(CONFIG_MITIGATION_CALL_DEPTH_TRACKING) += --hacks=skylake
|
2022-09-07 02:49:35 +08:00
|
|
|
objtool-args-$(CONFIG_X86_KERNEL_IBT) += --ibt
|
2022-10-27 17:28:14 +08:00
|
|
|
objtool-args-$(CONFIG_FINEIBT) += --cfi
|
2022-09-07 02:49:35 +08:00
|
|
|
objtool-args-$(CONFIG_FTRACE_MCOUNT_USE_OBJTOOL) += --mcount
|
2022-11-15 01:57:49 +08:00
|
|
|
ifdef CONFIG_FTRACE_MCOUNT_USE_OBJTOOL
|
|
|
|
objtool-args-$(CONFIG_HAVE_OBJTOOL_NOP_MCOUNT) += --mnop
|
|
|
|
endif
|
2022-09-07 02:49:35 +08:00
|
|
|
objtool-args-$(CONFIG_UNWINDER_ORC) += --orc
|
2023-11-22 00:07:32 +08:00
|
|
|
objtool-args-$(CONFIG_MITIGATION_RETPOLINE) += --retpoline
|
2023-11-22 00:07:37 +08:00
|
|
|
objtool-args-$(CONFIG_MITIGATION_RETHUNK) += --rethunk
|
2023-11-22 00:07:33 +08:00
|
|
|
objtool-args-$(CONFIG_MITIGATION_SLS) += --sls
|
2022-09-07 02:49:35 +08:00
|
|
|
objtool-args-$(CONFIG_STACK_VALIDATION) += --stackval
|
|
|
|
objtool-args-$(CONFIG_HAVE_STATIC_CALL_INLINE) += --static-call
|
|
|
|
objtool-args-$(CONFIG_HAVE_UACCESS_VALIDATION) += --uaccess
|
|
|
|
objtool-args-$(CONFIG_GCOV_KERNEL) += --no-unreachable
|
2022-10-29 03:08:19 +08:00
|
|
|
objtool-args-$(CONFIG_PREFIX_SYMBOLS) += --prefix=$(CONFIG_FUNCTION_PADDING_BYTES)
|
2022-09-07 02:49:35 +08:00
|
|
|
|
|
|
|
objtool-args = $(objtool-args-y) \
|
2022-05-28 23:47:04 +08:00
|
|
|
$(if $(delay-objtool), --link) \
|
2022-09-07 02:49:35 +08:00
|
|
|
$(if $(part-of-module), --module)
|
2022-05-28 23:47:04 +08:00
|
|
|
|
|
|
|
delay-objtool := $(or $(CONFIG_LTO_CLANG),$(CONFIG_X86_KERNEL_IBT))
|
|
|
|
|
2022-09-07 02:49:35 +08:00
|
|
|
cmd_objtool = $(if $(objtool-enabled), ; $(objtool) $(objtool-args) $@)
|
2022-05-28 23:47:04 +08:00
|
|
|
cmd_gen_objtooldep = $(if $(objtool-enabled), { echo ; echo '$@: $$(wildcard $(objtool))' ; } >> $(dot-target).cmd)
|
|
|
|
|
|
|
|
endif # CONFIG_OBJTOOL
|
|
|
|
|
2014-08-19 15:34:20 +08:00
|
|
|
# Useful for describing the dependency of composite objects
|
|
|
|
# Usage:
|
|
|
|
# $(call multi_depend, multi_used_targets, suffix_to_remove, suffix_to_add)
|
|
|
|
define multi_depend
|
2022-04-06 23:30:18 +08:00
|
|
|
$(foreach m, $1, \
|
|
|
|
$(eval $m: \
|
|
|
|
$(addprefix $(obj)/, $(call suffix-search, $(patsubst $(obj)/%,%,$m), $2, $3))))
|
2014-08-19 15:34:20 +08:00
|
|
|
endef
|
|
|
|
|
2022-01-25 14:40:27 +08:00
|
|
|
# Copy a file
|
2005-04-17 06:20:36 +08:00
|
|
|
# ===========================================================================
|
2021-04-24 19:55:53 +08:00
|
|
|
# 'cp' preserves permissions. If you use it to copy a file in read-only srctree,
|
|
|
|
# the copy would be read-only as well, leading to an error when executing the
|
|
|
|
# rule next time. Use 'cat' instead in order to generate a writable file.
|
2022-01-25 14:40:27 +08:00
|
|
|
quiet_cmd_copy = COPY $@
|
|
|
|
cmd_copy = cat $< > $@
|
2005-04-17 06:20:36 +08:00
|
|
|
|
2011-06-08 01:09:28 +08:00
|
|
|
$(obj)/%: $(src)/%_shipped
|
2022-01-25 14:40:27 +08:00
|
|
|
$(call cmd,copy)
|
2005-04-17 06:20:36 +08:00
|
|
|
|
|
|
|
# Commands useful for building a boot image
|
|
|
|
# ===========================================================================
|
2014-04-28 15:26:18 +08:00
|
|
|
#
|
2005-04-17 06:20:36 +08:00
|
|
|
# Use as following:
|
|
|
|
#
|
|
|
|
# target: source(s) FORCE
|
|
|
|
# $(if_changed,ld/objcopy/gzip)
|
|
|
|
#
|
2021-01-20 14:23:51 +08:00
|
|
|
# and add target to 'targets' so that we know we have to
|
2005-04-17 06:20:36 +08:00
|
|
|
# read in the saved command line
|
|
|
|
|
|
|
|
# Linking
|
|
|
|
# ---------------------------------------------------------------------------
|
|
|
|
|
|
|
|
quiet_cmd_ld = LD $@
|
2019-01-17 18:02:43 +08:00
|
|
|
cmd_ld = $(LD) $(ld_flags) $(real-prereqs) -o $@
|
2005-04-17 06:20:36 +08:00
|
|
|
|
2019-02-05 15:33:37 +08:00
|
|
|
# Archive
|
|
|
|
# ---------------------------------------------------------------------------
|
|
|
|
|
|
|
|
quiet_cmd_ar = AR $@
|
2019-09-21 14:49:54 +08:00
|
|
|
cmd_ar = rm -f $@; $(AR) cDPrsT $@ $(real-prereqs)
|
2019-02-05 15:33:37 +08:00
|
|
|
|
2005-04-17 06:20:36 +08:00
|
|
|
# Objcopy
|
|
|
|
# ---------------------------------------------------------------------------
|
|
|
|
|
|
|
|
quiet_cmd_objcopy = OBJCOPY $@
|
|
|
|
cmd_objcopy = $(OBJCOPY) $(OBJCOPYFLAGS) $(OBJCOPYFLAGS_$(@F)) $< $@
|
|
|
|
|
|
|
|
# Gzip
|
|
|
|
# ---------------------------------------------------------------------------
|
|
|
|
|
|
|
|
quiet_cmd_gzip = GZIP $@
|
kbuild: fix broken builds because of GZIP,BZIP2,LZOP variables
Redefine GZIP, BZIP2, LZOP variables as KGZIP, KBZIP2, KLZOP resp.
GZIP, BZIP2, LZOP env variables are reserved by the tools. The original
attempt to redefine them internally doesn't work in makefiles/scripts
intercall scenarios, e.g., "make GZIP=gzip bindeb-pkg" and results in
broken builds. There can be other broken build commands because of this,
so the universal solution is to use non-reserved env variables for the
compression tools.
Fixes: 8dfb61dcbace ("kbuild: add variables for compression tools")
Signed-off-by: Denis Efremov <efremov@linux.com>
Tested-by: Guenter Roeck <linux@roeck-us.net>
Signed-off-by: Masahiro Yamada <masahiroy@kernel.org>
2020-06-08 17:59:44 +08:00
|
|
|
cmd_gzip = cat $(real-prereqs) | $(KGZIP) -n -f -9 > $@
|
2005-04-17 06:20:36 +08:00
|
|
|
|
2009-01-05 05:46:16 +08:00
|
|
|
# Bzip2
|
|
|
|
# ---------------------------------------------------------------------------
|
|
|
|
|
2009-05-06 12:17:15 +08:00
|
|
|
# Bzip2 and LZMA do not include size in file... so we have to fake that;
|
|
|
|
# append the size as a 32-bit littleendian number as gzip does.
|
2009-10-14 04:22:46 +08:00
|
|
|
size_append = printf $(shell \
|
2009-05-06 12:17:15 +08:00
|
|
|
dec_size=0; \
|
2019-01-17 18:02:43 +08:00
|
|
|
for F in $(real-prereqs); do \
|
kbuild: Use ls(1) instead of stat(1) to obtain file size
stat(1) is not standardized and different implementations have their own
(conflicting) flags for querying the size of a file.
ls(1) provides the same information (value of st.st_size) in the 5th
column, except when the file is a character or block device. This output
is standardized[0]. The -n option turns on -l, which writes lines
formatted like
"%s %u %s %s %u %s %s\n", <file mode>, <number of links>,
<owner name>, <group name>, <size>, <date and time>,
<pathname>
but instead of writing the <owner name> and <group name>, it writes the
numeric owner and group IDs (this avoids /etc/passwd and /etc/group
lookups as well as potential field splitting issues).
The <size> field is specified as "the value that would be returned for
the file in the st_size field of struct stat".
To avoid duplicating logic in several locations in the tree, create
scripts/file-size.sh and update callers to use that instead of stat(1).
[0] http://pubs.opengroup.org/onlinepubs/9699919799/utilities/ls.html#tag_20_73_10
Signed-off-by: Michael Forney <forney@google.com>
Signed-off-by: Masahiro Yamada <yamada.masahiro@socionext.com>
2018-03-19 08:54:02 +08:00
|
|
|
fsize=$$($(CONFIG_SHELL) $(srctree)/scripts/file-size.sh $$F); \
|
2009-05-06 12:17:15 +08:00
|
|
|
dec_size=$$(expr $$dec_size + $$fsize); \
|
|
|
|
done; \
|
2009-12-29 03:38:27 +08:00
|
|
|
printf "%08x\n" $$dec_size | \
|
|
|
|
sed 's/\(..\)/\1 /g' | { \
|
|
|
|
read ch0 ch1 ch2 ch3; \
|
|
|
|
for ch in $$ch3 $$ch2 $$ch1 $$ch0; do \
|
|
|
|
printf '%s%03o' '\\' $$((0x$$ch)); \
|
|
|
|
done; \
|
|
|
|
} \
|
2009-05-06 12:17:15 +08:00
|
|
|
)
|
|
|
|
|
kbuild: add cmd_file_size
Some architectures support self-extracting kernel, which embeds the
compressed vmlinux.
It has 4 byte data at the end so the decompressor can know the vmlinux
size beforehand.
GZIP natively has it in the trailer, but for the other compression
algorithms, the hand-crafted trailer is added.
It is unneeded to generate such _corrupted_ compressed files because
it is possible to pass the size data as a separate file.
For example, the assembly code:
.incbin "compressed-vmlinux-with-size-data"
can be transformed to:
.incbin "compressed-vmlinux"
.incbin "size-data"
My hope is, after some reworks of the decompressors, the macros
cmd_{bzip2,lzma,lzo,lz4,xzkern,zstd22}_with_size will go away.
This new macro, cmd_file_size, will be useful to generate a separate
size-data file.
Signed-off-by: Masahiro Yamada <masahiroy@kernel.org>
Reviewed-by: Nicolas Schier <n.schier@avm.de>
2022-01-10 02:15:29 +08:00
|
|
|
quiet_cmd_file_size = GEN $@
|
|
|
|
cmd_file_size = $(size_append) > $@
|
|
|
|
|
2009-05-06 12:17:15 +08:00
|
|
|
quiet_cmd_bzip2 = BZIP2 $@
|
kbuild: rename cmd_{bzip2,lzma,lzo,lz4,xzkern,zstd22}
GZIP-compressed files end with 4 byte data that represents the size
of the original input. The decompressors (the self-extracting kernel)
exploit it to know the vmlinux size beforehand. To mimic the GZIP's
trailer, Kbuild provides cmd_{bzip2,lzma,lzo,lz4,xzkern,zstd22}.
Unfortunately these macros are used everywhere despite the appended
size data is only useful for the decompressors.
There is no guarantee that such hand-crafted trailers are safely ignored.
In fact, the kernel refuses compressed initramdfs with the garbage data.
That is why usr/Makefile overrides size_append to make it no-op.
To limit the use of such broken compressed files, this commit renames
the existing macros as follows:
cmd_bzip2 --> cmd_bzip2_with_size
cmd_lzma --> cmd_lzma_with_size
cmd_lzo --> cmd_lzo_with_size
cmd_lz4 --> cmd_lz4_with_size
cmd_xzkern --> cmd_xzkern_with_size
cmd_zstd22 --> cmd_zstd22_with_size
To keep the decompressors working, I updated the following Makefiles
accordingly:
arch/arm/boot/compressed/Makefile
arch/h8300/boot/compressed/Makefile
arch/mips/boot/compressed/Makefile
arch/parisc/boot/compressed/Makefile
arch/s390/boot/compressed/Makefile
arch/sh/boot/compressed/Makefile
arch/x86/boot/compressed/Makefile
I reused the current macro names for the normal usecases; they produce
the compressed data in the proper format.
I did not touch the following:
arch/arc/boot/Makefile
arch/arm64/boot/Makefile
arch/csky/boot/Makefile
arch/mips/boot/Makefile
arch/riscv/boot/Makefile
arch/sh/boot/Makefile
kernel/Makefile
This means those Makefiles will stop appending the size data.
I dropped the 'override size_append' hack from usr/Makefile.
Signed-off-by: Masahiro Yamada <masahiroy@kernel.org>
Reviewed-by: Nicolas Schier <n.schier@avm.de>
2022-01-10 02:15:27 +08:00
|
|
|
cmd_bzip2 = cat $(real-prereqs) | $(KBZIP2) -9 > $@
|
|
|
|
|
|
|
|
quiet_cmd_bzip2_with_size = BZIP2 $@
|
|
|
|
cmd_bzip2_with_size = { cat $(real-prereqs) | $(KBZIP2) -9; $(size_append); } > $@
|
2009-01-05 05:46:16 +08:00
|
|
|
|
|
|
|
# Lzma
|
|
|
|
# ---------------------------------------------------------------------------
|
|
|
|
|
|
|
|
quiet_cmd_lzma = LZMA $@
|
kbuild: rename cmd_{bzip2,lzma,lzo,lz4,xzkern,zstd22}
GZIP-compressed files end with 4 byte data that represents the size
of the original input. The decompressors (the self-extracting kernel)
exploit it to know the vmlinux size beforehand. To mimic the GZIP's
trailer, Kbuild provides cmd_{bzip2,lzma,lzo,lz4,xzkern,zstd22}.
Unfortunately these macros are used everywhere despite the appended
size data is only useful for the decompressors.
There is no guarantee that such hand-crafted trailers are safely ignored.
In fact, the kernel refuses compressed initramdfs with the garbage data.
That is why usr/Makefile overrides size_append to make it no-op.
To limit the use of such broken compressed files, this commit renames
the existing macros as follows:
cmd_bzip2 --> cmd_bzip2_with_size
cmd_lzma --> cmd_lzma_with_size
cmd_lzo --> cmd_lzo_with_size
cmd_lz4 --> cmd_lz4_with_size
cmd_xzkern --> cmd_xzkern_with_size
cmd_zstd22 --> cmd_zstd22_with_size
To keep the decompressors working, I updated the following Makefiles
accordingly:
arch/arm/boot/compressed/Makefile
arch/h8300/boot/compressed/Makefile
arch/mips/boot/compressed/Makefile
arch/parisc/boot/compressed/Makefile
arch/s390/boot/compressed/Makefile
arch/sh/boot/compressed/Makefile
arch/x86/boot/compressed/Makefile
I reused the current macro names for the normal usecases; they produce
the compressed data in the proper format.
I did not touch the following:
arch/arc/boot/Makefile
arch/arm64/boot/Makefile
arch/csky/boot/Makefile
arch/mips/boot/Makefile
arch/riscv/boot/Makefile
arch/sh/boot/Makefile
kernel/Makefile
This means those Makefiles will stop appending the size data.
I dropped the 'override size_append' hack from usr/Makefile.
Signed-off-by: Masahiro Yamada <masahiroy@kernel.org>
Reviewed-by: Nicolas Schier <n.schier@avm.de>
2022-01-10 02:15:27 +08:00
|
|
|
cmd_lzma = cat $(real-prereqs) | $(LZMA) -9 > $@
|
|
|
|
|
|
|
|
quiet_cmd_lzma_with_size = LZMA $@
|
|
|
|
cmd_lzma_with_size = { cat $(real-prereqs) | $(LZMA) -9; $(size_append); } > $@
|
lib: add support for LZO-compressed kernels
This patch series adds generic support for creating and extracting
LZO-compressed kernel images, as well as support for using such images on
the x86 and ARM architectures, and support for creating and using
LZO-compressed initrd and initramfs images.
Russell King said:
: Testing on a Cortex A9 model:
: - lzo decompressor is 65% of the time gzip takes to decompress a kernel
: - lzo kernel is 9% larger than a gzip kernel
:
: which I'm happy to say confirms your figures when comparing the two.
:
: However, when comparing your new gzip code to the old gzip code:
: - new is 99% of the size of the old code
: - new takes 42% of the time to decompress than the old code
:
: What this means is that for a proper comparison, the results get even better:
: - lzo is 7.5% larger than the old gzip'd kernel image
: - lzo takes 28% of the time that the old gzip code took
:
: So the expense seems definitely worth the effort. The only reason I
: can think of ever using gzip would be if you needed the additional
: compression (eg, because you have limited flash to store the image.)
:
: I would argue that the default for ARM should therefore be LZO.
This patch:
The lzo compressor is worse than gzip at compression, but faster at
extraction. Here are some figures for an ARM board I'm working on:
Uncompressed size: 3.24Mo
gzip 1.61Mo 0.72s
lzo 1.75Mo 0.48s
So for a compression ratio that is still relatively close to gzip, it's
much faster to extract, at least in that case.
This part contains:
- Makefile routine to support lzo compression
- Fixes to the existing lzo compressor so that it can be used in
compressed kernels
- wrapper around the existing lzo1x_decompress, as it only extracts one
block at a time, while we need to extract a whole file here
- config dialog for kernel compression
[akpm@linux-foundation.org: coding-style fixes]
[akpm@linux-foundation.org: cleanup]
Signed-off-by: Albin Tonnerre <albin.tonnerre@free-electrons.com>
Tested-by: Wu Zhangjin <wuzhangjin@gmail.com>
Acked-by: "H. Peter Anvin" <hpa@zytor.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Thomas Gleixner <tglx@linutronix.de>
Tested-by: Russell King <rmk@arm.linux.org.uk>
Acked-by: Russell King <rmk@arm.linux.org.uk>
Cc: Ralf Baechle <ralf@linux-mips.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
2010-01-09 06:42:42 +08:00
|
|
|
|
2010-03-11 17:42:14 +08:00
|
|
|
quiet_cmd_lzo = LZO $@
|
kbuild: rename cmd_{bzip2,lzma,lzo,lz4,xzkern,zstd22}
GZIP-compressed files end with 4 byte data that represents the size
of the original input. The decompressors (the self-extracting kernel)
exploit it to know the vmlinux size beforehand. To mimic the GZIP's
trailer, Kbuild provides cmd_{bzip2,lzma,lzo,lz4,xzkern,zstd22}.
Unfortunately these macros are used everywhere despite the appended
size data is only useful for the decompressors.
There is no guarantee that such hand-crafted trailers are safely ignored.
In fact, the kernel refuses compressed initramdfs with the garbage data.
That is why usr/Makefile overrides size_append to make it no-op.
To limit the use of such broken compressed files, this commit renames
the existing macros as follows:
cmd_bzip2 --> cmd_bzip2_with_size
cmd_lzma --> cmd_lzma_with_size
cmd_lzo --> cmd_lzo_with_size
cmd_lz4 --> cmd_lz4_with_size
cmd_xzkern --> cmd_xzkern_with_size
cmd_zstd22 --> cmd_zstd22_with_size
To keep the decompressors working, I updated the following Makefiles
accordingly:
arch/arm/boot/compressed/Makefile
arch/h8300/boot/compressed/Makefile
arch/mips/boot/compressed/Makefile
arch/parisc/boot/compressed/Makefile
arch/s390/boot/compressed/Makefile
arch/sh/boot/compressed/Makefile
arch/x86/boot/compressed/Makefile
I reused the current macro names for the normal usecases; they produce
the compressed data in the proper format.
I did not touch the following:
arch/arc/boot/Makefile
arch/arm64/boot/Makefile
arch/csky/boot/Makefile
arch/mips/boot/Makefile
arch/riscv/boot/Makefile
arch/sh/boot/Makefile
kernel/Makefile
This means those Makefiles will stop appending the size data.
I dropped the 'override size_append' hack from usr/Makefile.
Signed-off-by: Masahiro Yamada <masahiroy@kernel.org>
Reviewed-by: Nicolas Schier <n.schier@avm.de>
2022-01-10 02:15:27 +08:00
|
|
|
cmd_lzo = cat $(real-prereqs) | $(KLZOP) -9 > $@
|
|
|
|
|
|
|
|
quiet_cmd_lzo_with_size = LZO $@
|
|
|
|
cmd_lzo_with_size = { cat $(real-prereqs) | $(KLZOP) -9; $(size_append); } > $@
|
2010-03-06 00:34:46 +08:00
|
|
|
|
2013-07-09 07:01:46 +08:00
|
|
|
quiet_cmd_lz4 = LZ4 $@
|
kbuild: rename cmd_{bzip2,lzma,lzo,lz4,xzkern,zstd22}
GZIP-compressed files end with 4 byte data that represents the size
of the original input. The decompressors (the self-extracting kernel)
exploit it to know the vmlinux size beforehand. To mimic the GZIP's
trailer, Kbuild provides cmd_{bzip2,lzma,lzo,lz4,xzkern,zstd22}.
Unfortunately these macros are used everywhere despite the appended
size data is only useful for the decompressors.
There is no guarantee that such hand-crafted trailers are safely ignored.
In fact, the kernel refuses compressed initramdfs with the garbage data.
That is why usr/Makefile overrides size_append to make it no-op.
To limit the use of such broken compressed files, this commit renames
the existing macros as follows:
cmd_bzip2 --> cmd_bzip2_with_size
cmd_lzma --> cmd_lzma_with_size
cmd_lzo --> cmd_lzo_with_size
cmd_lz4 --> cmd_lz4_with_size
cmd_xzkern --> cmd_xzkern_with_size
cmd_zstd22 --> cmd_zstd22_with_size
To keep the decompressors working, I updated the following Makefiles
accordingly:
arch/arm/boot/compressed/Makefile
arch/h8300/boot/compressed/Makefile
arch/mips/boot/compressed/Makefile
arch/parisc/boot/compressed/Makefile
arch/s390/boot/compressed/Makefile
arch/sh/boot/compressed/Makefile
arch/x86/boot/compressed/Makefile
I reused the current macro names for the normal usecases; they produce
the compressed data in the proper format.
I did not touch the following:
arch/arc/boot/Makefile
arch/arm64/boot/Makefile
arch/csky/boot/Makefile
arch/mips/boot/Makefile
arch/riscv/boot/Makefile
arch/sh/boot/Makefile
kernel/Makefile
This means those Makefiles will stop appending the size data.
I dropped the 'override size_append' hack from usr/Makefile.
Signed-off-by: Masahiro Yamada <masahiroy@kernel.org>
Reviewed-by: Nicolas Schier <n.schier@avm.de>
2022-01-10 02:15:27 +08:00
|
|
|
cmd_lz4 = cat $(real-prereqs) | $(LZ4) -l -c1 stdin stdout > $@
|
|
|
|
|
|
|
|
quiet_cmd_lz4_with_size = LZ4 $@
|
|
|
|
cmd_lz4_with_size = { cat $(real-prereqs) | $(LZ4) -l -c1 stdin stdout; \
|
2019-01-17 18:02:44 +08:00
|
|
|
$(size_append); } > $@
|
2013-07-09 07:01:46 +08:00
|
|
|
|
2012-03-17 05:03:55 +08:00
|
|
|
# U-Boot mkimage
|
|
|
|
# ---------------------------------------------------------------------------
|
|
|
|
|
|
|
|
MKIMAGE := $(srctree)/scripts/mkuboot.sh
|
|
|
|
|
|
|
|
# SRCARCH just happens to match slightly more than ARCH (on sparc), so reduces
|
|
|
|
# the number of overrides in arch makefiles
|
|
|
|
UIMAGE_ARCH ?= $(SRCARCH)
|
kbuild: replace $(if A,A,B) with $(or A,B)
$(or ...) is available since GNU Make 3.81, and useful to shorten the
code in some places.
Covert as follows:
$(if A,A,B) --> $(or A,B)
This patch also converts:
$(if A, A, B) --> $(or A, B)
Strictly speaking, the latter is not an equivalent conversion because
GNU Make keeps spaces after commas; if A is not empty, $(if A, A, B)
expands to " A", while $(or A, B) expands to "A".
Anyway, preceding spaces are not significant in the code hunks I touched.
Signed-off-by: Masahiro Yamada <masahiroy@kernel.org>
Reviewed-by: Nicolas Schier <nicolas@fjasle.eu>
2022-02-11 13:14:11 +08:00
|
|
|
UIMAGE_COMPRESSION ?= $(or $(2),none)
|
2012-03-17 05:03:55 +08:00
|
|
|
UIMAGE_OPTS-y ?=
|
|
|
|
UIMAGE_TYPE ?= kernel
|
|
|
|
UIMAGE_LOADADDR ?= arch_must_set_this
|
|
|
|
UIMAGE_ENTRYADDR ?= $(UIMAGE_LOADADDR)
|
2023-11-11 08:28:01 +08:00
|
|
|
UIMAGE_NAME ?= Linux-$(KERNELRELEASE)
|
2012-03-17 05:03:55 +08:00
|
|
|
|
2018-12-31 09:05:01 +08:00
|
|
|
quiet_cmd_uimage = UIMAGE $@
|
2019-08-25 21:28:37 +08:00
|
|
|
cmd_uimage = $(BASH) $(MKIMAGE) -A $(UIMAGE_ARCH) -O linux \
|
2012-03-17 05:03:55 +08:00
|
|
|
-C $(UIMAGE_COMPRESSION) $(UIMAGE_OPTS-y) \
|
|
|
|
-T $(UIMAGE_TYPE) \
|
|
|
|
-a $(UIMAGE_LOADADDR) -e $(UIMAGE_ENTRYADDR) \
|
2023-11-11 08:28:01 +08:00
|
|
|
-n '$(UIMAGE_NAME)' -d $< $@
|
2012-03-17 05:03:55 +08:00
|
|
|
|
2024-03-29 11:28:36 +08:00
|
|
|
# Flat Image Tree (FIT)
|
|
|
|
# This allows for packaging of a kernel and all devicetrees files, using
|
|
|
|
# compression.
|
|
|
|
# ---------------------------------------------------------------------------
|
|
|
|
|
|
|
|
MAKE_FIT := $(srctree)/scripts/make_fit.py
|
|
|
|
|
|
|
|
# Use this to override the compression algorithm
|
|
|
|
FIT_COMPRESSION ?= gzip
|
|
|
|
|
|
|
|
quiet_cmd_fit = FIT $@
|
|
|
|
cmd_fit = $(MAKE_FIT) -o $@ --arch $(UIMAGE_ARCH) --os linux \
|
|
|
|
--name '$(UIMAGE_NAME)' \
|
|
|
|
$(if $(findstring 1,$(KBUILD_VERBOSE)),-v) \
|
2024-06-13 17:34:32 +08:00
|
|
|
$(if $(FIT_DECOMPOSE_DTBS),--decompose-dtbs) \
|
2024-03-29 11:28:36 +08:00
|
|
|
--compress $(FIT_COMPRESSION) -k $< @$(word 2,$^)
|
|
|
|
|
2011-01-13 09:01:22 +08:00
|
|
|
# XZ
|
|
|
|
# ---------------------------------------------------------------------------
|
2024-07-21 21:36:19 +08:00
|
|
|
# Use xzkern or xzkern_with_size to compress the kernel image and xzmisc to
|
|
|
|
# compress other things.
|
2011-01-13 09:01:22 +08:00
|
|
|
#
|
|
|
|
# xzkern uses a big LZMA2 dictionary since it doesn't increase memory usage
|
|
|
|
# of the kernel decompressor. A BCJ filter is used if it is available for
|
2024-07-21 21:36:19 +08:00
|
|
|
# the target architecture.
|
|
|
|
#
|
|
|
|
# xzkern_with_size also appends uncompressed size of the data using
|
|
|
|
# size_append. The .xz format has the size information available at the end
|
|
|
|
# of the file too, but it's in more complex format and it's good to avoid
|
|
|
|
# changing the part of the boot code that reads the uncompressed size.
|
2011-01-13 09:01:22 +08:00
|
|
|
# Note that the bytes added by size_append will make the xz tool think that
|
|
|
|
# the file is corrupt. This is expected.
|
|
|
|
#
|
|
|
|
# xzmisc doesn't use size_append, so it can be used to create normal .xz
|
|
|
|
# files. xzmisc uses smaller LZMA2 dictionary than xzkern, because a very
|
|
|
|
# big dictionary would increase the memory usage too much in the multi-call
|
|
|
|
# decompression mode. A BCJ filter isn't used either.
|
|
|
|
quiet_cmd_xzkern = XZKERN $@
|
kbuild: rename cmd_{bzip2,lzma,lzo,lz4,xzkern,zstd22}
GZIP-compressed files end with 4 byte data that represents the size
of the original input. The decompressors (the self-extracting kernel)
exploit it to know the vmlinux size beforehand. To mimic the GZIP's
trailer, Kbuild provides cmd_{bzip2,lzma,lzo,lz4,xzkern,zstd22}.
Unfortunately these macros are used everywhere despite the appended
size data is only useful for the decompressors.
There is no guarantee that such hand-crafted trailers are safely ignored.
In fact, the kernel refuses compressed initramdfs with the garbage data.
That is why usr/Makefile overrides size_append to make it no-op.
To limit the use of such broken compressed files, this commit renames
the existing macros as follows:
cmd_bzip2 --> cmd_bzip2_with_size
cmd_lzma --> cmd_lzma_with_size
cmd_lzo --> cmd_lzo_with_size
cmd_lz4 --> cmd_lz4_with_size
cmd_xzkern --> cmd_xzkern_with_size
cmd_zstd22 --> cmd_zstd22_with_size
To keep the decompressors working, I updated the following Makefiles
accordingly:
arch/arm/boot/compressed/Makefile
arch/h8300/boot/compressed/Makefile
arch/mips/boot/compressed/Makefile
arch/parisc/boot/compressed/Makefile
arch/s390/boot/compressed/Makefile
arch/sh/boot/compressed/Makefile
arch/x86/boot/compressed/Makefile
I reused the current macro names for the normal usecases; they produce
the compressed data in the proper format.
I did not touch the following:
arch/arc/boot/Makefile
arch/arm64/boot/Makefile
arch/csky/boot/Makefile
arch/mips/boot/Makefile
arch/riscv/boot/Makefile
arch/sh/boot/Makefile
kernel/Makefile
This means those Makefiles will stop appending the size data.
I dropped the 'override size_append' hack from usr/Makefile.
Signed-off-by: Masahiro Yamada <masahiroy@kernel.org>
Reviewed-by: Nicolas Schier <n.schier@avm.de>
2022-01-10 02:15:27 +08:00
|
|
|
cmd_xzkern = cat $(real-prereqs) | sh $(srctree)/scripts/xz_wrap.sh > $@
|
|
|
|
|
|
|
|
quiet_cmd_xzkern_with_size = XZKERN $@
|
|
|
|
cmd_xzkern_with_size = { cat $(real-prereqs) | sh $(srctree)/scripts/xz_wrap.sh; \
|
2019-01-17 18:02:44 +08:00
|
|
|
$(size_append); } > $@
|
2011-01-13 09:01:22 +08:00
|
|
|
|
|
|
|
quiet_cmd_xzmisc = XZMISC $@
|
kbuild: add variables for compression tools
Allow user to use alternative implementations of compression tools,
such as pigz, pbzip2, pxz. For example, multi-threaded tools to
speed up the build:
$ make GZIP=pigz BZIP2=pbzip2
Variables _GZIP, _BZIP2, _LZOP are used internally because original env
vars are reserved by the tools. The use of GZIP in gzip tool is obsolete
since 2015. However, alternative implementations (e.g., pigz) still rely
on it. BZIP2, BZIP, LZOP vars are not obsolescent.
The credit goes to @grsecurity.
As a sidenote, for multi-threaded lzma, xz compression one can use:
$ export XZ_OPT="--threads=0"
Signed-off-by: Denis Efremov <efremov@linux.com>
Signed-off-by: Masahiro Yamada <masahiroy@kernel.org>
2020-06-05 15:39:55 +08:00
|
|
|
cmd_xzmisc = cat $(real-prereqs) | $(XZ) --check=crc32 --lzma2=dict=1MiB > $@
|
2017-04-13 03:43:52 +08:00
|
|
|
|
2020-07-31 03:08:36 +08:00
|
|
|
# ZSTD
|
|
|
|
# ---------------------------------------------------------------------------
|
|
|
|
# Appends the uncompressed size of the data using size_append. The .zst
|
|
|
|
# format has the size information available at the beginning of the file too,
|
|
|
|
# but it's in a more complex format and it's good to avoid changing the part
|
|
|
|
# of the boot code that reads the uncompressed size.
|
|
|
|
#
|
|
|
|
# Note that the bytes added by size_append will make the zstd tool think that
|
|
|
|
# the file is corrupt. This is expected.
|
|
|
|
#
|
|
|
|
# zstd uses a maximum window size of 8 MB. zstd22 uses a maximum window size of
|
|
|
|
# 128 MB. zstd22 is used for kernel compression because it is decompressed in a
|
|
|
|
# single pass, so zstd doesn't need to allocate a window buffer. When streaming
|
|
|
|
# decompression is used, like initramfs decompression, zstd22 should likely not
|
|
|
|
# be used because it would require zstd to allocate a 128 MB buffer.
|
|
|
|
|
|
|
|
quiet_cmd_zstd = ZSTD $@
|
2022-01-10 02:15:26 +08:00
|
|
|
cmd_zstd = cat $(real-prereqs) | $(ZSTD) -19 > $@
|
2020-07-31 03:08:36 +08:00
|
|
|
|
|
|
|
quiet_cmd_zstd22 = ZSTD22 $@
|
kbuild: rename cmd_{bzip2,lzma,lzo,lz4,xzkern,zstd22}
GZIP-compressed files end with 4 byte data that represents the size
of the original input. The decompressors (the self-extracting kernel)
exploit it to know the vmlinux size beforehand. To mimic the GZIP's
trailer, Kbuild provides cmd_{bzip2,lzma,lzo,lz4,xzkern,zstd22}.
Unfortunately these macros are used everywhere despite the appended
size data is only useful for the decompressors.
There is no guarantee that such hand-crafted trailers are safely ignored.
In fact, the kernel refuses compressed initramdfs with the garbage data.
That is why usr/Makefile overrides size_append to make it no-op.
To limit the use of such broken compressed files, this commit renames
the existing macros as follows:
cmd_bzip2 --> cmd_bzip2_with_size
cmd_lzma --> cmd_lzma_with_size
cmd_lzo --> cmd_lzo_with_size
cmd_lz4 --> cmd_lz4_with_size
cmd_xzkern --> cmd_xzkern_with_size
cmd_zstd22 --> cmd_zstd22_with_size
To keep the decompressors working, I updated the following Makefiles
accordingly:
arch/arm/boot/compressed/Makefile
arch/h8300/boot/compressed/Makefile
arch/mips/boot/compressed/Makefile
arch/parisc/boot/compressed/Makefile
arch/s390/boot/compressed/Makefile
arch/sh/boot/compressed/Makefile
arch/x86/boot/compressed/Makefile
I reused the current macro names for the normal usecases; they produce
the compressed data in the proper format.
I did not touch the following:
arch/arc/boot/Makefile
arch/arm64/boot/Makefile
arch/csky/boot/Makefile
arch/mips/boot/Makefile
arch/riscv/boot/Makefile
arch/sh/boot/Makefile
kernel/Makefile
This means those Makefiles will stop appending the size data.
I dropped the 'override size_append' hack from usr/Makefile.
Signed-off-by: Masahiro Yamada <masahiroy@kernel.org>
Reviewed-by: Nicolas Schier <n.schier@avm.de>
2022-01-10 02:15:27 +08:00
|
|
|
cmd_zstd22 = cat $(real-prereqs) | $(ZSTD) -22 --ultra > $@
|
|
|
|
|
|
|
|
quiet_cmd_zstd22_with_size = ZSTD22 $@
|
|
|
|
cmd_zstd22_with_size = { cat $(real-prereqs) | $(ZSTD) -22 --ultra; $(size_append); } > $@
|
2020-07-31 03:08:36 +08:00
|
|
|
|
2017-04-13 03:43:52 +08:00
|
|
|
# ASM offsets
|
|
|
|
# ---------------------------------------------------------------------------
|
|
|
|
|
|
|
|
# Default sed regexp - multiline due to syntax constraints
|
2017-04-21 14:21:11 +08:00
|
|
|
#
|
|
|
|
# Use [:space:] because LLVM's integrated assembler inserts <tab> around
|
|
|
|
# the .ascii directive whereas GCC keeps the <space> as-is.
|
2017-04-13 03:43:52 +08:00
|
|
|
define sed-offsets
|
2017-04-21 14:21:11 +08:00
|
|
|
's:^[[:space:]]*\.ascii[[:space:]]*"\(.*\)".*:\1:; \
|
|
|
|
/^->/{s:->#\(.*\):/* \1 */:; \
|
2017-04-13 03:43:52 +08:00
|
|
|
s:^->\([^ ]*\) [\$$#]*\([^ ]*\) \(.*\):#define \1 \2 /* \3 */:; \
|
2017-04-21 14:21:11 +08:00
|
|
|
s:->::; p;}'
|
2017-04-13 03:43:52 +08:00
|
|
|
endef
|
|
|
|
|
|
|
|
# Use filechk to avoid rebuilds when a header changes, but the resulting file
|
|
|
|
# does not
|
|
|
|
define filechk_offsets
|
|
|
|
echo "#ifndef $2"; \
|
|
|
|
echo "#define $2"; \
|
|
|
|
echo "/*"; \
|
|
|
|
echo " * DO NOT MODIFY."; \
|
|
|
|
echo " *"; \
|
|
|
|
echo " * This file was generated by Kbuild"; \
|
|
|
|
echo " */"; \
|
|
|
|
echo ""; \
|
2018-07-25 13:16:11 +08:00
|
|
|
sed -ne $(sed-offsets) < $<; \
|
2017-04-13 03:43:52 +08:00
|
|
|
echo ""; \
|
2018-12-31 16:24:09 +08:00
|
|
|
echo "#endif"
|
2017-04-13 03:43:52 +08:00
|
|
|
endef
|