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: Arnd Bergmann <arnd@arndb.de>
This commit is contained in:
@@ -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 {
|
|||||||
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 {
|
|||||||
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)
|
|||||||
{
|
{
|
||||||
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)
|
|||||||
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,
|
|||||||
{
|
{
|
||||||
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 @@ out_err:
|
|||||||
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,
|
|||||||
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,
|
|||||||
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,
|
|||||||
|
|
||||||
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,
|
|||||||
|
|
||||||
/* 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,
|
|||||||
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,
|
|||||||
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,
|
|||||||
.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,
|
|||||||
|
|
||||||
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)
|
|||||||
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)
|
|||||||
|
|
||||||
/* 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,
|
|||||||
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,
|
|||||||
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)
|
|||||||
/* 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
|
|||||||
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,
|
|||||||
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,
|
|||||||
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));
|
||||||
|
Reference in New Issue
Block a user