0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011 #include <linux/module.h>
0012 #include <linux/errno.h>
0013 #include <linux/kernel.h>
0014 #include <linux/uaccess.h>
0015 #include <linux/slab.h>
0016 #include <linux/sched.h>
0017 #include <linux/stddef.h>
0018 #include <linux/types.h>
0019 #include <linux/uio.h>
0020 #include <net/9p/9p.h>
0021 #include <net/9p/client.h>
0022 #include "protocol.h"
0023
0024 #include <trace/events/9p.h>
0025
0026 static int
0027 p9pdu_writef(struct p9_fcall *pdu, int proto_version, const char *fmt, ...);
0028
0029 void p9stat_free(struct p9_wstat *stbuf)
0030 {
0031 kfree(stbuf->name);
0032 stbuf->name = NULL;
0033 kfree(stbuf->uid);
0034 stbuf->uid = NULL;
0035 kfree(stbuf->gid);
0036 stbuf->gid = NULL;
0037 kfree(stbuf->muid);
0038 stbuf->muid = NULL;
0039 kfree(stbuf->extension);
0040 stbuf->extension = NULL;
0041 }
0042 EXPORT_SYMBOL(p9stat_free);
0043
0044 size_t pdu_read(struct p9_fcall *pdu, void *data, size_t size)
0045 {
0046 size_t len = min(pdu->size - pdu->offset, size);
0047
0048 memcpy(data, &pdu->sdata[pdu->offset], len);
0049 pdu->offset += len;
0050 return size - len;
0051 }
0052
0053 static size_t pdu_write(struct p9_fcall *pdu, const void *data, size_t size)
0054 {
0055 size_t len = min(pdu->capacity - pdu->size, size);
0056
0057 memcpy(&pdu->sdata[pdu->size], data, len);
0058 pdu->size += len;
0059 return size - len;
0060 }
0061
0062 static size_t
0063 pdu_write_u(struct p9_fcall *pdu, struct iov_iter *from, size_t size)
0064 {
0065 size_t len = min(pdu->capacity - pdu->size, size);
0066
0067 if (!copy_from_iter_full(&pdu->sdata[pdu->size], len, from))
0068 len = 0;
0069
0070 pdu->size += len;
0071 return size - len;
0072 }
0073
0074
0075
0076
0077
0078
0079
0080
0081
0082
0083
0084
0085
0086
0087
0088
0089
0090 static int
0091 p9pdu_vreadf(struct p9_fcall *pdu, int proto_version, const char *fmt,
0092 va_list ap)
0093 {
0094 const char *ptr;
0095 int errcode = 0;
0096
0097 for (ptr = fmt; *ptr; ptr++) {
0098 switch (*ptr) {
0099 case 'b':{
0100 int8_t *val = va_arg(ap, int8_t *);
0101 if (pdu_read(pdu, val, sizeof(*val))) {
0102 errcode = -EFAULT;
0103 break;
0104 }
0105 }
0106 break;
0107 case 'w':{
0108 int16_t *val = va_arg(ap, int16_t *);
0109 __le16 le_val;
0110 if (pdu_read(pdu, &le_val, sizeof(le_val))) {
0111 errcode = -EFAULT;
0112 break;
0113 }
0114 *val = le16_to_cpu(le_val);
0115 }
0116 break;
0117 case 'd':{
0118 int32_t *val = va_arg(ap, int32_t *);
0119 __le32 le_val;
0120 if (pdu_read(pdu, &le_val, sizeof(le_val))) {
0121 errcode = -EFAULT;
0122 break;
0123 }
0124 *val = le32_to_cpu(le_val);
0125 }
0126 break;
0127 case 'q':{
0128 int64_t *val = va_arg(ap, int64_t *);
0129 __le64 le_val;
0130 if (pdu_read(pdu, &le_val, sizeof(le_val))) {
0131 errcode = -EFAULT;
0132 break;
0133 }
0134 *val = le64_to_cpu(le_val);
0135 }
0136 break;
0137 case 's':{
0138 char **sptr = va_arg(ap, char **);
0139 uint16_t len;
0140
0141 errcode = p9pdu_readf(pdu, proto_version,
0142 "w", &len);
0143 if (errcode)
0144 break;
0145
0146 *sptr = kmalloc(len + 1, GFP_NOFS);
0147 if (*sptr == NULL) {
0148 errcode = -ENOMEM;
0149 break;
0150 }
0151 if (pdu_read(pdu, *sptr, len)) {
0152 errcode = -EFAULT;
0153 kfree(*sptr);
0154 *sptr = NULL;
0155 } else
0156 (*sptr)[len] = 0;
0157 }
0158 break;
0159 case 'u': {
0160 kuid_t *uid = va_arg(ap, kuid_t *);
0161 __le32 le_val;
0162 if (pdu_read(pdu, &le_val, sizeof(le_val))) {
0163 errcode = -EFAULT;
0164 break;
0165 }
0166 *uid = make_kuid(&init_user_ns,
0167 le32_to_cpu(le_val));
0168 } break;
0169 case 'g': {
0170 kgid_t *gid = va_arg(ap, kgid_t *);
0171 __le32 le_val;
0172 if (pdu_read(pdu, &le_val, sizeof(le_val))) {
0173 errcode = -EFAULT;
0174 break;
0175 }
0176 *gid = make_kgid(&init_user_ns,
0177 le32_to_cpu(le_val));
0178 } break;
0179 case 'Q':{
0180 struct p9_qid *qid =
0181 va_arg(ap, struct p9_qid *);
0182
0183 errcode = p9pdu_readf(pdu, proto_version, "bdq",
0184 &qid->type, &qid->version,
0185 &qid->path);
0186 }
0187 break;
0188 case 'S':{
0189 struct p9_wstat *stbuf =
0190 va_arg(ap, struct p9_wstat *);
0191
0192 memset(stbuf, 0, sizeof(struct p9_wstat));
0193 stbuf->n_uid = stbuf->n_muid = INVALID_UID;
0194 stbuf->n_gid = INVALID_GID;
0195
0196 errcode =
0197 p9pdu_readf(pdu, proto_version,
0198 "wwdQdddqssss?sugu",
0199 &stbuf->size, &stbuf->type,
0200 &stbuf->dev, &stbuf->qid,
0201 &stbuf->mode, &stbuf->atime,
0202 &stbuf->mtime, &stbuf->length,
0203 &stbuf->name, &stbuf->uid,
0204 &stbuf->gid, &stbuf->muid,
0205 &stbuf->extension,
0206 &stbuf->n_uid, &stbuf->n_gid,
0207 &stbuf->n_muid);
0208 if (errcode)
0209 p9stat_free(stbuf);
0210 }
0211 break;
0212 case 'D':{
0213 uint32_t *count = va_arg(ap, uint32_t *);
0214 void **data = va_arg(ap, void **);
0215
0216 errcode =
0217 p9pdu_readf(pdu, proto_version, "d", count);
0218 if (!errcode) {
0219 *count =
0220 min_t(uint32_t, *count,
0221 pdu->size - pdu->offset);
0222 *data = &pdu->sdata[pdu->offset];
0223 }
0224 }
0225 break;
0226 case 'T':{
0227 uint16_t *nwname = va_arg(ap, uint16_t *);
0228 char ***wnames = va_arg(ap, char ***);
0229
0230 errcode = p9pdu_readf(pdu, proto_version,
0231 "w", nwname);
0232 if (!errcode) {
0233 *wnames =
0234 kmalloc_array(*nwname,
0235 sizeof(char *),
0236 GFP_NOFS);
0237 if (!*wnames)
0238 errcode = -ENOMEM;
0239 }
0240
0241 if (!errcode) {
0242 int i;
0243
0244 for (i = 0; i < *nwname; i++) {
0245 errcode =
0246 p9pdu_readf(pdu,
0247 proto_version,
0248 "s",
0249 &(*wnames)[i]);
0250 if (errcode)
0251 break;
0252 }
0253 }
0254
0255 if (errcode) {
0256 if (*wnames) {
0257 int i;
0258
0259 for (i = 0; i < *nwname; i++)
0260 kfree((*wnames)[i]);
0261 }
0262 kfree(*wnames);
0263 *wnames = NULL;
0264 }
0265 }
0266 break;
0267 case 'R':{
0268 uint16_t *nwqid = va_arg(ap, uint16_t *);
0269 struct p9_qid **wqids =
0270 va_arg(ap, struct p9_qid **);
0271
0272 *wqids = NULL;
0273
0274 errcode =
0275 p9pdu_readf(pdu, proto_version, "w", nwqid);
0276 if (!errcode) {
0277 *wqids =
0278 kmalloc_array(*nwqid,
0279 sizeof(struct p9_qid),
0280 GFP_NOFS);
0281 if (*wqids == NULL)
0282 errcode = -ENOMEM;
0283 }
0284
0285 if (!errcode) {
0286 int i;
0287
0288 for (i = 0; i < *nwqid; i++) {
0289 errcode =
0290 p9pdu_readf(pdu,
0291 proto_version,
0292 "Q",
0293 &(*wqids)[i]);
0294 if (errcode)
0295 break;
0296 }
0297 }
0298
0299 if (errcode) {
0300 kfree(*wqids);
0301 *wqids = NULL;
0302 }
0303 }
0304 break;
0305 case 'A': {
0306 struct p9_stat_dotl *stbuf =
0307 va_arg(ap, struct p9_stat_dotl *);
0308
0309 memset(stbuf, 0, sizeof(struct p9_stat_dotl));
0310 errcode =
0311 p9pdu_readf(pdu, proto_version,
0312 "qQdugqqqqqqqqqqqqqqq",
0313 &stbuf->st_result_mask,
0314 &stbuf->qid,
0315 &stbuf->st_mode,
0316 &stbuf->st_uid, &stbuf->st_gid,
0317 &stbuf->st_nlink,
0318 &stbuf->st_rdev, &stbuf->st_size,
0319 &stbuf->st_blksize, &stbuf->st_blocks,
0320 &stbuf->st_atime_sec,
0321 &stbuf->st_atime_nsec,
0322 &stbuf->st_mtime_sec,
0323 &stbuf->st_mtime_nsec,
0324 &stbuf->st_ctime_sec,
0325 &stbuf->st_ctime_nsec,
0326 &stbuf->st_btime_sec,
0327 &stbuf->st_btime_nsec,
0328 &stbuf->st_gen,
0329 &stbuf->st_data_version);
0330 }
0331 break;
0332 case '?':
0333 if ((proto_version != p9_proto_2000u) &&
0334 (proto_version != p9_proto_2000L))
0335 return 0;
0336 break;
0337 default:
0338 BUG();
0339 break;
0340 }
0341
0342 if (errcode)
0343 break;
0344 }
0345
0346 return errcode;
0347 }
0348
0349 int
0350 p9pdu_vwritef(struct p9_fcall *pdu, int proto_version, const char *fmt,
0351 va_list ap)
0352 {
0353 const char *ptr;
0354 int errcode = 0;
0355
0356 for (ptr = fmt; *ptr; ptr++) {
0357 switch (*ptr) {
0358 case 'b':{
0359 int8_t val = va_arg(ap, int);
0360 if (pdu_write(pdu, &val, sizeof(val)))
0361 errcode = -EFAULT;
0362 }
0363 break;
0364 case 'w':{
0365 __le16 val = cpu_to_le16(va_arg(ap, int));
0366 if (pdu_write(pdu, &val, sizeof(val)))
0367 errcode = -EFAULT;
0368 }
0369 break;
0370 case 'd':{
0371 __le32 val = cpu_to_le32(va_arg(ap, int32_t));
0372 if (pdu_write(pdu, &val, sizeof(val)))
0373 errcode = -EFAULT;
0374 }
0375 break;
0376 case 'q':{
0377 __le64 val = cpu_to_le64(va_arg(ap, int64_t));
0378 if (pdu_write(pdu, &val, sizeof(val)))
0379 errcode = -EFAULT;
0380 }
0381 break;
0382 case 's':{
0383 const char *sptr = va_arg(ap, const char *);
0384 uint16_t len = 0;
0385 if (sptr)
0386 len = min_t(size_t, strlen(sptr),
0387 USHRT_MAX);
0388
0389 errcode = p9pdu_writef(pdu, proto_version,
0390 "w", len);
0391 if (!errcode && pdu_write(pdu, sptr, len))
0392 errcode = -EFAULT;
0393 }
0394 break;
0395 case 'u': {
0396 kuid_t uid = va_arg(ap, kuid_t);
0397 __le32 val = cpu_to_le32(
0398 from_kuid(&init_user_ns, uid));
0399 if (pdu_write(pdu, &val, sizeof(val)))
0400 errcode = -EFAULT;
0401 } break;
0402 case 'g': {
0403 kgid_t gid = va_arg(ap, kgid_t);
0404 __le32 val = cpu_to_le32(
0405 from_kgid(&init_user_ns, gid));
0406 if (pdu_write(pdu, &val, sizeof(val)))
0407 errcode = -EFAULT;
0408 } break;
0409 case 'Q':{
0410 const struct p9_qid *qid =
0411 va_arg(ap, const struct p9_qid *);
0412 errcode =
0413 p9pdu_writef(pdu, proto_version, "bdq",
0414 qid->type, qid->version,
0415 qid->path);
0416 } break;
0417 case 'S':{
0418 const struct p9_wstat *stbuf =
0419 va_arg(ap, const struct p9_wstat *);
0420 errcode =
0421 p9pdu_writef(pdu, proto_version,
0422 "wwdQdddqssss?sugu",
0423 stbuf->size, stbuf->type,
0424 stbuf->dev, &stbuf->qid,
0425 stbuf->mode, stbuf->atime,
0426 stbuf->mtime, stbuf->length,
0427 stbuf->name, stbuf->uid,
0428 stbuf->gid, stbuf->muid,
0429 stbuf->extension, stbuf->n_uid,
0430 stbuf->n_gid, stbuf->n_muid);
0431 } break;
0432 case 'V':{
0433 uint32_t count = va_arg(ap, uint32_t);
0434 struct iov_iter *from =
0435 va_arg(ap, struct iov_iter *);
0436 errcode = p9pdu_writef(pdu, proto_version, "d",
0437 count);
0438 if (!errcode && pdu_write_u(pdu, from, count))
0439 errcode = -EFAULT;
0440 }
0441 break;
0442 case 'T':{
0443 uint16_t nwname = va_arg(ap, int);
0444 const char **wnames = va_arg(ap, const char **);
0445
0446 errcode = p9pdu_writef(pdu, proto_version, "w",
0447 nwname);
0448 if (!errcode) {
0449 int i;
0450
0451 for (i = 0; i < nwname; i++) {
0452 errcode =
0453 p9pdu_writef(pdu,
0454 proto_version,
0455 "s",
0456 wnames[i]);
0457 if (errcode)
0458 break;
0459 }
0460 }
0461 }
0462 break;
0463 case 'R':{
0464 uint16_t nwqid = va_arg(ap, int);
0465 struct p9_qid *wqids =
0466 va_arg(ap, struct p9_qid *);
0467
0468 errcode = p9pdu_writef(pdu, proto_version, "w",
0469 nwqid);
0470 if (!errcode) {
0471 int i;
0472
0473 for (i = 0; i < nwqid; i++) {
0474 errcode =
0475 p9pdu_writef(pdu,
0476 proto_version,
0477 "Q",
0478 &wqids[i]);
0479 if (errcode)
0480 break;
0481 }
0482 }
0483 }
0484 break;
0485 case 'I':{
0486 struct p9_iattr_dotl *p9attr = va_arg(ap,
0487 struct p9_iattr_dotl *);
0488
0489 errcode = p9pdu_writef(pdu, proto_version,
0490 "ddugqqqqq",
0491 p9attr->valid,
0492 p9attr->mode,
0493 p9attr->uid,
0494 p9attr->gid,
0495 p9attr->size,
0496 p9attr->atime_sec,
0497 p9attr->atime_nsec,
0498 p9attr->mtime_sec,
0499 p9attr->mtime_nsec);
0500 }
0501 break;
0502 case '?':
0503 if ((proto_version != p9_proto_2000u) &&
0504 (proto_version != p9_proto_2000L))
0505 return 0;
0506 break;
0507 default:
0508 BUG();
0509 break;
0510 }
0511
0512 if (errcode)
0513 break;
0514 }
0515
0516 return errcode;
0517 }
0518
0519 int p9pdu_readf(struct p9_fcall *pdu, int proto_version, const char *fmt, ...)
0520 {
0521 va_list ap;
0522 int ret;
0523
0524 va_start(ap, fmt);
0525 ret = p9pdu_vreadf(pdu, proto_version, fmt, ap);
0526 va_end(ap);
0527
0528 return ret;
0529 }
0530
0531 static int
0532 p9pdu_writef(struct p9_fcall *pdu, int proto_version, const char *fmt, ...)
0533 {
0534 va_list ap;
0535 int ret;
0536
0537 va_start(ap, fmt);
0538 ret = p9pdu_vwritef(pdu, proto_version, fmt, ap);
0539 va_end(ap);
0540
0541 return ret;
0542 }
0543
0544 int p9stat_read(struct p9_client *clnt, char *buf, int len, struct p9_wstat *st)
0545 {
0546 struct p9_fcall fake_pdu;
0547 int ret;
0548
0549 fake_pdu.size = len;
0550 fake_pdu.capacity = len;
0551 fake_pdu.sdata = buf;
0552 fake_pdu.offset = 0;
0553
0554 ret = p9pdu_readf(&fake_pdu, clnt->proto_version, "S", st);
0555 if (ret) {
0556 p9_debug(P9_DEBUG_9P, "<<< p9stat_read failed: %d\n", ret);
0557 trace_9p_protocol_dump(clnt, &fake_pdu);
0558 return ret;
0559 }
0560
0561 return fake_pdu.offset;
0562 }
0563 EXPORT_SYMBOL(p9stat_read);
0564
0565 int p9pdu_prepare(struct p9_fcall *pdu, int16_t tag, int8_t type)
0566 {
0567 pdu->id = type;
0568 return p9pdu_writef(pdu, 0, "dbw", 0, type, tag);
0569 }
0570
0571 int p9pdu_finalize(struct p9_client *clnt, struct p9_fcall *pdu)
0572 {
0573 int size = pdu->size;
0574 int err;
0575
0576 pdu->size = 0;
0577 err = p9pdu_writef(pdu, 0, "d", size);
0578 pdu->size = size;
0579
0580 trace_9p_protocol_dump(clnt, pdu);
0581 p9_debug(P9_DEBUG_9P, ">>> size=%d type: %d tag: %d\n",
0582 pdu->size, pdu->id, pdu->tag);
0583
0584 return err;
0585 }
0586
0587 void p9pdu_reset(struct p9_fcall *pdu)
0588 {
0589 pdu->offset = 0;
0590 pdu->size = 0;
0591 }
0592
0593 int p9dirent_read(struct p9_client *clnt, char *buf, int len,
0594 struct p9_dirent *dirent)
0595 {
0596 struct p9_fcall fake_pdu;
0597 int ret;
0598 char *nameptr;
0599
0600 fake_pdu.size = len;
0601 fake_pdu.capacity = len;
0602 fake_pdu.sdata = buf;
0603 fake_pdu.offset = 0;
0604
0605 ret = p9pdu_readf(&fake_pdu, clnt->proto_version, "Qqbs", &dirent->qid,
0606 &dirent->d_off, &dirent->d_type, &nameptr);
0607 if (ret) {
0608 p9_debug(P9_DEBUG_9P, "<<< p9dirent_read failed: %d\n", ret);
0609 trace_9p_protocol_dump(clnt, &fake_pdu);
0610 return ret;
0611 }
0612
0613 ret = strscpy(dirent->d_name, nameptr, sizeof(dirent->d_name));
0614 if (ret < 0) {
0615 p9_debug(P9_DEBUG_ERROR,
0616 "On the wire dirent name too long: %s\n",
0617 nameptr);
0618 kfree(nameptr);
0619 return ret;
0620 }
0621 kfree(nameptr);
0622
0623 return fake_pdu.offset;
0624 }
0625 EXPORT_SYMBOL(p9dirent_read);