9

I have some tasks requiring massive temporary named pipes to deal with.

Originally, I just simply think that generate random numbers, then append it as <number>.fifo be the name of named pipe.

However, I found this post: Create a temporary FIFO (named pipe) in Python?

It seems there is something I don't know that may cause some security issue there.

So my question here is that, what's the best way to generate a named pipe?

Notice that even though I am referencing a Python related post, I don't really mean to ask only in Python.

UPDATE:

Since I want to use a named pipe to connect unrelated processes, my plan is having process A call process B first via shell, and capture stdout to acquire the name of pipe, then both know what to open.

Here I am just worrying about whether leaking the name of pipe will become an issue. Before I never thought of it, until I read that Python post.

Community
  • 1
  • 1
Jason Hu
  • 6,239
  • 1
  • 20
  • 41
  • What security issues are you thinking of? Where would you store the name of the fifos? Why can't you use plain anonymous pipes? – Basile Starynkevitch Nov 03 '14 at 20:22
  • @BasileStarynkevitch because it requires IPC between processes have no relationship. the security problem here seems to be malicious attacker? i don't quite understand actually. i worry because i found that post. – Jason Hu Nov 03 '14 at 20:37
  • But you could use random names, and the issue is how do you share (or where do you store) these names. You should edit your question to explain more. – Basile Starynkevitch Nov 03 '14 at 20:39
  • @BasileStarynkevitch i am confused after reading that post. it seems randomization may be error-prone too. i updated my question. – Jason Hu Nov 03 '14 at 20:47
  • BTW, I am skeptical about the massive usage of `mkfifo`. Do you need a dozen of them or a million of them? (at some given moment, I guess that the kernel is limiting the number of fifos to several hundred thousands). – Basile Starynkevitch Nov 03 '14 at 22:05
  • @BasileStarynkevitch i changed my mind a little bit, so it won't need too many now. it has chance to go hundreds at most, which should be ok. – Jason Hu Nov 04 '14 at 15:18

2 Answers2

5

If you have to use named FIFOs and need to ensure that overlap/overwriting cannot occur, your best bet is probably to use some combination of mktemp and mkfifo.

Although mktemp itself cannot create FIFOs, it can be used to create unique temporary directories, which you can then put your FIFOs into.

The GNU mktemp documentation has an example of this.

yossarian
  • 1,537
  • 14
  • 21
  • The trouble with using `mktemp()` is that some systems warn about its use at link time, and that is a nuisance if you're aiming for no warnings in your build. I got here looking for a solution to that problem; this wouldn't meet my requirements. – Jonathan Leffler Aug 20 '15 at 23:13
  • @JonathanLeffler Perhaps `mkstemp()`, then? – yossarian Aug 22 '15 at 22:13
  • I concluded that creating a function `int mkptemp(char *pattern, mode_t mode)` would likely be best, doing roughly the same job as `mkdtemp()` does — creating a 'pipe' (FIFO) with a random name, which would be stored in the `pattern` argument. I've not implemented it, but could easily modify an implementation of `mkstemp()` to create a FIFO instead of a file. The `mkfifo()` system call won't create a FIFO at the end of a broken symlink — like the `mkdir()` system call, it fails if the name exists in the file system. I'd use p for 'pipe' rather than f for 'fifo' because f suggests 'file' too. – Jonathan Leffler Aug 22 '15 at 22:28
1

Alternatively, you could create some name containing well random letters. You could read from /dev/random (or /dev/urandom, read random(4)) some random bytes to e.g. seed a PRNG (e.g. random(3) seeded by srandom), and/or mix the PID and time, etc.

And since named fifo(7) are files, you should use the permission system (and/or ACL) on them. In particular, you might create a command Linux user to run all your processes and restrict the FIFOs to be only owner-readable, etc.

Of course, and in all cases, you need to "store" or "transmit" securely these FIFO names.

If you start your programs in some bash script, you might consider making your fifo names using mktemp(1) as:

fifoname=$(mktemp -u -t yourprog_XXXXXX).fifo-$RANDOM-$$
mkfifo -m 0600 $fifoname

(perhaps in some loop). I guess it would be secure enough if the script is running in a dedicated user (and then pass the $fifoname in some pipe or file, not as a program argument)

The recent renameat2(2) syscall might be helpful (atomicity of RENAME_EXCHANGE).

BTW, you might want some SElinux. Remember that opened file descriptors -and that includes your fifos- are available as symlinks in proc(5) !

PS. it all depends upon how paranoid are you. A well sysadmined Linux system can be quite secure...

Basile Starynkevitch
  • 223,805
  • 18
  • 296
  • 547