roast icon indicating copy to clipboard operation
roast copied to clipboard

Change directory to $*TMPDIR

Open Kaiepi opened this issue 3 years ago • 4 comments

Fixes https://github.com/Raku/roast/issues/718

Kaiepi avatar Apr 10 '21 11:04 Kaiepi

My opinion: put temporary files into TMPDIR. That's what it's for. roast has traditionally littered directories and I'd like to get rid of that. On the contrary, it should set a good example.

As to safely creating a temp file, the best option is to rely on POSIX' mkstemp() or mkstemps() functions. These combine secure file name generation with atomic check and open.

The only safe alternative is to set the O_CREAT and O_EXCL flags, so that if the file already exists, the openat() call errors with EEXIST and then loop until you find an untaken name. The File::Temp module uses this approach.

Just for completeness as I don't think it would work here: on Linux even better than mkstemp is openat() with the O_TMPFILE flag which creates an unnamed temporary file, so there can never be any name clash and no security issues due to predictable temp file names. Of course that doesn't work if you need the file to be available to other processes. Unless those processes are fork()ed or you pass the file descriptor via a pipe.

FWIW the whole discussion shows why I wished that we included secure temporary file creation in Raku itself. Temporary files are a very common need and creating them is something most people get wrong as the wronger a way is, the easier it seems to be.

niner avatar Apr 11 '21 07:04 niner

My bad, I haven't done it in first place, but a search in packages/Test-Helpers came up with make-temp-* family of routines in Test::Util. Moreover, they record all files/dirs created and wipe them out in END phaser.

vrurg avatar Apr 11 '21 19:04 vrurg

I tried out the patch and I'm afraid it doesn't really work as intended. For me (on FreeBSD 12.4) the socket files are created in the directory where I start rakudo-m -- and not in $*TMPDIR.

I'm not totally sure about the why, but from what I've seen the C code that actually creates the socket file (IIUC it's the bind in https://github.com/MoarVM/MoarVM/blob/6b456a6c05/src/io/syncsocket.c#L453) has its current working directory unchanged -- it's still the directory where I started rakudo-m. Since bind only gets a (relative) file name in dest->sa_data the socket file is not created in /tmp, but in the "start directory".

But maybe we should just use an absolute path instead of a relative one. (There's still the potential problem with $*TMPDIR already having a long path, but that's probably manageable by the user who wants to run the tests.) I'll open an alternative PR ...

usev6 avatar Feb 05 '23 16:02 usev6

Alternative PR: https://github.com/Raku/roast/pull/829

usev6 avatar Feb 05 '23 17:02 usev6