Skip to content

Commit 120a201

Browse files
committed
Merge tag 'hardening-v6.8-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/kees/linux
Pull hardening updates from Kees Cook: - Introduce the param_unknown_fn type and other clean ups (Andy Shevchenko) - Various __counted_by annotations (Christophe JAILLET, Gustavo A. R. Silva, Kees Cook) - Add KFENCE test to LKDTM (Stephen Boyd) - Various strncpy() refactorings (Justin Stitt) - Fix qnx4 to avoid writing into the smaller of two overlapping buffers - Various strlcpy() refactorings * tag 'hardening-v6.8-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/kees/linux: qnx4: Use get_directory_fname() in qnx4_match() qnx4: Extract dir entry filename processing into helper atags_proc: Add __counted_by for struct buffer and use struct_size() tracing/uprobe: Replace strlcpy() with strscpy() params: Fix multi-line comment style params: Sort headers params: Use size_add() for kmalloc() params: Do not go over the limit when getting the string length params: Introduce the param_unknown_fn type lkdtm: Add kfence read after free crash type nvme-fc: replace deprecated strncpy with strscpy nvdimm/btt: replace deprecated strncpy with strscpy nvme-fabrics: replace deprecated strncpy with strscpy drm/modes: replace deprecated strncpy with strscpy_pad afs: Add __counted_by for struct afs_acl and use struct_size() VMCI: Annotate struct vmci_handle_arr with __counted_by i40e: Annotate struct i40e_qvlist_info with __counted_by HID: uhid: replace deprecated strncpy with strscpy samples: Replace strlcpy() with strscpy() SUNRPC: Replace strlcpy() with strscpy()
2 parents 72116ef + a75b380 commit 120a201

File tree

21 files changed

+208
-124
lines changed

21 files changed

+208
-124
lines changed

arch/arm/kernel/atags_proc.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77

88
struct buffer {
99
size_t size;
10-
char data[];
10+
char data[] __counted_by(size);
1111
};
1212

1313
static ssize_t atags_read(struct file *file, char __user *buf,
@@ -54,7 +54,7 @@ static int __init init_atags_procfs(void)
5454

5555
WARN_ON(tag->hdr.tag != ATAG_NONE);
5656

57-
b = kmalloc(sizeof(*b) + size, GFP_KERNEL);
57+
b = kmalloc(struct_size(b, data, size), GFP_KERNEL);
5858
if (!b)
5959
goto nomem;
6060

drivers/gpu/drm/drm_modes.c

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2617,8 +2617,7 @@ void drm_mode_convert_to_umode(struct drm_mode_modeinfo *out,
26172617
break;
26182618
}
26192619

2620-
strncpy(out->name, in->name, DRM_DISPLAY_MODE_LEN);
2621-
out->name[DRM_DISPLAY_MODE_LEN-1] = 0;
2620+
strscpy_pad(out->name, in->name, sizeof(out->name));
26222621
}
26232622

26242623
/**
@@ -2659,8 +2658,7 @@ int drm_mode_convert_umode(struct drm_device *dev,
26592658
* useful for the kernel->userspace direction anyway.
26602659
*/
26612660
out->type = in->type & DRM_MODE_TYPE_ALL;
2662-
strncpy(out->name, in->name, DRM_DISPLAY_MODE_LEN);
2663-
out->name[DRM_DISPLAY_MODE_LEN-1] = 0;
2661+
strscpy_pad(out->name, in->name, sizeof(out->name));
26642662

26652663
/* Clearing picture aspect ratio bits from out flags,
26662664
* as the aspect-ratio information is not stored in

drivers/hid/uhid.c

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -490,7 +490,7 @@ static int uhid_dev_create2(struct uhid_device *uhid,
490490
const struct uhid_event *ev)
491491
{
492492
struct hid_device *hid;
493-
size_t rd_size, len;
493+
size_t rd_size;
494494
void *rd_data;
495495
int ret;
496496

@@ -514,13 +514,12 @@ static int uhid_dev_create2(struct uhid_device *uhid,
514514
goto err_free;
515515
}
516516

517-
/* @hid is zero-initialized, strncpy() is correct, strlcpy() not */
518-
len = min(sizeof(hid->name), sizeof(ev->u.create2.name)) - 1;
519-
strncpy(hid->name, ev->u.create2.name, len);
520-
len = min(sizeof(hid->phys), sizeof(ev->u.create2.phys)) - 1;
521-
strncpy(hid->phys, ev->u.create2.phys, len);
522-
len = min(sizeof(hid->uniq), sizeof(ev->u.create2.uniq)) - 1;
523-
strncpy(hid->uniq, ev->u.create2.uniq, len);
517+
BUILD_BUG_ON(sizeof(hid->name) != sizeof(ev->u.create2.name));
518+
strscpy(hid->name, ev->u.create2.name, sizeof(hid->name));
519+
BUILD_BUG_ON(sizeof(hid->phys) != sizeof(ev->u.create2.phys));
520+
strscpy(hid->phys, ev->u.create2.phys, sizeof(hid->phys));
521+
BUILD_BUG_ON(sizeof(hid->uniq) != sizeof(ev->u.create2.uniq));
522+
strscpy(hid->uniq, ev->u.create2.uniq, sizeof(hid->uniq));
524523

525524
hid->ll_driver = &uhid_hid_driver;
526525
hid->bus = ev->u.create2.bus;

drivers/misc/lkdtm/heap.c

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
* page allocation and slab allocations.
55
*/
66
#include "lkdtm.h"
7+
#include <linux/kfence.h>
78
#include <linux/slab.h>
89
#include <linux/vmalloc.h>
910
#include <linux/sched.h>
@@ -132,6 +133,64 @@ static void lkdtm_READ_AFTER_FREE(void)
132133
kfree(val);
133134
}
134135

136+
static void lkdtm_KFENCE_READ_AFTER_FREE(void)
137+
{
138+
int *base, val, saw;
139+
unsigned long timeout, resched_after;
140+
size_t len = 1024;
141+
/*
142+
* The slub allocator will use the either the first word or
143+
* the middle of the allocation to store the free pointer,
144+
* depending on configurations. Store in the second word to
145+
* avoid running into the freelist.
146+
*/
147+
size_t offset = sizeof(*base);
148+
149+
/*
150+
* 100x the sample interval should be more than enough to ensure we get
151+
* a KFENCE allocation eventually.
152+
*/
153+
timeout = jiffies + msecs_to_jiffies(100 * kfence_sample_interval);
154+
/*
155+
* Especially for non-preemption kernels, ensure the allocation-gate
156+
* timer can catch up: after @resched_after, every failed allocation
157+
* attempt yields, to ensure the allocation-gate timer is scheduled.
158+
*/
159+
resched_after = jiffies + msecs_to_jiffies(kfence_sample_interval);
160+
do {
161+
base = kmalloc(len, GFP_KERNEL);
162+
if (!base) {
163+
pr_err("FAIL: Unable to allocate kfence memory!\n");
164+
return;
165+
}
166+
167+
if (is_kfence_address(base)) {
168+
val = 0x12345678;
169+
base[offset] = val;
170+
pr_info("Value in memory before free: %x\n", base[offset]);
171+
172+
kfree(base);
173+
174+
pr_info("Attempting bad read from freed memory\n");
175+
saw = base[offset];
176+
if (saw != val) {
177+
/* Good! Poisoning happened, so declare a win. */
178+
pr_info("Memory correctly poisoned (%x)\n", saw);
179+
} else {
180+
pr_err("FAIL: Memory was not poisoned!\n");
181+
pr_expected_config_param(CONFIG_INIT_ON_FREE_DEFAULT_ON, "init_on_free");
182+
}
183+
return;
184+
}
185+
186+
kfree(base);
187+
if (time_after(jiffies, resched_after))
188+
cond_resched();
189+
} while (time_before(jiffies, timeout));
190+
191+
pr_err("FAIL: kfence memory never allocated!\n");
192+
}
193+
135194
static void lkdtm_WRITE_BUDDY_AFTER_FREE(void)
136195
{
137196
unsigned long p = __get_free_page(GFP_KERNEL);
@@ -327,6 +386,7 @@ static struct crashtype crashtypes[] = {
327386
CRASHTYPE(VMALLOC_LINEAR_OVERFLOW),
328387
CRASHTYPE(WRITE_AFTER_FREE),
329388
CRASHTYPE(READ_AFTER_FREE),
389+
CRASHTYPE(KFENCE_READ_AFTER_FREE),
330390
CRASHTYPE(WRITE_BUDDY_AFTER_FREE),
331391
CRASHTYPE(READ_BUDDY_AFTER_FREE),
332392
CRASHTYPE(SLAB_INIT_ON_ALLOC),

drivers/misc/vmw_vmci/vmci_handle_array.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ struct vmci_handle_arr {
1717
u32 max_capacity;
1818
u32 size;
1919
u32 pad;
20-
struct vmci_handle entries[];
20+
struct vmci_handle entries[] __counted_by(capacity);
2121
};
2222

2323
#define VMCI_HANDLE_ARRAY_HEADER_SIZE \

drivers/nvdimm/btt.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -986,7 +986,7 @@ static int btt_arena_write_layout(struct arena_info *arena)
986986
if (!super)
987987
return -ENOMEM;
988988

989-
strncpy(super->signature, BTT_SIG, BTT_SIG_LEN);
989+
strscpy(super->signature, BTT_SIG, sizeof(super->signature));
990990
export_uuid(super->uuid, nd_btt->uuid);
991991
export_uuid(super->parent_uuid, parent_uuid);
992992
super->flags = cpu_to_le32(arena->flags);

drivers/nvme/host/fabrics.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -387,8 +387,8 @@ static struct nvmf_connect_data *nvmf_connect_data_prep(struct nvme_ctrl *ctrl,
387387

388388
uuid_copy(&data->hostid, &ctrl->opts->host->id);
389389
data->cntlid = cpu_to_le16(cntlid);
390-
strncpy(data->subsysnqn, ctrl->opts->subsysnqn, NVMF_NQN_SIZE);
391-
strncpy(data->hostnqn, ctrl->opts->host->nqn, NVMF_NQN_SIZE);
390+
strscpy(data->subsysnqn, ctrl->opts->subsysnqn, NVMF_NQN_SIZE);
391+
strscpy(data->hostnqn, ctrl->opts->host->nqn, NVMF_NQN_SIZE);
392392

393393
return data;
394394
}

drivers/nvme/host/fc.c

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1218,10 +1218,10 @@ nvme_fc_connect_admin_queue(struct nvme_fc_ctrl *ctrl,
12181218
/* Linux supports only Dynamic controllers */
12191219
assoc_rqst->assoc_cmd.cntlid = cpu_to_be16(0xffff);
12201220
uuid_copy(&assoc_rqst->assoc_cmd.hostid, &ctrl->ctrl.opts->host->id);
1221-
strncpy(assoc_rqst->assoc_cmd.hostnqn, ctrl->ctrl.opts->host->nqn,
1222-
min(FCNVME_ASSOC_HOSTNQN_LEN, NVMF_NQN_SIZE));
1223-
strncpy(assoc_rqst->assoc_cmd.subnqn, ctrl->ctrl.opts->subsysnqn,
1224-
min(FCNVME_ASSOC_SUBNQN_LEN, NVMF_NQN_SIZE));
1221+
strscpy(assoc_rqst->assoc_cmd.hostnqn, ctrl->ctrl.opts->host->nqn,
1222+
sizeof(assoc_rqst->assoc_cmd.hostnqn));
1223+
strscpy(assoc_rqst->assoc_cmd.subnqn, ctrl->ctrl.opts->subsysnqn,
1224+
sizeof(assoc_rqst->assoc_cmd.subnqn));
12251225

12261226
lsop->queue = queue;
12271227
lsreq->rqstaddr = assoc_rqst;

fs/afs/internal.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1213,7 +1213,7 @@ extern void afs_fs_inline_bulk_status(struct afs_operation *);
12131213

12141214
struct afs_acl {
12151215
u32 size;
1216-
u8 data[];
1216+
u8 data[] __counted_by(size);
12171217
};
12181218

12191219
extern void afs_fs_fetch_acl(struct afs_operation *);

fs/afs/xattr.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@ static bool afs_make_acl(struct afs_operation *op,
7575
{
7676
struct afs_acl *acl;
7777

78-
acl = kmalloc(sizeof(*acl) + size, GFP_KERNEL);
78+
acl = kmalloc(struct_size(acl, data, size), GFP_KERNEL);
7979
if (!acl) {
8080
afs_op_nomem(op);
8181
return false;

0 commit comments

Comments
 (0)