sunrpc: don't pass on-stack memory to sg_set_buf
As of ac4e97abce "scatterlist: sg_set_buf() argument must be in linear
mapping", sg_set_buf hits a BUG when make_checksum_v2->xdr_process_buf,
among other callers, passes it memory on the stack.
We only need a scatterlist to pass this to the crypto code, and it seems
like overkill to require kmalloc'd memory just to encrypt a few bytes,
but for now this seems the best fix.
Many of these callers are in the NFS write paths, so we allocate with
GFP_NOFS. It might be possible to do without allocations here entirely,
but that would probably be a bigger project.
Cc: Rusty Russell <rusty@rustcorp.com.au>
Signed-off-by: J. Bruce Fields <bfields@redhat.com>
This commit is contained in:
@@ -718,30 +718,37 @@ gss_write_null_verf(struct svc_rqst *rqstp)
|
||||
static int
|
||||
gss_write_verf(struct svc_rqst *rqstp, struct gss_ctx *ctx_id, u32 seq)
|
||||
{
|
||||
__be32 xdr_seq;
|
||||
__be32 *xdr_seq;
|
||||
u32 maj_stat;
|
||||
struct xdr_buf verf_data;
|
||||
struct xdr_netobj mic;
|
||||
__be32 *p;
|
||||
struct kvec iov;
|
||||
int err = -1;
|
||||
|
||||
svc_putnl(rqstp->rq_res.head, RPC_AUTH_GSS);
|
||||
xdr_seq = htonl(seq);
|
||||
xdr_seq = kmalloc(4, GFP_KERNEL);
|
||||
if (!xdr_seq)
|
||||
return -1;
|
||||
*xdr_seq = htonl(seq);
|
||||
|
||||
iov.iov_base = &xdr_seq;
|
||||
iov.iov_len = sizeof(xdr_seq);
|
||||
iov.iov_base = xdr_seq;
|
||||
iov.iov_len = 4;
|
||||
xdr_buf_from_iov(&iov, &verf_data);
|
||||
p = rqstp->rq_res.head->iov_base + rqstp->rq_res.head->iov_len;
|
||||
mic.data = (u8 *)(p + 1);
|
||||
maj_stat = gss_get_mic(ctx_id, &verf_data, &mic);
|
||||
if (maj_stat != GSS_S_COMPLETE)
|
||||
return -1;
|
||||
goto out;
|
||||
*p++ = htonl(mic.len);
|
||||
memset((u8 *)p + mic.len, 0, round_up_to_quad(mic.len) - mic.len);
|
||||
p += XDR_QUADLEN(mic.len);
|
||||
if (!xdr_ressize_check(rqstp, p))
|
||||
return -1;
|
||||
return 0;
|
||||
goto out;
|
||||
err = 0;
|
||||
out:
|
||||
kfree(xdr_seq);
|
||||
return err;
|
||||
}
|
||||
|
||||
struct gss_domain {
|
||||
|
||||
Reference in New Issue
Block a user