Skip to content

Commit 727dbda

Browse files
committed
Merge tag 'hardening-v6.6-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/kees/linux
Pull hardening updates from Kees Cook: "As has become normal, changes are scattered around the tree (either explicitly maintainer Acked or for trivial stuff that went ignored): - Carve out the new CONFIG_LIST_HARDENED as a more focused subset of CONFIG_DEBUG_LIST (Marco Elver) - Fix kallsyms lookup failure under Clang LTO (Yonghong Song) - Clarify documentation for CONFIG_UBSAN_TRAP (Jann Horn) - Flexible array member conversion not carried in other tree (Gustavo A. R. Silva) - Various strlcpy() and strncpy() removals not carried in other trees (Azeem Shaikh, Justin Stitt) - Convert nsproxy.count to refcount_t (Elena Reshetova) - Add handful of __counted_by annotations not carried in other trees, as well as an LKDTM test - Fix build failure with gcc-plugins on GCC 14+ - Fix selftests to respect SKIP for signal-delivery tests - Fix CFI warning for paravirt callback prototype - Clarify documentation for seq_show_option_n() usage" * tag 'hardening-v6.6-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/kees/linux: (23 commits) LoadPin: Annotate struct dm_verity_loadpin_trusted_root_digest with __counted_by kallsyms: Change func signature for cleanup_symbol_name() kallsyms: Fix kallsyms_selftest failure nsproxy: Convert nsproxy.count to refcount_t integrity: Annotate struct ima_rule_opt_list with __counted_by lkdtm: Add FAM_BOUNDS test for __counted_by Compiler Attributes: counted_by: Adjust name and identifier expansion um: refactor deprecated strncpy to memcpy um: vector: refactor deprecated strncpy alpha: Replace one-element array with flexible-array member hardening: Move BUG_ON_DATA_CORRUPTION to hardening options list: Introduce CONFIG_LIST_HARDENED list_debug: Introduce inline wrappers for debug checks compiler_types: Introduce the Clang __preserve_most function attribute gcc-plugins: Rename last_stmt() for GCC 14+ selftests/harness: Actually report SKIP for signal tests x86/paravirt: Fix tlb_remove_table function callback prototype warning EISA: Replace all non-returning strlcpy with strscpy perf: Replace strlcpy with strscpy um: Remove strlcpy declaration ...
2 parents b03a434 + 5f536ac commit 727dbda

File tree

31 files changed

+286
-123
lines changed

31 files changed

+286
-123
lines changed

arch/alpha/kernel/osf_sys.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,7 @@ struct osf_dirent {
9797
unsigned int d_ino;
9898
unsigned short d_reclen;
9999
unsigned short d_namlen;
100-
char d_name[1];
100+
char d_name[];
101101
};
102102

103103
struct osf_dirent_callback {

arch/arm64/kvm/hyp/nvhe/Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ hyp-obj-y := timer-sr.o sysreg-sr.o debug-sr.o switch.o tlb.o hyp-init.o host.o
2525
cache.o setup.o mm.o mem_protect.o sys_regs.o pkvm.o stacktrace.o ffa.o
2626
hyp-obj-y += ../vgic-v3-sr.o ../aarch32.o ../vgic-v2-cpuif-proxy.o ../entry.o \
2727
../fpsimd.o ../hyp-entry.o ../exception.o ../pgtable.o
28-
hyp-obj-$(CONFIG_DEBUG_LIST) += list_debug.o
28+
hyp-obj-$(CONFIG_LIST_HARDENED) += list_debug.o
2929
hyp-obj-y += $(lib-objs)
3030

3131
##

arch/arm64/kvm/hyp/nvhe/list_debug.c

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,9 @@ static inline __must_check bool nvhe_check_data_corruption(bool v)
2626

2727
/* The predicates checked here are taken from lib/list_debug.c. */
2828

29-
bool __list_add_valid(struct list_head *new, struct list_head *prev,
30-
struct list_head *next)
29+
__list_valid_slowpath
30+
bool __list_add_valid_or_report(struct list_head *new, struct list_head *prev,
31+
struct list_head *next)
3132
{
3233
if (NVHE_CHECK_DATA_CORRUPTION(next->prev != prev) ||
3334
NVHE_CHECK_DATA_CORRUPTION(prev->next != next) ||
@@ -37,7 +38,8 @@ bool __list_add_valid(struct list_head *new, struct list_head *prev,
3738
return true;
3839
}
3940

40-
bool __list_del_entry_valid(struct list_head *entry)
41+
__list_valid_slowpath
42+
bool __list_del_entry_valid_or_report(struct list_head *entry)
4143
{
4244
struct list_head *prev, *next;
4345

arch/um/drivers/mconsole_kern.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -554,7 +554,7 @@ struct mconsole_output {
554554

555555
static DEFINE_SPINLOCK(client_lock);
556556
static LIST_HEAD(clients);
557-
static char console_buf[MCONSOLE_MAX_DATA];
557+
static char console_buf[MCONSOLE_MAX_DATA] __nonstring;
558558

559559
static void console_write(struct console *console, const char *string,
560560
unsigned int len)
@@ -567,7 +567,7 @@ static void console_write(struct console *console, const char *string,
567567

568568
while (len > 0) {
569569
n = min((size_t) len, ARRAY_SIZE(console_buf));
570-
strncpy(console_buf, string, n);
570+
memcpy(console_buf, string, n);
571571
string += n;
572572
len -= n;
573573

arch/um/drivers/vector_user.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -141,7 +141,7 @@ static int create_tap_fd(char *iface)
141141
}
142142
memset(&ifr, 0, sizeof(ifr));
143143
ifr.ifr_flags = IFF_TAP | IFF_NO_PI | IFF_VNET_HDR;
144-
strncpy((char *)&ifr.ifr_name, iface, sizeof(ifr.ifr_name) - 1);
144+
strscpy(ifr.ifr_name, iface, sizeof(ifr.ifr_name));
145145

146146
err = ioctl(fd, TUNSETIFF, (void *) &ifr);
147147
if (err != 0) {
@@ -171,7 +171,7 @@ static int create_raw_fd(char *iface, int flags, int proto)
171171
goto raw_fd_cleanup;
172172
}
173173
memset(&ifr, 0, sizeof(ifr));
174-
strncpy((char *)&ifr.ifr_name, iface, sizeof(ifr.ifr_name) - 1);
174+
strscpy(ifr.ifr_name, iface, sizeof(ifr.ifr_name));
175175
if (ioctl(fd, SIOCGIFINDEX, (void *) &ifr) < 0) {
176176
err = -errno;
177177
goto raw_fd_cleanup;

arch/um/include/shared/user.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,6 @@ static inline int printk(const char *fmt, ...)
5050
#endif
5151

5252
extern int in_aton(char *str);
53-
extern size_t strlcpy(char *, const char *, size_t);
5453
extern size_t strlcat(char *, const char *, size_t);
5554
extern size_t strscpy(char *, const char *, size_t);
5655

arch/um/os-Linux/umid.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ static int __init make_uml_dir(void)
4040
__func__);
4141
goto err;
4242
}
43-
strlcpy(dir, home, sizeof(dir));
43+
strscpy(dir, home, sizeof(dir));
4444
uml_dir++;
4545
}
4646
strlcat(dir, uml_dir, sizeof(dir));
@@ -243,7 +243,7 @@ int __init set_umid(char *name)
243243
if (strlen(name) > UMID_LEN - 1)
244244
return -E2BIG;
245245

246-
strlcpy(umid, name, sizeof(umid));
246+
strscpy(umid, name, sizeof(umid));
247247

248248
return 0;
249249
}
@@ -262,7 +262,7 @@ static int __init make_umid(void)
262262
make_uml_dir();
263263

264264
if (*umid == '\0') {
265-
strlcpy(tmp, uml_dir, sizeof(tmp));
265+
strscpy(tmp, uml_dir, sizeof(tmp));
266266
strlcat(tmp, "XXXXXX", sizeof(tmp));
267267
fd = mkstemp(tmp);
268268
if (fd < 0) {

arch/x86/kernel/paravirt.c

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,11 @@ void __init native_pv_lock_init(void)
7979
static_branch_disable(&virt_spin_lock_key);
8080
}
8181

82+
static void native_tlb_remove_table(struct mmu_gather *tlb, void *table)
83+
{
84+
tlb_remove_page(tlb, table);
85+
}
86+
8287
unsigned int paravirt_patch(u8 type, void *insn_buff, unsigned long addr,
8388
unsigned int len)
8489
{
@@ -295,8 +300,7 @@ struct paravirt_patch_template pv_ops = {
295300
.mmu.flush_tlb_kernel = native_flush_tlb_global,
296301
.mmu.flush_tlb_one_user = native_flush_tlb_one_user,
297302
.mmu.flush_tlb_multi = native_flush_tlb_multi,
298-
.mmu.tlb_remove_table =
299-
(void (*)(struct mmu_gather *, void *))tlb_remove_page,
303+
.mmu.tlb_remove_table = native_tlb_remove_table,
300304

301305
.mmu.exit_mmap = paravirt_nop,
302306
.mmu.notify_page_enc_status_changed = paravirt_nop,

drivers/eisa/eisa-bus.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ static void __init eisa_name_device(struct eisa_device *edev)
6060
int i;
6161
for (i = 0; i < EISA_INFOS; i++) {
6262
if (!strcmp(edev->id.sig, eisa_table[i].id.sig)) {
63-
strlcpy(edev->pretty_name,
63+
strscpy(edev->pretty_name,
6464
eisa_table[i].name,
6565
sizeof(edev->pretty_name));
6666
return;

drivers/misc/lkdtm/bugs.c

Lines changed: 46 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -273,8 +273,8 @@ static void lkdtm_HUNG_TASK(void)
273273
schedule();
274274
}
275275

276-
volatile unsigned int huge = INT_MAX - 2;
277-
volatile unsigned int ignored;
276+
static volatile unsigned int huge = INT_MAX - 2;
277+
static volatile unsigned int ignored;
278278

279279
static void lkdtm_OVERFLOW_SIGNED(void)
280280
{
@@ -305,7 +305,7 @@ static void lkdtm_OVERFLOW_UNSIGNED(void)
305305
ignored = value;
306306
}
307307

308-
/* Intentionally using old-style flex array definition of 1 byte. */
308+
/* Intentionally using unannotated flex array definition. */
309309
struct array_bounds_flex_array {
310310
int one;
311311
int two;
@@ -357,6 +357,46 @@ static void lkdtm_ARRAY_BOUNDS(void)
357357
pr_expected_config(CONFIG_UBSAN_BOUNDS);
358358
}
359359

360+
struct lkdtm_annotated {
361+
unsigned long flags;
362+
int count;
363+
int array[] __counted_by(count);
364+
};
365+
366+
static volatile int fam_count = 4;
367+
368+
static void lkdtm_FAM_BOUNDS(void)
369+
{
370+
struct lkdtm_annotated *inst;
371+
372+
inst = kzalloc(struct_size(inst, array, fam_count + 1), GFP_KERNEL);
373+
if (!inst) {
374+
pr_err("FAIL: could not allocate test struct!\n");
375+
return;
376+
}
377+
378+
inst->count = fam_count;
379+
pr_info("Array access within bounds ...\n");
380+
inst->array[1] = fam_count;
381+
ignored = inst->array[1];
382+
383+
pr_info("Array access beyond bounds ...\n");
384+
inst->array[fam_count] = fam_count;
385+
ignored = inst->array[fam_count];
386+
387+
kfree(inst);
388+
389+
pr_err("FAIL: survived access of invalid flexible array member index!\n");
390+
391+
if (!__has_attribute(__counted_by__))
392+
pr_warn("This is expected since this %s was built a compiler supporting __counted_by\n",
393+
lkdtm_kernel_info);
394+
else if (IS_ENABLED(CONFIG_UBSAN_BOUNDS))
395+
pr_expected_config(CONFIG_UBSAN_TRAP);
396+
else
397+
pr_expected_config(CONFIG_UBSAN_BOUNDS);
398+
}
399+
360400
static void lkdtm_CORRUPT_LIST_ADD(void)
361401
{
362402
/*
@@ -393,7 +433,7 @@ static void lkdtm_CORRUPT_LIST_ADD(void)
393433
pr_err("Overwrite did not happen, but no BUG?!\n");
394434
else {
395435
pr_err("list_add() corruption not detected!\n");
396-
pr_expected_config(CONFIG_DEBUG_LIST);
436+
pr_expected_config(CONFIG_LIST_HARDENED);
397437
}
398438
}
399439

@@ -420,7 +460,7 @@ static void lkdtm_CORRUPT_LIST_DEL(void)
420460
pr_err("Overwrite did not happen, but no BUG?!\n");
421461
else {
422462
pr_err("list_del() corruption not detected!\n");
423-
pr_expected_config(CONFIG_DEBUG_LIST);
463+
pr_expected_config(CONFIG_LIST_HARDENED);
424464
}
425465
}
426466

@@ -616,6 +656,7 @@ static struct crashtype crashtypes[] = {
616656
CRASHTYPE(OVERFLOW_SIGNED),
617657
CRASHTYPE(OVERFLOW_UNSIGNED),
618658
CRASHTYPE(ARRAY_BOUNDS),
659+
CRASHTYPE(FAM_BOUNDS),
619660
CRASHTYPE(CORRUPT_LIST_ADD),
620661
CRASHTYPE(CORRUPT_LIST_DEL),
621662
CRASHTYPE(STACK_GUARD_PAGE_LEADING),

0 commit comments

Comments
 (0)