Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 4710e789 authored by Linus Torvalds's avatar Linus Torvalds
Browse files
Pull NFS client bugfixes from Trond Myklebust:
 "Highlights include:

  Bugfix:
   - Fix build issues on architectures that don't provide 64-bit cmpxchg

  Cleanups:
   - Fix a spelling mistake"

* tag 'nfs-for-4.20-2' of git://git.linux-nfs.org/projects/trondmy/linux-nfs:
  NFS: fix spelling mistake, EACCESS -> EACCES
  SUNRPC: Use atomic(64)_t for seq_send(64)
parents 35e74524 d3787af2
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -3788,7 +3788,7 @@ static int nfs4_find_root_sec(struct nfs_server *server, struct nfs_fh *fhandle,
	}

	/*
	 * -EACCESS could mean that the user doesn't have correct permissions
	 * -EACCES could mean that the user doesn't have correct permissions
	 * to access the mount.  It could also mean that we tried to mount
	 * with a gss auth flavor, but rpc.gssd isn't running.  Either way,
	 * existing mount programs don't handle -EACCES very well so it should
+2 −5
Original line number Diff line number Diff line
@@ -107,8 +107,8 @@ struct krb5_ctx {
	u8			Ksess[GSS_KRB5_MAX_KEYLEN]; /* session key */
	u8			cksum[GSS_KRB5_MAX_KEYLEN];
	s32			endtime;
	u32			seq_send;
	u64			seq_send64;
	atomic_t		seq_send;
	atomic64_t		seq_send64;
	struct xdr_netobj	mech_used;
	u8			initiator_sign[GSS_KRB5_MAX_KEYLEN];
	u8			acceptor_sign[GSS_KRB5_MAX_KEYLEN];
@@ -118,9 +118,6 @@ struct krb5_ctx {
	u8			acceptor_integ[GSS_KRB5_MAX_KEYLEN];
};

extern u32 gss_seq_send_fetch_and_inc(struct krb5_ctx *ctx);
extern u64 gss_seq_send64_fetch_and_inc(struct krb5_ctx *ctx);

/* The length of the Kerberos GSS token header */
#define GSS_KRB5_TOK_HDR_LEN	(16)

+10 −6
Original line number Diff line number Diff line
@@ -274,6 +274,7 @@ get_key(const void *p, const void *end,
static int
gss_import_v1_context(const void *p, const void *end, struct krb5_ctx *ctx)
{
	u32 seq_send;
	int tmp;

	p = simple_get_bytes(p, end, &ctx->initiate, sizeof(ctx->initiate));
@@ -315,9 +316,10 @@ gss_import_v1_context(const void *p, const void *end, struct krb5_ctx *ctx)
	p = simple_get_bytes(p, end, &ctx->endtime, sizeof(ctx->endtime));
	if (IS_ERR(p))
		goto out_err;
	p = simple_get_bytes(p, end, &ctx->seq_send, sizeof(ctx->seq_send));
	p = simple_get_bytes(p, end, &seq_send, sizeof(seq_send));
	if (IS_ERR(p))
		goto out_err;
	atomic_set(&ctx->seq_send, seq_send);
	p = simple_get_netobj(p, end, &ctx->mech_used);
	if (IS_ERR(p))
		goto out_err;
@@ -607,6 +609,7 @@ static int
gss_import_v2_context(const void *p, const void *end, struct krb5_ctx *ctx,
		gfp_t gfp_mask)
{
	u64 seq_send64;
	int keylen;

	p = simple_get_bytes(p, end, &ctx->flags, sizeof(ctx->flags));
@@ -617,14 +620,15 @@ gss_import_v2_context(const void *p, const void *end, struct krb5_ctx *ctx,
	p = simple_get_bytes(p, end, &ctx->endtime, sizeof(ctx->endtime));
	if (IS_ERR(p))
		goto out_err;
	p = simple_get_bytes(p, end, &ctx->seq_send64, sizeof(ctx->seq_send64));
	p = simple_get_bytes(p, end, &seq_send64, sizeof(seq_send64));
	if (IS_ERR(p))
		goto out_err;
	atomic64_set(&ctx->seq_send64, seq_send64);
	/* set seq_send for use by "older" enctypes */
	ctx->seq_send = ctx->seq_send64;
	if (ctx->seq_send64 != ctx->seq_send) {
		dprintk("%s: seq_send64 %lx, seq_send %x overflow?\n", __func__,
			(unsigned long)ctx->seq_send64, ctx->seq_send);
	atomic_set(&ctx->seq_send, seq_send64);
	if (seq_send64 != atomic_read(&ctx->seq_send)) {
		dprintk("%s: seq_send64 %llx, seq_send %x overflow?\n", __func__,
			seq_send64, atomic_read(&ctx->seq_send));
		p = ERR_PTR(-EINVAL);
		goto out_err;
	}
+2 −26
Original line number Diff line number Diff line
@@ -123,30 +123,6 @@ setup_token_v2(struct krb5_ctx *ctx, struct xdr_netobj *token)
	return krb5_hdr;
}

u32
gss_seq_send_fetch_and_inc(struct krb5_ctx *ctx)
{
	u32 old, seq_send = READ_ONCE(ctx->seq_send);

	do {
		old = seq_send;
		seq_send = cmpxchg(&ctx->seq_send, old, old + 1);
	} while (old != seq_send);
	return seq_send;
}

u64
gss_seq_send64_fetch_and_inc(struct krb5_ctx *ctx)
{
	u64 old, seq_send = READ_ONCE(ctx->seq_send);

	do {
		old = seq_send;
		seq_send = cmpxchg64(&ctx->seq_send64, old, old + 1);
	} while (old != seq_send);
	return seq_send;
}

static u32
gss_get_mic_v1(struct krb5_ctx *ctx, struct xdr_buf *text,
		struct xdr_netobj *token)
@@ -177,7 +153,7 @@ gss_get_mic_v1(struct krb5_ctx *ctx, struct xdr_buf *text,

	memcpy(ptr + GSS_KRB5_TOK_HDR_LEN, md5cksum.data, md5cksum.len);

	seq_send = gss_seq_send_fetch_and_inc(ctx);
	seq_send = atomic_fetch_inc(&ctx->seq_send);

	if (krb5_make_seq_num(ctx, ctx->seq, ctx->initiate ? 0 : 0xff,
			      seq_send, ptr + GSS_KRB5_TOK_HDR_LEN, ptr + 8))
@@ -205,7 +181,7 @@ gss_get_mic_v2(struct krb5_ctx *ctx, struct xdr_buf *text,

	/* Set up the sequence number. Now 64-bits in clear
	 * text and w/o direction indicator */
	seq_send_be64 = cpu_to_be64(gss_seq_send64_fetch_and_inc(ctx));
	seq_send_be64 = cpu_to_be64(atomic64_fetch_inc(&ctx->seq_send64));
	memcpy(krb5_hdr + 8, (char *) &seq_send_be64, 8);

	if (ctx->initiate) {
+2 −2
Original line number Diff line number Diff line
@@ -228,7 +228,7 @@ gss_wrap_kerberos_v1(struct krb5_ctx *kctx, int offset,

	memcpy(ptr + GSS_KRB5_TOK_HDR_LEN, md5cksum.data, md5cksum.len);

	seq_send = gss_seq_send_fetch_and_inc(kctx);
	seq_send = atomic_fetch_inc(&kctx->seq_send);

	/* XXX would probably be more efficient to compute checksum
	 * and encrypt at the same time: */
@@ -475,7 +475,7 @@ gss_wrap_kerberos_v2(struct krb5_ctx *kctx, u32 offset,
	*be16ptr++ = 0;

	be64ptr = (__be64 *)be16ptr;
	*be64ptr = cpu_to_be64(gss_seq_send64_fetch_and_inc(kctx));
	*be64ptr = cpu_to_be64(atomic64_fetch_inc(&kctx->seq_send64));

	err = (*kctx->gk5e->encrypt_v2)(kctx, offset, buf, pages);
	if (err)