Various hardening fixes and cleanups for 5.16-rc1

Hi Linus,
 
 Please, pull the following hardening fixes and cleanups that I've
 been collecting during the last development cycle. All of them have
 been baking in linux-next.
 
 Fix -Wcast-function-type error:
 
 - firewire: Remove function callback casts (Oscar Carter)
 
 Fix application of sizeof operator:
 
 - firmware/psci: fix application of sizeof to pointer (jing yangyang)
 
 Replace open coded instances with size_t saturating arithmetic helpers:
 
 - assoc_array: Avoid open coded arithmetic in allocator arguments (Len Baker)
 - writeback: prefer struct_size over open coded arithmetic (Len Baker)
 - aio: Prefer struct_size over open coded arithmetic (Len Baker)
 - dmaengine: pxa_dma: Prefer struct_size over open coded arithmetic (Len Baker)
 
 Flexible array transformation:
 
 - KVM: PPC: Replace zero-length array with flexible array member (Len Baker)
 
 Use 2-factor argument multiplication form:
 
 - nouveau/svm: Use kvcalloc() instead of kvzalloc() (Gustavo A. R. Silva)
 - xfs: Use kvcalloc() instead of kvzalloc() (Gustavo A. R. Silva)
 
 Thanks
 --
 Gustavo
 -----BEGIN PGP SIGNATURE-----
 
 iQIzBAABCAAdFiEEkmRahXBSurMIg1YvRwW0y0cG2zEFAmGAWzsACgkQRwW0y0cG
 2zF55A/+PTBZKg0XLQkPZ7HFipobeZpfvM0dU4JutwN6Kts1RmMRftPn6ootY18v
 4tWR4jXcnblvEr7UTgYAl6QQdytFXZKOK+JKMWV8LXLqyNGF6sS2PmA6zk/iQoa5
 1q0IKUaaqLIXwmm3xoz+/uNHsb+kfjYOHZpHA6HhYZQFDyShW7+hhIeS1NauJo2X
 op3IWasMumrawPkCJZ0ZJJQLELtZNGt4gHnOjB1MAYhOTAokowgeeDNtyfoJ9j1L
 iL8kimphVLI35H/GERBozmqdqRGIIZLlQF4P66VfNNEXSDoKOemAKDSFrfmYoVwE
 kdh6fqeKPV/aRImrCtNthfpiEjqEpm8afQGMC5H5uPnZontUX9tcU1Qagg0vwYx0
 fLZ8mMuNQK5AZfugK+1+2ShfBYUlhvWRhQdtjC9nIAoO80NqouWB7QD0zIHC2WV7
 durdlhzxik70ISnXqKmTR6bQNcXB6kFLPR30RpcA3E6+AgwlkP0FmaD3e+sDttJ0
 vtxDMHqMMNNzOWlLW2eqEdKMEfoU0gLyRt5iM7EN6R8HUXwup5f9bu7V4LuCnR6y
 FAX4tEa8b5wg01zNfyWClCccU6tetSeXjdrhdIk7szQVsOsYXc4zxDrp6xvqsAh2
 B7GbGk5qeUzM/O7QWNIl+5s/NhUjEzQ3QiQebRDdjVyINU2OKsI=
 =Jk0U
 -----END PGP SIGNATURE-----

Merge tag 'kspp-misc-fixes-5.16-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gustavoars/linux

Pull hardening fixes and cleanups from Gustavo A. R. Silva:
 "Various hardening fixes and cleanups that I've been collecting during
  the last development cycle:

  Fix -Wcast-function-type error:

   - firewire: Remove function callback casts (Oscar Carter)

  Fix application of sizeof operator:

   - firmware/psci: fix application of sizeof to pointer (jing yangyang)

  Replace open coded instances with size_t saturating arithmetic
  helpers:

   - assoc_array: Avoid open coded arithmetic in allocator arguments
     (Len Baker)

   - writeback: prefer struct_size over open coded arithmetic (Len
     Baker)

   - aio: Prefer struct_size over open coded arithmetic (Len Baker)

   - dmaengine: pxa_dma: Prefer struct_size over open coded arithmetic
     (Len Baker)

  Flexible array transformation:

   - KVM: PPC: Replace zero-length array with flexible array member (Len
     Baker)

  Use 2-factor argument multiplication form:

   - nouveau/svm: Use kvcalloc() instead of kvzalloc() (Gustavo A. R.
     Silva)

   - xfs: Use kvcalloc() instead of kvzalloc() (Gustavo A. R. Silva)"

* tag 'kspp-misc-fixes-5.16-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gustavoars/linux:
  firewire: Remove function callback casts
  nouveau/svm: Use kvcalloc() instead of kvzalloc()
  firmware/psci: fix application of sizeof to pointer
  dmaengine: pxa_dma: Prefer struct_size over open coded arithmetic
  KVM: PPC: Replace zero-length array with flexible array member
  aio: Prefer struct_size over open coded arithmetic
  writeback: prefer struct_size over open coded arithmetic
  xfs: Use kvcalloc() instead of kvzalloc()
  assoc_array: Avoid open coded arithmetic in allocator arguments
This commit is contained in:
Linus Torvalds 2021-11-01 17:29:10 -07:00
commit bf953917be
11 changed files with 55 additions and 37 deletions

View File

@ -190,7 +190,7 @@ struct kvmppc_spapr_tce_table {
u64 size; /* window size in pages */ u64 size; /* window size in pages */
struct list_head iommu_tables; struct list_head iommu_tables;
struct mutex alloc_lock; struct mutex alloc_lock;
struct page *pages[0]; struct page *pages[];
}; };
/* XICS components, defined in book3s_xics.c */ /* XICS components, defined in book3s_xics.c */

View File

@ -295,8 +295,7 @@ long kvm_vm_ioctl_create_spapr_tce(struct kvm *kvm,
return ret; return ret;
ret = -ENOMEM; ret = -ENOMEM;
stt = kzalloc(sizeof(*stt) + npages * sizeof(struct page *), stt = kzalloc(struct_size(stt, pages, npages), GFP_KERNEL);
GFP_KERNEL);
if (!stt) if (!stt)
goto fail_acct; goto fail_acct;

View File

@ -742,8 +742,7 @@ pxad_alloc_desc(struct pxad_chan *chan, unsigned int nb_hw_desc)
dma_addr_t dma; dma_addr_t dma;
int i; int i;
sw_desc = kzalloc(sizeof(*sw_desc) + sw_desc = kzalloc(struct_size(sw_desc, hw_desc, nb_hw_desc),
nb_hw_desc * sizeof(struct pxad_desc_hw *),
GFP_NOWAIT); GFP_NOWAIT);
if (!sw_desc) if (!sw_desc)
return NULL; return NULL;

View File

@ -10,6 +10,7 @@
#include <linux/delay.h> #include <linux/delay.h>
#include <linux/device.h> #include <linux/device.h>
#include <linux/dma-mapping.h> #include <linux/dma-mapping.h>
#include <linux/err.h>
#include <linux/errno.h> #include <linux/errno.h>
#include <linux/firewire.h> #include <linux/firewire.h>
#include <linux/firewire-cdev.h> #include <linux/firewire-cdev.h>
@ -953,11 +954,25 @@ static enum dma_data_direction iso_dma_direction(struct fw_iso_context *context)
return DMA_FROM_DEVICE; return DMA_FROM_DEVICE;
} }
static struct fw_iso_context *fw_iso_mc_context_create(struct fw_card *card,
fw_iso_mc_callback_t callback,
void *callback_data)
{
struct fw_iso_context *ctx;
ctx = fw_iso_context_create(card, FW_ISO_CONTEXT_RECEIVE_MULTICHANNEL,
0, 0, 0, NULL, callback_data);
if (!IS_ERR(ctx))
ctx->callback.mc = callback;
return ctx;
}
static int ioctl_create_iso_context(struct client *client, union ioctl_arg *arg) static int ioctl_create_iso_context(struct client *client, union ioctl_arg *arg)
{ {
struct fw_cdev_create_iso_context *a = &arg->create_iso_context; struct fw_cdev_create_iso_context *a = &arg->create_iso_context;
struct fw_iso_context *context; struct fw_iso_context *context;
fw_iso_callback_t cb; union fw_iso_callback cb;
int ret; int ret;
BUILD_BUG_ON(FW_CDEV_ISO_CONTEXT_TRANSMIT != FW_ISO_CONTEXT_TRANSMIT || BUILD_BUG_ON(FW_CDEV_ISO_CONTEXT_TRANSMIT != FW_ISO_CONTEXT_TRANSMIT ||
@ -970,7 +985,7 @@ static int ioctl_create_iso_context(struct client *client, union ioctl_arg *arg)
if (a->speed > SCODE_3200 || a->channel > 63) if (a->speed > SCODE_3200 || a->channel > 63)
return -EINVAL; return -EINVAL;
cb = iso_callback; cb.sc = iso_callback;
break; break;
case FW_ISO_CONTEXT_RECEIVE: case FW_ISO_CONTEXT_RECEIVE:
@ -978,19 +993,24 @@ static int ioctl_create_iso_context(struct client *client, union ioctl_arg *arg)
a->channel > 63) a->channel > 63)
return -EINVAL; return -EINVAL;
cb = iso_callback; cb.sc = iso_callback;
break; break;
case FW_ISO_CONTEXT_RECEIVE_MULTICHANNEL: case FW_ISO_CONTEXT_RECEIVE_MULTICHANNEL:
cb = (fw_iso_callback_t)iso_mc_callback; cb.mc = iso_mc_callback;
break; break;
default: default:
return -EINVAL; return -EINVAL;
} }
context = fw_iso_context_create(client->device->card, a->type, if (a->type == FW_ISO_CONTEXT_RECEIVE_MULTICHANNEL)
a->channel, a->speed, a->header_size, cb, client); context = fw_iso_mc_context_create(client->device->card, cb.mc,
client);
else
context = fw_iso_context_create(client->device->card, a->type,
a->channel, a->speed,
a->header_size, cb.sc, client);
if (IS_ERR(context)) if (IS_ERR(context))
return PTR_ERR(context); return PTR_ERR(context);
if (client->version < FW_CDEV_VERSION_AUTO_FLUSH_ISO_OVERFLOW) if (client->version < FW_CDEV_VERSION_AUTO_FLUSH_ISO_OVERFLOW)

View File

@ -155,7 +155,7 @@ static int alloc_init_cpu_groups(cpumask_var_t **pcpu_groups)
if (!alloc_cpumask_var(&tmp, GFP_KERNEL)) if (!alloc_cpumask_var(&tmp, GFP_KERNEL))
return -ENOMEM; return -ENOMEM;
cpu_groups = kcalloc(nb_available_cpus, sizeof(cpu_groups), cpu_groups = kcalloc(nb_available_cpus, sizeof(*cpu_groups),
GFP_KERNEL); GFP_KERNEL);
if (!cpu_groups) { if (!cpu_groups) {
free_cpumask_var(tmp); free_cpumask_var(tmp);

View File

@ -992,7 +992,7 @@ nouveau_svm_fault_buffer_ctor(struct nouveau_svm *svm, s32 oclass, int id)
if (ret) if (ret)
return ret; return ret;
buffer->fault = kvzalloc(sizeof(*buffer->fault) * buffer->entries, GFP_KERNEL); buffer->fault = kvcalloc(sizeof(*buffer->fault), buffer->entries, GFP_KERNEL);
if (!buffer->fault) if (!buffer->fault)
return -ENOMEM; return -ENOMEM;

View File

@ -659,8 +659,7 @@ static int ioctx_add_table(struct kioctx *ctx, struct mm_struct *mm)
new_nr = (table ? table->nr : 1) * 4; new_nr = (table ? table->nr : 1) * 4;
spin_unlock(&mm->ioctx_lock); spin_unlock(&mm->ioctx_lock);
table = kzalloc(sizeof(*table) + sizeof(struct kioctx *) * table = kzalloc(struct_size(table, table, new_nr), GFP_KERNEL);
new_nr, GFP_KERNEL);
if (!table) if (!table)
return -ENOMEM; return -ENOMEM;

View File

@ -566,7 +566,7 @@ static void inode_switch_wbs(struct inode *inode, int new_wb_id)
if (atomic_read(&isw_nr_in_flight) > WB_FRN_MAX_IN_FLIGHT) if (atomic_read(&isw_nr_in_flight) > WB_FRN_MAX_IN_FLIGHT)
return; return;
isw = kzalloc(sizeof(*isw) + 2 * sizeof(struct inode *), GFP_ATOMIC); isw = kzalloc(struct_size(isw, inodes, 2), GFP_ATOMIC);
if (!isw) if (!isw)
return; return;
@ -624,8 +624,8 @@ bool cleanup_offline_cgwb(struct bdi_writeback *wb)
int nr; int nr;
bool restart = false; bool restart = false;
isw = kzalloc(sizeof(*isw) + WB_MAX_INODES_PER_ISW * isw = kzalloc(struct_size(isw, inodes, WB_MAX_INODES_PER_ISW),
sizeof(struct inode *), GFP_KERNEL); GFP_KERNEL);
if (!isw) if (!isw)
return restart; return restart;

View File

@ -1547,7 +1547,7 @@ xfs_ioc_getbmap(
if (bmx.bmv_count > ULONG_MAX / recsize) if (bmx.bmv_count > ULONG_MAX / recsize)
return -ENOMEM; return -ENOMEM;
buf = kvzalloc(bmx.bmv_count * sizeof(*buf), GFP_KERNEL); buf = kvcalloc(bmx.bmv_count, sizeof(*buf), GFP_KERNEL);
if (!buf) if (!buf)
return -ENOMEM; return -ENOMEM;
@ -1601,11 +1601,11 @@ xfs_ioc_getfsmap(
*/ */
count = min_t(unsigned int, head.fmh_count, count = min_t(unsigned int, head.fmh_count,
131072 / sizeof(struct fsmap)); 131072 / sizeof(struct fsmap));
recs = kvzalloc(count * sizeof(struct fsmap), GFP_KERNEL); recs = kvcalloc(count, sizeof(struct fsmap), GFP_KERNEL);
if (!recs) { if (!recs) {
count = min_t(unsigned int, head.fmh_count, count = min_t(unsigned int, head.fmh_count,
PAGE_SIZE / sizeof(struct fsmap)); PAGE_SIZE / sizeof(struct fsmap));
recs = kvzalloc(count * sizeof(struct fsmap), GFP_KERNEL); recs = kvcalloc(count, sizeof(struct fsmap), GFP_KERNEL);
if (!recs) if (!recs)
return -ENOMEM; return -ENOMEM;
} }

View File

@ -436,6 +436,12 @@ typedef void (*fw_iso_callback_t)(struct fw_iso_context *context,
void *header, void *data); void *header, void *data);
typedef void (*fw_iso_mc_callback_t)(struct fw_iso_context *context, typedef void (*fw_iso_mc_callback_t)(struct fw_iso_context *context,
dma_addr_t completed, void *data); dma_addr_t completed, void *data);
union fw_iso_callback {
fw_iso_callback_t sc;
fw_iso_mc_callback_t mc;
};
struct fw_iso_context { struct fw_iso_context {
struct fw_card *card; struct fw_card *card;
int type; int type;
@ -443,10 +449,7 @@ struct fw_iso_context {
int speed; int speed;
bool drop_overflow_headers; bool drop_overflow_headers;
size_t header_size; size_t header_size;
union { union fw_iso_callback callback;
fw_iso_callback_t sc;
fw_iso_mc_callback_t mc;
} callback;
void *callback_data; void *callback_data;
}; };

View File

@ -741,8 +741,7 @@ static bool assoc_array_insert_into_terminal_node(struct assoc_array_edit *edit,
keylen = round_up(diff, ASSOC_ARRAY_KEY_CHUNK_SIZE); keylen = round_up(diff, ASSOC_ARRAY_KEY_CHUNK_SIZE);
keylen >>= ASSOC_ARRAY_KEY_CHUNK_SHIFT; keylen >>= ASSOC_ARRAY_KEY_CHUNK_SHIFT;
new_s0 = kzalloc(sizeof(struct assoc_array_shortcut) + new_s0 = kzalloc(struct_size(new_s0, index_key, keylen), GFP_KERNEL);
keylen * sizeof(unsigned long), GFP_KERNEL);
if (!new_s0) if (!new_s0)
return false; return false;
edit->new_meta[2] = assoc_array_shortcut_to_ptr(new_s0); edit->new_meta[2] = assoc_array_shortcut_to_ptr(new_s0);
@ -849,8 +848,8 @@ static bool assoc_array_insert_mid_shortcut(struct assoc_array_edit *edit,
keylen = round_up(diff, ASSOC_ARRAY_KEY_CHUNK_SIZE); keylen = round_up(diff, ASSOC_ARRAY_KEY_CHUNK_SIZE);
keylen >>= ASSOC_ARRAY_KEY_CHUNK_SHIFT; keylen >>= ASSOC_ARRAY_KEY_CHUNK_SHIFT;
new_s0 = kzalloc(sizeof(struct assoc_array_shortcut) + new_s0 = kzalloc(struct_size(new_s0, index_key, keylen),
keylen * sizeof(unsigned long), GFP_KERNEL); GFP_KERNEL);
if (!new_s0) if (!new_s0)
return false; return false;
edit->new_meta[1] = assoc_array_shortcut_to_ptr(new_s0); edit->new_meta[1] = assoc_array_shortcut_to_ptr(new_s0);
@ -864,7 +863,7 @@ static bool assoc_array_insert_mid_shortcut(struct assoc_array_edit *edit,
new_n0->parent_slot = 0; new_n0->parent_slot = 0;
memcpy(new_s0->index_key, shortcut->index_key, memcpy(new_s0->index_key, shortcut->index_key,
keylen * sizeof(unsigned long)); flex_array_size(new_s0, index_key, keylen));
blank = ULONG_MAX << (diff & ASSOC_ARRAY_KEY_CHUNK_MASK); blank = ULONG_MAX << (diff & ASSOC_ARRAY_KEY_CHUNK_MASK);
pr_devel("blank off [%zu] %d: %lx\n", keylen - 1, diff, blank); pr_devel("blank off [%zu] %d: %lx\n", keylen - 1, diff, blank);
@ -899,8 +898,8 @@ static bool assoc_array_insert_mid_shortcut(struct assoc_array_edit *edit,
keylen = round_up(shortcut->skip_to_level, ASSOC_ARRAY_KEY_CHUNK_SIZE); keylen = round_up(shortcut->skip_to_level, ASSOC_ARRAY_KEY_CHUNK_SIZE);
keylen >>= ASSOC_ARRAY_KEY_CHUNK_SHIFT; keylen >>= ASSOC_ARRAY_KEY_CHUNK_SHIFT;
new_s1 = kzalloc(sizeof(struct assoc_array_shortcut) + new_s1 = kzalloc(struct_size(new_s1, index_key, keylen),
keylen * sizeof(unsigned long), GFP_KERNEL); GFP_KERNEL);
if (!new_s1) if (!new_s1)
return false; return false;
edit->new_meta[2] = assoc_array_shortcut_to_ptr(new_s1); edit->new_meta[2] = assoc_array_shortcut_to_ptr(new_s1);
@ -913,7 +912,7 @@ static bool assoc_array_insert_mid_shortcut(struct assoc_array_edit *edit,
new_n0->slots[sc_slot] = assoc_array_shortcut_to_ptr(new_s1); new_n0->slots[sc_slot] = assoc_array_shortcut_to_ptr(new_s1);
memcpy(new_s1->index_key, shortcut->index_key, memcpy(new_s1->index_key, shortcut->index_key,
keylen * sizeof(unsigned long)); flex_array_size(new_s1, index_key, keylen));
edit->set[1].ptr = &side->back_pointer; edit->set[1].ptr = &side->back_pointer;
edit->set[1].to = assoc_array_shortcut_to_ptr(new_s1); edit->set[1].to = assoc_array_shortcut_to_ptr(new_s1);
@ -1490,13 +1489,12 @@ int assoc_array_gc(struct assoc_array *array,
shortcut = assoc_array_ptr_to_shortcut(cursor); shortcut = assoc_array_ptr_to_shortcut(cursor);
keylen = round_up(shortcut->skip_to_level, ASSOC_ARRAY_KEY_CHUNK_SIZE); keylen = round_up(shortcut->skip_to_level, ASSOC_ARRAY_KEY_CHUNK_SIZE);
keylen >>= ASSOC_ARRAY_KEY_CHUNK_SHIFT; keylen >>= ASSOC_ARRAY_KEY_CHUNK_SHIFT;
new_s = kmalloc(sizeof(struct assoc_array_shortcut) + new_s = kmalloc(struct_size(new_s, index_key, keylen),
keylen * sizeof(unsigned long), GFP_KERNEL); GFP_KERNEL);
if (!new_s) if (!new_s)
goto enomem; goto enomem;
pr_devel("dup shortcut %p -> %p\n", shortcut, new_s); pr_devel("dup shortcut %p -> %p\n", shortcut, new_s);
memcpy(new_s, shortcut, (sizeof(struct assoc_array_shortcut) + memcpy(new_s, shortcut, struct_size(new_s, index_key, keylen));
keylen * sizeof(unsigned long)));
new_s->back_pointer = new_parent; new_s->back_pointer = new_parent;
new_s->parent_slot = shortcut->parent_slot; new_s->parent_slot = shortcut->parent_slot;
*new_ptr_pp = new_parent = assoc_array_shortcut_to_ptr(new_s); *new_ptr_pp = new_parent = assoc_array_shortcut_to_ptr(new_s);