"file status flags", and "file decriptor flags"
Some rewriting of discussion of file descriptor flags
Under F_DUPFD, replaced some text duplicated in dup.2 with a cross ref to dup.2
Minor wording and formatting fixes
Added text on permissions required to send signal to owner.
====
Hello Johannes,
> Betreff: Inaccuracy of fcntl man page
> Datum: Mon, 2 May 2005 20:07:12 +0200
Thanks for yor note.
Sorry for the delay in getting back to you. I needed to find time
to set aside to look at the details. Now I've finally got there.
> I have attached a simple program
Thanks -- a little program is always helpful.
> that uses the fcntl system call in order
> to kill an arbitrary process of the same user.
> According to the fcntl man page, fcntl(fd,F_SETOWN,pid) returns zero if
> it has success.
Yes.
> If you strace the program while killing for exampe man running in another
> terminal, you will see that man is killed, but fcntl(fd,F_SETOWN,pid)
> will return EPERM,
I confirm that I see this problem in 2.4, with both Unix domain
and Internet domain sockets.
> where you can only find a very confusing explanation
> in the fcntl man page.
I'm not sure what explanation you mean here. As far as I can
tell, the manual page just doesn't cover this point.
> I have looked into the kernel source of 2.4.30 and found out, that
> net/core/socket::sock_no_fcntl is the culprit if you use fcntl on Unix
> sockets.
Yes, looks that way to me, as well, And the 2.2 code looks
similar.
> If pid is not your own pid or not your own process group,
> the system call will return EPERM but will also set the pid
> as you wanted to.
Yes.
> In the 2.6 kernel line, fcntl will react according the specification in
> the manual page.
Yes.
> If you also think, that one should clarify the return specification of
> fcntl(fd,F_SETOWN,pid) or 2.4.x kernels, please tell me and I will
> provide you with a patch for the manual page.
In fact I've written some new text under BUGS, which describes
the problem:
In Linux 2.4 and earlier, there is bug that can occur when an
unprivileged process uses F_SETOWN to specify the owner of a
socket file descriptor as a process (group) other than the
caller. In this case, fcntl() can return -1 with errno set to
EPERM, even when the owner process (group) is one that the
caller has permission to send signals to. Despite this error
return, the file descriptor owner is set, and signals will be
sent to the owner.
Does that seem okay to you?
> Furthermore, it would be interseting to write there, what permissions
> one need in order to send signals to processes via fcntl
Good idea. I added the following new text:
Sending a signal to the owner process (group) specified by
F_SETOWN is subject to the same permissions checks as are
described for kill(2), where the sending process is the one that
employs F_SETOWN (but see BUGS below).
====
#define _GNU_SOURCE /* needed to get the defines */
#include <fcntl.h> /* in glibc 2.2 this has the needed
values defined */
#include <signal.h>
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/un.h>
/**
* Funnykill kills a program with fcntl
**/
int
main (int argc, char **argv)
{
if (argc != 2)
{
fprintf (stderr, "Usage: funnykill <pid>\n");
return 1;
}
int sockets[2];
socketpair (AF_UNIX, SOCK_STREAM, 0, sockets);
if (fcntl (sockets[0], F_SETFL, O_ASYNC | O_NONBLOCK) == -1)
errMsg("fcntl-F_SETFL");
if (fcntl (sockets[0], F_SETOWN, atoi (argv[1])) == -1)
errMsg("fcntl-F_SETOWN");
// fcntl (sockets[0], F_SETOWN, getpid());
if (fcntl (sockets[0], F_SETSIG, SIGKILL) == -1)
errMsg("fcntl-_FSETSIG");
write (sockets[1], "good bye", 9);
}