Commit 6390460a authored by Aneesh Kumar K.V's avatar Aneesh Kumar K.V Committed by Eric Van Hensbergen

net/9p: Handle error in zero copy request correctly for 9p2000.u

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: default avatarAneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com>
Signed-off-by: default avatarEric Van Hensbergen <ericvh@gmail.com>
parent c1be5a5b
...@@ -562,36 +562,19 @@ static int p9_check_zc_errors(struct p9_client *c, struct p9_req_t *req, ...@@ -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)) { if (!p9_is_proto_dotl(c)) {
/* Error is reported in string format */ /* Error is reported in string format */
uint16_t len; int len;
/* 7 = header size for RERROR, 2 is the size of string len; */ /* 7 = header size for RERROR; */
int inline_len = in_hdrlen - (7 + 2); int inline_len = in_hdrlen - 7;
/* Read the size of error string */ len = req->rc->size - req->rc->offset;
err = p9pdu_readf(req->rc, c->proto_version, "w", &len); if (len > (P9_ZC_HDR_SZ - 7)) {
if (err)
goto out_err;
ename = kmalloc(len + 1, GFP_NOFS);
if (!ename) {
err = -ENOMEM;
goto out_err;
}
if (len <= inline_len) {
/* We have error in protocol buffer itself */
if (pdu_read(req->rc, ename, len)) {
err = -EFAULT; err = -EFAULT;
goto out_free; goto out_err;
} }
} 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) { if (kern_buf) {
memcpy(ename + inline_len, uidata, memcpy(ename + inline_len, uidata,
len - inline_len); len - inline_len);
...@@ -600,19 +583,19 @@ static int p9_check_zc_errors(struct p9_client *c, struct p9_req_t *req, ...@@ -600,19 +583,19 @@ static int p9_check_zc_errors(struct p9_client *c, struct p9_req_t *req,
uidata, len - inline_len); uidata, len - inline_len);
if (err) { if (err) {
err = -EFAULT; err = -EFAULT;
goto out_free; goto out_err;
} }
} }
} }
ename[len] = 0; ename = NULL;
if (p9_is_proto_dotu(c)) { err = p9pdu_readf(req->rc, c->proto_version, "s?d",
/* For dotu we also have error code */ &ename, &ecode);
err = p9pdu_readf(req->rc,
c->proto_version, "d", &ecode);
if (err) if (err)
goto out_free; goto out_err;
if (p9_is_proto_dotu(c))
err = -ecode; err = -ecode;
}
if (!err || !IS_ERR_VALUE(err)) { if (!err || !IS_ERR_VALUE(err)) {
err = p9_errstr2errno(ename, strlen(ename)); err = p9_errstr2errno(ename, strlen(ename));
...@@ -628,8 +611,6 @@ static int p9_check_zc_errors(struct p9_client *c, struct p9_req_t *req, ...@@ -628,8 +611,6 @@ static int p9_check_zc_errors(struct p9_client *c, struct p9_req_t *req,
} }
return err; return err;
out_free:
kfree(ename);
out_err: out_err:
p9_debug(P9_DEBUG_ERROR, "couldn't parse error%d\n", err); p9_debug(P9_DEBUG_ERROR, "couldn't parse error%d\n", err);
return err; return err;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment