Re: [patch 7/8] fdmap v2 - implement sys_socket2
From: Eric Dumazet
Date: Sun Jun 10 2007 - 05:16:47 EST
Linus Torvalds a écrit :
(And dammit, that _is_ a *real*issue*. No races necessary, no NR_OPEN
iterations, no even *halfway* suspect code. It's perfectly fine to do
close(0);
close(1);
close(2);
.. generate filenames, whatever ..
if (open(..) < 0 || open(..) < 0 || open(..) < 0)
die("Couldn't redirect stdin/stdout/stderr");
and there's absolutely nothing wrong with this kind of setup, even if you
could obviously have done it other ways too (ie by using "dup2()" instead
of "close + open"),
This kind of setup was OK 25 years ago, before multithreading era.
You cannot reasonably expect it to work in a multithreaded program.
Anyway, I would like to give an alternative idea of the double fdmap, and
probably more *secure* .
Current fd API mandates integers (32 bits)
Lot of broken code consider a fd must be >= 0, so we currently are limited to
31 bits.
With NR_OPEN = 1024*1024 = 2^20, that give us 11 bits that we could use as a
signature.
That is, we could use O_NONSEQ as a indication to kernel to give us a
composite fd : 20 low order bits give the slot in file table, then 11 bits can
be use to make sure the fd was not stolen by malicious code.
Legacy app, (without O_NONSEQ in flags) would get POSIX compatables fd in [0,
2^20-1] range, with the lowest available fd.
If O_NONSEQ is given, kernel is free to give an fd in [0, 2^31 - 1], with a
strategy that could be the one Davide gave in its patch (with a list of
available slots). But instead of FIFO, we can use now LIFO, more cache friendly.
In fget()/fget_light()/close(), we can then use 20 bits to select the slot in
the single fdmap.
And 11 bits to check the 'signature'.
So if open( O_NONSEQFD) gave us 0x77000010, we cannot do close(0x10) or
read(0x10, ....)
Storage for these bits is already there in Davide fd_slot structure, where we
currently use one long to store 3 bits 'only'.
This should work even bumping NR_OPEN to say... 8*1024*1024, and 8 bits signature.
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/