Skip to content

Commit db1d616

Browse files
committed
SUNRPC: Go back to using gsd->body_start
Now that svcauth_gss_prepare_to_wrap() no longer computes the location of RPC header fields in the response buffer, svcauth_gss_accept() can save the location of the databody rather than the location of the verifier. Reviewed-by: Jeff Layton <[email protected]> Signed-off-by: Chuck Lever <[email protected]>
1 parent 4bcf034 commit db1d616

File tree

1 file changed

+36
-42
lines changed

1 file changed

+36
-42
lines changed

net/sunrpc/auth_gss/svcauth_gss.c

Lines changed: 36 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -71,9 +71,7 @@
7171
struct gss_svc_data {
7272
/* decoded gss client cred: */
7373
struct rpc_gss_wire_cred clcred;
74-
/* save a pointer to the beginning of the encoded verifier,
75-
* for use in encryption/checksumming in svcauth_gss_release: */
76-
__be32 *verf_start;
74+
u32 gsd_databody_offset;
7775
struct rsc *rsci;
7876

7977
/* for temporary results */
@@ -1595,7 +1593,7 @@ svcauth_gss_accept(struct svc_rqst *rqstp)
15951593
if (!svcdata)
15961594
goto auth_err;
15971595
rqstp->rq_auth_data = svcdata;
1598-
svcdata->verf_start = NULL;
1596+
svcdata->gsd_databody_offset = 0;
15991597
svcdata->rsci = NULL;
16001598
gc = &svcdata->clcred;
16011599

@@ -1647,11 +1645,11 @@ svcauth_gss_accept(struct svc_rqst *rqstp)
16471645
goto complete;
16481646
case RPC_GSS_PROC_DATA:
16491647
rqstp->rq_auth_stat = rpcsec_gsserr_ctxproblem;
1650-
svcdata->verf_start = xdr_reserve_space(&rqstp->rq_res_stream, 0);
16511648
if (!svcauth_gss_encode_verf(rqstp, rsci->mechctx, gc->gc_seq))
16521649
goto auth_err;
16531650
if (!svcxdr_set_accept_stat(rqstp))
16541651
goto auth_err;
1652+
svcdata->gsd_databody_offset = xdr_stream_pos(&rqstp->rq_res_stream);
16551653
rqstp->rq_cred = rsci->cred;
16561654
get_group_info(rsci->cred.cr_group_info);
16571655
rqstp->rq_auth_stat = rpc_autherr_badcred;
@@ -1705,30 +1703,24 @@ svcauth_gss_accept(struct svc_rqst *rqstp)
17051703
return ret;
17061704
}
17071705

1708-
static __be32 *
1706+
static u32
17091707
svcauth_gss_prepare_to_wrap(struct svc_rqst *rqstp, struct gss_svc_data *gsd)
17101708
{
1711-
__be32 *p;
1712-
u32 verf_len;
1709+
u32 offset;
17131710

1714-
p = gsd->verf_start;
1715-
gsd->verf_start = NULL;
1711+
/* Release can be called twice, but we only wrap once. */
1712+
offset = gsd->gsd_databody_offset;
1713+
gsd->gsd_databody_offset = 0;
17161714

17171715
/* AUTH_ERROR replies are not wrapped. */
17181716
if (rqstp->rq_auth_stat != rpc_auth_ok)
1719-
return NULL;
1720-
1721-
/* Skip the verifier: */
1722-
p += 1;
1723-
verf_len = ntohl(*p++);
1724-
p += XDR_QUADLEN(verf_len);
1717+
return 0;
17251718

17261719
/* Also don't wrap if the accept_stat is nonzero: */
17271720
if (*rqstp->rq_accept_statp != rpc_success)
1728-
return NULL;
1721+
return 0;
17291722

1730-
p++;
1731-
return p;
1723+
return offset;
17321724
}
17331725

17341726
/*
@@ -1756,21 +1748,21 @@ static int svcauth_gss_wrap_integ(struct svc_rqst *rqstp)
17561748
struct xdr_buf *buf = xdr->buf;
17571749
struct xdr_buf databody_integ;
17581750
struct xdr_netobj checksum;
1759-
u32 offset, len, maj_stat;
1760-
__be32 *p;
1751+
u32 offset, maj_stat;
17611752

1762-
p = svcauth_gss_prepare_to_wrap(rqstp, gsd);
1763-
if (p == NULL)
1753+
offset = svcauth_gss_prepare_to_wrap(rqstp, gsd);
1754+
if (!offset)
17641755
goto out;
17651756

1766-
offset = (u8 *)(p + 1) - (u8 *)buf->head[0].iov_base;
1767-
len = buf->len - offset;
1768-
if (xdr_buf_subsegment(buf, &databody_integ, offset, len))
1757+
if (xdr_buf_subsegment(buf, &databody_integ, offset + XDR_UNIT,
1758+
buf->len - offset - XDR_UNIT))
17691759
goto wrap_failed;
17701760
/* Buffer space for these has already been reserved in
17711761
* svcauth_gss_accept(). */
1772-
*p++ = cpu_to_be32(len);
1773-
*p = cpu_to_be32(gc->gc_seq);
1762+
if (xdr_encode_word(buf, offset, databody_integ.len))
1763+
goto wrap_failed;
1764+
if (xdr_encode_word(buf, offset + XDR_UNIT, gc->gc_seq))
1765+
goto wrap_failed;
17741766

17751767
checksum.data = gsd->gsd_scratch;
17761768
maj_stat = gss_get_mic(gsd->rsci->mechctx, &databody_integ, &checksum);
@@ -1817,17 +1809,19 @@ static int svcauth_gss_wrap_priv(struct svc_rqst *rqstp)
18171809
struct kvec *head = buf->head;
18181810
struct kvec *tail = buf->tail;
18191811
u32 offset, pad, maj_stat;
1820-
__be32 *p, *lenp;
1812+
__be32 *p;
18211813

1822-
p = svcauth_gss_prepare_to_wrap(rqstp, gsd);
1823-
if (p == NULL)
1814+
offset = svcauth_gss_prepare_to_wrap(rqstp, gsd);
1815+
if (!offset)
18241816
return 0;
18251817

1826-
lenp = p++;
1827-
offset = (u8 *)p - (u8 *)head->iov_base;
1828-
/* Buffer space for this field has already been reserved
1829-
* in svcauth_gss_accept(). */
1830-
*p = cpu_to_be32(gc->gc_seq);
1818+
/*
1819+
* Buffer space for this field has already been reserved
1820+
* in svcauth_gss_accept(). Note that the GSS sequence
1821+
* number is encrypted along with the RPC reply payload.
1822+
*/
1823+
if (xdr_encode_word(buf, offset + XDR_UNIT, gc->gc_seq))
1824+
goto wrap_failed;
18311825

18321826
/*
18331827
* If there is currently tail data, make sure there is
@@ -1863,12 +1857,15 @@ static int svcauth_gss_wrap_priv(struct svc_rqst *rqstp)
18631857
tail->iov_len = 0;
18641858
}
18651859

1866-
maj_stat = gss_wrap(gsd->rsci->mechctx, offset, buf, buf->pages);
1860+
maj_stat = gss_wrap(gsd->rsci->mechctx, offset + XDR_UNIT, buf,
1861+
buf->pages);
18671862
if (maj_stat != GSS_S_COMPLETE)
18681863
goto bad_wrap;
18691864

1870-
*lenp = cpu_to_be32(buf->len - offset);
1871-
pad = xdr_pad_size(buf->len - offset);
1865+
/* Wrapping can change the size of databody_priv. */
1866+
if (xdr_encode_word(buf, offset, buf->len - offset - XDR_UNIT))
1867+
goto wrap_failed;
1868+
pad = xdr_pad_size(buf->len - offset - XDR_UNIT);
18721869
p = (__be32 *)(tail->iov_base + tail->iov_len);
18731870
memset(p, 0, pad);
18741871
tail->iov_len += pad;
@@ -1908,9 +1905,6 @@ svcauth_gss_release(struct svc_rqst *rqstp)
19081905
gc = &gsd->clcred;
19091906
if (gc->gc_proc != RPC_GSS_PROC_DATA)
19101907
goto out;
1911-
/* Release can be called twice, but we only wrap once. */
1912-
if (gsd->verf_start == NULL)
1913-
goto out;
19141908

19151909
switch (gc->gc_svc) {
19161910
case RPC_GSS_SVC_NONE:

0 commit comments

Comments
 (0)