Commit 53b425ce authored by Armin Wolf's avatar Armin Wolf Committed by Qi Xi
Browse files

ACPICA: Fix memory leak if acpi_ps_get_next_field() fails

stable inclusion
from stable-v4.19.323
commit 40fa60e0bf406ced3dfd857015dafdcd677a4929
category: bugfix
bugzilla: https://gitee.com/openeuler/kernel/issues/IBBN6V

Reference: https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?id=40fa60e0bf406ced3dfd857015dafdcd677a4929

--------------------------------

[ Upstream commit e6169a8ffee8a012badd8c703716e761ce851b15 ]

ACPICA commit 1280045754264841b119a5ede96cd005bc09b5a7

If acpi_ps_get_next_field() fails, the previously created field list
needs to be properly disposed before returning the status code.

Link: https://github.com/acpica/acpica/commit/12800457


Signed-off-by: default avatarArmin Wolf <W_Armin@gmx.de>
[ rjw: Rename local variable to avoid compiler confusion ]
Signed-off-by: default avatarRafael J. Wysocki <rafael.j.wysocki@intel.com>
Signed-off-by: default avatarSasha Levin <sashal@kernel.org>
Signed-off-by: default avatarQi Xi <xiqi2@huawei.com>
parent 4faa095b
Loading
Loading
Loading
Loading
+39 −0
Original line number Diff line number Diff line
@@ -25,6 +25,8 @@ acpi_ps_get_next_package_length(struct acpi_parse_state *parser_state);
static union acpi_parse_object *acpi_ps_get_next_field(struct acpi_parse_state
						       *parser_state);

static void acpi_ps_free_field_list(union acpi_parse_object *start);

/*******************************************************************************
 *
 * FUNCTION:    acpi_ps_get_next_package_length
@@ -683,6 +685,39 @@ static union acpi_parse_object *acpi_ps_get_next_field(struct acpi_parse_state
	return_PTR(field);
}

/*******************************************************************************
 *
 * FUNCTION:    acpi_ps_free_field_list
 *
 * PARAMETERS:  start               - First Op in field list
 *
 * RETURN:      None.
 *
 * DESCRIPTION: Free all Op objects inside a field list.
 *
 ******************************************************************************/

static void acpi_ps_free_field_list(union acpi_parse_object *start)
{
	union acpi_parse_object *cur = start;
	union acpi_parse_object *next;
	union acpi_parse_object *arg;

	while (cur) {
		next = cur->common.next;

		/* AML_INT_CONNECTION_OP can have a single argument */

		arg = acpi_ps_get_arg(cur, 0);
		if (arg) {
			acpi_ps_free_op(arg);
		}

		acpi_ps_free_op(cur);
		cur = next;
	}
}

/*******************************************************************************
 *
 * FUNCTION:    acpi_ps_get_next_arg
@@ -751,6 +786,10 @@ acpi_ps_get_next_arg(struct acpi_walk_state *walk_state,
			while (parser_state->aml < parser_state->pkg_end) {
				field = acpi_ps_get_next_field(parser_state);
				if (!field) {
					if (arg) {
						acpi_ps_free_field_list(arg);
					}

					return_ACPI_STATUS(AE_NO_MEMORY);
				}