Skip to content

Commit

Permalink
Merge tag 'overflow-v4.18-rc1' of git://git.kernel.org/pub/scm/linux/…
Browse files Browse the repository at this point in the history
…kernel/git/kees/linux

Pull overflow updates from Kees Cook:
 "This adds the new overflow checking helpers and adds them to the
  2-factor argument allocators. And this adds the saturating size
  helpers and does a treewide replacement for the struct_size() usage.
  Additionally this adds the overflow testing modules to make sure
  everything works.

  I'm still working on the treewide replacements for allocators with
  "simple" multiplied arguments:

     *alloc(a * b, ...) -> *alloc_array(a, b, ...)

  and

     *zalloc(a * b, ...) -> *calloc(a, b, ...)

  as well as the more complex cases, but that's separable from this
  portion of the series. I expect to have the rest sent before -rc1
  closes; there are a lot of messy cases to clean up.

  Summary:

   - Introduce arithmetic overflow test helper functions (Rasmus)

   - Use overflow helpers in 2-factor allocators (Kees, Rasmus)

   - Introduce overflow test module (Rasmus, Kees)

   - Introduce saturating size helper functions (Matthew, Kees)

   - Treewide use of struct_size() for allocators (Kees)"

* tag 'overflow-v4.18-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/kees/linux:
  treewide: Use struct_size() for devm_kmalloc() and friends
  treewide: Use struct_size() for vmalloc()-family
  treewide: Use struct_size() for kmalloc()-family
  device: Use overflow helpers for devm_kmalloc()
  mm: Use overflow helpers in kvmalloc()
  mm: Use overflow helpers in kmalloc_array*()
  test_overflow: Add memory allocation overflow tests
  overflow.h: Add allocation size calculation helpers
  test_overflow: Report test failures
  test_overflow: macrofy some more, do more tests for free
  lib: add runtime test of check_*_overflow functions
  compiler.h: enable builtin overflow checkers and add fallback code
  • Loading branch information
torvalds committed Jun 7, 2018
2 parents 5eb6eed + 0ed2dd0 commit 2857676
Show file tree
Hide file tree
Showing 99 changed files with 916 additions and 205 deletions.
4 changes: 2 additions & 2 deletions crypto/af_alg.c
Original file line number Diff line number Diff line change
Expand Up @@ -500,8 +500,8 @@ int af_alg_alloc_tsgl(struct sock *sk)
sg = sgl->sg;

if (!sg || sgl->cur >= MAX_SGL_ENTS) {
sgl = sock_kmalloc(sk, sizeof(*sgl) +
sizeof(sgl->sg[0]) * (MAX_SGL_ENTS + 1),
sgl = sock_kmalloc(sk,
struct_size(sgl, sg, (MAX_SGL_ENTS + 1)),
GFP_KERNEL);
if (!sgl)
return -ENOMEM;
Expand Down
7 changes: 6 additions & 1 deletion drivers/base/devres.c
Original file line number Diff line number Diff line change
Expand Up @@ -84,9 +84,14 @@ static struct devres_group * node_to_group(struct devres_node *node)
static __always_inline struct devres * alloc_dr(dr_release_t release,
size_t size, gfp_t gfp, int nid)
{
size_t tot_size = sizeof(struct devres) + size;
size_t tot_size;
struct devres *dr;

/* We must catch any near-SIZE_MAX cases that could overflow. */
if (unlikely(check_add_overflow(sizeof(struct devres), size,
&tot_size)))
return NULL;

dr = kmalloc_node_track_caller(tot_size, gfp, nid);
if (unlikely(!dr))
return NULL;
Expand Down
6 changes: 4 additions & 2 deletions drivers/clk/bcm/clk-bcm2835-aux.c
Original file line number Diff line number Diff line change
Expand Up @@ -40,8 +40,10 @@ static int bcm2835_aux_clk_probe(struct platform_device *pdev)
if (IS_ERR(reg))
return PTR_ERR(reg);

onecell = devm_kmalloc(dev, sizeof(*onecell) + sizeof(*onecell->hws) *
BCM2835_AUX_CLOCK_COUNT, GFP_KERNEL);
onecell = devm_kmalloc(dev,
struct_size(onecell, hws,
BCM2835_AUX_CLOCK_COUNT),
GFP_KERNEL);
if (!onecell)
return -ENOMEM;
onecell->num = BCM2835_AUX_CLOCK_COUNT;
Expand Down
4 changes: 2 additions & 2 deletions drivers/clk/bcm/clk-bcm2835.c
Original file line number Diff line number Diff line change
Expand Up @@ -2147,8 +2147,8 @@ static int bcm2835_clk_probe(struct platform_device *pdev)
size_t i;
int ret;

cprman = devm_kzalloc(dev, sizeof(*cprman) +
sizeof(*cprman->onecell.hws) * asize,
cprman = devm_kzalloc(dev,
struct_size(cprman, onecell.hws, asize),
GFP_KERNEL);
if (!cprman)
return -ENOMEM;
Expand Down
4 changes: 2 additions & 2 deletions drivers/clk/bcm/clk-iproc-asiu.c
Original file line number Diff line number Diff line change
Expand Up @@ -197,8 +197,8 @@ void __init iproc_asiu_setup(struct device_node *node,
if (WARN_ON(!asiu))
return;

asiu->clk_data = kzalloc(sizeof(*asiu->clk_data->hws) * num_clks +
sizeof(*asiu->clk_data), GFP_KERNEL);
asiu->clk_data = kzalloc(struct_size(asiu->clk_data, hws, num_clks),
GFP_KERNEL);
if (WARN_ON(!asiu->clk_data))
goto err_clks;
asiu->clk_data->num = num_clks;
Expand Down
3 changes: 1 addition & 2 deletions drivers/clk/bcm/clk-iproc-pll.c
Original file line number Diff line number Diff line change
Expand Up @@ -744,8 +744,7 @@ void iproc_pll_clk_setup(struct device_node *node,
if (WARN_ON(!pll))
return;

clk_data = kzalloc(sizeof(*clk_data->hws) * num_clks +
sizeof(*clk_data), GFP_KERNEL);
clk_data = kzalloc(struct_size(clk_data, hws, num_clks), GFP_KERNEL);
if (WARN_ON(!clk_data))
goto err_clk_data;
clk_data->num = num_clks;
Expand Down
3 changes: 1 addition & 2 deletions drivers/clk/berlin/bg2.c
Original file line number Diff line number Diff line change
Expand Up @@ -509,8 +509,7 @@ static void __init berlin2_clock_setup(struct device_node *np)
u8 avpll_flags = 0;
int n, ret;

clk_data = kzalloc(sizeof(*clk_data) +
sizeof(*clk_data->hws) * MAX_CLKS, GFP_KERNEL);
clk_data = kzalloc(struct_size(clk_data, hws, MAX_CLKS), GFP_KERNEL);
if (!clk_data)
return;
clk_data->num = MAX_CLKS;
Expand Down
3 changes: 1 addition & 2 deletions drivers/clk/berlin/bg2q.c
Original file line number Diff line number Diff line change
Expand Up @@ -295,8 +295,7 @@ static void __init berlin2q_clock_setup(struct device_node *np)
struct clk_hw **hws;
int n, ret;

clk_data = kzalloc(sizeof(*clk_data) +
sizeof(*clk_data->hws) * MAX_CLKS, GFP_KERNEL);
clk_data = kzalloc(struct_size(clk_data, hws, MAX_CLKS), GFP_KERNEL);
if (!clk_data)
return;
clk_data->num = MAX_CLKS;
Expand Down
3 changes: 1 addition & 2 deletions drivers/clk/clk-asm9260.c
Original file line number Diff line number Diff line change
Expand Up @@ -273,8 +273,7 @@ static void __init asm9260_acc_init(struct device_node *np)
int n;
u32 accuracy = 0;

clk_data = kzalloc(sizeof(*clk_data) +
sizeof(*clk_data->hws) * MAX_CLKS, GFP_KERNEL);
clk_data = kzalloc(struct_size(clk_data, hws, MAX_CLKS), GFP_KERNEL);
if (!clk_data)
return;
clk_data->num = MAX_CLKS;
Expand Down
6 changes: 3 additions & 3 deletions drivers/clk/clk-aspeed.c
Original file line number Diff line number Diff line change
Expand Up @@ -627,9 +627,9 @@ static void __init aspeed_cc_init(struct device_node *np)
if (!scu_base)
return;

aspeed_clk_data = kzalloc(sizeof(*aspeed_clk_data) +
sizeof(*aspeed_clk_data->hws) * ASPEED_NUM_CLKS,
GFP_KERNEL);
aspeed_clk_data = kzalloc(struct_size(aspeed_clk_data, hws,
ASPEED_NUM_CLKS),
GFP_KERNEL);
if (!aspeed_clk_data)
return;

Expand Down
6 changes: 3 additions & 3 deletions drivers/clk/clk-clps711x.c
Original file line number Diff line number Diff line change
Expand Up @@ -54,9 +54,9 @@ static struct clps711x_clk * __init _clps711x_clk_init(void __iomem *base,
if (!base)
return ERR_PTR(-ENOMEM);

clps711x_clk = kzalloc(sizeof(*clps711x_clk) +
sizeof(*clps711x_clk->clk_data.hws) * CLPS711X_CLK_MAX,
GFP_KERNEL);
clps711x_clk = kzalloc(struct_size(clps711x_clk, clk_data.hws,
CLPS711X_CLK_MAX),
GFP_KERNEL);
if (!clps711x_clk)
return ERR_PTR(-ENOMEM);

Expand Down
4 changes: 2 additions & 2 deletions drivers/clk/clk-efm32gg.c
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,8 @@ static void __init efm32gg_cmu_init(struct device_node *np)
void __iomem *base;
struct clk_hw **hws;

clk_data = kzalloc(sizeof(*clk_data) +
sizeof(*clk_data->hws) * CMU_MAX_CLKS, GFP_KERNEL);
clk_data = kzalloc(struct_size(clk_data, hws, CMU_MAX_CLKS),
GFP_KERNEL);

if (!clk_data)
return;
Expand Down
6 changes: 3 additions & 3 deletions drivers/clk/clk-gemini.c
Original file line number Diff line number Diff line change
Expand Up @@ -399,9 +399,9 @@ static void __init gemini_cc_init(struct device_node *np)
int ret;
int i;

gemini_clk_data = kzalloc(sizeof(*gemini_clk_data) +
sizeof(*gemini_clk_data->hws) * GEMINI_NUM_CLKS,
GFP_KERNEL);
gemini_clk_data = kzalloc(struct_size(gemini_clk_data, hws,
GEMINI_NUM_CLKS),
GFP_KERNEL);
if (!gemini_clk_data)
return;

Expand Down
4 changes: 2 additions & 2 deletions drivers/clk/clk-s2mps11.c
Original file line number Diff line number Diff line change
Expand Up @@ -147,8 +147,8 @@ static int s2mps11_clk_probe(struct platform_device *pdev)
if (!s2mps11_clks)
return -ENOMEM;

clk_data = devm_kzalloc(&pdev->dev, sizeof(*clk_data) +
sizeof(*clk_data->hws) * S2MPS11_CLKS_NUM,
clk_data = devm_kzalloc(&pdev->dev,
struct_size(clk_data, hws, S2MPS11_CLKS_NUM),
GFP_KERNEL);
if (!clk_data)
return -ENOMEM;
Expand Down
4 changes: 2 additions & 2 deletions drivers/clk/clk-scmi.c
Original file line number Diff line number Diff line change
Expand Up @@ -137,8 +137,8 @@ static int scmi_clocks_probe(struct scmi_device *sdev)
return -EINVAL;
}

clk_data = devm_kzalloc(dev, sizeof(*clk_data) +
sizeof(*clk_data->hws) * count, GFP_KERNEL);
clk_data = devm_kzalloc(dev, struct_size(clk_data, hws, count),
GFP_KERNEL);
if (!clk_data)
return -ENOMEM;

Expand Down
5 changes: 2 additions & 3 deletions drivers/clk/clk-stm32h7.c
Original file line number Diff line number Diff line change
Expand Up @@ -1201,9 +1201,8 @@ static void __init stm32h7_rcc_init(struct device_node *np)
const char *hse_clk, *lse_clk, *i2s_clk;
struct regmap *pdrm;

clk_data = kzalloc(sizeof(*clk_data) +
sizeof(*clk_data->hws) * STM32H7_MAX_CLKS,
GFP_KERNEL);
clk_data = kzalloc(struct_size(clk_data, hws, STM32H7_MAX_CLKS),
GFP_KERNEL);
if (!clk_data)
return;

Expand Down
5 changes: 2 additions & 3 deletions drivers/clk/clk-stm32mp1.c
Original file line number Diff line number Diff line change
Expand Up @@ -2060,9 +2060,8 @@ static int stm32_rcc_init(struct device_node *np,

max_binding = data->maxbinding;

clk_data = kzalloc(sizeof(*clk_data) +
sizeof(*clk_data->hws) * max_binding,
GFP_KERNEL);
clk_data = kzalloc(struct_size(clk_data, hws, max_binding),
GFP_KERNEL);
if (!clk_data)
return -ENOMEM;

Expand Down
4 changes: 2 additions & 2 deletions drivers/clk/davinci/da8xx-cfgchip.c
Original file line number Diff line number Diff line change
Expand Up @@ -650,8 +650,8 @@ static int of_da8xx_usb_phy_clk_init(struct device *dev, struct regmap *regmap)
struct da8xx_usb0_clk48 *usb0;
struct da8xx_usb1_clk48 *usb1;

clk_data = devm_kzalloc(dev, sizeof(*clk_data) + 2 *
sizeof(*clk_data->hws), GFP_KERNEL);
clk_data = devm_kzalloc(dev, struct_size(clk_data, hws, 2),
GFP_KERNEL);
if (!clk_data)
return -ENOMEM;

Expand Down
7 changes: 4 additions & 3 deletions drivers/clk/mvebu/armada-37xx-periph.c
Original file line number Diff line number Diff line change
Expand Up @@ -667,9 +667,10 @@ static int armada_3700_periph_clock_probe(struct platform_device *pdev)
if (!driver_data)
return -ENOMEM;

driver_data->hw_data = devm_kzalloc(dev, sizeof(*driver_data->hw_data) +
sizeof(*driver_data->hw_data->hws) * num_periph,
GFP_KERNEL);
driver_data->hw_data = devm_kzalloc(dev,
struct_size(driver_data->hw_data,
hws, num_periph),
GFP_KERNEL);
if (!driver_data->hw_data)
return -ENOMEM;
driver_data->hw_data->num = num_periph;
Expand Down
4 changes: 2 additions & 2 deletions drivers/clk/mvebu/armada-37xx-tbg.c
Original file line number Diff line number Diff line change
Expand Up @@ -91,8 +91,8 @@ static int armada_3700_tbg_clock_probe(struct platform_device *pdev)
void __iomem *reg;
int i, ret;

hw_tbg_data = devm_kzalloc(&pdev->dev, sizeof(*hw_tbg_data)
+ sizeof(*hw_tbg_data->hws) * NUM_TBG,
hw_tbg_data = devm_kzalloc(&pdev->dev,
struct_size(hw_tbg_data, hws, NUM_TBG),
GFP_KERNEL);
if (!hw_tbg_data)
return -ENOMEM;
Expand Down
3 changes: 1 addition & 2 deletions drivers/clk/qcom/clk-spmi-pmic-div.c
Original file line number Diff line number Diff line change
Expand Up @@ -239,8 +239,7 @@ static int spmi_pmic_clkdiv_probe(struct platform_device *pdev)
if (!nclks)
return -EINVAL;

cc = devm_kzalloc(dev, sizeof(*cc) + sizeof(*cc->clks) * nclks,
GFP_KERNEL);
cc = devm_kzalloc(dev, struct_size(cc, clks, nclks), GFP_KERNEL);
if (!cc)
return -ENOMEM;
cc->nclks = nclks;
Expand Down
4 changes: 2 additions & 2 deletions drivers/clk/samsung/clk-exynos-audss.c
Original file line number Diff line number Diff line change
Expand Up @@ -149,8 +149,8 @@ static int exynos_audss_clk_probe(struct platform_device *pdev)
epll = ERR_PTR(-ENODEV);

clk_data = devm_kzalloc(dev,
sizeof(*clk_data) +
sizeof(*clk_data->hws) * EXYNOS_AUDSS_MAX_CLKS,
struct_size(clk_data, hws,
EXYNOS_AUDSS_MAX_CLKS),
GFP_KERNEL);
if (!clk_data)
return -ENOMEM;
Expand Down
3 changes: 1 addition & 2 deletions drivers/clk/samsung/clk-exynos-clkout.c
Original file line number Diff line number Diff line change
Expand Up @@ -61,8 +61,7 @@ static void __init exynos_clkout_init(struct device_node *node, u32 mux_mask)
int ret;
int i;

clkout = kzalloc(sizeof(*clkout) +
sizeof(*clkout->data.hws) * EXYNOS_CLKOUT_NR_CLKS,
clkout = kzalloc(struct_size(clkout, data.hws, EXYNOS_CLKOUT_NR_CLKS),
GFP_KERNEL);
if (!clkout)
return;
Expand Down
4 changes: 2 additions & 2 deletions drivers/clk/samsung/clk-exynos5433.c
Original file line number Diff line number Diff line change
Expand Up @@ -5505,8 +5505,8 @@ static int __init exynos5433_cmu_probe(struct platform_device *pdev)

info = of_device_get_match_data(dev);

data = devm_kzalloc(dev, sizeof(*data) +
sizeof(*data->ctx.clk_data.hws) * info->nr_clk_ids,
data = devm_kzalloc(dev,
struct_size(data, ctx.clk_data.hws, info->nr_clk_ids),
GFP_KERNEL);
if (!data)
return -ENOMEM;
Expand Down
7 changes: 4 additions & 3 deletions drivers/clk/samsung/clk-s3c2410-dclk.c
Original file line number Diff line number Diff line change
Expand Up @@ -247,9 +247,10 @@ static int s3c24xx_dclk_probe(struct platform_device *pdev)
struct clk_hw **clk_table;
int ret, i;

s3c24xx_dclk = devm_kzalloc(&pdev->dev, sizeof(*s3c24xx_dclk) +
sizeof(*s3c24xx_dclk->clk_data.hws) * DCLK_MAX_CLKS,
GFP_KERNEL);
s3c24xx_dclk = devm_kzalloc(&pdev->dev,
struct_size(s3c24xx_dclk, clk_data.hws,
DCLK_MAX_CLKS),
GFP_KERNEL);
if (!s3c24xx_dclk)
return -ENOMEM;

Expand Down
3 changes: 1 addition & 2 deletions drivers/clk/samsung/clk-s5pv210-audss.c
Original file line number Diff line number Diff line change
Expand Up @@ -81,8 +81,7 @@ static int s5pv210_audss_clk_probe(struct platform_device *pdev)
}

clk_data = devm_kzalloc(&pdev->dev,
sizeof(*clk_data) +
sizeof(*clk_data->hws) * AUDSS_MAX_CLKS,
struct_size(clk_data, hws, AUDSS_MAX_CLKS),
GFP_KERNEL);

if (!clk_data)
Expand Down
2 changes: 1 addition & 1 deletion drivers/dax/device.c
Original file line number Diff line number Diff line change
Expand Up @@ -594,7 +594,7 @@ struct dev_dax *devm_create_dev_dax(struct dax_region *dax_region,
if (!count)
return ERR_PTR(-EINVAL);

dev_dax = kzalloc(sizeof(*dev_dax) + sizeof(*res) * count, GFP_KERNEL);
dev_dax = kzalloc(struct_size(dev_dax, res, count), GFP_KERNEL);
if (!dev_dax)
return ERR_PTR(-ENOMEM);

Expand Down
5 changes: 2 additions & 3 deletions drivers/dma/bcm-sba-raid.c
Original file line number Diff line number Diff line change
Expand Up @@ -1499,9 +1499,8 @@ static int sba_prealloc_channel_resources(struct sba_device *sba)

for (i = 0; i < sba->max_req; i++) {
req = devm_kzalloc(sba->dev,
sizeof(*req) +
sba->max_cmd_per_req * sizeof(req->cmds[0]),
GFP_KERNEL);
struct_size(req, cmds, sba->max_cmd_per_req),
GFP_KERNEL);
if (!req) {
ret = -ENOMEM;
goto fail_free_cmds_pool;
Expand Down
9 changes: 3 additions & 6 deletions drivers/dma/edma.c
Original file line number Diff line number Diff line change
Expand Up @@ -1074,8 +1074,7 @@ static struct dma_async_tx_descriptor *edma_prep_slave_sg(
return NULL;
}

edesc = kzalloc(sizeof(*edesc) + sg_len * sizeof(edesc->pset[0]),
GFP_ATOMIC);
edesc = kzalloc(struct_size(edesc, pset, sg_len), GFP_ATOMIC);
if (!edesc)
return NULL;

Expand Down Expand Up @@ -1192,8 +1191,7 @@ static struct dma_async_tx_descriptor *edma_prep_dma_memcpy(
nslots = 2;
}

edesc = kzalloc(sizeof(*edesc) + nslots * sizeof(edesc->pset[0]),
GFP_ATOMIC);
edesc = kzalloc(struct_size(edesc, pset, nslots), GFP_ATOMIC);
if (!edesc)
return NULL;

Expand Down Expand Up @@ -1315,8 +1313,7 @@ static struct dma_async_tx_descriptor *edma_prep_dma_cyclic(
}
}

edesc = kzalloc(sizeof(*edesc) + nslots * sizeof(edesc->pset[0]),
GFP_ATOMIC);
edesc = kzalloc(struct_size(edesc, pset, nslots), GFP_ATOMIC);
if (!edesc)
return NULL;

Expand Down
2 changes: 1 addition & 1 deletion drivers/dma/moxart-dma.c
Original file line number Diff line number Diff line change
Expand Up @@ -309,7 +309,7 @@ static struct dma_async_tx_descriptor *moxart_prep_slave_sg(
return NULL;
}

d = kzalloc(sizeof(*d) + sg_len * sizeof(d->sg[0]), GFP_ATOMIC);
d = kzalloc(struct_size(d, sg, sg_len), GFP_ATOMIC);
if (!d)
return NULL;

Expand Down
4 changes: 2 additions & 2 deletions drivers/dma/nbpfaxi.c
Original file line number Diff line number Diff line change
Expand Up @@ -1305,8 +1305,8 @@ static int nbpf_probe(struct platform_device *pdev)
cfg = of_device_get_match_data(dev);
num_channels = cfg->num_channels;

nbpf = devm_kzalloc(dev, sizeof(*nbpf) + num_channels *
sizeof(nbpf->chan[0]), GFP_KERNEL);
nbpf = devm_kzalloc(dev, struct_size(nbpf, chan, num_channels),
GFP_KERNEL);
if (!nbpf)
return -ENOMEM;

Expand Down
2 changes: 1 addition & 1 deletion drivers/dma/omap-dma.c
Original file line number Diff line number Diff line change
Expand Up @@ -917,7 +917,7 @@ static struct dma_async_tx_descriptor *omap_dma_prep_slave_sg(
}

/* Now allocate and setup the descriptor. */
d = kzalloc(sizeof(*d) + sglen * sizeof(d->sg[0]), GFP_ATOMIC);
d = kzalloc(struct_size(d, sg, sglen), GFP_ATOMIC);
if (!d)
return NULL;

Expand Down
4 changes: 2 additions & 2 deletions drivers/dma/sa11x0-dma.c
Original file line number Diff line number Diff line change
Expand Up @@ -557,7 +557,7 @@ static struct dma_async_tx_descriptor *sa11x0_dma_prep_slave_sg(
}
}

txd = kzalloc(sizeof(*txd) + j * sizeof(txd->sg[0]), GFP_ATOMIC);
txd = kzalloc(struct_size(txd, sg, j), GFP_ATOMIC);
if (!txd) {
dev_dbg(chan->device->dev, "vchan %p: kzalloc failed\n", &c->vc);
return NULL;
Expand Down Expand Up @@ -627,7 +627,7 @@ static struct dma_async_tx_descriptor *sa11x0_dma_prep_dma_cyclic(
if (sglen == 0)
return NULL;

txd = kzalloc(sizeof(*txd) + sglen * sizeof(txd->sg[0]), GFP_ATOMIC);
txd = kzalloc(struct_size(txd, sg, sglen), GFP_ATOMIC);
if (!txd) {
dev_dbg(chan->device->dev, "vchan %p: kzalloc failed\n", &c->vc);
return NULL;
Expand Down
Loading

0 comments on commit 2857676

Please sign in to comment.