1 // SPDX-License-Identifier: GPL-2.0-only
3 * 9P Protocol Support Code
8 * Copyright (C) 2008 by IBM, Corp.
11 #include <linux/module.h>
12 #include <linux/errno.h>
13 #include <linux/kernel.h>
14 #include <linux/uaccess.h>
15 #include <linux/slab.h>
16 #include <linux/sched.h>
17 #include <linux/stddef.h>
18 #include <linux/types.h>
19 #include <linux/uio.h>
20 #include <net/9p/9p.h>
21 #include <net/9p/client.h>
24 #include <trace/events/9p.h>
26 /* len[2] text[len] */
27 #define P9_STRLEN(s) \
28 (2 + min_t(size_t, s ? strlen(s) : 0, USHRT_MAX))
31 * p9_msg_buf_size - Returns a buffer size sufficiently large to hold the
32 * intended 9p message.
35 * @fmt: format template for assembling request message
37 * @ap: variable arguments to be fed to passed format template
40 * Note: Even for response types (P9_R*) the format template and variable
41 * arguments must always be for the originating request type (P9_T*).
43 size_t p9_msg_buf_size(struct p9_client *c, enum p9_msg_t type,
44 const char *fmt, va_list ap)
46 /* size[4] type[1] tag[2] */
47 const int hdr = 4 + 1 + 2;
48 /* ename[s] errno[4] */
49 const int rerror_size = hdr + P9_ERRMAX + 4;
51 const int rlerror_size = hdr + 4;
53 c->proto_version == p9_proto_2000L ? rlerror_size : rerror_size;
55 static_assert(NAME_MAX <= 4*1024, "p9_msg_buf_size() currently assumes "
56 "a max. allowed directory entry name length of 4k");
60 /* message types not used at all */
67 /* variable length & potentially large message types */
69 BUG_ON(strcmp("ddss?u", fmt));
73 const char *uname = va_arg(ap, const char *);
74 const char *aname = va_arg(ap, const char *);
75 /* fid[4] afid[4] uname[s] aname[s] n_uname[4] */
76 return hdr + 4 + 4 + P9_STRLEN(uname) + P9_STRLEN(aname) + 4;
79 BUG_ON(strcmp("ddT", fmt));
83 uint i, nwname = va_arg(ap, int);
85 const char **wnames = va_arg(ap, const char **);
86 for (i = 0, wname_all = 0; i < nwname; ++i) {
87 wname_all += P9_STRLEN(wnames[i]);
89 /* fid[4] newfid[4] nwname[2] nwname*(wname[s]) */
90 return hdr + 4 + 4 + 2 + wname_all;
93 BUG_ON(strcmp("ddT", fmt));
97 uint nwname = va_arg(ap, int);
98 /* nwqid[2] nwqid*(wqid[13]) */
99 return max_t(size_t, hdr + 2 + nwname * 13, err_size);
102 BUG_ON(strcmp("dsdb?s", fmt));
105 const char *name = va_arg(ap, const char *);
106 if (c->proto_version == p9_proto_legacy) {
107 /* fid[4] name[s] perm[4] mode[1] */
108 return hdr + 4 + P9_STRLEN(name) + 4 + 1;
113 const char *ext = va_arg(ap, const char *);
114 /* fid[4] name[s] perm[4] mode[1] extension[s] */
115 return hdr + 4 + P9_STRLEN(name) + 4 + 1 + P9_STRLEN(ext);
120 BUG_ON(strcmp("dsddg", fmt));
123 const char *name = va_arg(ap, const char *);
124 /* fid[4] name[s] flags[4] mode[4] gid[4] */
125 return hdr + 4 + P9_STRLEN(name) + 4 + 4 + 4;
129 BUG_ON(strcmp("dqd", fmt));
133 const int32_t count = va_arg(ap, int32_t);
134 /* count[4] data[count] */
135 return max_t(size_t, hdr + 4 + count, err_size);
138 BUG_ON(strcmp("dqV", fmt));
142 const int32_t count = va_arg(ap, int32_t);
143 /* fid[4] offset[8] count[4] data[count] */
144 return hdr + 4 + 8 + 4 + count;
147 BUG_ON(strcmp("dsds", fmt));
150 const char *oldname, *newname;
151 oldname = va_arg(ap, const char *);
153 newname = va_arg(ap, const char *);
154 /* olddirfid[4] oldname[s] newdirfid[4] newname[s] */
155 return hdr + 4 + P9_STRLEN(oldname) + 4 + P9_STRLEN(newname);
158 BUG_ON(strcmp("dssg", fmt));
161 const char *name = va_arg(ap, const char *);
162 const char *symtgt = va_arg(ap, const char *);
163 /* fid[4] name[s] symtgt[s] gid[4] */
164 return hdr + 4 + P9_STRLEN(name) + P9_STRLEN(symtgt) + 4;
172 /* small message types */
177 case P9_TXATTRCREATE:
186 /* tiny message types */
194 p9pdu_writef(struct p9_fcall *pdu, int proto_version, const char *fmt, ...);
196 void p9stat_free(struct p9_wstat *stbuf)
206 kfree(stbuf->extension);
207 stbuf->extension = NULL;
209 EXPORT_SYMBOL(p9stat_free);
211 size_t pdu_read(struct p9_fcall *pdu, void *data, size_t size)
213 size_t len = min(pdu->size - pdu->offset, size);
215 memcpy(data, &pdu->sdata[pdu->offset], len);
220 static size_t pdu_write(struct p9_fcall *pdu, const void *data, size_t size)
222 size_t len = min(pdu->capacity - pdu->size, size);
224 memcpy(&pdu->sdata[pdu->size], data, len);
230 pdu_write_u(struct p9_fcall *pdu, struct iov_iter *from, size_t size)
232 size_t len = min(pdu->capacity - pdu->size, size);
234 if (!copy_from_iter_full(&pdu->sdata[pdu->size], len, from))
250 * D - data blob (int32_t size followed by void *, results are not freed)
251 * T - array of strings (int16_t count, followed by strings)
252 * R - array of qids (int16_t count, followed by qids)
253 * A - stat for 9p2000.L (p9_stat_dotl)
254 * ? - if optional = 1, continue parsing
258 p9pdu_vreadf(struct p9_fcall *pdu, int proto_version, const char *fmt,
264 for (ptr = fmt; *ptr; ptr++) {
267 int8_t *val = va_arg(ap, int8_t *);
268 if (pdu_read(pdu, val, sizeof(*val))) {
275 int16_t *val = va_arg(ap, int16_t *);
277 if (pdu_read(pdu, &le_val, sizeof(le_val))) {
281 *val = le16_to_cpu(le_val);
285 int32_t *val = va_arg(ap, int32_t *);
287 if (pdu_read(pdu, &le_val, sizeof(le_val))) {
291 *val = le32_to_cpu(le_val);
295 int64_t *val = va_arg(ap, int64_t *);
297 if (pdu_read(pdu, &le_val, sizeof(le_val))) {
301 *val = le64_to_cpu(le_val);
305 char **sptr = va_arg(ap, char **);
308 errcode = p9pdu_readf(pdu, proto_version,
313 *sptr = kmalloc(len + 1, GFP_NOFS);
318 if (pdu_read(pdu, *sptr, len)) {
327 kuid_t *uid = va_arg(ap, kuid_t *);
329 if (pdu_read(pdu, &le_val, sizeof(le_val))) {
333 *uid = make_kuid(&init_user_ns,
334 le32_to_cpu(le_val));
337 kgid_t *gid = va_arg(ap, kgid_t *);
339 if (pdu_read(pdu, &le_val, sizeof(le_val))) {
343 *gid = make_kgid(&init_user_ns,
344 le32_to_cpu(le_val));
348 va_arg(ap, struct p9_qid *);
350 errcode = p9pdu_readf(pdu, proto_version, "bdq",
351 &qid->type, &qid->version,
356 struct p9_wstat *stbuf =
357 va_arg(ap, struct p9_wstat *);
359 memset(stbuf, 0, sizeof(struct p9_wstat));
360 stbuf->n_uid = stbuf->n_muid = INVALID_UID;
361 stbuf->n_gid = INVALID_GID;
364 p9pdu_readf(pdu, proto_version,
366 &stbuf->size, &stbuf->type,
367 &stbuf->dev, &stbuf->qid,
368 &stbuf->mode, &stbuf->atime,
369 &stbuf->mtime, &stbuf->length,
370 &stbuf->name, &stbuf->uid,
371 &stbuf->gid, &stbuf->muid,
373 &stbuf->n_uid, &stbuf->n_gid,
380 uint32_t *count = va_arg(ap, uint32_t *);
381 void **data = va_arg(ap, void **);
384 p9pdu_readf(pdu, proto_version, "d", count);
387 min_t(uint32_t, *count,
388 pdu->size - pdu->offset);
389 *data = &pdu->sdata[pdu->offset];
394 uint16_t *nwname = va_arg(ap, uint16_t *);
395 char ***wnames = va_arg(ap, char ***);
397 errcode = p9pdu_readf(pdu, proto_version,
401 kmalloc_array(*nwname,
411 for (i = 0; i < *nwname; i++) {
426 for (i = 0; i < *nwname; i++)
435 uint16_t *nwqid = va_arg(ap, uint16_t *);
436 struct p9_qid **wqids =
437 va_arg(ap, struct p9_qid **);
442 p9pdu_readf(pdu, proto_version, "w", nwqid);
445 kmalloc_array(*nwqid,
446 sizeof(struct p9_qid),
455 for (i = 0; i < *nwqid; i++) {
473 struct p9_stat_dotl *stbuf =
474 va_arg(ap, struct p9_stat_dotl *);
476 memset(stbuf, 0, sizeof(struct p9_stat_dotl));
478 p9pdu_readf(pdu, proto_version,
479 "qQdugqqqqqqqqqqqqqqq",
480 &stbuf->st_result_mask,
483 &stbuf->st_uid, &stbuf->st_gid,
485 &stbuf->st_rdev, &stbuf->st_size,
486 &stbuf->st_blksize, &stbuf->st_blocks,
487 &stbuf->st_atime_sec,
488 &stbuf->st_atime_nsec,
489 &stbuf->st_mtime_sec,
490 &stbuf->st_mtime_nsec,
491 &stbuf->st_ctime_sec,
492 &stbuf->st_ctime_nsec,
493 &stbuf->st_btime_sec,
494 &stbuf->st_btime_nsec,
496 &stbuf->st_data_version);
500 if ((proto_version != p9_proto_2000u) &&
501 (proto_version != p9_proto_2000L))
517 p9pdu_vwritef(struct p9_fcall *pdu, int proto_version, const char *fmt,
523 for (ptr = fmt; *ptr; ptr++) {
526 int8_t val = va_arg(ap, int);
527 if (pdu_write(pdu, &val, sizeof(val)))
532 __le16 val = cpu_to_le16(va_arg(ap, int));
533 if (pdu_write(pdu, &val, sizeof(val)))
538 __le32 val = cpu_to_le32(va_arg(ap, int32_t));
539 if (pdu_write(pdu, &val, sizeof(val)))
544 __le64 val = cpu_to_le64(va_arg(ap, int64_t));
545 if (pdu_write(pdu, &val, sizeof(val)))
550 const char *sptr = va_arg(ap, const char *);
553 len = min_t(size_t, strlen(sptr),
556 errcode = p9pdu_writef(pdu, proto_version,
558 if (!errcode && pdu_write(pdu, sptr, len))
563 kuid_t uid = va_arg(ap, kuid_t);
564 __le32 val = cpu_to_le32(
565 from_kuid(&init_user_ns, uid));
566 if (pdu_write(pdu, &val, sizeof(val)))
570 kgid_t gid = va_arg(ap, kgid_t);
571 __le32 val = cpu_to_le32(
572 from_kgid(&init_user_ns, gid));
573 if (pdu_write(pdu, &val, sizeof(val)))
577 const struct p9_qid *qid =
578 va_arg(ap, const struct p9_qid *);
580 p9pdu_writef(pdu, proto_version, "bdq",
581 qid->type, qid->version,
585 const struct p9_wstat *stbuf =
586 va_arg(ap, const struct p9_wstat *);
588 p9pdu_writef(pdu, proto_version,
590 stbuf->size, stbuf->type,
591 stbuf->dev, &stbuf->qid,
592 stbuf->mode, stbuf->atime,
593 stbuf->mtime, stbuf->length,
594 stbuf->name, stbuf->uid,
595 stbuf->gid, stbuf->muid,
596 stbuf->extension, stbuf->n_uid,
597 stbuf->n_gid, stbuf->n_muid);
600 uint32_t count = va_arg(ap, uint32_t);
601 struct iov_iter *from =
602 va_arg(ap, struct iov_iter *);
603 errcode = p9pdu_writef(pdu, proto_version, "d",
605 if (!errcode && pdu_write_u(pdu, from, count))
610 uint16_t nwname = va_arg(ap, int);
611 const char **wnames = va_arg(ap, const char **);
613 errcode = p9pdu_writef(pdu, proto_version, "w",
618 for (i = 0; i < nwname; i++) {
631 uint16_t nwqid = va_arg(ap, int);
632 struct p9_qid *wqids =
633 va_arg(ap, struct p9_qid *);
635 errcode = p9pdu_writef(pdu, proto_version, "w",
640 for (i = 0; i < nwqid; i++) {
653 struct p9_iattr_dotl *p9attr = va_arg(ap,
654 struct p9_iattr_dotl *);
656 errcode = p9pdu_writef(pdu, proto_version,
670 if ((proto_version != p9_proto_2000u) &&
671 (proto_version != p9_proto_2000L))
686 int p9pdu_readf(struct p9_fcall *pdu, int proto_version, const char *fmt, ...)
692 ret = p9pdu_vreadf(pdu, proto_version, fmt, ap);
699 p9pdu_writef(struct p9_fcall *pdu, int proto_version, const char *fmt, ...)
705 ret = p9pdu_vwritef(pdu, proto_version, fmt, ap);
711 int p9stat_read(struct p9_client *clnt, char *buf, int len, struct p9_wstat *st)
713 struct p9_fcall fake_pdu;
717 fake_pdu.capacity = len;
718 fake_pdu.sdata = buf;
721 ret = p9pdu_readf(&fake_pdu, clnt->proto_version, "S", st);
723 p9_debug(P9_DEBUG_9P, "<<< p9stat_read failed: %d\n", ret);
724 trace_9p_protocol_dump(clnt, &fake_pdu);
728 return fake_pdu.offset;
730 EXPORT_SYMBOL(p9stat_read);
732 int p9pdu_prepare(struct p9_fcall *pdu, int16_t tag, int8_t type)
735 return p9pdu_writef(pdu, 0, "dbw", 0, type, tag);
738 int p9pdu_finalize(struct p9_client *clnt, struct p9_fcall *pdu)
740 int size = pdu->size;
744 err = p9pdu_writef(pdu, 0, "d", size);
747 trace_9p_protocol_dump(clnt, pdu);
748 p9_debug(P9_DEBUG_9P, ">>> size=%d type: %d tag: %d\n",
749 pdu->size, pdu->id, pdu->tag);
754 void p9pdu_reset(struct p9_fcall *pdu)
760 int p9dirent_read(struct p9_client *clnt, char *buf, int len,
761 struct p9_dirent *dirent)
763 struct p9_fcall fake_pdu;
768 fake_pdu.capacity = len;
769 fake_pdu.sdata = buf;
772 ret = p9pdu_readf(&fake_pdu, clnt->proto_version, "Qqbs", &dirent->qid,
773 &dirent->d_off, &dirent->d_type, &nameptr);
775 p9_debug(P9_DEBUG_9P, "<<< p9dirent_read failed: %d\n", ret);
776 trace_9p_protocol_dump(clnt, &fake_pdu);
780 ret = strscpy(dirent->d_name, nameptr, sizeof(dirent->d_name));
782 p9_debug(P9_DEBUG_ERROR,
783 "On the wire dirent name too long: %s\n",
790 return fake_pdu.offset;
792 EXPORT_SYMBOL(p9dirent_read);