It should be sem_ids.rwsem, and at least according to the documentation both freeary() and newary() hold it.
newary initializes a bunch of things after the call to
ipc_addid, however some things are initialized inside
ipc_addid as well
Looking closer at newary, I suppose that it should be
possible to move those other initializations before
the call to ipc_addid. That would likely get rid of
the problem, too.
However, I also see this line in newary, and I have
no idea what protects that data:
ns->used_sems += nsems;