Fix crashes in cupsDNSSDDelete() when Avahi fails to initialize. - #164
Fix crashes in cupsDNSSDDelete() when Avahi fails to initialize.#164Abd002 wants to merge 1 commit into
Conversation
|
|
||
| cupsThreadCancel(dnssd->monitor); | ||
| cupsThreadWait(dnssd->monitor); | ||
| if (dnssd->monitor) |
There was a problem hiding this comment.
This isn't a valid test - pthread_t doesn't have a defined "uninitialized" value (IMHO a big oversight in POSIX) and isn't a simple type.
michaelrsweet
left a comment
There was a problem hiding this comment.
I am OK with the concept of these changes, but you can't actually compare a pthread_t to anything directly like this (it is an opaque type).
|
But I do understand your point that a But since libcups has a single POSIX branch that treats every POSIX platform the same way, and |
|
I think it would be cleaner to eventually separate |
Agreed, but we can't "break" this API until v4.0 at this point... :/ Maybe I can just introduce a The current code relies on |
|
Thanks! I've updated the change to use CUPS_THREAD_INVALID and rebased it onto master. Also, I'd be interested in working on the cupsThreadCreate2 API you mentioned for v4.0 after I finish and submit my GSoC work. If you're okay with that, I'd be happy to take it up when the time comes. |
cupsDNSSDNew()callscupsDNSSDDelete()to clean up when Avahi initialization fails. The problem is that some cleanup calls incupsDNSSDDelete()were made even when the related fields had not been initialized yet.This could cause three different problems:
avahi_domain_browser_free(dnssd->dbrowser)was called whendbrowserwasNULL. Avahi's_free()functions don't check forNULLthemselves — they assert forward and abort the process if the caller doesn't:This is the one that actually crashed a real running application, which is what led to digging into this code path in the first place.
cupsThreadCancel(dnssd->monitor)andcupsThreadWait(dnssd->monitor)were called whenmonitorwas0because the monitor thread had not been created. This causespthread_cancel(0)to segfault.When
avahi_client_new()failed, its failure path freeddnssd->polland then calledcupsDNSSDDelete(), which freed the samednssd->pollagain, causing a double-free (free(): double free detected in tcache 2).cupsDNSSDDelete()'s own cleanup then reaches:The fix checks that
dbrowserandmonitorare valid before cleaning them up, using the same pattern already used elsewhere incupsDNSSDDelete(). The manualavahi_simple_poll_free(dnssd->poll)in theavahi_client_new()failure path is also removed, sincecupsDNSSDDelete()already handles freeingdnssd->poll.