linux/drivers/clk/visconti/clkc.h
Dan Carpenter c5601e0720 clk: visconti: prevent array overflow in visconti_clk_register_gates()
This code was using -1 to represent that there was no reset function.
Unfortunately, the -1 was stored in u8 so the if (clks[i].rs_id >= 0)
condition was always true.  This lead to an out of bounds access in
visconti_clk_register_gates().

Fixes: b4cbe606dc ("clk: visconti: Add support common clock driver and reset driver")
Signed-off-by: Dan Carpenter <dan.carpenter@oracle.com>
Link: https://lore.kernel.org/r/20220316083533.GA30941@kili
Acked-by: Nobuhiro Iwamatsu <nobuhiro1.iwamatsu@toshiba.co.jp>
Signed-off-by: Stephen Boyd <sboyd@kernel.org>
2022-03-17 12:21:28 -07:00

80 lines
1.7 KiB
C

/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Toshiba Visconti clock controller
*
* Copyright (c) 2021 TOSHIBA CORPORATION
* Copyright (c) 2021 Toshiba Electronic Devices & Storage Corporation
*
* Nobuhiro Iwamatsu <nobuhiro1.iwamatsu@toshiba.co.jp>
*/
#ifndef _VISCONTI_CLKC_H_
#define _VISCONTI_CLKC_H_
#include <linux/mfd/syscon.h>
#include <linux/clk-provider.h>
#include <linux/of.h>
#include <linux/of_address.h>
#include <linux/delay.h>
#include <linux/regmap.h>
#include <linux/slab.h>
#include <linux/string.h>
#include <linux/io.h>
#include <linux/spinlock.h>
#include "reset.h"
struct visconti_clk_provider {
struct device *dev;
struct regmap *regmap;
struct clk_hw_onecell_data clk_data;
};
struct visconti_clk_gate_table {
unsigned int id;
const char *name;
const struct clk_parent_data *parent_data;
u8 num_parents;
u8 flags;
u32 ckon_offset;
u32 ckoff_offset;
u8 ck_idx;
unsigned int div;
u8 rs_id;
};
struct visconti_fixed_clk {
unsigned int id;
const char *name;
const char *parent;
unsigned long flag;
unsigned int mult;
unsigned int div;
};
struct visconti_clk_gate {
struct clk_hw hw;
struct regmap *regmap;
u32 ckon_offset;
u32 ckoff_offset;
u8 ck_idx;
u8 flags;
u32 rson_offset;
u32 rsoff_offset;
u8 rs_idx;
spinlock_t *lock;
};
struct visconti_clk_provider *visconti_init_clk(struct device *dev,
struct regmap *regmap,
unsigned long nr_clks);
int visconti_clk_register_gates(struct visconti_clk_provider *data,
const struct visconti_clk_gate_table *clks,
int num_gate,
const struct visconti_reset_data *reset,
spinlock_t *lock);
#define NO_RESET 0xFF
#endif /* _VISCONTI_CLKC_H_ */