reference counting bug in swscanf et al
Florian Weimer
fweimer@redhat.com
Thu Apr 2 10:10:30 GMT 2026
* Adhemerval Zanella Netto:
> On 18/03/26 14:59, DJ Delorie wrote:
>>
>> In swscanf.c we have this:
>>
>> FILE *f = _IO_strfile_readw (&sf, &wd, s);
>>
>> . . .
>>
>> return done;
>>
>> _IO_strfile_readw calls:
>>
>> _IO_no_init (&sf->_sbf._f, _IO_USER_LOCK, 0, wd, &_IO_wstr_jumps);
>> _IO_fwide (&sf->_sbf._f, 1);
>>
>> This eventually ends up in __wcsmbs_clone_conv(), where it
>> reference-count-locks the shared object:
>>
>> bool overflow = false;
>> if (copy->towc->__shlib_handle != NULL)
>> overflow |= __builtin_add_overflow (copy->towc->__counter, 1,
>> ©->towc->__counter);
>> if (copy->tomb->__shlib_handle != NULL)
>> overflow |= __builtin_add_overflow (copy->tomb->__counter, 1,
>> ©->tomb->__counter);
>>
>> However, the only place this refcount is released is in _IO_fclose(),
>> where it does this:
>>
>> if (fp->_mode > 0)
>> {
>> /* This stream has a wide orientation. This means we have to free
>> the conversion functions. */
>> struct _IO_codecvt *cc = fp->_codecvt;
>>
>> __libc_lock_lock (__gconv_lock);
>> __gconv_release_step (cc->__cd_in.step);
>> __gconv_release_step (cc->__cd_out.step);
>> __libc_lock_unlock (__gconv_lock);
>>
>>
>> in swscanf.c fclose is never called, nor can it be, since fclose also
>> free's the FILE*, and in swscanf we're using a FILE struct on the
>> stack.
>>
>> Possible solutions? First, do we need to refcount these still? The
>> reproducer works just fine other than the overflow. Second, could we
>
> My understanding is the refcount is still required because the
> __shlib_handle struct can be shared amount multiple threads and the
> possible fix would to add _IO_new_fclose internal interface that expects
> an stack-allocated FILE * (so no _IO_deallocate_file call).
I assumed we could just stop calling dlclose for gconv modules
altogether (and open them with NODELETE). Then the reference counting
would not be needed anymore.
Thanks,
Florian
More information about the Libc-alpha
mailing list