cyrusimap / cyrus-sasl

Other
128 stars 146 forks source link

Fix that sasl_done segfaults without init #830

Closed adamyi closed 3 months ago

adamyi commented 3 months ago

In sasl_done_common, we free free_mutex. However, if sasl_mutex_init was never called, free_mutex is NULL.

This has been fine because user likely won't call sasl_set_mutex either if they never initalized sasl, but with #803, we start to supply default pthread implementation for sasl_mutex_free and this starts segfaulting when a process calls sasl_done without sasl_{client,server}_init.

This commit changes it such that we only free free_mutex if it's not null. We already have similar checks for other variables to free (e.g. global_mech_list)

The segfault can be reproduced with:

#include <stdio.h>
#include <sasl/sasl.h>

int main() {
  sasl_done();
  return 0;
}

I confirmed that it does not segfault after this commit (as well as before #803). sasl_{client,server}_done does not have this problem because they would have returned SASL_NOTINIT, but sasl_done is problematic. Although sasl_done has already been deprecated, nothing in its doc states that it cannot be called without initialization ever (it just says when application is completely done with the lib), let's just make the behavior nice.