prevent CNAME/PTR parsing from reading data past the response end
[musl] / src / stdio / __lockfile.c
index 9d967d6..0f60a14 100644 (file)
@@ -3,26 +3,21 @@
 
 int __lockfile(FILE *f)
 {
-       int owner, tid = __pthread_self()->tid;
-       if (f->lock == tid)
+       int owner = f->lock, tid = __pthread_self()->tid;
+       if ((owner & ~MAYBE_WAITERS) == tid)
                return 0;
-       while ((owner = a_cas(&f->lock, 0, tid)))
-               __wait(&f->lock, &f->waiters, owner, 1);
+       owner = a_cas(&f->lock, 0, tid);
+       if (!owner) return 1;
+       while ((owner = a_cas(&f->lock, 0, tid|MAYBE_WAITERS))) {
+               if ((owner & MAYBE_WAITERS) ||
+                   a_cas(&f->lock, owner, owner|MAYBE_WAITERS)==owner)
+                       __futexwait(&f->lock, owner|MAYBE_WAITERS, 1);
+       }
        return 1;
 }
 
 void __unlockfile(FILE *f)
 {
-       a_store(&f->lock, 0);
-
-       /* The following read is technically invalid under situations
-        * of self-synchronized destruction. Another thread may have
-        * called fclose as soon as the above store has completed.
-        * Nonetheless, since FILE objects always live in memory
-        * obtained by malloc from the heap, it's safe to assume
-        * the dereferences below will not fault. In the worst case,
-        * a spurious syscall will be made. If the implementation of
-        * malloc changes, this assumption needs revisiting. */
-
-       if (f->waiters) __wake(&f->lock, 1, 1);
+       if (a_swap(&f->lock, 0) & MAYBE_WAITERS)
+               __wake(&f->lock, 1, 1);
 }