Re: UNIX(7)

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Fri, Dec 1, 2023 at 11:08 PM Kuniyuki Iwashima <kuniyu@xxxxxxxxxx> wrote:
>
> From: Alejandro Colomar <alx@xxxxxxxxxx>
> Date: Fri, 1 Dec 2023 13:54:39 +0100
> > Hello Alexey,
> >
> > On Fri, Dec 01, 2023 at 01:16:27PM +0100, Alexey Tikhonov wrote:
> > > Hello.
> > >
> > > There is a discrepancy between the man page description of
> > > 'SO_PEERCRED' and real behavior.
> > >
> > > `man 7 unix` states:
> > > ```
> > >        SO_PEERCRED
> > >               This read-only socket option returns the credentials of
> > >               the peer process connected to this socket.  The returned
> > >               credentials are those that were in effect at the time of
> > >               the call to connect(2) or socketpair(2).
> > > ```
> > >
> > > This doesn't match real behavior in following situation (just an example):
> > >  - process starts with uid=0, gid=0
> > >  - process creates UNIX socket, binds it, listens on it
> > >  - process changes to uid=uid1, git=gid1 (using `setresuid()`, `setresgid()`)
> > >  - another process connects to the listening socket and requests
> > > peer's credentials using `getsockopt(... SOL_SOCKET, SO_PEERCRED ...)`
> > >
> > > According to the man page: SO_PEERCRED should report (uid1, gid1),
> > > because peer process was running under (uid1, gid1) "at the time of
> > > the call to connect(2)"
> > > In reality SO_PEERCRED reports (0, 0)
> > > Reproducing code is available in
> > > https://bugzilla.redhat.com/show_bug.cgi?id=2247682
> > >
> > > I'm not entirely sure if this is a real bug or rather a  poor
> > > description in the man page, but I tend to think that it's the latter.
>
> When calling getsockopt(), we cannot know dynamically who the peer's
> owner is.  So, we just initialise the cred when we know the owner,
> and it's the caller of listen(), connect(), and socketpair().
>
> In your case, the listener's cred is initialised with the caller's
> cred during the first liten().
>
>   listener's peer_cred = get_cred(rcu_dereference_protected(current->cred, 1))

Thank you for the explanation.
So this is an omission in the man page.

>
> And connect() will initialise two creds as follows:
>
>   connect()er's peer_cred = listener's peer_cred
>   new socket's peer_cred = get_cred(rcu_dereference_protected(current->cred, 1))
>
> If you call listen() again after setresuid() and before connect(),
> you can update the listener's cred and get the new IDs at the final
> getsockopt().
>






[Index of Archives]     [Kernel Documentation]     [Netdev]     [Linux Ethernet Bridging]     [Linux Wireless]     [Kernel Newbies]     [Security]     [Linux for Hams]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux RAID]     [Linux Admin]     [Samba]

  Powered by Linux