From: Philipp Reisner When one stresses the connector code, with sending many messages from userspace to kernel, one could get in the "unlikely()" part in cn_call_callback(). There a new __cbq gets allocated, and a NULL pointer got assigned to the callback by dereferencing __cbq. This is the bug. The right thing is the dereference the original __cbq. Therefore the bugfix is to use a new variable for the newly allocated __cbq. This is tested, and it fixes the issue. Signed-off-by: Philipp Reisner Signed-off-by: Lars Ellenberg Acked-by: Evgeniy Polyakov Cc: Signed-off-by: Andrew Morton --- drivers/connector/connector.c | 16 ++++++++-------- 1 files changed, 8 insertions(+), 8 deletions(-) diff -puN drivers/connector/connector.c~connector-bugfix-for-cn_call_callback drivers/connector/connector.c --- a/drivers/connector/connector.c~connector-bugfix-for-cn_call_callback +++ a/drivers/connector/connector.c @@ -128,7 +128,7 @@ EXPORT_SYMBOL_GPL(cn_netlink_send); */ static int cn_call_callback(struct cn_msg *msg, void (*destruct_data)(void *), void *data) { - struct cn_callback_entry *__cbq; + struct cn_callback_entry *__cbq, *__new_cbq; struct cn_dev *dev = &cdev; int err = -ENODEV; @@ -148,23 +148,23 @@ static int cn_call_callback(struct cn_ms } else { struct cn_callback_data *d; - __cbq = kzalloc(sizeof(*__cbq), GFP_ATOMIC); - if (__cbq) { - d = &__cbq->data; + __new_cbq = kzalloc(sizeof(*__new_cbq), GFP_ATOMIC); + if (__new_cbq) { + d = &__new_cbq->data; d->callback_priv = msg; d->callback = __cbq->data.callback; d->ddata = data; d->destruct_data = destruct_data; - d->free = __cbq; + d->free = __new_cbq; - INIT_WORK(&__cbq->work, + INIT_WORK(&__new_cbq->work, &cn_queue_wrapper); if (queue_work(dev->cbdev->cn_queue, - &__cbq->work)) + &__new_cbq->work)) err = 0; else { - kfree(__cbq); + kfree(__new_cbq); err = -EINVAL; } } else _