Skip to content

temporary filename is non-random, causing bad state and the killthreads fedora flake #9

Closed

Description

@k4lizen

Bug

In this code:

fn getTempFilepath(allocator: std.mem.Allocator, local_path: []const u8) ![]u8 {
const local_dirname = std.fs.path.dirname(local_path) orelse return error.InvalidLocalPath;
// todo: security? random filename?
const tmp_basename = try std.mem.concat(allocator, u8, &.{ ".tmp.", std.fs.path.basename(local_path) });
defer allocator.free(tmp_basename);
return try std.fs.path.join(allocator, &.{ local_dirname, tmp_basename });
}

If multiple requests run in parallel, they will both perform a file-system write to the same file. This sequence of events happens
in the fedora killthreads flake https://github.com/pwndbg/pwndbg/actions/runs/34255810405/job/102161276306 :

  1. thread A starts a requests and starts writing to the .tmp.debuginfo file
  2. thread A writes up to offset X
  3. thread B starts a request and starts writing to the same .tmp.debuginfo file, truncating it in the process, and zeroing out everything that thread A wrote
  4. thread A continues writing from offset X
  5. thread B writes from the beginning of the file
  6. thread A finishes, and GDB reads the DWARF while it has a zero-hole inside
  7. symbol lookups don't work anymore
  8. the expression pthread_kill() does not get evaluated due to a gdb error
  9. our killthread function swallows up the error and doesn't think anything is wrong
  10. but the thread doesn't actually get killed, and the assert fails

Repro

In the pwndbg root folder you can run:

docker compose run --rm -v $(pwd):/pwndbg fedora42 bash /pwndbg/repro-debuginfod-race.sh

with the repro file (slopped):
repro-debuginfod-race.sh

You'll see that debuginfod-zig repro's the bug while elfutils does not.

Fix

Use mktemp or equivalent.

Activity

  1. patryk4815 commented on Sep 9, 2026

    @patryk4815
    Member

    That is easy to fix, but I didn't realize GDB could call functions in different GDB threads - GDB doesn't use threads.. wtf?
    I think gdb don't use threads at all (inferior can have threads)

  2. k4lizen commented on Sep 9, 2026

    @k4lizen
    Author

    oh good point, but we do run multiple GDB's in parallel in our tests, could be anything that fetches debuginfo colliding

  3. patryk4815 commented on Sep 9, 2026

    @patryk4815
    Member

    oh good point, but we do run multiple GDB's in parallel in our tests, could be anything that fetches debuginfo colliding

    yes! probably this is issue

  4. added a commit that references this issue on Sep 9, 2026
  5. patryk4815 commented on Sep 9, 2026

    @patryk4815
    Member
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions