Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit effbeaa9 authored by Guru Das Srinagesh's avatar Guru Das Srinagesh
Browse files

power: battery: Fix error handling in votables' creation



The error handling path for failed calls to create_votable() currently
transfers program execution control to the label destroy_votable, where
the return code of the create_votable() call is directly passed to
destroy_votable(), ostensibly for cleanup.

Upon closer inspection, it is observed that the create_votable()
function cleans up after itself in the case of errors in all of its
intermediate steps before returning an error code. The error code is
essentially a negative integer returned as a typecasted pointer which,
when directly passed to destroy_votable(), will surely cause a crash at
the list_del() step within, as that function doesn't really do thorough
input sanitization.

Fix this by overwriting the return code of calls to create_votable()
with NULL in the case of error, before invoking destroy_votable(). This
prevents a crash because there is a NULL check at the very beginning of
that function.

Change-Id: Ic923051319c4af89b22752e6bea4afbf0111d777
Signed-off-by: default avatarGuru Das Srinagesh <gurus@codeaurora.org>
parent 871eac76
Loading
Loading
Loading
Loading
+8 −2
Original line number Diff line number Diff line
@@ -1610,6 +1610,7 @@ int qcom_batt_init(int smb_version)
					chip);
	if (IS_ERR(chip->fcc_votable)) {
		rc = PTR_ERR(chip->fcc_votable);
		chip->fcc_votable = NULL;
		goto release_wakeup_source;
	}

@@ -1618,6 +1619,7 @@ int qcom_batt_init(int smb_version)
					chip);
	if (IS_ERR(chip->fv_votable)) {
		rc = PTR_ERR(chip->fv_votable);
		chip->fv_votable = NULL;
		goto destroy_votable;
	}

@@ -1626,6 +1628,7 @@ int qcom_batt_init(int smb_version)
					chip);
	if (IS_ERR(chip->usb_icl_votable)) {
		rc = PTR_ERR(chip->usb_icl_votable);
		chip->usb_icl_votable = NULL;
		goto destroy_votable;
	}

@@ -1634,6 +1637,7 @@ int qcom_batt_init(int smb_version)
					chip);
	if (IS_ERR(chip->pl_disable_votable)) {
		rc = PTR_ERR(chip->pl_disable_votable);
		chip->pl_disable_votable = NULL;
		goto destroy_votable;
	}
	vote(chip->pl_disable_votable, CHG_STATE_VOTER, true, 0);
@@ -1644,7 +1648,8 @@ int qcom_batt_init(int smb_version)
					pl_awake_vote_callback,
					chip);
	if (IS_ERR(chip->pl_awake_votable)) {
		rc = PTR_ERR(chip->pl_disable_votable);
		rc = PTR_ERR(chip->pl_awake_votable);
		chip->pl_awake_votable = NULL;
		goto destroy_votable;
	}

@@ -1654,7 +1659,8 @@ int qcom_batt_init(int smb_version)
					chip);
	if (IS_ERR(chip->pl_enable_votable_indirect)) {
		rc = PTR_ERR(chip->pl_enable_votable_indirect);
		return rc;
		chip->pl_enable_votable_indirect = NULL;
		goto destroy_votable;
	}

	vote(chip->pl_disable_votable, PL_INDIRECT_VOTER, true, 0);