All of lore.kernel.org
 help / color / mirror / Atom feed
From: Oliver Hartkopp <socketcan-fJ+pQTUTwRTk1uMJSBkQmQ@public.gmane.org>
To: Arnd Bergmann <arnd-r2nGTMty4D4@public.gmane.org>,
	netdev-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
Cc: y2038-cunTk1MwBs8s++Sfvej+rw@public.gmane.org,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
	"David S. Miller" <davem-fT/PcQaiUtIeIZ0/mPfg9Q@public.gmane.org>,
	Marc Kleine-Budde <mkl-bIcnvbaLZ9MEGnE8C9+IrQ@public.gmane.org>,
	linux-can-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
	linux-api-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
Subject: Re: [PATCH 12/12] [RFC] can: avoid using timeval for uapi
Date: Mon, 05 Oct 2015 20:51:08 +0200	[thread overview]
Message-ID: <5612C69C.7020803@hartkopp.net> (raw)
In-Reply-To: <1443612402-3000775-13-git-send-email-arnd-r2nGTMty4D4@public.gmane.org>

Hello Arnd,

thanks for picking up this y2038 api issue.

On 09/30/2015 01:26 PM, Arnd Bergmann wrote:
> The can subsystem communicates with user space using a bcm_msg_head
> header, which contains two timestamps. This is problematic for
> multiple reasons:
> 
> a) The structure layout is currently incompatible between 64-bit
>    user space and 32-bit user space, and cannot work in compat
>    mode (other than x32).
> 
> b) The timeval structure layout will change in 32-bit user
>    space when we fix the y2038 overflow problem by redefining
>    time_t to 64-bit, making new 32-bit user space incompatible
>    with the current kernel interface.
>    Cars last a long time and often use old kernels, so the actual
>    users of this code are the most likely ones to migrate to y2038
>    safe user space.
> 
> This tries to work around part of the problem by changing the
> publicly visible user interface in the header, but not the binary
> interface. Fortunately, the values passed around in the structure
> are relative times and do not actually suffer from the y2038
> overflow, so 32-bit is enough here.
> 
> We replace the use of 'struct timeval' with a newly defined
> 'struct bcm_timeval' that uses the exact same binary layout
> as before and that still suffers from problem a) but not problem
> b).
> 
> The downside of this approach is that any user space program
> that currently assigns a timeval structure to these members
> rather than writing the tv_sec/tv_usec portions individually
> will suffer a compile-time error when built with an updated
> kernel header. Fixing this error makes it work fine with old
> and new headers though.

I double checked some (more) BCM applications I have access to.

E.g. https://github.com/linux-can/can-tests

When you do a 'git grep ival1' there you get something like

tst-bcm-cycle.c:        msg.msg_head.ival1.tv_sec = 1;
tst-bcm-cycle.c:        msg.msg_head.ival1.tv_usec = 0;
tst-bcm-cycle.c:        msg.msg_head.ival1.tv_sec = 0;
tst-bcm-cycle.c:        msg.msg_head.ival1.tv_usec = 0;
tst-bcm-dump.c: msg.msg_head.ival1.tv_sec       = timeout / 1000000;
tst-bcm-dump.c: msg.msg_head.ival1.tv_usec      = timeout % 1000000;
(..)

So the usual way to assign values to ival1 and ival2 is NOT to assign an
existing struct timeval but to directly assign its tv_[u]sec elements.

I applied your bcm.h changes to my local can-tests tree and it compiles
without any problems - as expected. I don't see any serious drawback with your
idea. I wonder whether developers would ever notice this change ...

> We could address problem a) by using '__u32' or 'int' members
> rather than 'long', but that would have a more significant
> downside in also breaking support for all existing 64-bit user
> binaries that might be using this interface, which is likely
> not acceptable.

Indeed.

> Signed-off-by: Arnd Bergmann <arnd-r2nGTMty4D4@public.gmane.org>
> Cc: Oliver Hartkopp <socketcan-fJ+pQTUTwRTk1uMJSBkQmQ@public.gmane.org>

Thanks for your good suggestion to make the BCM API y2038 proof!

Acked-by: Oliver Hartkopp <socketcan-fJ+pQTUTwRTk1uMJSBkQmQ@public.gmane.org>

> Cc: Marc Kleine-Budde <mkl-bIcnvbaLZ9MEGnE8C9+IrQ@public.gmane.org>
> Cc: linux-can-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
> Cc: linux-api-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
> ---
>  include/uapi/linux/can/bcm.h |  7 ++++++-
>  net/can/bcm.c                | 15 ++++++++++-----
>  2 files changed, 16 insertions(+), 6 deletions(-)
> 
> diff --git a/include/uapi/linux/can/bcm.h b/include/uapi/linux/can/bcm.h
> index 89ddb9dc9bdf..7a291dc1ff15 100644
> --- a/include/uapi/linux/can/bcm.h
> +++ b/include/uapi/linux/can/bcm.h
> @@ -47,6 +47,11 @@
>  #include <linux/types.h>
>  #include <linux/can.h>
>  
> +struct bcm_timeval {
> +	long tv_sec;
> +	long tv_usec;
> +};
> +
>  /**
>   * struct bcm_msg_head - head of messages to/from the broadcast manager
>   * @opcode:    opcode, see enum below.
> @@ -62,7 +67,7 @@ struct bcm_msg_head {
>  	__u32 opcode;
>  	__u32 flags;
>  	__u32 count;
> -	struct timeval ival1, ival2;
> +	struct bcm_timeval ival1, ival2;
>  	canid_t can_id;
>  	__u32 nframes;
>  	struct can_frame frames[0];
> diff --git a/net/can/bcm.c b/net/can/bcm.c
> index a1ba6875c2a2..6863310d6973 100644
> --- a/net/can/bcm.c
> +++ b/net/can/bcm.c
> @@ -96,7 +96,7 @@ struct bcm_op {
>  	canid_t can_id;
>  	u32 flags;
>  	unsigned long frames_abs, frames_filtered;
> -	struct timeval ival1, ival2;
> +	struct bcm_timeval ival1, ival2;
>  	struct hrtimer timer, thrtimer;
>  	struct tasklet_struct tsklet, thrtsklet;
>  	ktime_t rx_stamp, kt_ival1, kt_ival2, kt_lastmsg;
> @@ -131,6 +131,11 @@ static inline struct bcm_sock *bcm_sk(const struct sock *sk)
>  	return (struct bcm_sock *)sk;
>  }
>  
> +static inline ktime_t bcm_timeval_to_ktime(struct bcm_timeval tv)
> +{
> +	return ktime_set(tv.tv_sec, tv.tv_usec * NSEC_PER_USEC);
> +}
> +
>  #define CFSIZ sizeof(struct can_frame)
>  #define OPSIZ sizeof(struct bcm_op)
>  #define MHSIZ sizeof(struct bcm_msg_head)
> @@ -953,8 +958,8 @@ static int bcm_tx_setup(struct bcm_msg_head *msg_head, struct msghdr *msg,
>  		op->count = msg_head->count;
>  		op->ival1 = msg_head->ival1;
>  		op->ival2 = msg_head->ival2;
> -		op->kt_ival1 = timeval_to_ktime(msg_head->ival1);
> -		op->kt_ival2 = timeval_to_ktime(msg_head->ival2);
> +		op->kt_ival1 = bcm_timeval_to_ktime(msg_head->ival1);
> +		op->kt_ival2 = bcm_timeval_to_ktime(msg_head->ival2);
>  
>  		/* disable an active timer due to zero values? */
>  		if (!op->kt_ival1.tv64 && !op->kt_ival2.tv64)
> @@ -1134,8 +1139,8 @@ static int bcm_rx_setup(struct bcm_msg_head *msg_head, struct msghdr *msg,
>  			/* set timer value */
>  			op->ival1 = msg_head->ival1;
>  			op->ival2 = msg_head->ival2;
> -			op->kt_ival1 = timeval_to_ktime(msg_head->ival1);
> -			op->kt_ival2 = timeval_to_ktime(msg_head->ival2);
> +			op->kt_ival1 = bcm_timeval_to_ktime(msg_head->ival1);
> +			op->kt_ival2 = bcm_timeval_to_ktime(msg_head->ival2);
>  
>  			/* disable an active timer due to zero value? */
>  			if (!op->kt_ival1.tv64)
> 

WARNING: multiple messages have this Message-ID (diff)
From: Oliver Hartkopp <socketcan@hartkopp.net>
To: Arnd Bergmann <arnd@arndb.de>, netdev@vger.kernel.org
Cc: y2038@lists.linaro.org, linux-kernel@vger.kernel.org,
	"David S. Miller" <davem@davemloft.net>,
	Marc Kleine-Budde <mkl@pengutronix.de>,
	linux-can@vger.kernel.org, linux-api@vger.kernel.org
Subject: Re: [PATCH 12/12] [RFC] can: avoid using timeval for uapi
Date: Mon, 05 Oct 2015 20:51:08 +0200	[thread overview]
Message-ID: <5612C69C.7020803@hartkopp.net> (raw)
In-Reply-To: <1443612402-3000775-13-git-send-email-arnd@arndb.de>

Hello Arnd,

thanks for picking up this y2038 api issue.

On 09/30/2015 01:26 PM, Arnd Bergmann wrote:
> The can subsystem communicates with user space using a bcm_msg_head
> header, which contains two timestamps. This is problematic for
> multiple reasons:
> 
> a) The structure layout is currently incompatible between 64-bit
>    user space and 32-bit user space, and cannot work in compat
>    mode (other than x32).
> 
> b) The timeval structure layout will change in 32-bit user
>    space when we fix the y2038 overflow problem by redefining
>    time_t to 64-bit, making new 32-bit user space incompatible
>    with the current kernel interface.
>    Cars last a long time and often use old kernels, so the actual
>    users of this code are the most likely ones to migrate to y2038
>    safe user space.
> 
> This tries to work around part of the problem by changing the
> publicly visible user interface in the header, but not the binary
> interface. Fortunately, the values passed around in the structure
> are relative times and do not actually suffer from the y2038
> overflow, so 32-bit is enough here.
> 
> We replace the use of 'struct timeval' with a newly defined
> 'struct bcm_timeval' that uses the exact same binary layout
> as before and that still suffers from problem a) but not problem
> b).
> 
> The downside of this approach is that any user space program
> that currently assigns a timeval structure to these members
> rather than writing the tv_sec/tv_usec portions individually
> will suffer a compile-time error when built with an updated
> kernel header. Fixing this error makes it work fine with old
> and new headers though.

I double checked some (more) BCM applications I have access to.

E.g. https://github.com/linux-can/can-tests

When you do a 'git grep ival1' there you get something like

tst-bcm-cycle.c:        msg.msg_head.ival1.tv_sec = 1;
tst-bcm-cycle.c:        msg.msg_head.ival1.tv_usec = 0;
tst-bcm-cycle.c:        msg.msg_head.ival1.tv_sec = 0;
tst-bcm-cycle.c:        msg.msg_head.ival1.tv_usec = 0;
tst-bcm-dump.c: msg.msg_head.ival1.tv_sec       = timeout / 1000000;
tst-bcm-dump.c: msg.msg_head.ival1.tv_usec      = timeout % 1000000;
(..)

So the usual way to assign values to ival1 and ival2 is NOT to assign an
existing struct timeval but to directly assign its tv_[u]sec elements.

I applied your bcm.h changes to my local can-tests tree and it compiles
without any problems - as expected. I don't see any serious drawback with your
idea. I wonder whether developers would ever notice this change ...

> We could address problem a) by using '__u32' or 'int' members
> rather than 'long', but that would have a more significant
> downside in also breaking support for all existing 64-bit user
> binaries that might be using this interface, which is likely
> not acceptable.

Indeed.

> Signed-off-by: Arnd Bergmann <arnd@arndb.de>
> Cc: Oliver Hartkopp <socketcan@hartkopp.net>

Thanks for your good suggestion to make the BCM API y2038 proof!

Acked-by: Oliver Hartkopp <socketcan@hartkopp.net>

> Cc: Marc Kleine-Budde <mkl@pengutronix.de>
> Cc: linux-can@vger.kernel.org
> Cc: linux-api@vger.kernel.org
> ---
>  include/uapi/linux/can/bcm.h |  7 ++++++-
>  net/can/bcm.c                | 15 ++++++++++-----
>  2 files changed, 16 insertions(+), 6 deletions(-)
> 
> diff --git a/include/uapi/linux/can/bcm.h b/include/uapi/linux/can/bcm.h
> index 89ddb9dc9bdf..7a291dc1ff15 100644
> --- a/include/uapi/linux/can/bcm.h
> +++ b/include/uapi/linux/can/bcm.h
> @@ -47,6 +47,11 @@
>  #include <linux/types.h>
>  #include <linux/can.h>
>  
> +struct bcm_timeval {
> +	long tv_sec;
> +	long tv_usec;
> +};
> +
>  /**
>   * struct bcm_msg_head - head of messages to/from the broadcast manager
>   * @opcode:    opcode, see enum below.
> @@ -62,7 +67,7 @@ struct bcm_msg_head {
>  	__u32 opcode;
>  	__u32 flags;
>  	__u32 count;
> -	struct timeval ival1, ival2;
> +	struct bcm_timeval ival1, ival2;
>  	canid_t can_id;
>  	__u32 nframes;
>  	struct can_frame frames[0];
> diff --git a/net/can/bcm.c b/net/can/bcm.c
> index a1ba6875c2a2..6863310d6973 100644
> --- a/net/can/bcm.c
> +++ b/net/can/bcm.c
> @@ -96,7 +96,7 @@ struct bcm_op {
>  	canid_t can_id;
>  	u32 flags;
>  	unsigned long frames_abs, frames_filtered;
> -	struct timeval ival1, ival2;
> +	struct bcm_timeval ival1, ival2;
>  	struct hrtimer timer, thrtimer;
>  	struct tasklet_struct tsklet, thrtsklet;
>  	ktime_t rx_stamp, kt_ival1, kt_ival2, kt_lastmsg;
> @@ -131,6 +131,11 @@ static inline struct bcm_sock *bcm_sk(const struct sock *sk)
>  	return (struct bcm_sock *)sk;
>  }
>  
> +static inline ktime_t bcm_timeval_to_ktime(struct bcm_timeval tv)
> +{
> +	return ktime_set(tv.tv_sec, tv.tv_usec * NSEC_PER_USEC);
> +}
> +
>  #define CFSIZ sizeof(struct can_frame)
>  #define OPSIZ sizeof(struct bcm_op)
>  #define MHSIZ sizeof(struct bcm_msg_head)
> @@ -953,8 +958,8 @@ static int bcm_tx_setup(struct bcm_msg_head *msg_head, struct msghdr *msg,
>  		op->count = msg_head->count;
>  		op->ival1 = msg_head->ival1;
>  		op->ival2 = msg_head->ival2;
> -		op->kt_ival1 = timeval_to_ktime(msg_head->ival1);
> -		op->kt_ival2 = timeval_to_ktime(msg_head->ival2);
> +		op->kt_ival1 = bcm_timeval_to_ktime(msg_head->ival1);
> +		op->kt_ival2 = bcm_timeval_to_ktime(msg_head->ival2);
>  
>  		/* disable an active timer due to zero values? */
>  		if (!op->kt_ival1.tv64 && !op->kt_ival2.tv64)
> @@ -1134,8 +1139,8 @@ static int bcm_rx_setup(struct bcm_msg_head *msg_head, struct msghdr *msg,
>  			/* set timer value */
>  			op->ival1 = msg_head->ival1;
>  			op->ival2 = msg_head->ival2;
> -			op->kt_ival1 = timeval_to_ktime(msg_head->ival1);
> -			op->kt_ival2 = timeval_to_ktime(msg_head->ival2);
> +			op->kt_ival1 = bcm_timeval_to_ktime(msg_head->ival1);
> +			op->kt_ival2 = bcm_timeval_to_ktime(msg_head->ival2);
>  
>  			/* disable an active timer due to zero value? */
>  			if (!op->kt_ival1.tv64)
> 

  parent reply	other threads:[~2015-10-05 18:51 UTC|newest]

Thread overview: 72+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2015-09-30 11:26 [Intel-wired-lan] [PATCH 00/12] net: assorted y2038 changes Arnd Bergmann
2015-09-30 11:26 ` Arnd Bergmann
2015-09-30 11:26 ` Arnd Bergmann
2015-09-30 11:26 ` Arnd Bergmann
2015-09-30 11:26 ` [PATCH 01/12] net: fec: avoid timespec use Arnd Bergmann
2015-10-01 19:08   ` Richard Cochran
2015-09-30 11:26 ` [PATCH 02/12] net: stmmac: avoid using timespec Arnd Bergmann
2015-09-30 11:26   ` Arnd Bergmann
2015-10-01 19:08   ` Richard Cochran
2015-09-30 11:26 ` [Intel-wired-lan] [PATCH 03/12] net: igb: " Arnd Bergmann
2015-09-30 11:26   ` Arnd Bergmann
2015-09-30 11:26   ` Arnd Bergmann
2015-10-01 19:17   ` [Intel-wired-lan] " Richard Cochran
2015-10-01 19:17     ` Richard Cochran
2015-10-01 19:17     ` Richard Cochran
2015-10-01 20:01     ` [Intel-wired-lan] " Arnd Bergmann
2015-10-01 20:01       ` Arnd Bergmann
2015-10-01 20:01       ` Arnd Bergmann
2015-10-02  7:47       ` [Intel-wired-lan] " Richard Cochran
2015-10-02  7:47         ` Richard Cochran
2015-10-02  7:47         ` Richard Cochran
2015-09-30 11:26 ` [PATCH 04/12] mwifiex: use ktime_get_real for timestamping Arnd Bergmann
2015-09-30 11:26   ` Arnd Bergmann
2015-10-09 11:36   ` Amitkumar Karwar
2015-09-30 11:26 ` [PATCH 05/12] mwifiex: avoid gettimeofday in ba_threshold setting Arnd Bergmann
2015-09-30 11:26   ` Arnd Bergmann
2015-10-09 11:35   ` Amitkumar Karwar
2015-10-09 11:35     ` Amitkumar Karwar
2015-09-30 11:26 ` [PATCH 06/12] mac80211: use ktime_get_seconds Arnd Bergmann
2015-09-30 11:26   ` Arnd Bergmann
2015-09-30 11:26 ` [PATCH 07/12] atm: hide 'struct zatm_t_hist' Arnd Bergmann
2015-09-30 11:26   ` Arnd Bergmann
2015-09-30 15:24   ` Charles (Chas) Williams
2015-09-30 15:31     ` Arnd Bergmann
2015-09-30 15:31       ` Arnd Bergmann
2015-09-30 15:32     ` [PATCH v2] atm: remove " Arnd Bergmann
2015-09-30 11:26 ` [PATCH 08/12] nfnetlink: use y2038 safe timestamp Arnd Bergmann
2015-10-02 12:53   ` Pablo Neira Ayuso
2015-10-02 21:23     ` Arnd Bergmann
2015-10-02 21:23       ` Arnd Bergmann
2015-09-30 11:26 ` [PATCH 09/12] ipv6: use ktime_t for internal timestamps Arnd Bergmann
2015-09-30 11:26 ` [PATCH 10/12] net: sctp: avoid incorrect time_t use Arnd Bergmann
2015-09-30 11:26   ` Arnd Bergmann
2015-09-30 13:57   ` Neil Horman
2015-09-30 13:57     ` Neil Horman
2015-09-30 14:15     ` Marcelo Ricardo Leitner
2015-09-30 14:15       ` Marcelo Ricardo Leitner
2015-09-30 14:19       ` Neil Horman
2015-09-30 14:19         ` Neil Horman
2015-09-30 14:28   ` Marcelo Ricardo Leitner
2015-09-30 14:28     ` Marcelo Ricardo Leitner
2015-09-30 11:26 ` [PATCH 11/12] [RFC] ipv4: avoid timespec in timestamp computation Arnd Bergmann
2015-09-30 11:55   ` kbuild test robot
2015-09-30 12:39     ` [Y2038] " Arnd Bergmann
2015-09-30 12:58       ` [RFC v2] " Arnd Bergmann
2015-09-30 12:15   ` [RFC PATCH] ipv4: ktime_get_ms_of_day() can be static kbuild test robot
2015-09-30 12:15   ` [PATCH 11/12] [RFC] ipv4: avoid timespec in timestamp computation kbuild test robot
2015-09-30 12:15     ` kbuild test robot
2015-09-30 11:26 ` [PATCH 12/12] [RFC] can: avoid using timeval for uapi Arnd Bergmann
2015-09-30 11:26   ` Arnd Bergmann
     [not found]   ` <1443612402-3000775-13-git-send-email-arnd-r2nGTMty4D4@public.gmane.org>
2015-10-05 18:51     ` Oliver Hartkopp [this message]
2015-10-05 18:51       ` Oliver Hartkopp
2015-10-06  8:32       ` Arnd Bergmann
2015-10-06  8:32         ` Arnd Bergmann
2015-10-06  9:05         ` Marc Kleine-Budde
2015-10-06  9:18           ` Arnd Bergmann
2015-10-06  9:37             ` Marc Kleine-Budde
2015-10-06  9:37               ` Marc Kleine-Budde
2015-10-05 10:17 ` [Intel-wired-lan] [PATCH 00/12] net: assorted y2038 changes David Miller
2015-10-05 10:17   ` David Miller
2015-10-05 10:17   ` David Miller
2015-10-05 10:17   ` David Miller

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=5612C69C.7020803@hartkopp.net \
    --to=socketcan-fj+pqtutwrtk1umjsbkqmq@public.gmane.org \
    --cc=arnd-r2nGTMty4D4@public.gmane.org \
    --cc=davem-fT/PcQaiUtIeIZ0/mPfg9Q@public.gmane.org \
    --cc=linux-api-u79uwXL29TY76Z2rM5mHXA@public.gmane.org \
    --cc=linux-can-u79uwXL29TY76Z2rM5mHXA@public.gmane.org \
    --cc=linux-kernel-u79uwXL29TY76Z2rM5mHXA@public.gmane.org \
    --cc=mkl-bIcnvbaLZ9MEGnE8C9+IrQ@public.gmane.org \
    --cc=netdev-u79uwXL29TY76Z2rM5mHXA@public.gmane.org \
    --cc=y2038-cunTk1MwBs8s++Sfvej+rw@public.gmane.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.