Skip to content

Commit f6cc4b6

Browse files
AlexiousLukuba-moo
authored andcommitted
fjes: fix memleaks in fjes_hw_setup
In fjes_hw_setup, it allocates several memory and delay the deallocation to the fjes_hw_exit in fjes_probe through the following call chain: fjes_probe |-> fjes_hw_init |-> fjes_hw_setup |-> fjes_hw_exit However, when fjes_hw_setup fails, fjes_hw_exit won't be called and thus all the resources allocated in fjes_hw_setup will be leaked. In this patch, we free those resources in fjes_hw_setup and prevents such leaks. Fixes: 2fcbca6 ("fjes: platform_driver's .probe and .remove routine") Signed-off-by: Zhipeng Lu <alexious@zju.edu.cn> Reviewed-by: Simon Horman <horms@kernel.org> Link: https://lore.kernel.org/r/20240122172445.3841883-1-alexious@zju.edu.cn Signed-off-by: Jakub Kicinski <kuba@kernel.org>
1 parent 77be224 commit f6cc4b6

1 file changed

Lines changed: 30 additions & 7 deletions

File tree

drivers/net/fjes/fjes_hw.c

Lines changed: 30 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -221,21 +221,25 @@ static int fjes_hw_setup(struct fjes_hw *hw)
221221

222222
mem_size = FJES_DEV_REQ_BUF_SIZE(hw->max_epid);
223223
hw->hw_info.req_buf = kzalloc(mem_size, GFP_KERNEL);
224-
if (!(hw->hw_info.req_buf))
225-
return -ENOMEM;
224+
if (!(hw->hw_info.req_buf)) {
225+
result = -ENOMEM;
226+
goto free_ep_info;
227+
}
226228

227229
hw->hw_info.req_buf_size = mem_size;
228230

229231
mem_size = FJES_DEV_RES_BUF_SIZE(hw->max_epid);
230232
hw->hw_info.res_buf = kzalloc(mem_size, GFP_KERNEL);
231-
if (!(hw->hw_info.res_buf))
232-
return -ENOMEM;
233+
if (!(hw->hw_info.res_buf)) {
234+
result = -ENOMEM;
235+
goto free_req_buf;
236+
}
233237

234238
hw->hw_info.res_buf_size = mem_size;
235239

236240
result = fjes_hw_alloc_shared_status_region(hw);
237241
if (result)
238-
return result;
242+
goto free_res_buf;
239243

240244
hw->hw_info.buffer_share_bit = 0;
241245
hw->hw_info.buffer_unshare_reserve_bit = 0;
@@ -246,11 +250,11 @@ static int fjes_hw_setup(struct fjes_hw *hw)
246250

247251
result = fjes_hw_alloc_epbuf(&buf_pair->tx);
248252
if (result)
249-
return result;
253+
goto free_epbuf;
250254

251255
result = fjes_hw_alloc_epbuf(&buf_pair->rx);
252256
if (result)
253-
return result;
257+
goto free_epbuf;
254258

255259
spin_lock_irqsave(&hw->rx_status_lock, flags);
256260
fjes_hw_setup_epbuf(&buf_pair->tx, mac,
@@ -273,6 +277,25 @@ static int fjes_hw_setup(struct fjes_hw *hw)
273277
fjes_hw_init_command_registers(hw, &param);
274278

275279
return 0;
280+
281+
free_epbuf:
282+
for (epidx = 0; epidx < hw->max_epid ; epidx++) {
283+
if (epidx == hw->my_epid)
284+
continue;
285+
fjes_hw_free_epbuf(&hw->ep_shm_info[epidx].tx);
286+
fjes_hw_free_epbuf(&hw->ep_shm_info[epidx].rx);
287+
}
288+
fjes_hw_free_shared_status_region(hw);
289+
free_res_buf:
290+
kfree(hw->hw_info.res_buf);
291+
hw->hw_info.res_buf = NULL;
292+
free_req_buf:
293+
kfree(hw->hw_info.req_buf);
294+
hw->hw_info.req_buf = NULL;
295+
free_ep_info:
296+
kfree(hw->ep_shm_info);
297+
hw->ep_shm_info = NULL;
298+
return result;
276299
}
277300

278301
static void fjes_hw_cleanup(struct fjes_hw *hw)

0 commit comments

Comments
 (0)