Commit 152036d1 authored by Linus Torvalds's avatar Linus Torvalds
Browse files

Merge tag 'nfsd-5.7-rc-2' of git://git.linux-nfs.org/projects/cel/cel-2.6

Pull nfsd fixes from Chuck Lever:
 "Resolve a data integrity problem with NFSD that I inadvertently
  introduced last year.

  The change I made makes the NFS server's duplicate reply cache
  ineffective when krb5i or krb5p are in use, thus allowing the replay
  of non-idempotent NFS requests such as RENAME, SETATTR, or even
  WRITEs"

* tag 'nfsd-5.7-rc-2' of git://git.linux-nfs.org/projects/cel/cel-2.6:
  SUNRPC: Revert 241b1f41 ("SUNRPC: Remove xdr_buf_trim()")
  SUNRPC: Fix GSS privacy computation of auth->au_ralign
  SUNRPC: Add "@len" parameter to gss_unwrap()
parents 995b819f 0a8e7b7d
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -21,6 +21,7 @@
struct gss_ctx {
	struct gss_api_mech	*mech_type;
	void			*internal_ctx_id;
	unsigned int		slack, align;
};

#define GSS_C_NO_BUFFER		((struct xdr_netobj) 0)
@@ -66,6 +67,7 @@ u32 gss_wrap(
u32 gss_unwrap(
		struct gss_ctx		*ctx_id,
		int			offset,
		int			len,
		struct xdr_buf		*inbuf);
u32 gss_delete_sec_context(
		struct gss_ctx		**ctx_id);
@@ -126,6 +128,7 @@ struct gss_api_ops {
	u32 (*gss_unwrap)(
			struct gss_ctx		*ctx_id,
			int			offset,
			int			len,
			struct xdr_buf		*buf);
	void (*gss_delete_sec_context)(
			void			*internal_ctx_id);
+3 −3
Original line number Diff line number Diff line
@@ -83,7 +83,7 @@ struct gss_krb5_enctype {
	u32 (*encrypt_v2) (struct krb5_ctx *kctx, u32 offset,
			   struct xdr_buf *buf,
			   struct page **pages); /* v2 encryption function */
	u32 (*decrypt_v2) (struct krb5_ctx *kctx, u32 offset,
	u32 (*decrypt_v2) (struct krb5_ctx *kctx, u32 offset, u32 len,
			   struct xdr_buf *buf, u32 *headskip,
			   u32 *tailskip);	/* v2 decryption function */
};
@@ -255,7 +255,7 @@ gss_wrap_kerberos(struct gss_ctx *ctx_id, int offset,
		struct xdr_buf *outbuf, struct page **pages);

u32
gss_unwrap_kerberos(struct gss_ctx *ctx_id, int offset,
gss_unwrap_kerberos(struct gss_ctx *ctx_id, int offset, int len,
		struct xdr_buf *buf);


@@ -312,7 +312,7 @@ gss_krb5_aes_encrypt(struct krb5_ctx *kctx, u32 offset,
		     struct page **pages);

u32
gss_krb5_aes_decrypt(struct krb5_ctx *kctx, u32 offset,
gss_krb5_aes_decrypt(struct krb5_ctx *kctx, u32 offset, u32 len,
		     struct xdr_buf *buf, u32 *plainoffset,
		     u32 *plainlen);

+1 −0
Original line number Diff line number Diff line
@@ -184,6 +184,7 @@ xdr_adjust_iovec(struct kvec *iov, __be32 *p)
extern void xdr_shift_buf(struct xdr_buf *, size_t);
extern void xdr_buf_from_iov(struct kvec *, struct xdr_buf *);
extern int xdr_buf_subsegment(struct xdr_buf *, struct xdr_buf *, unsigned int, unsigned int);
extern void xdr_buf_trim(struct xdr_buf *, unsigned int);
extern int read_bytes_from_xdr_buf(struct xdr_buf *, unsigned int, void *, unsigned int);
extern int write_bytes_to_xdr_buf(struct xdr_buf *, unsigned int, void *, unsigned int);

+5 −7
Original line number Diff line number Diff line
@@ -2032,7 +2032,6 @@ gss_unwrap_resp_priv(struct rpc_task *task, struct rpc_cred *cred,
	struct xdr_buf *rcv_buf = &rqstp->rq_rcv_buf;
	struct kvec *head = rqstp->rq_rcv_buf.head;
	struct rpc_auth *auth = cred->cr_auth;
	unsigned int savedlen = rcv_buf->len;
	u32 offset, opaque_len, maj_stat;
	__be32 *p;

@@ -2043,9 +2042,9 @@ gss_unwrap_resp_priv(struct rpc_task *task, struct rpc_cred *cred,
	offset = (u8 *)(p) - (u8 *)head->iov_base;
	if (offset + opaque_len > rcv_buf->len)
		goto unwrap_failed;
	rcv_buf->len = offset + opaque_len;

	maj_stat = gss_unwrap(ctx->gc_gss_ctx, offset, rcv_buf);
	maj_stat = gss_unwrap(ctx->gc_gss_ctx, offset,
			      offset + opaque_len, rcv_buf);
	if (maj_stat == GSS_S_CONTEXT_EXPIRED)
		clear_bit(RPCAUTH_CRED_UPTODATE, &cred->cr_flags);
	if (maj_stat != GSS_S_COMPLETE)
@@ -2059,10 +2058,9 @@ gss_unwrap_resp_priv(struct rpc_task *task, struct rpc_cred *cred,
	 */
	xdr_init_decode(xdr, rcv_buf, p, rqstp);

	auth->au_rslack = auth->au_verfsize + 2 +
			  XDR_QUADLEN(savedlen - rcv_buf->len);
	auth->au_ralign = auth->au_verfsize + 2 +
			  XDR_QUADLEN(savedlen - rcv_buf->len);
	auth->au_rslack = auth->au_verfsize + 2 + ctx->gc_gss_ctx->slack;
	auth->au_ralign = auth->au_verfsize + 2 + ctx->gc_gss_ctx->align;

	return 0;
unwrap_failed:
	trace_rpcgss_unwrap_failed(task);
+4 −4
Original line number Diff line number Diff line
@@ -851,8 +851,8 @@ out_err:
}

u32
gss_krb5_aes_decrypt(struct krb5_ctx *kctx, u32 offset, struct xdr_buf *buf,
		     u32 *headskip, u32 *tailskip)
gss_krb5_aes_decrypt(struct krb5_ctx *kctx, u32 offset, u32 len,
		     struct xdr_buf *buf, u32 *headskip, u32 *tailskip)
{
	struct xdr_buf subbuf;
	u32 ret = 0;
@@ -881,7 +881,7 @@ gss_krb5_aes_decrypt(struct krb5_ctx *kctx, u32 offset, struct xdr_buf *buf,

	/* create a segment skipping the header and leaving out the checksum */
	xdr_buf_subsegment(buf, &subbuf, offset + GSS_KRB5_TOK_HDR_LEN,
				    (buf->len - offset - GSS_KRB5_TOK_HDR_LEN -
				    (len - offset - GSS_KRB5_TOK_HDR_LEN -
				     kctx->gk5e->cksumlength));

	nblocks = (subbuf.len + blocksize - 1) / blocksize;
@@ -926,7 +926,7 @@ gss_krb5_aes_decrypt(struct krb5_ctx *kctx, u32 offset, struct xdr_buf *buf,
		goto out_err;

	/* Get the packet's hmac value */
	ret = read_bytes_from_xdr_buf(buf, buf->len - kctx->gk5e->cksumlength,
	ret = read_bytes_from_xdr_buf(buf, len - kctx->gk5e->cksumlength,
				      pkt_hmac, kctx->gk5e->cksumlength);
	if (ret)
		goto out_err;
Loading