summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDmitry Torokhov <dmitry.torokhov@gmail.com>2026-03-26 09:25:38 +0300
committerJiri Kosina <jkosina@suse.com>2026-03-27 14:07:12 +0300
commit8c58be287604da91a4da6b0b1af866c1c193576c (patch)
tree49405ee5a49a489bf470f73498c9f1fe71f78d36
parentd7db259bd6df56f9540ef92535a5c709b375c4d5 (diff)
downloadlinux-8c58be287604da91a4da6b0b1af866c1c193576c.tar.xz
HID: core: use __free(kfree) and __free(kvfree) to clean up temporary buffers
This simplifies error handling and protects against memory leaks. Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com> Signed-off-by: Jiri Kosina <jkosina@suse.com>
-rw-r--r--drivers/hid/hid-core.c34
1 files changed, 12 insertions, 22 deletions
diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c
index 2c8c9d05e450..49775e3624ef 100644
--- a/drivers/hid/hid-core.c
+++ b/drivers/hid/hid-core.c
@@ -924,7 +924,6 @@ static int hid_scan_main(struct hid_parser *parser, struct hid_item *item)
*/
static int hid_scan_report(struct hid_device *hid)
{
- struct hid_parser *parser;
struct hid_item item;
const __u8 *start = hid->dev_rdesc;
const __u8 *end = start + hid->dev_rsize;
@@ -936,7 +935,7 @@ static int hid_scan_report(struct hid_device *hid)
hid_parser_reserved
};
- parser = vzalloc(sizeof(struct hid_parser));
+ struct hid_parser *parser __free(kvfree) = vzalloc(sizeof(*parser));
if (!parser)
return -ENOMEM;
@@ -987,7 +986,6 @@ static int hid_scan_report(struct hid_device *hid)
}
kfree(parser->collection_stack);
- vfree(parser);
return 0;
}
@@ -1246,7 +1244,6 @@ EXPORT_SYMBOL_GPL(hid_setup_resolution_multiplier);
static int hid_parse_collections(struct hid_device *device)
{
- struct hid_parser *parser;
struct hid_item item;
const u8 *start = device->rdesc;
const u8 *end = start + device->rsize;
@@ -1259,7 +1256,7 @@ static int hid_parse_collections(struct hid_device *device)
hid_parser_reserved
};
- parser = vzalloc(sizeof(*parser));
+ struct hid_parser *parser __free(kvfree) = vzalloc(sizeof(*parser));
if (!parser)
return -ENOMEM;
@@ -1267,10 +1264,9 @@ static int hid_parse_collections(struct hid_device *device)
device->collection = kzalloc_objs(*device->collection,
HID_DEFAULT_NUM_COLLECTIONS);
- if (!device->collection) {
- ret = -ENOMEM;
- goto out;
- }
+ if (!device->collection)
+ return -ENOMEM;
+
device->collection_size = HID_DEFAULT_NUM_COLLECTIONS;
for (unsigned int i = 0; i < HID_DEFAULT_NUM_COLLECTIONS; i++)
device->collection[i].parent_idx = -1;
@@ -1322,7 +1318,6 @@ static int hid_parse_collections(struct hid_device *device)
out:
kfree(parser->collection_stack);
- vfree(parser);
return ret;
}
@@ -1358,9 +1353,9 @@ int hid_open_report(struct hid_device *device)
* on a copy of our report descriptor so it can
* change it.
*/
- __u8 *buf = kmemdup(start, size, GFP_KERNEL);
+ u8 *buf __free(kfree) = kmemdup(start, size, GFP_KERNEL);
- if (buf == NULL)
+ if (!buf)
return -ENOMEM;
start = device->driver->report_fixup(device, buf, &size);
@@ -1371,8 +1366,7 @@ int hid_open_report(struct hid_device *device)
* needs to be cleaned up or not at the end.
*/
start = kmemdup(start, size, GFP_KERNEL);
- kfree(buf);
- if (start == NULL)
+ if (!start)
return -ENOMEM;
}
@@ -1998,11 +1992,11 @@ static struct hid_report *hid_get_report(struct hid_report_enum *report_enum,
int __hid_request(struct hid_device *hid, struct hid_report *report,
enum hid_class_request reqtype)
{
- char *buf, *data_buf;
+ u8 *data_buf;
int ret;
u32 len;
- buf = hid_alloc_report_buf(report, GFP_KERNEL);
+ u8 *buf __free(kfree) = hid_alloc_report_buf(report, GFP_KERNEL);
if (!buf)
return -ENOMEM;
@@ -2021,17 +2015,13 @@ int __hid_request(struct hid_device *hid, struct hid_report *report,
ret = hid_hw_raw_request(hid, report->id, buf, len, report->type, reqtype);
if (ret < 0) {
dbg_hid("unable to complete request: %d\n", ret);
- goto out;
+ return ret;
}
if (reqtype == HID_REQ_GET_REPORT)
hid_input_report(hid, report->type, buf, ret, 0);
- ret = 0;
-
-out:
- kfree(buf);
- return ret;
+ return 0;
}
EXPORT_SYMBOL_GPL(__hid_request);