Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

HID: hid-steam: Fix cleanup in probe()

There are a number of issues in this code. First of all if
steam_create_client_hid() fails then it leads to an error pointer
dereference when we call hid_destroy_device(steam->client_hdev).

Also there are a number of leaks. hid_hw_stop() is not called if
hid_hw_open() fails for example. And it doesn't call steam_unregister()
or hid_hw_close().

Fixes: 691ead124a0c ("HID: hid-steam: Clean up locking")
Signed-off-by: Dan Carpenter <dan.carpenter@linaro.org>
Reviewed-by: Vicki Pfau <vi@endrift.com>
Link: https://lore.kernel.org/r/1fd87904-dabf-4879-bb89-72d13ebfc91e@moroto.mountain
Signed-off-by: Benjamin Tissoires <bentiss@kernel.org>

authored by

Dan Carpenter and committed by
Benjamin Tissoires
a9f1da09 a9668169

+15 -11
+15 -11
drivers/hid/hid-steam.c
··· 1128 1128 */ 1129 1129 ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT & ~HID_CONNECT_HIDRAW); 1130 1130 if (ret) 1131 - goto hid_hw_start_fail; 1131 + goto err_cancel_work; 1132 1132 1133 1133 ret = hid_hw_open(hdev); 1134 1134 if (ret) { 1135 1135 hid_err(hdev, 1136 1136 "%s:hid_hw_open\n", 1137 1137 __func__); 1138 - goto hid_hw_open_fail; 1138 + goto err_hw_stop; 1139 1139 } 1140 1140 1141 1141 if (steam->quirks & STEAM_QUIRK_WIRELESS) { ··· 1151 1151 hid_err(hdev, 1152 1152 "%s:steam_register failed with error %d\n", 1153 1153 __func__, ret); 1154 - goto input_register_fail; 1154 + goto err_hw_close; 1155 1155 } 1156 1156 } 1157 1157 1158 1158 steam->client_hdev = steam_create_client_hid(hdev); 1159 1159 if (IS_ERR(steam->client_hdev)) { 1160 1160 ret = PTR_ERR(steam->client_hdev); 1161 - goto client_hdev_fail; 1161 + goto err_stream_unregister; 1162 1162 } 1163 1163 steam->client_hdev->driver_data = steam; 1164 1164 1165 1165 ret = hid_add_device(steam->client_hdev); 1166 1166 if (ret) 1167 - goto client_hdev_add_fail; 1167 + goto err_destroy; 1168 1168 1169 1169 return 0; 1170 1170 1171 - client_hdev_add_fail: 1172 - hid_hw_stop(hdev); 1173 - client_hdev_fail: 1171 + err_destroy: 1174 1172 hid_destroy_device(steam->client_hdev); 1175 - input_register_fail: 1176 - hid_hw_open_fail: 1177 - hid_hw_start_fail: 1173 + err_stream_unregister: 1174 + if (steam->connected) 1175 + steam_unregister(steam); 1176 + err_hw_close: 1177 + hid_hw_close(hdev); 1178 + err_hw_stop: 1179 + hid_hw_stop(hdev); 1180 + err_cancel_work: 1178 1181 cancel_work_sync(&steam->work_connect); 1179 1182 cancel_delayed_work_sync(&steam->mode_switch); 1180 1183 cancel_work_sync(&steam->rumble_work); 1184 + 1181 1185 return ret; 1182 1186 } 1183 1187