Currently just running: test/test-kdbus will trigger the BUG_ON() appended at the bottom.
This is due to the test in check_domain_make() where we try to register the same domain twice line: 297, hence kdbus_domain_new() fails with -EEXIST at line domain.c:289 Later on error path we clear the non-finalized domain: kdbus_domain_unref() => __kdbus_domain_free() => BUG_ON(!domain->disconnected) After a closer look, it seems we will hit this BUG_ON() on every time kdbus_domain_new() fails. domain was not finalized so kdbus_domain_disconnect() is never called, and domain->disconnect can't be true. To fix this, as suggested by Kay we remove the kdbus_domain_unref() call and clean up things manually. While we are it, make sure we unregister the chrdev and restore the idr slot on error paths too. [16254.397574] ------------[ cut here ]------------ [16254.398272] kernel BUG at /home/tixxdz/code/d-bus/domain.c:163! [16254.398524] invalid opcode: 0000 [#1] SMP [16254.398524] Modules linked in: kdbus(OE) ip6t_rpfilter bnep bluetooth ip6t_REJECT cfg80211 rfkill xt_conntrack ebtable_nat ebtable_broute bridge stp llc ebtable_filter ebtables ip6table_nat nf_conntrack_ipv6 nf_defrag_ipv6 nf_nat_ipv6 ip6table_mangle ip6table_security ip6table_raw ip6table_filter ip6_tables iptable_nat nf_conntrack_ipv4 nf_defrag_ipv4 nf_nat_ipv4 nf_nat nf_conntrack iptable_mangle iptable_security iptable_raw ppdev serio_raw 8139too i2c_piix4 parport_pc parport microcode bochs_drm drm_kms_helper ttm drm 8139cp i2c_core mii ata_generic pata_acpi [16254.398524] CPU: 3 PID: 30638 Comm: test-kdbus Tainted: G OE 3.15.0-0.rc5.git2.9.fc21.x86_64 #1 [16254.398524] Hardware name: Bochs Bochs, BIOS Bochs 01/01/2011 [16254.398524] task: ffff88005c11cd40 ti: ffff880005958000 task.ti: ffff880005958000 [16254.398524] RIP: 0010:[<ffffffffa031939b>] [<ffffffffa031939b>] __kdbus_domain_free+0x9b/0xa0 [kdbus] [16254.398524] RSP: 0018:ffff880005959de8 EFLAGS: 00010246 [16254.398524] RAX: ffff88005c11cd40 RBX: ffff880046743400 RCX: 0000000000008b40 [16254.398524] RDX: 0000000000000001 RSI: 0000000000000001 RDI: ffff880046743400 [16254.398524] RBP: ffff880005959df0 R08: 0000000000000000 R09: 0000000000000000 [16254.398524] R10: 0000000000000000 R11: 0000000000000000 R12: ffff8800466fa800 [16254.398524] R13: 00000000ffffffef R14: ffff8800466fa960 R15: ffff880046741400 [16254.398524] FS: 00007fa151358740(0000) GS:ffff88005dc00000(0000) knlGS:0000000000000000 [16254.398524] CS: 0010 DS: 0000 ES: 0000 CR0: 000000008005003b [16254.398524] CR2: 00007fa13db78048 CR3: 0000000005a25000 CR4: 00000000000006e0 [16254.398524] Stack: [16254.398524] ffff880046743400 ffff880005959e40 ffffffffa03199e8 ffff880005959e68 [16254.398524] ffff8800466fa8a8 01ffffffa031c0a0 ffff880005a58540 00000000ffff0180 [16254.398524] ffff880005a589c0 0000000000000005 00007fff3dc96990 ffff880005959ec0 [16254.398524] Call Trace: [16254.398524] [<ffffffffa03199e8>] kdbus_domain_new+0x218/0x4c0 [kdbus] [16254.398524] [<ffffffffa0315546>] kdbus_handle_ioctl+0xb46/0xbd0 [kdbus] [16254.398524] [<ffffffff81360c21>] ? inode_has_perm.isra.47+0x51/0x90 [16254.398524] [<ffffffff81251540>] do_vfs_ioctl+0x2f0/0x520 [16254.398524] [<ffffffff812517f1>] SyS_ioctl+0x81/0xa0 [16254.398524] [<ffffffff817fc769>] system_call_fastpath+0x16/0x1b [16254.398524] Code: 8b 7b 08 e8 98 ca ef e0 48 8b 7b 10 e8 8f ca ef e0 48 89 df e8 87 ca ef e0 5b 5d c3 0f 1f 40 00 e8 6b ff ff ff eb d8 0f 0b 0f 0b <0f> 0b 0f 1f 00 0f 1f 44 00 00 55 48 89 e5 53 8b 47 28 48 89 fb [16254.398524] RIP [<ffffffffa031939b>] __kdbus_domain_free+0x9b/0xa0 [kdbus] [16254.437815] ---[ end trace bb9a1036dec78fcc ]--- Signed-off-by: Djalal Harouni <[email protected]> --- domain.c | 22 ++++++++++++++++------ 1 file changed, 16 insertions(+), 6 deletions(-) diff --git a/domain.c b/domain.c index 4748a17..c4912fa 100644 --- a/domain.c +++ b/domain.c @@ -267,7 +267,8 @@ int kdbus_domain_new(struct kdbus_domain *parent, const char *name, mutex_lock(&parent->lock); if (parent->disconnected) { mutex_unlock(&parent->lock); - return -ESHUTDOWN; + ret = -ESHUTDOWN; + goto exit_free; } } @@ -300,6 +301,7 @@ int kdbus_domain_new(struct kdbus_domain *parent, const char *name, d->name = kstrdup(name, GFP_KERNEL); if (!d->name) { + kfree(d->devpath); ret = -ENOMEM; goto exit_unlock; } @@ -308,7 +310,7 @@ int kdbus_domain_new(struct kdbus_domain *parent, const char *name, /* get dynamic major */ ret = register_chrdev(0, d->devpath, &kdbus_device_ops); if (ret < 0) - goto exit_unlock; + goto exit_free_devpath; d->major = ret; @@ -320,7 +322,7 @@ int kdbus_domain_new(struct kdbus_domain *parent, const char *name, if (ret < 0) { if (ret == -ENOSPC) ret = -EEXIST; - goto exit_unlock; + goto exit_chrdev; } /* get id for this domain */ @@ -330,7 +332,7 @@ int kdbus_domain_new(struct kdbus_domain *parent, const char *name, d->dev = kzalloc(sizeof(*d->dev), GFP_KERNEL); if (!d->dev) { ret = -ENOMEM; - goto exit_unlock; + goto exit_idr; } dev_set_name(d->dev, "%s/control", d->devpath); @@ -342,7 +344,7 @@ int kdbus_domain_new(struct kdbus_domain *parent, const char *name, if (ret < 0) { put_device(d->dev); d->dev = NULL; - goto exit_unlock; + goto exit_idr; } /* link into parent domain */ @@ -358,11 +360,19 @@ int kdbus_domain_new(struct kdbus_domain *parent, const char *name, *domain = d; return 0; +exit_idr: + idr_remove(&kdbus_domain_major_idr, d->major); +exit_chrdev: + unregister_chrdev(d->major, d->devpath); +exit_free_devpath: + kfree(d->name); + kfree(d->devpath); exit_unlock: mutex_unlock(&kdbus_subsys_lock); if (parent) mutex_unlock(&parent->lock); - kdbus_domain_unref(d); +exit_free: + kfree(d); return ret; } -- 1.9.0 _______________________________________________ systemd-devel mailing list [email protected] http://lists.freedesktop.org/mailman/listinfo/systemd-devel
