diff options
| author | Linus Torvalds <torvalds@linux-foundation.org> | 2018-06-12 18:28:00 -0700 |
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2018-06-12 18:28:00 -0700 |
| commit | b08fc5277aaa1d8ea15470d38bf36f19dfb0e125 (patch) | |
| tree | 1910dc474cb1ede95581dd9faa81a3bebeded0dc /fs | |
| parent | 4597fcff07044d89c646d0c5d8b42cd976d966a1 (diff) | |
| parent | 9d2a789c1db75d0f55b14fa57bec548d94332ad8 (diff) | |
| download | linux-b08fc5277aaa1d8ea15470d38bf36f19dfb0e125.tar.gz linux-b08fc5277aaa1d8ea15470d38bf36f19dfb0e125.tar.bz2 linux-b08fc5277aaa1d8ea15470d38bf36f19dfb0e125.zip | |
Merge tag 'overflow-v4.18-rc1-part2' of git://git.kernel.org/pub/scm/linux/kernel/git/kees/linux
Pull more overflow updates from Kees Cook:
"The rest of the overflow changes for v4.18-rc1.
This includes the explicit overflow fixes from Silvio, further
struct_size() conversions from Matthew, and a bug fix from Dan.
But the bulk of it is the treewide conversions to use either the
2-factor argument allocators (e.g. kmalloc(a * b, ...) into
kmalloc_array(a, b, ...) or the array_size() macros (e.g. vmalloc(a *
b) into vmalloc(array_size(a, b)).
Coccinelle was fighting me on several fronts, so I've done a bunch of
manual whitespace updates in the patches as well.
Summary:
- Error path bug fix for overflow tests (Dan)
- Additional struct_size() conversions (Matthew, Kees)
- Explicitly reported overflow fixes (Silvio, Kees)
- Add missing kvcalloc() function (Kees)
- Treewide conversions of allocators to use either 2-factor argument
variant when available, or array_size() and array3_size() as needed
(Kees)"
* tag 'overflow-v4.18-rc1-part2' of git://git.kernel.org/pub/scm/linux/kernel/git/kees/linux: (26 commits)
treewide: Use array_size in f2fs_kvzalloc()
treewide: Use array_size() in f2fs_kzalloc()
treewide: Use array_size() in f2fs_kmalloc()
treewide: Use array_size() in sock_kmalloc()
treewide: Use array_size() in kvzalloc_node()
treewide: Use array_size() in vzalloc_node()
treewide: Use array_size() in vzalloc()
treewide: Use array_size() in vmalloc()
treewide: devm_kzalloc() -> devm_kcalloc()
treewide: devm_kmalloc() -> devm_kmalloc_array()
treewide: kvzalloc() -> kvcalloc()
treewide: kvmalloc() -> kvmalloc_array()
treewide: kzalloc_node() -> kcalloc_node()
treewide: kzalloc() -> kcalloc()
treewide: kmalloc() -> kmalloc_array()
mm: Introduce kvcalloc()
video: uvesafb: Fix integer overflow in allocation
UBIFS: Fix potential integer overflow in allocation
leds: Use struct_size() in allocation
Convert intel uncore to struct_size
...
Diffstat (limited to 'fs')
75 files changed, 225 insertions, 158 deletions
diff --git a/fs/9p/fid.c b/fs/9p/fid.c index ed4f8519b627..a9ef46f02354 100644 --- a/fs/9p/fid.c +++ b/fs/9p/fid.c @@ -100,7 +100,7 @@ static int build_path_from_dentry(struct v9fs_session_info *v9ses, for (ds = dentry; !IS_ROOT(ds); ds = ds->d_parent) n++; - wnames = kmalloc(sizeof(char *) * n, GFP_KERNEL); + wnames = kmalloc_array(n, sizeof(char *), GFP_KERNEL); if (!wnames) goto err_out; diff --git a/fs/adfs/super.c b/fs/adfs/super.c index cfda2c7caedc..71fa525d63a0 100644 --- a/fs/adfs/super.c +++ b/fs/adfs/super.c @@ -313,7 +313,7 @@ static struct adfs_discmap *adfs_read_map(struct super_block *sb, struct adfs_di asb->s_ids_per_zone = zone_size / (asb->s_idlen + 1); - dm = kmalloc(nzones * sizeof(*dm), GFP_KERNEL); + dm = kmalloc_array(nzones, sizeof(*dm), GFP_KERNEL); if (dm == NULL) { adfs_error(sb, "not enough memory"); return ERR_PTR(-ENOMEM); diff --git a/fs/afs/cmservice.c b/fs/afs/cmservice.c index c332c95a6940..238fd28cfdd2 100644 --- a/fs/afs/cmservice.c +++ b/fs/afs/cmservice.c @@ -191,7 +191,8 @@ static int afs_deliver_cb_callback(struct afs_call *call) if (call->count > AFSCBMAX) return afs_protocol_error(call, -EBADMSG); - call->buffer = kmalloc(call->count * 3 * 4, GFP_KERNEL); + call->buffer = kmalloc(array3_size(call->count, 3, 4), + GFP_KERNEL); if (!call->buffer) return -ENOMEM; call->offset = 0; @@ -330,7 +331,7 @@ static int afs_deliver_cb_init_call_back_state3(struct afs_call *call) switch (call->unmarshall) { case 0: call->offset = 0; - call->buffer = kmalloc(11 * sizeof(__be32), GFP_KERNEL); + call->buffer = kmalloc_array(11, sizeof(__be32), GFP_KERNEL); if (!call->buffer) return -ENOMEM; call->unmarshall++; @@ -453,7 +454,7 @@ static int afs_deliver_cb_probe_uuid(struct afs_call *call) switch (call->unmarshall) { case 0: call->offset = 0; - call->buffer = kmalloc(11 * sizeof(__be32), GFP_KERNEL); + call->buffer = kmalloc_array(11, sizeof(__be32), GFP_KERNEL); if (!call->buffer) return -ENOMEM; call->unmarshall++; diff --git a/fs/binfmt_elf.c b/fs/binfmt_elf.c index 4ad6f669fe34..070b6184642d 100644 --- a/fs/binfmt_elf.c +++ b/fs/binfmt_elf.c @@ -2010,7 +2010,7 @@ static int elf_note_info_init(struct elf_note_info *info) INIT_LIST_HEAD(&info->thread_list); /* Allocate space for ELF notes */ - info->notes = kmalloc(8 * sizeof(struct memelfnote), GFP_KERNEL); + info->notes = kmalloc_array(8, sizeof(struct memelfnote), GFP_KERNEL); if (!info->notes) return 0; info->psinfo = kmalloc(sizeof(*info->psinfo), GFP_KERNEL); @@ -2294,7 +2294,7 @@ static int elf_core_dump(struct coredump_params *cprm) if (segs - 1 > ULONG_MAX / sizeof(*vma_filesz)) goto end_coredump; - vma_filesz = vmalloc((segs - 1) * sizeof(*vma_filesz)); + vma_filesz = vmalloc(array_size(sizeof(*vma_filesz), (segs - 1))); if (!vma_filesz) goto end_coredump; diff --git a/fs/binfmt_elf_fdpic.c b/fs/binfmt_elf_fdpic.c index d90993adeffa..b53bb3729ac1 100644 --- a/fs/binfmt_elf_fdpic.c +++ b/fs/binfmt_elf_fdpic.c @@ -1600,7 +1600,8 @@ static int elf_fdpic_core_dump(struct coredump_params *cprm) psinfo = kmalloc(sizeof(*psinfo), GFP_KERNEL); if (!psinfo) goto cleanup; - notes = kmalloc(NUM_NOTES * sizeof(struct memelfnote), GFP_KERNEL); + notes = kmalloc_array(NUM_NOTES, sizeof(struct memelfnote), + GFP_KERNEL); if (!notes) goto cleanup; fpu = kmalloc(sizeof(*fpu), GFP_KERNEL); diff --git a/fs/block_dev.c b/fs/block_dev.c index 05e12aea2404..0dd87aaeb39a 100644 --- a/fs/block_dev.c +++ b/fs/block_dev.c @@ -205,7 +205,8 @@ __blkdev_direct_IO_simple(struct kiocb *iocb, struct iov_iter *iter, if (nr_pages <= DIO_INLINE_BIO_VECS) vecs = inline_vecs; else { - vecs = kmalloc(nr_pages * sizeof(struct bio_vec), GFP_KERNEL); + vecs = kmalloc_array(nr_pages, sizeof(struct bio_vec), + GFP_KERNEL); if (!vecs) return -ENOMEM; } diff --git a/fs/btrfs/check-integrity.c b/fs/btrfs/check-integrity.c index dc062b195c46..a3fdb4fe967d 100644 --- a/fs/btrfs/check-integrity.c +++ b/fs/btrfs/check-integrity.c @@ -1603,8 +1603,8 @@ static int btrfsic_read_block(struct btrfsic_state *state, num_pages = (block_ctx->len + (u64)PAGE_SIZE - 1) >> PAGE_SHIFT; - block_ctx->mem_to_free = kzalloc((sizeof(*block_ctx->datav) + - sizeof(*block_ctx->pagev)) * + block_ctx->mem_to_free = kcalloc(sizeof(*block_ctx->datav) + + sizeof(*block_ctx->pagev), num_pages, GFP_NOFS); if (!block_ctx->mem_to_free) return -ENOMEM; diff --git a/fs/ceph/addr.c b/fs/ceph/addr.c index 5f7ad3d0df2e..c9cb2f33a6d6 100644 --- a/fs/ceph/addr.c +++ b/fs/ceph/addr.c @@ -370,7 +370,7 @@ static int start_read(struct inode *inode, struct ceph_rw_context *rw_ctx, /* build page vector */ nr_pages = calc_pages_for(0, len); - pages = kmalloc(sizeof(*pages) * nr_pages, GFP_KERNEL); + pages = kmalloc_array(nr_pages, sizeof(*pages), GFP_KERNEL); if (!pages) { ret = -ENOMEM; goto out_put; @@ -966,8 +966,9 @@ get_more_pages: BUG_ON(pages); max_pages = calc_pages_for(0, (u64)len); - pages = kmalloc(max_pages * sizeof (*pages), - GFP_NOFS); + pages = kmalloc_array(max_pages, + sizeof(*pages), + GFP_NOFS); if (!pages) { pool = fsc->wb_pagevec_pool; pages = mempool_alloc(pool, GFP_NOFS); @@ -1113,8 +1114,8 @@ new_request: /* allocate new pages array for next request */ data_pages = pages; - pages = kmalloc(locked_pages * sizeof (*pages), - GFP_NOFS); + pages = kmalloc_array(locked_pages, sizeof(*pages), + GFP_NOFS); if (!pages) { pool = fsc->wb_pagevec_pool; pages = mempool_alloc(pool, GFP_NOFS); diff --git a/fs/ceph/mds_client.c b/fs/ceph/mds_client.c index 5ece2e6ad154..cf8d24812cc0 100644 --- a/fs/ceph/mds_client.c +++ b/fs/ceph/mds_client.c @@ -2992,8 +2992,9 @@ encode_again: num_flock_locks = 0; } if (num_fcntl_locks + num_flock_locks > 0) { - flocks = kmalloc((num_fcntl_locks + num_flock_locks) * - sizeof(struct ceph_filelock), GFP_NOFS); + flocks = kmalloc_array(num_fcntl_locks + num_flock_locks, + sizeof(struct ceph_filelock), + GFP_NOFS); if (!flocks) { err = -ENOMEM; goto out_free; diff --git a/fs/cifs/asn1.c b/fs/cifs/asn1.c index a3b56544c21b..3d19595eb352 100644 --- a/fs/cifs/asn1.c +++ b/fs/cifs/asn1.c @@ -428,7 +428,7 @@ asn1_oid_decode(struct asn1_ctx *ctx, if (size < 2 || size > UINT_MAX/sizeof(unsigned long)) return 0; - *oid = kmalloc(size * sizeof(unsigned long), GFP_ATOMIC); + *oid = kmalloc_array(size, sizeof(unsigned long), GFP_ATOMIC); if (*oid == NULL) return 0; diff --git a/fs/cifs/cifsacl.c b/fs/cifs/cifsacl.c index 13a8a77322c9..1d377b7f2860 100644 --- a/fs/cifs/cifsacl.c +++ b/fs/cifs/cifsacl.c @@ -747,8 +747,8 @@ static void parse_dacl(struct cifs_acl *pdacl, char *end_of_acl, if (num_aces > ULONG_MAX / sizeof(struct cifs_ace *)) return; - ppace = kmalloc(num_aces * sizeof(struct cifs_ace *), - GFP_KERNEL); + ppace = kmalloc_array(num_aces, sizeof(struct cifs_ace *), + GFP_KERNEL); if (!ppace) return; diff --git a/fs/cifs/cifssmb.c b/fs/cifs/cifssmb.c index 5aca336642c0..42329b25877d 100644 --- a/fs/cifs/cifssmb.c +++ b/fs/cifs/cifssmb.c @@ -2077,7 +2077,7 @@ struct cifs_writedata * cifs_writedata_alloc(unsigned int nr_pages, work_func_t complete) { struct page **pages = - kzalloc(sizeof(struct page *) * nr_pages, GFP_NOFS); + kcalloc(nr_pages, sizeof(struct page *), GFP_NOFS); if (pages) return cifs_writedata_direct_alloc(pages, complete); diff --git a/fs/cifs/file.c b/fs/cifs/file.c index 87eece6fbd48..8d41ca7bfcf1 100644 --- a/fs/cifs/file.c +++ b/fs/cifs/file.c @@ -2900,7 +2900,7 @@ static struct cifs_readdata * cifs_readdata_alloc(unsigned int nr_pages, work_func_t complete) { struct page **pages = - kzalloc(sizeof(struct page *) * nr_pages, GFP_KERNEL); + kcalloc(nr_pages, sizeof(struct page *), GFP_KERNEL); struct cifs_readdata *ret = NULL; if (pages) { diff --git a/fs/cifs/inode.c b/fs/cifs/inode.c index 745fd7fe8d0e..a94071c7b408 100644 --- a/fs/cifs/inode.c +++ b/fs/cifs/inode.c @@ -1792,7 +1792,7 @@ cifs_rename2(struct inode *source_dir, struct dentry *source_dentry, * with unix extensions enabled. */ info_buf_source = - kmalloc(2 * sizeof(FILE_UNIX_BASIC_INFO), + kmalloc_array(2, sizeof(FILE_UNIX_BASIC_INFO), GFP_KERNEL); if (info_buf_source == NULL) { rc = -ENOMEM; diff --git a/fs/cifs/misc.c b/fs/cifs/misc.c index f90d4ad6624c..af29ade195c0 100644 --- a/fs/cifs/misc.c +++ b/fs/cifs/misc.c @@ -789,7 +789,7 @@ setup_aio_ctx_iter(struct cifs_aio_ctx *ctx, struct iov_iter *iter, int rw) GFP_KERNEL); if (!bv) { - bv = vmalloc(max_pages * sizeof(struct bio_vec)); + bv = vmalloc(array_size(max_pages, sizeof(struct bio_vec))); if (!bv) return -ENOMEM; } @@ -799,7 +799,7 @@ setup_aio_ctx_iter(struct cifs_aio_ctx *ctx, struct iov_iter *iter, int rw) GFP_KERNEL); if (!pages) { - pages = vmalloc(max_pages * sizeof(struct page *)); + pages = vmalloc(array_size(max_pages, sizeof(struct page *))); if (!pages) { kvfree(bv); return -ENOMEM; diff --git a/fs/cifs/smb2pdu.c b/fs/cifs/smb2pdu.c index 48e2004c75fb..af032e1a3eac 100644 --- a/fs/cifs/smb2pdu.c +++ b/fs/cifs/smb2pdu.c @@ -3471,7 +3471,7 @@ send_set_info(const unsigned int xid, struct cifs_tcon *tcon, if (!num) return -EINVAL; - iov = kmalloc(sizeof(struct kvec) * num, GFP_KERNEL); + iov = kmalloc_array(num, sizeof(struct kvec), GFP_KERNEL); if (!iov) return -ENOMEM; @@ -3535,7 +3535,7 @@ SMB2_rename(const unsigned int xid, struct cifs_tcon *tcon, int rc; int len = (2 * UniStrnlen((wchar_t *)target_file, PATH_MAX)); - data = kmalloc(sizeof(void *) * 2, GFP_KERNEL); + data = kmalloc_array(2, sizeof(void *), GFP_KERNEL); if (!data) return -ENOMEM; @@ -3583,7 +3583,7 @@ SMB2_set_hardlink(const unsigned int xid, struct cifs_tcon *tcon, int rc; int len = (2 * UniStrnlen((wchar_t *)target_file, PATH_MAX)); - data = kmalloc(sizeof(void *) * 2, GFP_KERNEL); + data = kmalloc_array(2, sizeof(void *), GFP_KERNEL); if (!data) return -ENOMEM; diff --git a/fs/cifs/transport.c b/fs/cifs/transport.c index 24887a0898c0..1f1a68f89110 100644 --- a/fs/cifs/transport.c +++ b/fs/cifs/transport.c @@ -844,8 +844,8 @@ SendReceive2(const unsigned int xid, struct cifs_ses *ses, int rc; if (n_vec + 1 > CIFS_MAX_IOV_SIZE) { - new_iov = kmalloc(sizeof(struct kvec) * (n_vec + 1), - GFP_KERNEL); + new_iov = kmalloc_array(n_vec + 1, sizeof(struct kvec), + GFP_KERNEL); if (!new_iov) { /* otherwise cifs_send_recv below sets resp_buf_type */ *resp_buf_type = CIFS_NO_BUFFER; @@ -886,8 +886,8 @@ smb2_send_recv(const unsigned int xid, struct cifs_ses *ses, __be32 rfc1002_marker; if (n_vec + 1 > CIFS_MAX_IOV_SIZE) { - new_iov = kmalloc(sizeof(struct kvec) * (n_vec + 1), - GFP_KERNEL); + new_iov = kmalloc_array(n_vec + 1, sizeof(struct kvec), + GFP_KERNEL); if (!new_iov) return -ENOMEM; } else diff --git a/fs/dlm/lockspace.c b/fs/dlm/lockspace.c index 78a7c855b06b..5ba94be006ee 100644 --- a/fs/dlm/lockspace.c +++ b/fs/dlm/lockspace.c @@ -517,7 +517,7 @@ static int new_lockspace(const char *name, const char *cluster, size = dlm_config.ci_rsbtbl_size; ls->ls_rsbtbl_size = size; - ls->ls_rsbtbl = vmalloc(sizeof(struct dlm_rsbtable) * size); + ls->ls_rsbtbl = vmalloc(array_size(size, sizeof(struct dlm_rsbtable))); if (!ls->ls_rsbtbl) goto out_lsfree; for (i = 0; i < size; i++) { diff --git a/fs/exofs/inode.c b/fs/exofs/inode.c index 0ac62811b341..5f81fcd383a4 100644 --- a/fs/exofs/inode.c +++ b/fs/exofs/inode.c @@ -110,8 +110,8 @@ static int pcol_try_alloc(struct page_collect *pcol) pages = exofs_max_io_pages(&pcol->sbi->layout, pcol->expected_pages); for (; pages; pages >>= 1) { - pcol->pages = kmalloc(pages * sizeof(struct page *), - GFP_KERNEL); + pcol->pages = kmalloc_array(pages, sizeof(struct page *), + GFP_KERNEL); if (likely(pcol->pages)) { pcol->alloc_pages = pages; return 0; diff --git a/fs/ext2/super.c b/fs/ext2/super.c index c09289a42dc5..25ab1274090f 100644 --- a/fs/ext2/super.c +++ b/fs/ext2/super.c @@ -1082,7 +1082,9 @@ static int ext2_fill_super(struct super_block *sb, void *data, int silent) / EXT2_BLOCKS_PER_GROUP(sb)) + 1; db_count = (sbi->s_groups_count + EXT2_DESC_PER_BLOCK(sb) - 1) / EXT2_DESC_PER_BLOCK(sb); - sbi->s_group_desc = kmalloc (db_count * sizeof (struct buffer_head *), GFP_KERNEL); + sbi->s_group_desc = kmalloc_array (db_count, + sizeof(struct buffer_head *), + GFP_KERNEL); if (sbi->s_group_desc == NULL) { ext2_msg(sb, KERN_ERR, "error: not enough memory"); goto failed_mount; diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c index c969275ce3ee..0057fe3f248d 100644 --- a/fs/ext4/extents.c +++ b/fs/ext4/extents.c @@ -577,7 +577,7 @@ int ext4_ext_precache(struct inode *inode) down_read(&ei->i_data_sem); depth = ext_depth(inode); - path = kzalloc(sizeof(struct ext4_ext_path) * (depth + 1), + path = kcalloc(depth + 1, sizeof(struct ext4_ext_path), GFP_NOFS); if (path == NULL) { up_read(&ei->i_data_sem); @@ -879,7 +879,7 @@ ext4_find_extent(struct inode *inode, ext4_lblk_t block, } if (!path) { /* account possible depth increase */ - path = kzalloc(sizeof(struct ext4_ext_path) * (depth + 2), + path = kcalloc(depth + 2, sizeof(struct ext4_ext_path), GFP_NOFS); if (unlikely(!path)) return ERR_PTR(-ENOMEM); @@ -1063,7 +1063,7 @@ static int ext4_ext_split(handle_t *handle, struct inode *inode, * We need this to handle errors and free blocks * upon them. */ - ablocks = kzalloc(sizeof(ext4_fsblk_t) * depth, GFP_NOFS); + ablocks = kcalloc(depth, sizeof(ext4_fsblk_t), GFP_NOFS); if (!ablocks) return -ENOMEM; @@ -2921,7 +2921,7 @@ again: path[k].p_block = le16_to_cpu(path[k].p_hdr->eh_entries)+1; } else { - path = kzalloc(sizeof(struct ext4_ext_path) * (depth + 1), + path = kcallo |
