Commit 52879b46 authored by Arnd Bergmann's avatar Arnd Bergmann Committed by Anna Schumaker
Browse files

sunrpc: convert to time64_t for expiry



Using signed 32-bit types for UTC time leads to the y2038 overflow,
which is what happens in the sunrpc code at the moment.

This changes the sunrpc code over to use time64_t where possible.
The one exception is the gss_import_v{1,2}_context() function for
kerberos5, which uses 32-bit timestamps in the protocol. Here,
we can at least treat the numbers as 'unsigned', which extends the
range from 2038 to 2106.

Signed-off-by: default avatarArnd Bergmann <arnd@arndb.de>
Signed-off-by: default avatarAnna Schumaker <Anna.Schumaker@Netapp.com>
parent ce8866f0
Loading
Loading
Loading
Loading
+2 −2
Original line number Diff line number Diff line
@@ -48,7 +48,7 @@ int gss_import_sec_context(
		size_t			bufsize,
		struct gss_api_mech	*mech,
		struct gss_ctx		**ctx_id,
		time_t			*endtime,
		time64_t		*endtime,
		gfp_t			gfp_mask);
u32 gss_get_mic(
		struct gss_ctx		*ctx_id,
@@ -108,7 +108,7 @@ struct gss_api_ops {
			const void		*input_token,
			size_t			bufsize,
			struct gss_ctx		*ctx_id,
			time_t			*endtime,
			time64_t		*endtime,
			gfp_t			gfp_mask);
	u32 (*gss_get_mic)(
			struct gss_ctx		*ctx_id,
+1 −1
Original line number Diff line number Diff line
@@ -106,9 +106,9 @@ struct krb5_ctx {
	struct crypto_sync_skcipher *initiator_enc_aux;
	u8			Ksess[GSS_KRB5_MAX_KEYLEN]; /* session key */
	u8			cksum[GSS_KRB5_MAX_KEYLEN];
	s32			endtime;
	atomic_t		seq_send;
	atomic64_t		seq_send64;
	time64_t		endtime;
	struct xdr_netobj	mech_used;
	u8			initiator_sign[GSS_KRB5_MAX_KEYLEN];
	u8			acceptor_sign[GSS_KRB5_MAX_KEYLEN];
+9 −3
Original line number Diff line number Diff line
@@ -253,6 +253,7 @@ gss_import_v1_context(const void *p, const void *end, struct krb5_ctx *ctx)
{
	u32 seq_send;
	int tmp;
	u32 time32;

	p = simple_get_bytes(p, end, &ctx->initiate, sizeof(ctx->initiate));
	if (IS_ERR(p))
@@ -290,9 +291,11 @@ gss_import_v1_context(const void *p, const void *end, struct krb5_ctx *ctx)
		p = ERR_PTR(-ENOSYS);
		goto out_err;
	}
	p = simple_get_bytes(p, end, &ctx->endtime, sizeof(ctx->endtime));
	p = simple_get_bytes(p, end, &time32, sizeof(time32));
	if (IS_ERR(p))
		goto out_err;
	/* unsigned 32-bit time overflows in year 2106 */
	ctx->endtime = (time64_t)time32;
	p = simple_get_bytes(p, end, &seq_send, sizeof(seq_send));
	if (IS_ERR(p))
		goto out_err;
@@ -587,15 +590,18 @@ gss_import_v2_context(const void *p, const void *end, struct krb5_ctx *ctx,
{
	u64 seq_send64;
	int keylen;
	u32 time32;

	p = simple_get_bytes(p, end, &ctx->flags, sizeof(ctx->flags));
	if (IS_ERR(p))
		goto out_err;
	ctx->initiate = ctx->flags & KRB5_CTX_FLAG_INITIATOR;

	p = simple_get_bytes(p, end, &ctx->endtime, sizeof(ctx->endtime));
	p = simple_get_bytes(p, end, &time32, sizeof(time32));
	if (IS_ERR(p))
		goto out_err;
	/* unsigned 32-bit time overflows in year 2106 */
	ctx->endtime = (time64_t)time32;
	p = simple_get_bytes(p, end, &seq_send64, sizeof(seq_send64));
	if (IS_ERR(p))
		goto out_err;
@@ -659,7 +665,7 @@ out_err:
static int
gss_import_sec_context_kerberos(const void *p, size_t len,
				struct gss_ctx *ctx_id,
				time_t *endtime,
				time64_t *endtime,
				gfp_t gfp_mask)
{
	const void *end = (const void *)((const char *)p + len);
+4 −4
Original line number Diff line number Diff line
@@ -131,14 +131,14 @@ gss_get_mic_v1(struct krb5_ctx *ctx, struct xdr_buf *text,
	struct xdr_netobj	md5cksum = {.len = sizeof(cksumdata),
					    .data = cksumdata};
	void			*ptr;
	s32			now;
	time64_t		now;
	u32			seq_send;
	u8			*cksumkey;

	dprintk("RPC:       %s\n", __func__);
	BUG_ON(ctx == NULL);

	now = get_seconds();
	now = ktime_get_real_seconds();

	ptr = setup_token(ctx, token);

@@ -170,7 +170,7 @@ gss_get_mic_v2(struct krb5_ctx *ctx, struct xdr_buf *text,
	struct xdr_netobj cksumobj = { .len = sizeof(cksumdata),
				       .data = cksumdata};
	void *krb5_hdr;
	s32 now;
	time64_t now;
	u8 *cksumkey;
	unsigned int cksum_usage;
	__be64 seq_send_be64;
@@ -198,7 +198,7 @@ gss_get_mic_v2(struct krb5_ctx *ctx, struct xdr_buf *text,

	memcpy(krb5_hdr + GSS_KRB5_TOK_HDR_LEN, cksumobj.data, cksumobj.len);

	now = get_seconds();
	now = ktime_get_real_seconds();

	return (ctx->endtime < now) ? GSS_S_CONTEXT_EXPIRED : GSS_S_COMPLETE;
}
+3 −3
Original line number Diff line number Diff line
@@ -124,7 +124,7 @@ gss_verify_mic_v1(struct krb5_ctx *ctx,

	/* it got through unscathed.  Make sure the context is unexpired */

	now = get_seconds();
	now = ktime_get_real_seconds();

	if (now > ctx->endtime)
		return GSS_S_CONTEXT_EXPIRED;
@@ -149,7 +149,7 @@ gss_verify_mic_v2(struct krb5_ctx *ctx,
	char cksumdata[GSS_KRB5_MAX_CKSUM_LEN];
	struct xdr_netobj cksumobj = {.len = sizeof(cksumdata),
				      .data = cksumdata};
	s32 now;
	time64_t now;
	u8 *ptr = read_token->data;
	u8 *cksumkey;
	u8 flags;
@@ -194,7 +194,7 @@ gss_verify_mic_v2(struct krb5_ctx *ctx,
		return GSS_S_BAD_SIG;

	/* it got through unscathed.  Make sure the context is unexpired */
	now = get_seconds();
	now = ktime_get_real_seconds();
	if (now > ctx->endtime)
		return GSS_S_CONTEXT_EXPIRED;

Loading