Commit eaa82edf20d738a7ae31f4b0a5f72f64c14a58df

Authored by J. Bruce Fields
Committed by Trond Myklebust
1 parent 096455a22a

SUNRPC,RPCSEC_GSS: fix krb5 sequence numbers.

Use a spinlock to ensure unique sequence numbers when creating krb5 gss tokens.

Signed-off-by: J. Bruce Fields <bfields@citi.umich.edu>
Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>

Showing 3 changed files with 16 additions and 6 deletions Side-by-side Diff

include/linux/sunrpc/gss_krb5.h
... ... @@ -53,6 +53,8 @@
53 53 struct xdr_netobj mech_used;
54 54 };
55 55  
  56 +extern spinlock_t krb5_seq_lock;
  57 +
56 58 #define KG_TOK_MIC_MSG 0x0101
57 59 #define KG_TOK_WRAP_MSG 0x0201
58 60  
net/sunrpc/auth_gss/gss_krb5_seal.c
... ... @@ -70,6 +70,8 @@
70 70 # define RPCDBG_FACILITY RPCDBG_AUTH
71 71 #endif
72 72  
  73 +spinlock_t krb5_seq_lock = SPIN_LOCK_UNLOCKED;
  74 +
73 75 u32
74 76 gss_get_mic_kerberos(struct gss_ctx *gss_ctx, struct xdr_buf *text,
75 77 struct xdr_netobj *token)
... ... @@ -80,6 +82,7 @@
80 82 struct xdr_netobj md5cksum = {.len = 0, .data = cksumdata};
81 83 unsigned char *ptr, *krb5_hdr, *msg_start;
82 84 s32 now;
  85 + u32 seq_send;
83 86  
84 87 dprintk("RPC: gss_krb5_seal\n");
85 88  
86 89  
87 90  
... ... @@ -134,11 +137,13 @@
134 137 BUG();
135 138 }
136 139  
  140 + spin_lock(&krb5_seq_lock);
  141 + seq_send = ctx->seq_send++;
  142 + spin_unlock(&krb5_seq_lock);
  143 +
137 144 if ((krb5_make_seq_num(ctx->seq, ctx->initiate ? 0 : 0xff,
138   - ctx->seq_send, krb5_hdr + 16, krb5_hdr + 8)))
  145 + seq_send, krb5_hdr + 16, krb5_hdr + 8)))
139 146 goto out_err;
140   -
141   - ctx->seq_send++;
142 147  
143 148 return ((ctx->endtime < now) ? GSS_S_CONTEXT_EXPIRED : GSS_S_COMPLETE);
144 149 out_err:
net/sunrpc/auth_gss/gss_krb5_wrap.c
... ... @@ -128,6 +128,7 @@
128 128 s32 now;
129 129 int headlen;
130 130 struct page **tmp_pages;
  131 + u32 seq_send;
131 132  
132 133 dprintk("RPC: gss_wrap_kerberos\n");
133 134  
134 135  
135 136  
... ... @@ -206,17 +207,19 @@
206 207 BUG();
207 208 }
208 209  
  210 + spin_lock(&krb5_seq_lock);
  211 + seq_send = kctx->seq_send++;
  212 + spin_unlock(&krb5_seq_lock);
  213 +
209 214 /* XXX would probably be more efficient to compute checksum
210 215 * and encrypt at the same time: */
211 216 if ((krb5_make_seq_num(kctx->seq, kctx->initiate ? 0 : 0xff,
212   - kctx->seq_send, krb5_hdr + 16, krb5_hdr + 8)))
  217 + seq_send, krb5_hdr + 16, krb5_hdr + 8)))
213 218 goto out_err;
214 219  
215 220 if (gss_encrypt_xdr_buf(kctx->enc, buf, offset + headlen - blocksize,
216 221 pages))
217 222 goto out_err;
218   -
219   - kctx->seq_send++;
220 223  
221 224 return ((kctx->endtime < now) ? GSS_S_CONTEXT_EXPIRED : GSS_S_COMPLETE);
222 225 out_err: