summaryrefslogtreecommitdiffstats
path: root/drivers/platform/x86
diff options
context:
space:
mode:
authorShyam Sundar S K <Shyam-sundar.S-k@amd.com>2023-10-10 20:20:01 +0530
committerIlpo Järvinen <ilpo.jarvinen@linux.intel.com>2023-10-12 16:40:09 +0300
commitd9f421da6b9287000f8253628d54cf89b0c14da5 (patch)
treeb4eb58c21dff4e5dc37f82cc3500688b1670c811 /drivers/platform/x86
parent5a026767275ef0ba6d7aba37629d9ec638aabb7d (diff)
downloadlinux-stable-d9f421da6b9287000f8253628d54cf89b0c14da5.tar.gz
linux-stable-d9f421da6b9287000f8253628d54cf89b0c14da5.tar.bz2
linux-stable-d9f421da6b9287000f8253628d54cf89b0c14da5.zip
platform/x86/amd/pmc: Use flex array when calling amd_pmc_stb_debugfs_open_v2()
Currently in amd_pmc_stb_debugfs_open_v2() the buffer size is assumed to be fixed and a second call to amd_pmc_stb_debugfs_open_v2() may race with a process holding open another fd. This could change "fsize" to a bigger size causing an out of bounds read. Instead create a struct with a flexarray to solve this. Suggested-by: Hans de Goede <hdegoede@redhat.com> Reviewed-by: Hans de Goede <hdegoede@redhat.com> Signed-off-by: Sanket Goswami <Sanket.Goswami@amd.com> Signed-off-by: Shyam Sundar S K <Shyam-sundar.S-k@amd.com> Link: https://lore.kernel.org/r/20231010145003.139932-1-Shyam-sundar.S-k@amd.com [ij: renamed flex_arr -> stb_data_arr] Reviewed-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com> Signed-off-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
Diffstat (limited to 'drivers/platform/x86')
-rw-r--r--drivers/platform/x86/amd/pmc/pmc.c32
1 files changed, 19 insertions, 13 deletions
diff --git a/drivers/platform/x86/amd/pmc/pmc.c b/drivers/platform/x86/amd/pmc/pmc.c
index 922932a71233..77dca9a1f00f 100644
--- a/drivers/platform/x86/amd/pmc/pmc.c
+++ b/drivers/platform/x86/amd/pmc/pmc.c
@@ -52,7 +52,7 @@
#define AMD_S2D_REGISTER_ARGUMENT 0xA88
/* STB Spill to DRAM Parameters */
-#define S2D_TELEMETRY_BYTES_MAX 0x100000
+#define S2D_TELEMETRY_BYTES_MAX 0x100000U
#define S2D_TELEMETRY_DRAMBYTES_MAX 0x1000000
/* STB Spill to DRAM Message Definition */
@@ -122,6 +122,11 @@ enum s2d_arg {
S2D_DRAM_SIZE,
};
+struct amd_pmc_stb_v2_data {
+ size_t size;
+ u8 data[] __counted_by(size);
+};
+
struct amd_pmc_bit_map {
const char *name;
u32 bit_mask;
@@ -239,7 +244,8 @@ static const struct file_operations amd_pmc_stb_debugfs_fops = {
static int amd_pmc_stb_debugfs_open_v2(struct inode *inode, struct file *filp)
{
struct amd_pmc_dev *dev = filp->f_inode->i_private;
- u32 *buf, fsize, num_samples, val, stb_rdptr_offset = 0;
+ u32 fsize, num_samples, val, stb_rdptr_offset = 0;
+ struct amd_pmc_stb_v2_data *stb_data_arr;
int ret;
/* Write dummy postcode while reading the STB buffer */
@@ -247,10 +253,6 @@ static int amd_pmc_stb_debugfs_open_v2(struct inode *inode, struct file *filp)
if (ret)
dev_err(dev->dev, "error writing to STB: %d\n", ret);
- buf = kzalloc(S2D_TELEMETRY_BYTES_MAX, GFP_KERNEL);
- if (!buf)
- return -ENOMEM;
-
/* Spill to DRAM num_samples uses separate SMU message port */
dev->msg_port = 1;
@@ -264,10 +266,16 @@ static int amd_pmc_stb_debugfs_open_v2(struct inode *inode, struct file *filp)
dev->msg_port = 0;
if (ret) {
dev_err(dev->dev, "error: S2D_NUM_SAMPLES not supported : %d\n", ret);
- kfree(buf);
return ret;
}
+ fsize = min(num_samples, S2D_TELEMETRY_BYTES_MAX);
+ stb_data_arr = kmalloc(struct_size(stb_data_arr, data, fsize), GFP_KERNEL);
+ if (!stb_data_arr)
+ return -ENOMEM;
+
+ stb_data_arr->size = fsize;
+
/* Start capturing data from the last push location */
if (num_samples > S2D_TELEMETRY_BYTES_MAX) {
fsize = S2D_TELEMETRY_BYTES_MAX;
@@ -277,8 +285,8 @@ static int amd_pmc_stb_debugfs_open_v2(struct inode *inode, struct file *filp)
stb_rdptr_offset = 0;
}
- memcpy_fromio(buf, dev->stb_virt_addr + stb_rdptr_offset, fsize);
- filp->private_data = buf;
+ memcpy_fromio(stb_data_arr->data, dev->stb_virt_addr + stb_rdptr_offset, fsize);
+ filp->private_data = stb_data_arr;
return 0;
}
@@ -286,11 +294,9 @@ static int amd_pmc_stb_debugfs_open_v2(struct inode *inode, struct file *filp)
static ssize_t amd_pmc_stb_debugfs_read_v2(struct file *filp, char __user *buf, size_t size,
loff_t *pos)
{
- if (!filp->private_data)
- return -EINVAL;
+ struct amd_pmc_stb_v2_data *data = filp->private_data;
- return simple_read_from_buffer(buf, size, pos, filp->private_data,
- S2D_TELEMETRY_BYTES_MAX);
+ return simple_read_from_buffer(buf, size, pos, data->data, data->size);
}
static int amd_pmc_stb_debugfs_release_v2(struct inode *inode, struct file *filp)