mac/log: fix use after free when freeing mpv handle

the mp_log is freed when the corresponding mpv_handle (ta_parent) is
freed in the EventHelper, though it could still be used from different
threads. instead don't use a ta_parent and manually free on manual
dereferencing. on app shutdown (memory cleanup) this is not called but
instead is freed by the usual cleanup and freeing.

the LogHelper is only able to be manually dereferenced in the AppHub,
so no race conditions are possible in all other cases (vo).in the AppHub
it's impossible to hit a race condition atm, because of how the init
process works and how/where the log is used. only manually forcing
logging in the exit process itself could theoretically trigger a use
after free.

Fixes #13823
This commit is contained in:
der richter 2024-04-10 19:41:38 +02:00
parent 096d35dac7
commit e42a8d537f
2 changed files with 8 additions and 2 deletions

View File

@ -55,7 +55,7 @@ class AppHub: NSObject {
event = EventHelper(self, mpv)
if let mpv = event?.mpv {
self.mpv = mpv
log.log = mp_log_new(UnsafeMutablePointer(mpv), mp_client_get_log(mpv), "app")
log.log = mp_log_new(nil, mp_client_get_log(mpv), "app")
option = OptionHelper(UnsafeMutablePointer(mpv), mp_client_get_global(mpv))
input.option = option
}

View File

@ -50,7 +50,7 @@ class LogHelper {
}
func send(message: String, type: Int) {
guard let log = log, UnsafeRawPointer(log).load(as: UInt8.self) != 0 else {
guard let log = log else {
logger.log(level: loggerMapping[type] ?? .default, "\(message, privacy: .public)")
return
}
@ -58,4 +58,10 @@ class LogHelper {
let args: [CVarArg] = [(message as NSString).utf8String ?? "NO MESSAGE"]
mp_msg_va(log, Int32(type), "%s\n", getVaList(args))
}
deinit {
// only a manual dereferencing will trigger this, cleanup properly in that case
ta_free(UnsafeMutablePointer(log))
log = nil
}
}