mirror of
https://github.com/torvalds/linux.git
synced 2024-12-06 19:11:31 +00:00
greybus: power_supply: rework get descriptors
Rework the get property descriptors function to fix a memory handling error for the response structure. This could corrupt the stack and throw nonalignment PC or SP error: Internal error: SP or PC abort: 8a000000 1 PREEMPT SMP Modules linked in: gb_power_supply(O) gb_arche(O) gb_camera(O) gb_es2(O) gb_vibrator(O) gb_raw(O) g] CPU: 3 PID: 51 Comm: kworker/u16:2 Tainted: G W O 3.10.73-g8a6af60-00118-g599a5c1 #1 Workqueue: greybus1:svc gb_svc_connection_destroy [greybus] task: ffffffc0ba249580 ti: ffffffc0ba294000 task.ti: ffffffc0ba294000 PC is at gb_power_supply_connection_init+0x81/0x1dc [gb_power_supply] LR is at gb_power_supply_connection_init+0x81/0x1dc [gb_power_supply] pc : [<ffffffbffc03b901>] lr : [<ffffffbffc03b901>] pstate: 80000145 sp : ffffffc0ba297a00 x29: 32002e002a001100 x28: ffffffc042cb2c80 To fix this, allocate firstly the operation and handle request and response using operation payload. Signed-off-by: Rui Miguel Silva <rui.silva@linaro.org> Signed-off-by: Greg Kroah-Hartman <gregkh@google.com>
This commit is contained in:
parent
db81b76970
commit
9d15134d06
@ -249,39 +249,53 @@ static int gb_power_supply_description_get(struct gb_power_supply *gbpsy)
|
||||
static int gb_power_supply_prop_descriptors_get(struct gb_power_supply *gbpsy)
|
||||
{
|
||||
struct gb_connection *connection = get_conn_from_psy(gbpsy);
|
||||
struct gb_power_supply_get_property_descriptors_request req;
|
||||
struct gb_power_supply_get_property_descriptors_response resp;
|
||||
struct gb_power_supply_get_property_descriptors_request *req;
|
||||
struct gb_power_supply_get_property_descriptors_response *resp;
|
||||
struct gb_operation *op;
|
||||
u8 props_count = gbpsy->properties_count;
|
||||
int ret;
|
||||
int i;
|
||||
|
||||
if (gbpsy->properties_count == 0)
|
||||
if (props_count == 0)
|
||||
return 0;
|
||||
|
||||
req.psy_id = gbpsy->id;
|
||||
op = gb_operation_create(connection,
|
||||
GB_POWER_SUPPLY_TYPE_GET_PROP_DESCRIPTORS,
|
||||
sizeof(req), sizeof(*resp) + props_count *
|
||||
sizeof(struct gb_power_supply_props_desc),
|
||||
GFP_KERNEL);
|
||||
if (!op)
|
||||
return -ENOMEM;
|
||||
|
||||
ret = gb_operation_sync(connection,
|
||||
GB_POWER_SUPPLY_TYPE_GET_PROP_DESCRIPTORS,
|
||||
&req, sizeof(req), &resp,
|
||||
sizeof(resp) + gbpsy->properties_count *
|
||||
sizeof(struct gb_power_supply_props_desc));
|
||||
req = op->request->payload;
|
||||
req->psy_id = gbpsy->id;
|
||||
|
||||
ret = gb_operation_request_send_sync(op);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
goto out_put_operation;
|
||||
|
||||
resp = op->response->payload;
|
||||
|
||||
gbpsy->props = kcalloc(gbpsy->properties_count, sizeof(*gbpsy->props),
|
||||
GFP_KERNEL);
|
||||
if (!gbpsy->props)
|
||||
return -ENOMEM;
|
||||
if (!gbpsy->props) {
|
||||
ret = -ENOMEM;
|
||||
goto out_put_operation;
|
||||
}
|
||||
|
||||
gbpsy->props_raw = kcalloc(gbpsy->properties_count,
|
||||
sizeof(*gbpsy->props_raw), GFP_KERNEL);
|
||||
if (!gbpsy->props_raw) {
|
||||
ret = -ENOMEM;
|
||||
goto out_put_operation;
|
||||
}
|
||||
|
||||
gbpsy->props_raw = kzalloc(gbpsy->properties_count *
|
||||
sizeof(*gbpsy->props_raw), GFP_KERNEL);
|
||||
if (!gbpsy->props_raw)
|
||||
return -ENOMEM;
|
||||
|
||||
/* Store available properties */
|
||||
for (i = 0; i < gbpsy->properties_count; i++) {
|
||||
gbpsy->props[i].prop = resp.props[i].property;
|
||||
gbpsy->props_raw[i] = resp.props[i].property;
|
||||
if (resp.props[i].is_writeable)
|
||||
gbpsy->props[i].prop = resp->props[i].property;
|
||||
gbpsy->props_raw[i] = resp->props[i].property;
|
||||
if (resp->props[i].is_writeable)
|
||||
gbpsy->props[i].is_writeable = true;
|
||||
}
|
||||
|
||||
@ -291,7 +305,10 @@ static int gb_power_supply_prop_descriptors_get(struct gb_power_supply *gbpsy)
|
||||
*/
|
||||
_gb_power_supply_append_props(gbpsy);
|
||||
|
||||
return 0;
|
||||
out_put_operation:
|
||||
gb_operation_put(op);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int __gb_power_supply_property_update(struct gb_power_supply *gbpsy,
|
||||
|
Loading…
Reference in New Issue
Block a user