Skip to content

Commit

Permalink
net/9p: Handle error in zero copy request correctly for 9p2000.u
Browse files Browse the repository at this point in the history
For zero copy request, error will be encoded in the user space buffer.
So copy the error code correctly using copy_from_user. Here we use the
extra bytes we allocate for zero copy request. If total error details
are more than P9_ZC_HDR_SZ - 7 bytes, we return -EFAULT. The patch also
avoid a memory allocation in the error path.

Signed-off-by: Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com>
Signed-off-by: Eric Van Hensbergen <ericvh@gmail.com>
  • Loading branch information
Aneesh Kumar K.V authored and Eric Van Hensbergen committed May 28, 2013
1 parent 535bcd3 commit 42fe648
Showing 1 changed file with 18 additions and 37 deletions.
55 changes: 18 additions & 37 deletions net/9p/client.c
Original file line number Diff line number Diff line change
Expand Up @@ -562,36 +562,19 @@ static int p9_check_zc_errors(struct p9_client *c, struct p9_req_t *req,

if (!p9_is_proto_dotl(c)) {
/* Error is reported in string format */
uint16_t len;
/* 7 = header size for RERROR, 2 is the size of string len; */
int inline_len = in_hdrlen - (7 + 2);
int len;
/* 7 = header size for RERROR; */
int inline_len = in_hdrlen - 7;

/* Read the size of error string */
err = p9pdu_readf(req->rc, c->proto_version, "w", &len);
if (err)
goto out_err;

ename = kmalloc(len + 1, GFP_NOFS);
if (!ename) {
err = -ENOMEM;
len = req->rc->size - req->rc->offset;
if (len > (P9_ZC_HDR_SZ - 7)) {
err = -EFAULT;
goto out_err;
}
if (len <= inline_len) {
/* We have error in protocol buffer itself */
if (pdu_read(req->rc, ename, len)) {
err = -EFAULT;
goto out_free;

}
} else {
/*
* Part of the data is in user space buffer.
*/
if (pdu_read(req->rc, ename, inline_len)) {
err = -EFAULT;
goto out_free;

}
ename = &req->rc->sdata[req->rc->offset];
if (len > inline_len) {
/* We have error in external buffer */
if (kern_buf) {
memcpy(ename + inline_len, uidata,
len - inline_len);
Expand All @@ -600,19 +583,19 @@ static int p9_check_zc_errors(struct p9_client *c, struct p9_req_t *req,
uidata, len - inline_len);
if (err) {
err = -EFAULT;
goto out_free;
goto out_err;
}
}
}
ename[len] = 0;
if (p9_is_proto_dotu(c)) {
/* For dotu we also have error code */
err = p9pdu_readf(req->rc,
c->proto_version, "d", &ecode);
if (err)
goto out_free;
ename = NULL;
err = p9pdu_readf(req->rc, c->proto_version, "s?d",
&ename, &ecode);
if (err)
goto out_err;

if (p9_is_proto_dotu(c))
err = -ecode;
}

if (!err || !IS_ERR_VALUE(err)) {
err = p9_errstr2errno(ename, strlen(ename));

Expand All @@ -628,8 +611,6 @@ static int p9_check_zc_errors(struct p9_client *c, struct p9_req_t *req,
}
return err;

out_free:
kfree(ename);
out_err:
p9_debug(P9_DEBUG_ERROR, "couldn't parse error%d\n", err);
return err;
Expand Down

0 comments on commit 42fe648

Please sign in to comment.