Commit 07400405 authored by Linus Torvalds's avatar Linus Torvalds
Browse files

Merge tag 'for-linus-5.16-3' of git://github.com/cminyard/linux-ipmi

Pull IPMI fixes from Corey Minyard:
 "Fix some IPMI crashes

  Some crash fixes have come in dealing with various error handling
  issues. They have sat in next for 5 days or more without issue, and
  they are fairly critical"

* tag 'for-linus-5.16-3' of git://github.com/cminyard/linux-ipmi:
  ipmi: Fix UAF when uninstall ipmi_si and ipmi_msghandler module
  ipmi: fix initialization when workqueue allocation fails
  ipmi: bail out if init_srcu_struct fails
  ipmi: ssif: initialize ssif_info->client early
parents c9ea870c ffb76a86
Loading
Loading
Loading
Loading
+13 −8
Original line number Diff line number Diff line
@@ -3031,7 +3031,7 @@ cleanup_bmc_device(struct kref *ref)
	 * with removing the device attributes while reading a device
	 * attribute.
	 */
	schedule_work(&bmc->remove_work);
	queue_work(remove_work_wq, &bmc->remove_work);
}

/*
@@ -5392,22 +5392,27 @@ static int ipmi_init_msghandler(void)
	if (initialized)
		goto out;

	init_srcu_struct(&ipmi_interfaces_srcu);

	timer_setup(&ipmi_timer, ipmi_timeout, 0);
	mod_timer(&ipmi_timer, jiffies + IPMI_TIMEOUT_JIFFIES);

	atomic_notifier_chain_register(&panic_notifier_list, &panic_block);
	rv = init_srcu_struct(&ipmi_interfaces_srcu);
	if (rv)
		goto out;

	remove_work_wq = create_singlethread_workqueue("ipmi-msghandler-remove-wq");
	if (!remove_work_wq) {
		pr_err("unable to create ipmi-msghandler-remove-wq workqueue");
		rv = -ENOMEM;
		goto out;
		goto out_wq;
	}

	timer_setup(&ipmi_timer, ipmi_timeout, 0);
	mod_timer(&ipmi_timer, jiffies + IPMI_TIMEOUT_JIFFIES);

	atomic_notifier_chain_register(&panic_notifier_list, &panic_block);

	initialized = true;

out_wq:
	if (rv)
		cleanup_srcu_struct(&ipmi_interfaces_srcu);
out:
	mutex_unlock(&ipmi_interfaces_mutex);
	return rv;
+4 −3
Original line number Diff line number Diff line
@@ -1659,6 +1659,9 @@ static int ssif_probe(struct i2c_client *client, const struct i2c_device_id *id)
		}
	}

	ssif_info->client = client;
	i2c_set_clientdata(client, ssif_info);

	rv = ssif_check_and_remove(client, ssif_info);
	/* If rv is 0 and addr source is not SI_ACPI, continue probing */
	if (!rv && ssif_info->addr_source == SI_ACPI) {
@@ -1679,9 +1682,6 @@ static int ssif_probe(struct i2c_client *client, const struct i2c_device_id *id)
		ipmi_addr_src_to_str(ssif_info->addr_source),
		client->addr, client->adapter->name, slave_addr);

	ssif_info->client = client;
	i2c_set_clientdata(client, ssif_info);

	/* Now check for system interface capabilities */
	msg[0] = IPMI_NETFN_APP_REQUEST << 2;
	msg[1] = IPMI_GET_SYSTEM_INTERFACE_CAPABILITIES_CMD;
@@ -1881,6 +1881,7 @@ static int ssif_probe(struct i2c_client *client, const struct i2c_device_id *id)

		dev_err(&ssif_info->client->dev,
			"Unable to start IPMI SSIF: %d\n", rv);
		i2c_set_clientdata(client, NULL);
		kfree(ssif_info);
	}
	kfree(resp);