ping issue with rdomains

classic Classic list List threaded Threaded
9 messages Options
Reply | Threaded
Open this post in threaded view
|

ping issue with rdomains

Pierre Emeriaud
Hello,

As explain in another mail to bugs@ ("rcctl issue with rdomains"), my
shell is spawn from a sshd running in rtable 1.

lg(rdomain1)$ id -R
1

I can't however use `ping -V` to set the rtable I'm interested in:

lg(rdomain1)$ ping -V0 1.1.1.1
ping: setsockopt SO_RTABLE: Operation not permitted

lg(rdomain1)$ doas ping -V0 1.1.1.1
ping: setsockopt SO_RTABLE: Operation not permitted

lg(rdomain1)$ doas route -T0 exec ping -qc1 1.1.1.1
PING 1.1.1.1 (1.1.1.1): 56 data bytes
--- 1.1.1.1 ping statistics ---
1 packets transmitted, 1 packets received, 0.0% packet loss
round-trip min/avg/max/std-dev = 7.827/7.827/7.827/0.000 ms

Don't know if that's a bug or a known/expected behavior too, so I
wanted to have some input on this matter.

Thanks,
pierre

Reply | Threaded
Open this post in threaded view
|

Re: ping issue with rdomains

Claudio Jeker-3
On Mon, Mar 18, 2019 at 10:10:26PM +0100, Pierre Emeriaud wrote:

> Hello,
>
> As explain in another mail to bugs@ ("rcctl issue with rdomains"), my
> shell is spawn from a sshd running in rtable 1.
>
> lg(rdomain1)$ id -R
> 1
>
> I can't however use `ping -V` to set the rtable I'm interested in:
>
> lg(rdomain1)$ ping -V0 1.1.1.1
> ping: setsockopt SO_RTABLE: Operation not permitted
>
> lg(rdomain1)$ doas ping -V0 1.1.1.1
> ping: setsockopt SO_RTABLE: Operation not permitted
>
> lg(rdomain1)$ doas route -T0 exec ping -qc1 1.1.1.1
> PING 1.1.1.1 (1.1.1.1): 56 data bytes
> --- 1.1.1.1 ping statistics ---
> 1 packets transmitted, 1 packets received, 0.0% packet loss
> round-trip min/avg/max/std-dev = 7.827/7.827/7.827/0.000 ms
>
> Don't know if that's a bug or a known/expected behavior too, so I
> wanted to have some input on this matter.
>

This is expected behaviour. From setrtable(2):

     Only the superuser is allowed to change the process routing table if it
     is already set to a non-zero value.

--
:wq Claudio

Reply | Threaded
Open this post in threaded view
|

Re: ping issue with rdomains

Pierre Emeriaud
Hello Claudio,

Le lun. 18 mars 2019 à 23:07, Claudio Jeker <[hidden email]> a écrit :
>
> > lg(rdomain1)$ doas ping -V0 1.1.1.1
> > ping: setsockopt SO_RTABLE: Operation not permitted
>
> This is expected behaviour. From setrtable(2):
>
>      Only the superuser is allowed to change the process routing table if it
>      is already set to a non-zero value.

I tried with doas, so now with root:

lg(rdomain1)$ doas su -
lg# id
uid=0(root) gid=0(wheel) groups=0(wheel), 2(kmem), 3(sys), 4(tty),
5(operator), 20(staff), 31(guest)
lg# id -R
1
lg# ping -V0 1.1.1.1
ping: setsockopt SO_RTABLE: Operation not permitted

I was aware of the root restriction, and I'm thankfull for it :)

--
pierre

Reply | Threaded
Open this post in threaded view
|

Re: ping issue with rdomains

Claudio Jeker-3
On Mon, Mar 18, 2019 at 11:27:40PM +0100, Pierre Emeriaud wrote:

> Hello Claudio,
>
> Le lun. 18 mars 2019 à 23:07, Claudio Jeker <[hidden email]> a écrit :
> >
> > > lg(rdomain1)$ doas ping -V0 1.1.1.1
> > > ping: setsockopt SO_RTABLE: Operation not permitted
> >
> > This is expected behaviour. From setrtable(2):
> >
> >      Only the superuser is allowed to change the process routing table if it
> >      is already set to a non-zero value.
>
> I tried with doas, so now with root:
>
> lg(rdomain1)$ doas su -
> lg# id
> uid=0(root) gid=0(wheel) groups=0(wheel), 2(kmem), 3(sys), 4(tty),
> 5(operator), 20(staff), 31(guest)
> lg# id -R
> 1
> lg# ping -V0 1.1.1.1
> ping: setsockopt SO_RTABLE: Operation not permitted
>
> I was aware of the root restriction, and I'm thankfull for it :)
>

Ping is a bit of a special case since it runs with user _ping when started
as root. So by the time the SO_RTABLE is issued it does not have the privs
to do it. The ping -V option only works when used in rdomain 0.
You can use route -T0 exec ping 1.1.1.1 (but I guess you already knew
that).

--
:wq Claudio

Reply | Threaded
Open this post in threaded view
|

Re: ping issue with rdomains

Ted Unangst-6
Claudio Jeker wrote:
> Ping is a bit of a special case since it runs with user _ping when started
> as root. So by the time the SO_RTABLE is issued it does not have the privs
> to do it. The ping -V option only works when used in rdomain 0.

Maybe we can drop privs a little later if we started running as root?
Just after getopt, which lets the setsockopt work, but before we do anything
dangerous.

Index: ping.c
===================================================================
RCS file: /home/cvs/src/sbin/ping/ping.c,v
retrieving revision 1.234
diff -u -p -r1.234 ping.c
--- ping.c 13 Nov 2018 14:30:36 -0000 1.234
+++ ping.c 19 Mar 2019 03:07:27 -0000
@@ -283,9 +283,9 @@ main(int argc, char *argv[])
  uid = getuid();
  gid = getgid();
  }
- if (setgroups(1, &gid) ||
+ if (ouid && (setgroups(1, &gid) ||
     setresgid(gid, gid, gid) ||
-    setresuid(uid, uid, uid))
+    setresuid(uid, uid, uid)))
  err(1, "unable to revoke privs");
 
  preload = 0;
@@ -428,6 +428,11 @@ main(int argc, char *argv[])
  usage();
  }
  }
+
+ if (ouid == 0 && (setgroups(1, &gid) ||
+    setresgid(gid, gid, gid) ||
+    setresuid(uid, uid, uid)))
+ err(1, "unable to revoke privs");
 
  argc -= optind;
  argv += optind;

Reply | Threaded
Open this post in threaded view
|

Re: ping issue with rdomains

Sebastian Benoit-3
Ted Unangst([hidden email]) on 2019.03.18 23:11:24 -0400:
> Claudio Jeker wrote:
> > Ping is a bit of a special case since it runs with user _ping when started
> > as root. So by the time the SO_RTABLE is issued it does not have the privs
> > to do it. The ping -V option only works when used in rdomain 0.
>
> Maybe we can drop privs a little later if we started running as root?
> Just after getopt, which lets the setsockopt work, but before we do anything
> dangerous.

We might as well get rid of the -V option?

And traceroute has the same problem. Whatever we do here should be done
there as well.

/B.
 

> Index: ping.c
> ===================================================================
> RCS file: /home/cvs/src/sbin/ping/ping.c,v
> retrieving revision 1.234
> diff -u -p -r1.234 ping.c
> --- ping.c 13 Nov 2018 14:30:36 -0000 1.234
> +++ ping.c 19 Mar 2019 03:07:27 -0000
> @@ -283,9 +283,9 @@ main(int argc, char *argv[])
>   uid = getuid();
>   gid = getgid();
>   }
> - if (setgroups(1, &gid) ||
> + if (ouid && (setgroups(1, &gid) ||
>      setresgid(gid, gid, gid) ||
> -    setresuid(uid, uid, uid))
> +    setresuid(uid, uid, uid)))
>   err(1, "unable to revoke privs");
>  
>   preload = 0;
> @@ -428,6 +428,11 @@ main(int argc, char *argv[])
>   usage();
>   }
>   }
> +
> + if (ouid == 0 && (setgroups(1, &gid) ||
> +    setresgid(gid, gid, gid) ||
> +    setresuid(uid, uid, uid)))
> + err(1, "unable to revoke privs");
>  
>   argc -= optind;
>   argv += optind;
>

Reply | Threaded
Open this post in threaded view
|

Re: ping issue with rdomains

Pierre Emeriaud
Le lun. 18 mars 2019 à 23:40, Claudio Jeker <[hidden email]> a écrit :
>
> Ping is a bit of a special case since it runs with user _ping when started
> as root. So by the time the SO_RTABLE is issued it does not have the privs
> to do it. The ping -V option only works when used in rdomain 0.

Oh, ok, interesting, thanks. Maybe something like that would be
relevant, depending of the fate of -V:

--- ping.8      10 Nov 2018 23:44:53 -0000      1.61
+++ ping.8      19 Mar 2019 08:38:10 -0000
@@ -237,7 +237,8 @@ or a number in either hex or decimal.
 .Pq IPv4 only
 Use the specified time-to-live.
 .It Fl V Ar rtable
-Set the routing table to be used for outgoing packets.
+Set the routing table to be used for outgoing packets. Only works from
+default routing domain.
 .It Fl v
 Verbose output.
 ICMP packets other than



Le mar. 19 mars 2019 à 09:28, Sebastian Benoit <[hidden email]> a écrit :
>
> We might as well get rid of the -V option?

If possible, as a user (hence not realising what it requires under the
hood), I'd like to keep -V, much more easier on fingers that route -T
exec.

regards
pierre

Reply | Threaded
Open this post in threaded view
|

Re: ping issue with rdomains

Claudio Jeker-3
In reply to this post by Sebastian Benoit-3
On Tue, Mar 19, 2019 at 09:28:01AM +0100, Sebastian Benoit wrote:

> Ted Unangst([hidden email]) on 2019.03.18 23:11:24 -0400:
> > Claudio Jeker wrote:
> > > Ping is a bit of a special case since it runs with user _ping when started
> > > as root. So by the time the SO_RTABLE is issued it does not have the privs
> > > to do it. The ping -V option only works when used in rdomain 0.
> >
> > Maybe we can drop privs a little later if we started running as root?
> > Just after getopt, which lets the setsockopt work, but before we do anything
> > dangerous.
>
> We might as well get rid of the -V option?

This is my least preferred option.
 
> And traceroute has the same problem. Whatever we do here should be done
> there as well.

Indeed. It is the setuid priv-drop tools that have issues with this since
there is no way to run the setsockopt with the original privs.

I'm fine with tedu@'s diff. IMO this is a fairly simple solution.
 

> /B.
>  
> > Index: ping.c
> > ===================================================================
> > RCS file: /home/cvs/src/sbin/ping/ping.c,v
> > retrieving revision 1.234
> > diff -u -p -r1.234 ping.c
> > --- ping.c 13 Nov 2018 14:30:36 -0000 1.234
> > +++ ping.c 19 Mar 2019 03:07:27 -0000
> > @@ -283,9 +283,9 @@ main(int argc, char *argv[])
> >   uid = getuid();
> >   gid = getgid();
> >   }
> > - if (setgroups(1, &gid) ||
> > + if (ouid && (setgroups(1, &gid) ||
> >      setresgid(gid, gid, gid) ||
> > -    setresuid(uid, uid, uid))
> > +    setresuid(uid, uid, uid)))
> >   err(1, "unable to revoke privs");
> >  
> >   preload = 0;
> > @@ -428,6 +428,11 @@ main(int argc, char *argv[])
> >   usage();
> >   }
> >   }
> > +
> > + if (ouid == 0 && (setgroups(1, &gid) ||
> > +    setresgid(gid, gid, gid) ||
> > +    setresuid(uid, uid, uid)))
> > + err(1, "unable to revoke privs");
> >  
> >   argc -= optind;
> >   argv += optind;
> >
>

--
:wq Claudio

Reply | Threaded
Open this post in threaded view
|

Re: ping issue with rdomains

Sebastian Benoit-3
Claudio Jeker([hidden email]) on 2019.03.19 10:25:25 +0100:

> On Tue, Mar 19, 2019 at 09:28:01AM +0100, Sebastian Benoit wrote:
> > Ted Unangst([hidden email]) on 2019.03.18 23:11:24 -0400:
> > > Claudio Jeker wrote:
> > > > Ping is a bit of a special case since it runs with user _ping when started
> > > > as root. So by the time the SO_RTABLE is issued it does not have the privs
> > > > to do it. The ping -V option only works when used in rdomain 0.
> > >
> > > Maybe we can drop privs a little later if we started running as root?
> > > Just after getopt, which lets the setsockopt work, but before we do anything
> > > dangerous.
> >
> > We might as well get rid of the -V option?
>
> This is my least preferred option.

hehe
 
> > And traceroute has the same problem. Whatever we do here should be done
> > there as well.
>
> Indeed. It is the setuid priv-drop tools that have issues with this since
> there is no way to run the setsockopt with the original privs.
>
> I'm fine with tedu@'s diff. IMO this is a fairly simple solution.

i'm ok with it too.

Here is one for both ping and traceroute. Ted, you commit it?

diff --git sbin/ping/ping.c sbin/ping/ping.c
index b3b7d6ba8d6..162cbfe4e6b 100644
--- sbin/ping/ping.c
+++ sbin/ping/ping.c
@@ -283,9 +283,9 @@ main(int argc, char *argv[])
  uid = getuid();
  gid = getgid();
  }
- if (setgroups(1, &gid) ||
+ if (ouid && (setgroups(1, &gid) ||
     setresgid(gid, gid, gid) ||
-    setresuid(uid, uid, uid))
+    setresuid(uid, uid, uid)))
  err(1, "unable to revoke privs");
 
  preload = 0;
@@ -429,6 +429,11 @@ main(int argc, char *argv[])
  }
  }
 
+ if (ouid == 0 && (setgroups(1, &gid) ||
+    setresgid(gid, gid, gid) ||
+    setresuid(uid, uid, uid)))
+ err(1, "unable to revoke privs");
+
  argc -= optind;
  argv += optind;
 
diff --git usr.sbin/traceroute/traceroute.c usr.sbin/traceroute/traceroute.c
index 5ebb3df5573..81ee9ca3435 100644
--- usr.sbin/traceroute/traceroute.c
+++ usr.sbin/traceroute/traceroute.c
@@ -366,9 +366,9 @@ main(int argc, char *argv[])
  uid = getuid();
  gid = getgid();
  }
- if (setgroups(1, &gid) ||
+ if (ouid && (setgroups(1, &gid) ||
     setresgid(gid, gid, gid) ||
-    setresuid(uid, uid, uid))
+    setresuid(uid, uid, uid)))
  err(1, "unable to revoke privs");
 
  if (strcmp("traceroute6", __progname) == 0) {
@@ -559,6 +559,12 @@ main(int argc, char *argv[])
  default:
  usage(v6flag);
  }
+
+ if (ouid == 0 && (setgroups(1, &gid) ||
+    setresgid(gid, gid, gid) ||
+    setresuid(uid, uid, uid)))
+ err(1, "unable to revoke privs");
+
  argc -= optind;
  argv += optind;