Commit 294ec5b8 authored by Arnd Bergmann's avatar Arnd Bergmann

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>
parent 38c4a4cf
...@@ -48,7 +48,7 @@ int gss_import_sec_context( ...@@ -48,7 +48,7 @@ int gss_import_sec_context(
size_t bufsize, size_t bufsize,
struct gss_api_mech *mech, struct gss_api_mech *mech,
struct gss_ctx **ctx_id, struct gss_ctx **ctx_id,
time_t *endtime, time64_t *endtime,
gfp_t gfp_mask); gfp_t gfp_mask);
u32 gss_get_mic( u32 gss_get_mic(
struct gss_ctx *ctx_id, struct gss_ctx *ctx_id,
...@@ -108,7 +108,7 @@ struct gss_api_ops { ...@@ -108,7 +108,7 @@ struct gss_api_ops {
const void *input_token, const void *input_token,
size_t bufsize, size_t bufsize,
struct gss_ctx *ctx_id, struct gss_ctx *ctx_id,
time_t *endtime, time64_t *endtime,
gfp_t gfp_mask); gfp_t gfp_mask);
u32 (*gss_get_mic)( u32 (*gss_get_mic)(
struct gss_ctx *ctx_id, struct gss_ctx *ctx_id,
......
...@@ -106,9 +106,9 @@ struct krb5_ctx { ...@@ -106,9 +106,9 @@ struct krb5_ctx {
struct crypto_sync_skcipher *initiator_enc_aux; struct crypto_sync_skcipher *initiator_enc_aux;
u8 Ksess[GSS_KRB5_MAX_KEYLEN]; /* session key */ u8 Ksess[GSS_KRB5_MAX_KEYLEN]; /* session key */
u8 cksum[GSS_KRB5_MAX_KEYLEN]; u8 cksum[GSS_KRB5_MAX_KEYLEN];
s32 endtime;
atomic_t seq_send; atomic_t seq_send;
atomic64_t seq_send64; atomic64_t seq_send64;
time64_t endtime;
struct xdr_netobj mech_used; struct xdr_netobj mech_used;
u8 initiator_sign[GSS_KRB5_MAX_KEYLEN]; u8 initiator_sign[GSS_KRB5_MAX_KEYLEN];
u8 acceptor_sign[GSS_KRB5_MAX_KEYLEN]; u8 acceptor_sign[GSS_KRB5_MAX_KEYLEN];
......
...@@ -253,6 +253,7 @@ gss_import_v1_context(const void *p, const void *end, struct krb5_ctx *ctx) ...@@ -253,6 +253,7 @@ gss_import_v1_context(const void *p, const void *end, struct krb5_ctx *ctx)
{ {
u32 seq_send; u32 seq_send;
int tmp; int tmp;
u32 time32;
p = simple_get_bytes(p, end, &ctx->initiate, sizeof(ctx->initiate)); p = simple_get_bytes(p, end, &ctx->initiate, sizeof(ctx->initiate));
if (IS_ERR(p)) if (IS_ERR(p))
...@@ -290,9 +291,11 @@ gss_import_v1_context(const void *p, const void *end, struct krb5_ctx *ctx) ...@@ -290,9 +291,11 @@ gss_import_v1_context(const void *p, const void *end, struct krb5_ctx *ctx)
p = ERR_PTR(-ENOSYS); p = ERR_PTR(-ENOSYS);
goto out_err; 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)) if (IS_ERR(p))
goto out_err; 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)); p = simple_get_bytes(p, end, &seq_send, sizeof(seq_send));
if (IS_ERR(p)) if (IS_ERR(p))
goto out_err; goto out_err;
...@@ -587,15 +590,18 @@ gss_import_v2_context(const void *p, const void *end, struct krb5_ctx *ctx, ...@@ -587,15 +590,18 @@ gss_import_v2_context(const void *p, const void *end, struct krb5_ctx *ctx,
{ {
u64 seq_send64; u64 seq_send64;
int keylen; int keylen;
u32 time32;
p = simple_get_bytes(p, end, &ctx->flags, sizeof(ctx->flags)); p = simple_get_bytes(p, end, &ctx->flags, sizeof(ctx->flags));
if (IS_ERR(p)) if (IS_ERR(p))
goto out_err; goto out_err;
ctx->initiate = ctx->flags & KRB5_CTX_FLAG_INITIATOR; 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)) if (IS_ERR(p))
goto out_err; 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)); p = simple_get_bytes(p, end, &seq_send64, sizeof(seq_send64));
if (IS_ERR(p)) if (IS_ERR(p))
goto out_err; goto out_err;
...@@ -659,7 +665,7 @@ gss_import_v2_context(const void *p, const void *end, struct krb5_ctx *ctx, ...@@ -659,7 +665,7 @@ gss_import_v2_context(const void *p, const void *end, struct krb5_ctx *ctx,
static int static int
gss_import_sec_context_kerberos(const void *p, size_t len, gss_import_sec_context_kerberos(const void *p, size_t len,
struct gss_ctx *ctx_id, struct gss_ctx *ctx_id,
time_t *endtime, time64_t *endtime,
gfp_t gfp_mask) gfp_t gfp_mask)
{ {
const void *end = (const void *)((const char *)p + len); const void *end = (const void *)((const char *)p + len);
......
...@@ -131,14 +131,14 @@ gss_get_mic_v1(struct krb5_ctx *ctx, struct xdr_buf *text, ...@@ -131,14 +131,14 @@ gss_get_mic_v1(struct krb5_ctx *ctx, struct xdr_buf *text,
struct xdr_netobj md5cksum = {.len = sizeof(cksumdata), struct xdr_netobj md5cksum = {.len = sizeof(cksumdata),
.data = cksumdata}; .data = cksumdata};
void *ptr; void *ptr;
s32 now; time64_t now;
u32 seq_send; u32 seq_send;
u8 *cksumkey; u8 *cksumkey;
dprintk("RPC: %s\n", __func__); dprintk("RPC: %s\n", __func__);
BUG_ON(ctx == NULL); BUG_ON(ctx == NULL);
now = get_seconds(); now = ktime_get_real_seconds();
ptr = setup_token(ctx, token); ptr = setup_token(ctx, token);
...@@ -170,7 +170,7 @@ gss_get_mic_v2(struct krb5_ctx *ctx, struct xdr_buf *text, ...@@ -170,7 +170,7 @@ gss_get_mic_v2(struct krb5_ctx *ctx, struct xdr_buf *text,
struct xdr_netobj cksumobj = { .len = sizeof(cksumdata), struct xdr_netobj cksumobj = { .len = sizeof(cksumdata),
.data = cksumdata}; .data = cksumdata};
void *krb5_hdr; void *krb5_hdr;
s32 now; time64_t now;
u8 *cksumkey; u8 *cksumkey;
unsigned int cksum_usage; unsigned int cksum_usage;
__be64 seq_send_be64; __be64 seq_send_be64;
...@@ -198,7 +198,7 @@ gss_get_mic_v2(struct krb5_ctx *ctx, struct xdr_buf *text, ...@@ -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); 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; return (ctx->endtime < now) ? GSS_S_CONTEXT_EXPIRED : GSS_S_COMPLETE;
} }
......
...@@ -124,7 +124,7 @@ gss_verify_mic_v1(struct krb5_ctx *ctx, ...@@ -124,7 +124,7 @@ gss_verify_mic_v1(struct krb5_ctx *ctx,
/* it got through unscathed. Make sure the context is unexpired */ /* it got through unscathed. Make sure the context is unexpired */
now = get_seconds(); now = ktime_get_real_seconds();
if (now > ctx->endtime) if (now > ctx->endtime)
return GSS_S_CONTEXT_EXPIRED; return GSS_S_CONTEXT_EXPIRED;
...@@ -149,7 +149,7 @@ gss_verify_mic_v2(struct krb5_ctx *ctx, ...@@ -149,7 +149,7 @@ gss_verify_mic_v2(struct krb5_ctx *ctx,
char cksumdata[GSS_KRB5_MAX_CKSUM_LEN]; char cksumdata[GSS_KRB5_MAX_CKSUM_LEN];
struct xdr_netobj cksumobj = {.len = sizeof(cksumdata), struct xdr_netobj cksumobj = {.len = sizeof(cksumdata),
.data = cksumdata}; .data = cksumdata};
s32 now; time64_t now;
u8 *ptr = read_token->data; u8 *ptr = read_token->data;
u8 *cksumkey; u8 *cksumkey;
u8 flags; u8 flags;
...@@ -194,7 +194,7 @@ gss_verify_mic_v2(struct krb5_ctx *ctx, ...@@ -194,7 +194,7 @@ gss_verify_mic_v2(struct krb5_ctx *ctx,
return GSS_S_BAD_SIG; return GSS_S_BAD_SIG;
/* it got through unscathed. Make sure the context is unexpired */ /* it got through unscathed. Make sure the context is unexpired */
now = get_seconds(); now = ktime_get_real_seconds();
if (now > ctx->endtime) if (now > ctx->endtime)
return GSS_S_CONTEXT_EXPIRED; return GSS_S_CONTEXT_EXPIRED;
......
...@@ -163,7 +163,7 @@ gss_wrap_kerberos_v1(struct krb5_ctx *kctx, int offset, ...@@ -163,7 +163,7 @@ gss_wrap_kerberos_v1(struct krb5_ctx *kctx, int offset,
.data = cksumdata}; .data = cksumdata};
int blocksize = 0, plainlen; int blocksize = 0, plainlen;
unsigned char *ptr, *msg_start; unsigned char *ptr, *msg_start;
s32 now; time64_t now;
int headlen; int headlen;
struct page **tmp_pages; struct page **tmp_pages;
u32 seq_send; u32 seq_send;
...@@ -172,7 +172,7 @@ gss_wrap_kerberos_v1(struct krb5_ctx *kctx, int offset, ...@@ -172,7 +172,7 @@ gss_wrap_kerberos_v1(struct krb5_ctx *kctx, int offset,
dprintk("RPC: %s\n", __func__); dprintk("RPC: %s\n", __func__);
now = get_seconds(); now = ktime_get_real_seconds();
blocksize = crypto_sync_skcipher_blocksize(kctx->enc); blocksize = crypto_sync_skcipher_blocksize(kctx->enc);
gss_krb5_add_padding(buf, offset, blocksize); gss_krb5_add_padding(buf, offset, blocksize);
...@@ -268,7 +268,7 @@ gss_unwrap_kerberos_v1(struct krb5_ctx *kctx, int offset, struct xdr_buf *buf) ...@@ -268,7 +268,7 @@ gss_unwrap_kerberos_v1(struct krb5_ctx *kctx, int offset, struct xdr_buf *buf)
char cksumdata[GSS_KRB5_MAX_CKSUM_LEN]; char cksumdata[GSS_KRB5_MAX_CKSUM_LEN];
struct xdr_netobj md5cksum = {.len = sizeof(cksumdata), struct xdr_netobj md5cksum = {.len = sizeof(cksumdata),
.data = cksumdata}; .data = cksumdata};
s32 now; time64_t now;
int direction; int direction;
s32 seqnum; s32 seqnum;
unsigned char *ptr; unsigned char *ptr;
...@@ -359,7 +359,7 @@ gss_unwrap_kerberos_v1(struct krb5_ctx *kctx, int offset, struct xdr_buf *buf) ...@@ -359,7 +359,7 @@ gss_unwrap_kerberos_v1(struct krb5_ctx *kctx, int offset, struct xdr_buf *buf)
/* it got through unscathed. Make sure the context is unexpired */ /* it got through unscathed. Make sure the context is unexpired */
now = get_seconds(); now = ktime_get_real_seconds();
if (now > kctx->endtime) if (now > kctx->endtime)
return GSS_S_CONTEXT_EXPIRED; return GSS_S_CONTEXT_EXPIRED;
...@@ -439,7 +439,7 @@ gss_wrap_kerberos_v2(struct krb5_ctx *kctx, u32 offset, ...@@ -439,7 +439,7 @@ gss_wrap_kerberos_v2(struct krb5_ctx *kctx, u32 offset,
struct xdr_buf *buf, struct page **pages) struct xdr_buf *buf, struct page **pages)
{ {
u8 *ptr, *plainhdr; u8 *ptr, *plainhdr;
s32 now; time64_t now;
u8 flags = 0x00; u8 flags = 0x00;
__be16 *be16ptr; __be16 *be16ptr;
__be64 *be64ptr; __be64 *be64ptr;
...@@ -481,14 +481,14 @@ gss_wrap_kerberos_v2(struct krb5_ctx *kctx, u32 offset, ...@@ -481,14 +481,14 @@ gss_wrap_kerberos_v2(struct krb5_ctx *kctx, u32 offset,
if (err) if (err)
return err; return err;
now = get_seconds(); now = ktime_get_real_seconds();
return (kctx->endtime < now) ? GSS_S_CONTEXT_EXPIRED : GSS_S_COMPLETE; return (kctx->endtime < now) ? GSS_S_CONTEXT_EXPIRED : GSS_S_COMPLETE;
} }
static u32 static u32
gss_unwrap_kerberos_v2(struct krb5_ctx *kctx, int offset, struct xdr_buf *buf) gss_unwrap_kerberos_v2(struct krb5_ctx *kctx, int offset, struct xdr_buf *buf)
{ {
s32 now; time64_t now;
u8 *ptr; u8 *ptr;
u8 flags = 0x00; u8 flags = 0x00;
u16 ec, rrc; u16 ec, rrc;
...@@ -557,7 +557,7 @@ gss_unwrap_kerberos_v2(struct krb5_ctx *kctx, int offset, struct xdr_buf *buf) ...@@ -557,7 +557,7 @@ gss_unwrap_kerberos_v2(struct krb5_ctx *kctx, int offset, struct xdr_buf *buf)
/* do sequencing checks */ /* do sequencing checks */
/* it got through unscathed. Make sure the context is unexpired */ /* it got through unscathed. Make sure the context is unexpired */
now = get_seconds(); now = ktime_get_real_seconds();
if (now > kctx->endtime) if (now > kctx->endtime)
return GSS_S_CONTEXT_EXPIRED; return GSS_S_CONTEXT_EXPIRED;
......
...@@ -376,7 +376,7 @@ int ...@@ -376,7 +376,7 @@ int
gss_import_sec_context(const void *input_token, size_t bufsize, gss_import_sec_context(const void *input_token, size_t bufsize,
struct gss_api_mech *mech, struct gss_api_mech *mech,
struct gss_ctx **ctx_id, struct gss_ctx **ctx_id,
time_t *endtime, time64_t *endtime,
gfp_t gfp_mask) gfp_t gfp_mask)
{ {
if (!(*ctx_id = kzalloc(sizeof(**ctx_id), gfp_mask))) if (!(*ctx_id = kzalloc(sizeof(**ctx_id), gfp_mask)))
......
...@@ -436,7 +436,7 @@ static int rsc_parse(struct cache_detail *cd, ...@@ -436,7 +436,7 @@ static int rsc_parse(struct cache_detail *cd,
int id; int id;
int len, rv; int len, rv;
struct rsc rsci, *rscp = NULL; struct rsc rsci, *rscp = NULL;
time_t expiry; time64_t expiry;
int status = -EINVAL; int status = -EINVAL;
struct gss_api_mech *gm = NULL; struct gss_api_mech *gm = NULL;
...@@ -1221,7 +1221,7 @@ static int gss_proxy_save_rsc(struct cache_detail *cd, ...@@ -1221,7 +1221,7 @@ static int gss_proxy_save_rsc(struct cache_detail *cd,
static atomic64_t ctxhctr; static atomic64_t ctxhctr;
long long ctxh; long long ctxh;
struct gss_api_mech *gm = NULL; struct gss_api_mech *gm = NULL;
time_t expiry; time64_t expiry;
int status = -EINVAL; int status = -EINVAL;
memset(&rsci, 0, sizeof(rsci)); memset(&rsci, 0, sizeof(rsci));
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment