Skip to content

Commit

Permalink
[S390] vmur: Invalid allocation sequence for vmur class
Browse files Browse the repository at this point in the history
The vmur class is allocated after the CCW driver is registered
and it is destroyed before the CCW driver is unregistered.
This is not the correct sequence, because the vmur class can be used
via driver core callbacks that are triggered during the CCW driver
deregistration. For Example:

1. vmur device is online
2. vmur module is unloaded

This leads to the following function call stack:

    <4> [<0000000000387286>] device_destroy+0x36/0x5c
    <4> [<000003e000209714>] ur_set_offline_force+0x9c/0x10c [vmur]
    <4> [<000003e00020a928>] ur_remove+0x64/0xbc [vmur]
    <4> [<00000000003e4d2e>] ccw_device_remove+0x42/0x1ac
    <4> [<000000000038a1aa>] __device_release_driver+0x9a/0xe4
    <4> [<000000000038a2da>] driver_detach+0xe6/0xec
    <4> [<0000000000388ee4>] bus_remove_driver+0xc0/0x108
    <4> [<000003e00020ad5a>] ur_exit+0x52/0x84 [vmur]

In device_destroy() the vmur class is used. Since it is already freed,
this can lead to a kernel panic.

To fix the problem, the vmur class has to be allocated before the CCW
driver is registered and destroyed after the CCW driver has ben unregistered.

Signed-off-by: Michael Holzheu <holzheu@linux.vnet.ibm.com>
Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
  • Loading branch information
Michael Holzheu authored and Martin Schwidefsky committed Sep 11, 2009
1 parent 2395ecd commit 3f7cb51
Showing 1 changed file with 10 additions and 9 deletions.
19 changes: 10 additions & 9 deletions drivers/s390/char/vmur.c
Original file line number Diff line number Diff line change
Expand Up @@ -1026,9 +1026,15 @@ static int __init ur_init(void)

debug_set_level(vmur_dbf, 6);

vmur_class = class_create(THIS_MODULE, "vmur");
if (IS_ERR(vmur_class)) {
rc = PTR_ERR(vmur_class);
goto fail_free_dbf;
}

rc = ccw_driver_register(&ur_driver);
if (rc)
goto fail_free_dbf;
goto fail_class_destroy;

rc = alloc_chrdev_region(&dev, 0, NUM_MINORS, "vmur");
if (rc) {
Expand All @@ -1038,28 +1044,23 @@ static int __init ur_init(void)
}
ur_first_dev_maj_min = MKDEV(MAJOR(dev), 0);

vmur_class = class_create(THIS_MODULE, "vmur");
if (IS_ERR(vmur_class)) {
rc = PTR_ERR(vmur_class);
goto fail_unregister_region;
}
pr_info("%s loaded.\n", ur_banner);
return 0;

fail_unregister_region:
unregister_chrdev_region(ur_first_dev_maj_min, NUM_MINORS);
fail_unregister_driver:
ccw_driver_unregister(&ur_driver);
fail_class_destroy:
class_destroy(vmur_class);
fail_free_dbf:
debug_unregister(vmur_dbf);
return rc;
}

static void __exit ur_exit(void)
{
class_destroy(vmur_class);
unregister_chrdev_region(ur_first_dev_maj_min, NUM_MINORS);
ccw_driver_unregister(&ur_driver);
class_destroy(vmur_class);
debug_unregister(vmur_dbf);
pr_info("%s unloaded.\n", ur_banner);
}
Expand Down

0 comments on commit 3f7cb51

Please sign in to comment.