diff mbox series

[net,2/2] socket: don't clear SOCK_TSTAMP_NEW when SO_TIMESTAMPNS is disabled

Message ID 20201009103121.1004-2-ceggers@arri.de
State Changes Requested
Delegated to: David Miller
Headers show
Series [net,1/2] socket: fix option SO_TIMESTAMPING_NEW | expand

Commit Message

Christian Eggers Oct. 9, 2020, 10:31 a.m. UTC
SOCK_TSTAMP_NEW (timespec64 instead of timespec) is also used for
hardware time stamps (configured via SO_TIMESTAMPING_NEW).

User space (ptp4l) first configures hardware time stamping via
SO_TIMESTAMPING_NEW which sets SOCK_TSTAMP_NEW. In the next step, ptp4l
disables SO_TIMESTAMPNS(_NEW) (software time stamps), but this must not
switch hardware time stamps back to "32 bit mode".

This problem happens on 32 bit platforms were the libc has already
switched to struct timespec64 (from SO_TIMExxx_OLD to SO_TIMExxx_NEW
socket options). ptp4l complains with "missing timestamp on transmitted
peer delay request" because the wrong format is received (and
discarded).

Fixes: 887feae36aee ("socket: Add SO_TIMESTAMP[NS]_NEW")
Fixes: 783da70e8396 ("net: add sock_enable_timestamps")
Signed-off-by: Christian Eggers <ceggers@arri.de>
---
 net/core/sock.c | 1 -
 1 file changed, 1 deletion(-)

Comments

Willem de Bruijn Oct. 10, 2020, 12:34 a.m. UTC | #1
On Fri, Oct 9, 2020 at 6:32 AM Christian Eggers <ceggers@arri.de> wrote:
>
> SOCK_TSTAMP_NEW (timespec64 instead of timespec) is also used for
> hardware time stamps (configured via SO_TIMESTAMPING_NEW).
>
> User space (ptp4l) first configures hardware time stamping via
> SO_TIMESTAMPING_NEW which sets SOCK_TSTAMP_NEW. In the next step, ptp4l
> disables SO_TIMESTAMPNS(_NEW) (software time stamps), but this must not
> switch hardware time stamps back to "32 bit mode".
>
> This problem happens on 32 bit platforms were the libc has already
> switched to struct timespec64 (from SO_TIMExxx_OLD to SO_TIMExxx_NEW
> socket options). ptp4l complains with "missing timestamp on transmitted
> peer delay request" because the wrong format is received (and
> discarded).
>
> Fixes: 887feae36aee ("socket: Add SO_TIMESTAMP[NS]_NEW")
> Fixes: 783da70e8396 ("net: add sock_enable_timestamps")
> Signed-off-by: Christian Eggers <ceggers@arri.de>

Acked-by: Willem de Bruijn <willemb@google.com>

Yes, we should just select SOCK_TSTAMP_NEW based on which of the two
syscall variants the process uses.

There is no need to reset on timestamp disable: in the common case the
selection is immaterial as timestamping is disabled.

As this commit message shows, with SO_TIMESTAMP(NS) and
SO_TIMESTAMPING that can be independently turned on and off, disabling
one can incorrectly switch modes while the other is still active.
Deepa Dinamani Oct. 10, 2020, 3:38 a.m. UTC | #2
On Fri, Oct 9, 2020 at 5:35 PM Willem de Bruijn
<willemdebruijn.kernel@gmail.com> wrote:
>
> On Fri, Oct 9, 2020 at 6:32 AM Christian Eggers <ceggers@arri.de> wrote:
> >
> > SOCK_TSTAMP_NEW (timespec64 instead of timespec) is also used for
> > hardware time stamps (configured via SO_TIMESTAMPING_NEW).
> >
> > User space (ptp4l) first configures hardware time stamping via
> > SO_TIMESTAMPING_NEW which sets SOCK_TSTAMP_NEW. In the next step, ptp4l
> > disables SO_TIMESTAMPNS(_NEW) (software time stamps), but this must not
> > switch hardware time stamps back to "32 bit mode".
> >
> > This problem happens on 32 bit platforms were the libc has already
> > switched to struct timespec64 (from SO_TIMExxx_OLD to SO_TIMExxx_NEW
> > socket options). ptp4l complains with "missing timestamp on transmitted
> > peer delay request" because the wrong format is received (and
> > discarded).
> >
> > Fixes: 887feae36aee ("socket: Add SO_TIMESTAMP[NS]_NEW")
> > Fixes: 783da70e8396 ("net: add sock_enable_timestamps")
> > Signed-off-by: Christian Eggers <ceggers@arri.de>
>
> Acked-by: Willem de Bruijn <willemb@google.com>
>
> Yes, we should just select SOCK_TSTAMP_NEW based on which of the two
> syscall variants the process uses.
>
> There is no need to reset on timestamp disable: in the common case the
> selection is immaterial as timestamping is disabled.
>
> As this commit message shows, with SO_TIMESTAMP(NS) and
> SO_TIMESTAMPING that can be independently turned on and off, disabling
> one can incorrectly switch modes while the other is still active.

This will not help the case when a child process that inherits the fd
and then sets SO_TIMESTAMP*_OLD/NEW on it, while the parent uses the
other version.
One of the two processes might still be surprised. But, child and
parent actively using the same socket fd might be expecting trouble
already.

Acked-by: Deepa Dinamani <deepa.kernel@gmail.com>

-Deepa
diff mbox series

Patch

diff --git a/net/core/sock.c b/net/core/sock.c
index 3926804702c1..f09053dfb12c 100644
--- a/net/core/sock.c
+++ b/net/core/sock.c
@@ -757,7 +757,6 @@  static void __sock_set_timestamps(struct sock *sk, bool val, bool new, bool ns)
 	} else {
 		sock_reset_flag(sk, SOCK_RCVTSTAMP);
 		sock_reset_flag(sk, SOCK_RCVTSTAMPNS);
-		sock_reset_flag(sk, SOCK_TSTAMP_NEW);
 	}
 }