hardening updates for v6.12-rc1
- lib/string_choices: Add str_up_down() helper (Michal Wajdeczko) - lib/string_choices: Add str_true_false()/str_false_true() helper (Hongbo Li) - lib/string_choices: Introduce several opposite string choice helpers (Hongbo Li) - lib/string_helpers: rework overflow-dependent code (Justin Stitt) - fortify: refactor test_fortify Makefile to fix some build problems (Masahiro Yamada) - string: Check for "nonstring" attribute on strscpy() arguments - virt: vbox: Replace 1-element arrays with flexible arrays - media: venus: hfi_cmds: Replace 1-element arrays with flexible arrays -----BEGIN PGP SIGNATURE----- iHUEABYKAB0WIQRSPkdeREjth1dHnSE2KwveOeQkuwUCZufwawAKCRA2KwveOeQk u3n9AQCI8G1FSMFSa8MKSSwTo600dHbZGavJd33fl2VrV7KCvQD8CMPRC/itOIVI PXcGo9tekW+zAOOw+v47QorpxHGd1w4= =jSSr -----END PGP SIGNATURE----- Merge tag 'hardening-v6.12-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/kees/linux Pull hardening updates from Kees Cook: - lib/string_choices: - Add str_up_down() helper (Michal Wajdeczko) - Add str_true_false()/str_false_true() helper (Hongbo Li) - Introduce several opposite string choice helpers (Hongbo Li) - lib/string_helpers: - rework overflow-dependent code (Justin Stitt) - fortify: refactor test_fortify Makefile to fix some build problems (Masahiro Yamada) - string: Check for "nonstring" attribute on strscpy() arguments - virt: vbox: Replace 1-element arrays with flexible arrays - media: venus: hfi_cmds: Replace 1-element arrays with flexible arrays * tag 'hardening-v6.12-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/kees/linux: lib/string_choices: Add some comments to make more clear for string choices helpers. lib/string_choices: Introduce several opposite string choice helpers lib/string_choices: Add str_true_false()/str_false_true() helper string: Check for "nonstring" attribute on strscpy() arguments media: venus: hfi_cmds: struct hfi_session_release_buffer_pkt: Add __counted_by annotation media: venus: hfi_cmds: struct hfi_session_release_buffer_pkt: Replace 1-element array with flexible array virt: vbox: struct vmmdev_hgcm_pagelist: Replace 1-element array with flexible array lib/string_helpers: rework overflow-dependent code coccinelle: Add rules to find str_down_up() replacements string_choices: Add wrapper for str_down_up() coccinelle: Add rules to find str_up_down() replacements lib/string_choices: Add str_up_down() helper fortify: use if_changed_dep to record header dependency in *.cmd files fortify: move test_fortify.sh to lib/test_fortify/ fortify: refactor test_fortify Makefile to fix some build problems
This commit is contained in:
commit
39b3f4e0db
@ -8834,7 +8834,6 @@ F: include/linux/fortify-string.h
|
||||
F: lib/fortify_kunit.c
|
||||
F: lib/memcpy_kunit.c
|
||||
F: lib/test_fortify/*
|
||||
F: scripts/test_fortify.sh
|
||||
K: \b__NO_FORTIFY\b
|
||||
|
||||
FPGA DFL DRIVERS
|
||||
|
@ -227,7 +227,7 @@ struct hfi_session_release_buffer_pkt {
|
||||
u32 extradata_size;
|
||||
u32 response_req;
|
||||
u32 num_buffers;
|
||||
u32 buffer_info[1];
|
||||
u32 buffer_info[] __counted_by(num_buffers);
|
||||
};
|
||||
|
||||
struct hfi_session_release_resources_pkt {
|
||||
|
@ -242,6 +242,9 @@ static inline void *offset_to_ptr(const int *off)
|
||||
/* &a[0] degrades to a pointer: a different type from an array */
|
||||
#define __must_be_array(a) BUILD_BUG_ON_ZERO(__same_type((a), &(a)[0]))
|
||||
|
||||
/* Require C Strings (i.e. NUL-terminated) lack the "nonstring" attribute. */
|
||||
#define __must_be_cstr(p) BUILD_BUG_ON_ZERO(__annotated(p, nonstring))
|
||||
|
||||
/*
|
||||
* This returns a constant expression while determining if an argument is
|
||||
* a constant expression, most importantly without evaluating the argument.
|
||||
|
@ -421,6 +421,13 @@ struct ftrace_likely_data {
|
||||
#define __member_size(p) __builtin_object_size(p, 1)
|
||||
#endif
|
||||
|
||||
/* Determine if an attribute has been applied to a variable. */
|
||||
#if __has_builtin(__builtin_has_attribute)
|
||||
#define __annotated(var, attr) __builtin_has_attribute(var, attr)
|
||||
#else
|
||||
#define __annotated(var, attr) (false)
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Some versions of gcc do not mark 'asm goto' volatile:
|
||||
*
|
||||
|
@ -76,12 +76,16 @@ ssize_t sized_strscpy(char *, const char *, size_t);
|
||||
* known size.
|
||||
*/
|
||||
#define __strscpy0(dst, src, ...) \
|
||||
sized_strscpy(dst, src, sizeof(dst) + __must_be_array(dst))
|
||||
#define __strscpy1(dst, src, size) sized_strscpy(dst, src, size)
|
||||
sized_strscpy(dst, src, sizeof(dst) + __must_be_array(dst) + \
|
||||
__must_be_cstr(dst) + __must_be_cstr(src))
|
||||
#define __strscpy1(dst, src, size) \
|
||||
sized_strscpy(dst, src, size + __must_be_cstr(dst) + __must_be_cstr(src))
|
||||
|
||||
#define __strscpy_pad0(dst, src, ...) \
|
||||
sized_strscpy_pad(dst, src, sizeof(dst) + __must_be_array(dst))
|
||||
#define __strscpy_pad1(dst, src, size) sized_strscpy_pad(dst, src, size)
|
||||
sized_strscpy_pad(dst, src, sizeof(dst) + __must_be_array(dst) + \
|
||||
__must_be_cstr(dst) + __must_be_cstr(src))
|
||||
#define __strscpy_pad1(dst, src, size) \
|
||||
sized_strscpy_pad(dst, src, size + __must_be_cstr(dst) + __must_be_cstr(src))
|
||||
|
||||
/**
|
||||
* strscpy - Copy a C-string into a sized buffer
|
||||
|
@ -2,17 +2,32 @@
|
||||
#ifndef _LINUX_STRING_CHOICES_H_
|
||||
#define _LINUX_STRING_CHOICES_H_
|
||||
|
||||
/*
|
||||
* Here provide a series of helpers in the str_$TRUE_$FALSE format (you can
|
||||
* also expand some helpers as needed), where $TRUE and $FALSE are their
|
||||
* corresponding literal strings. These helpers can be used in the printing
|
||||
* and also in other places where constant strings are required. Using these
|
||||
* helpers offers the following benefits:
|
||||
* 1) Reducing the hardcoding of strings, which makes the code more elegant
|
||||
* through these simple literal-meaning helpers.
|
||||
* 2) Unifying the output, which prevents the same string from being printed
|
||||
* in various forms, such as enable/disable, enabled/disabled, en/dis.
|
||||
* 3) Deduping by the linker, which results in a smaller binary file.
|
||||
*/
|
||||
|
||||
#include <linux/types.h>
|
||||
|
||||
static inline const char *str_enable_disable(bool v)
|
||||
{
|
||||
return v ? "enable" : "disable";
|
||||
}
|
||||
#define str_disable_enable(v) str_enable_disable(!(v))
|
||||
|
||||
static inline const char *str_enabled_disabled(bool v)
|
||||
{
|
||||
return v ? "enabled" : "disabled";
|
||||
}
|
||||
#define str_disabled_enabled(v) str_enabled_disabled(!(v))
|
||||
|
||||
static inline const char *str_hi_lo(bool v)
|
||||
{
|
||||
@ -36,11 +51,25 @@ static inline const char *str_on_off(bool v)
|
||||
{
|
||||
return v ? "on" : "off";
|
||||
}
|
||||
#define str_off_on(v) str_on_off(!(v))
|
||||
|
||||
static inline const char *str_yes_no(bool v)
|
||||
{
|
||||
return v ? "yes" : "no";
|
||||
}
|
||||
#define str_no_yes(v) str_yes_no(!(v))
|
||||
|
||||
static inline const char *str_up_down(bool v)
|
||||
{
|
||||
return v ? "up" : "down";
|
||||
}
|
||||
#define str_down_up(v) str_up_down(!(v))
|
||||
|
||||
static inline const char *str_true_false(bool v)
|
||||
{
|
||||
return v ? "true" : "false";
|
||||
}
|
||||
#define str_false_true(v) str_true_false(!(v))
|
||||
|
||||
/**
|
||||
* str_plural - Return the simple pluralization based on English counts
|
||||
|
@ -282,7 +282,10 @@ struct vmmdev_hgcm_pagelist {
|
||||
__u32 flags; /** VMMDEV_HGCM_F_PARM_*. */
|
||||
__u16 offset_first_page; /** Data offset in the first page. */
|
||||
__u16 page_count; /** Number of pages. */
|
||||
__u64 pages[1]; /** Page addresses. */
|
||||
union {
|
||||
__u64 unused; /** Deprecated place-holder for first "pages" entry. */
|
||||
__DECLARE_FLEX_ARRAY(__u64, pages); /** Page addresses. */
|
||||
};
|
||||
};
|
||||
VMMDEV_ASSERT_SIZE(vmmdev_hgcm_pagelist, 4 + 2 + 2 + 8);
|
||||
|
||||
|
2
lib/.gitignore
vendored
2
lib/.gitignore
vendored
@ -5,5 +5,3 @@
|
||||
/gen_crc32table
|
||||
/gen_crc64table
|
||||
/oid_registry_data.c
|
||||
/test_fortify.log
|
||||
/test_fortify/*.log
|
||||
|
38
lib/Makefile
38
lib/Makefile
@ -393,40 +393,4 @@ obj-$(CONFIG_GENERIC_LIB_DEVMEM_IS_ALLOWED) += devmem_is_allowed.o
|
||||
|
||||
obj-$(CONFIG_FIRMWARE_TABLE) += fw_table.o
|
||||
|
||||
# FORTIFY_SOURCE compile-time behavior tests
|
||||
TEST_FORTIFY_SRCS = $(wildcard $(src)/test_fortify/*-*.c)
|
||||
TEST_FORTIFY_LOGS = $(patsubst $(src)/%.c, %.log, $(TEST_FORTIFY_SRCS))
|
||||
TEST_FORTIFY_LOG = test_fortify.log
|
||||
|
||||
quiet_cmd_test_fortify = TEST $@
|
||||
cmd_test_fortify = $(CONFIG_SHELL) $(srctree)/scripts/test_fortify.sh \
|
||||
$< $@ "$(NM)" $(CC) $(c_flags) \
|
||||
$(call cc-disable-warning,fortify-source) \
|
||||
-DKBUILD_EXTRA_WARN1
|
||||
|
||||
targets += $(TEST_FORTIFY_LOGS)
|
||||
clean-files += $(TEST_FORTIFY_LOGS)
|
||||
clean-files += $(addsuffix .o, $(TEST_FORTIFY_LOGS))
|
||||
$(obj)/test_fortify/%.log: $(src)/test_fortify/%.c \
|
||||
$(src)/test_fortify/test_fortify.h \
|
||||
$(srctree)/include/linux/fortify-string.h \
|
||||
$(srctree)/scripts/test_fortify.sh \
|
||||
FORCE
|
||||
$(call if_changed,test_fortify)
|
||||
|
||||
quiet_cmd_gen_fortify_log = GEN $@
|
||||
cmd_gen_fortify_log = cat </dev/null $(filter-out FORCE,$^) 2>/dev/null > $@ || true
|
||||
|
||||
targets += $(TEST_FORTIFY_LOG)
|
||||
clean-files += $(TEST_FORTIFY_LOG)
|
||||
$(obj)/$(TEST_FORTIFY_LOG): $(addprefix $(obj)/, $(TEST_FORTIFY_LOGS)) FORCE
|
||||
$(call if_changed,gen_fortify_log)
|
||||
|
||||
# Fake dependency to trigger the fortify tests.
|
||||
ifeq ($(CONFIG_FORTIFY_SOURCE),y)
|
||||
$(obj)/string.o: $(obj)/$(TEST_FORTIFY_LOG)
|
||||
endif
|
||||
|
||||
# Some architectures define __NO_FORTIFY if __SANITIZE_ADDRESS__ is undefined.
|
||||
# Pass CFLAGS_KASAN to avoid warnings.
|
||||
$(foreach x, $(patsubst %.log,%.o,$(TEST_FORTIFY_LOGS)), $(eval KASAN_SANITIZE_$(x) := y))
|
||||
subdir-$(CONFIG_FORTIFY_SOURCE) += test_fortify
|
||||
|
@ -321,6 +321,9 @@ int string_unescape(char *src, char *dst, size_t size, unsigned int flags)
|
||||
{
|
||||
char *out = dst;
|
||||
|
||||
if (!size)
|
||||
size = SIZE_MAX;
|
||||
|
||||
while (*src && --size) {
|
||||
if (src[0] == '\\' && src[1] != '\0' && size > 1) {
|
||||
src++;
|
||||
|
2
lib/test_fortify/.gitignore
vendored
Normal file
2
lib/test_fortify/.gitignore
vendored
Normal file
@ -0,0 +1,2 @@
|
||||
# SPDX-License-Identifier: GPL-2.0-only
|
||||
/*.log
|
28
lib/test_fortify/Makefile
Normal file
28
lib/test_fortify/Makefile
Normal file
@ -0,0 +1,28 @@
|
||||
# SPDX-License-Identifier: GPL-2.0
|
||||
|
||||
ccflags-y := $(call cc-disable-warning,fortify-source)
|
||||
|
||||
quiet_cmd_test_fortify = TEST $@
|
||||
cmd_test_fortify = $(CONFIG_SHELL) $(src)/test_fortify.sh \
|
||||
$< $@ "$(NM)" $(CC) $(c_flags) -DKBUILD_EXTRA_WARN1
|
||||
|
||||
$(obj)/%.log: $(src)/%.c $(src)/test_fortify.sh FORCE
|
||||
$(call if_changed_dep,test_fortify)
|
||||
|
||||
logs = $(patsubst $(src)/%.c, %.log, $(wildcard $(src)/*-*.c))
|
||||
targets += $(logs)
|
||||
|
||||
quiet_cmd_gen_fortify_log = CAT $@
|
||||
cmd_gen_fortify_log = cat $(or $(real-prereqs),/dev/null) > $@
|
||||
|
||||
$(obj)/test_fortify.log: $(addprefix $(obj)/, $(logs)) FORCE
|
||||
$(call if_changed,gen_fortify_log)
|
||||
|
||||
# GCC<=7 does not always produce *.d files.
|
||||
# Run the tests only for GCC>=8 or Clang.
|
||||
always-$(call gcc-min-version, 80000) += test_fortify.log
|
||||
always-$(CONFIG_CC_IS_CLANG) += test_fortify.log
|
||||
|
||||
# Some architectures define __NO_FORTIFY if __SANITIZE_ADDRESS__ is undefined.
|
||||
# Pass CFLAGS_KASAN to avoid warnings.
|
||||
KASAN_SANITIZE := y
|
@ -39,3 +39,49 @@ e << str_plural_r.E;
|
||||
@@
|
||||
|
||||
coccilib.report.print_report(p[0], "opportunity for str_plural(%s)" % e)
|
||||
|
||||
@str_up_down depends on patch@
|
||||
expression E;
|
||||
@@
|
||||
(
|
||||
- ((E) ? "up" : "down")
|
||||
+ str_up_down(E)
|
||||
)
|
||||
|
||||
@str_up_down_r depends on !patch exists@
|
||||
expression E;
|
||||
position P;
|
||||
@@
|
||||
(
|
||||
* ((E@P) ? "up" : "down")
|
||||
)
|
||||
|
||||
@script:python depends on report@
|
||||
p << str_up_down_r.P;
|
||||
e << str_up_down_r.E;
|
||||
@@
|
||||
|
||||
coccilib.report.print_report(p[0], "opportunity for str_up_down(%s)" % e)
|
||||
|
||||
@str_down_up depends on patch@
|
||||
expression E;
|
||||
@@
|
||||
(
|
||||
- ((E) ? "down" : "up")
|
||||
+ str_down_up(E)
|
||||
)
|
||||
|
||||
@str_down_up_r depends on !patch exists@
|
||||
expression E;
|
||||
position P;
|
||||
@@
|
||||
(
|
||||
* ((E@P) ? "down" : "up")
|
||||
)
|
||||
|
||||
@script:python depends on report@
|
||||
p << str_down_up_r.P;
|
||||
e << str_down_up_r.E;
|
||||
@@
|
||||
|
||||
coccilib.report.print_report(p[0], "opportunity for str_down_up(%s)" % e)
|
||||
|
@ -21,3 +21,5 @@ set -e
|
||||
# then will be really dead and removed from the code base entirely.
|
||||
|
||||
rm -f *.spec
|
||||
|
||||
rm -f lib/test_fortify.log
|
||||
|
Loading…
Reference in New Issue
Block a user