hc
2024-02-20 102a0743326a03cd1a1202ceda21e175b7d3575c
kernel/fs/nfs/callback_xdr.c
....@@ -18,6 +18,7 @@
1818 #include "callback.h"
1919 #include "internal.h"
2020 #include "nfs4session.h"
21
+#include "nfs4trace.h"
2122
2223 #define CB_OP_TAGLEN_MAXSZ (512)
2324 #define CB_OP_HDR_RES_MAXSZ (2 * 4) // opcode, status
....@@ -72,16 +73,6 @@
7273 return xdr_ressize_check(rqstp, p);
7374 }
7475
75
-static __be32 *read_buf(struct xdr_stream *xdr, size_t nbytes)
76
-{
77
- __be32 *p;
78
-
79
- p = xdr_inline_decode(xdr, nbytes);
80
- if (unlikely(p == NULL))
81
- printk(KERN_WARNING "NFS: NFSv4 callback reply buffer overflowed!\n");
82
- return p;
83
-}
84
-
8576 static __be32 decode_string(struct xdr_stream *xdr, unsigned int *len,
8677 const char **str, size_t maxlen)
8778 {
....@@ -98,13 +89,13 @@
9889 {
9990 __be32 *p;
10091
101
- p = read_buf(xdr, 4);
92
+ p = xdr_inline_decode(xdr, 4);
10293 if (unlikely(p == NULL))
10394 return htonl(NFS4ERR_RESOURCE);
10495 fh->size = ntohl(*p);
10596 if (fh->size > NFS4_FHSIZE)
10697 return htonl(NFS4ERR_BADHANDLE);
107
- p = read_buf(xdr, fh->size);
98
+ p = xdr_inline_decode(xdr, fh->size);
10899 if (unlikely(p == NULL))
109100 return htonl(NFS4ERR_RESOURCE);
110101 memcpy(&fh->data[0], p, fh->size);
....@@ -117,11 +108,11 @@
117108 __be32 *p;
118109 unsigned int attrlen;
119110
120
- p = read_buf(xdr, 4);
111
+ p = xdr_inline_decode(xdr, 4);
121112 if (unlikely(p == NULL))
122113 return htonl(NFS4ERR_RESOURCE);
123114 attrlen = ntohl(*p);
124
- p = read_buf(xdr, attrlen << 2);
115
+ p = xdr_inline_decode(xdr, attrlen << 2);
125116 if (unlikely(p == NULL))
126117 return htonl(NFS4ERR_RESOURCE);
127118 if (likely(attrlen > 0))
....@@ -135,7 +126,7 @@
135126 {
136127 __be32 *p;
137128
138
- p = read_buf(xdr, NFS4_STATEID_SIZE);
129
+ p = xdr_inline_decode(xdr, NFS4_STATEID_SIZE);
139130 if (unlikely(p == NULL))
140131 return htonl(NFS4ERR_RESOURCE);
141132 memcpy(stateid->data, p, NFS4_STATEID_SIZE);
....@@ -156,7 +147,7 @@
156147 status = decode_string(xdr, &hdr->taglen, &hdr->tag, CB_OP_TAGLEN_MAXSZ);
157148 if (unlikely(status != 0))
158149 return status;
159
- p = read_buf(xdr, 12);
150
+ p = xdr_inline_decode(xdr, 12);
160151 if (unlikely(p == NULL))
161152 return htonl(NFS4ERR_RESOURCE);
162153 hdr->minorversion = ntohl(*p++);
....@@ -176,7 +167,7 @@
176167 static __be32 decode_op_hdr(struct xdr_stream *xdr, unsigned int *op)
177168 {
178169 __be32 *p;
179
- p = read_buf(xdr, 4);
170
+ p = xdr_inline_decode(xdr, 4);
180171 if (unlikely(p == NULL))
181172 return htonl(NFS4ERR_RESOURCE_HDR);
182173 *op = ntohl(*p);
....@@ -205,7 +196,7 @@
205196 status = decode_delegation_stateid(xdr, &args->stateid);
206197 if (unlikely(status != 0))
207198 return status;
208
- p = read_buf(xdr, 4);
199
+ p = xdr_inline_decode(xdr, 4);
209200 if (unlikely(p == NULL))
210201 return htonl(NFS4ERR_RESOURCE);
211202 args->truncate = ntohl(*p);
....@@ -227,7 +218,7 @@
227218 __be32 status = 0;
228219 uint32_t iomode;
229220
230
- p = read_buf(xdr, 4 * sizeof(uint32_t));
221
+ p = xdr_inline_decode(xdr, 4 * sizeof(uint32_t));
231222 if (unlikely(p == NULL))
232223 return htonl(NFS4ERR_BADXDR);
233224
....@@ -245,14 +236,14 @@
245236 if (unlikely(status != 0))
246237 return status;
247238
248
- p = read_buf(xdr, 2 * sizeof(uint64_t));
239
+ p = xdr_inline_decode(xdr, 2 * sizeof(uint64_t));
249240 if (unlikely(p == NULL))
250241 return htonl(NFS4ERR_BADXDR);
251242 p = xdr_decode_hyper(p, &args->cbl_range.offset);
252243 p = xdr_decode_hyper(p, &args->cbl_range.length);
253244 return decode_layout_stateid(xdr, &args->cbl_stateid);
254245 } else if (args->cbl_recall_type == RETURN_FSID) {
255
- p = read_buf(xdr, 2 * sizeof(uint64_t));
246
+ p = xdr_inline_decode(xdr, 2 * sizeof(uint64_t));
256247 if (unlikely(p == NULL))
257248 return htonl(NFS4ERR_BADXDR);
258249 p = xdr_decode_hyper(p, &args->cbl_fsid.major);
....@@ -273,7 +264,7 @@
273264 __be32 status = 0;
274265
275266 /* Num of device notifications */
276
- p = read_buf(xdr, sizeof(uint32_t));
267
+ p = xdr_inline_decode(xdr, sizeof(uint32_t));
277268 if (unlikely(p == NULL)) {
278269 status = htonl(NFS4ERR_BADXDR);
279270 goto out;
....@@ -281,10 +272,6 @@
281272 n = ntohl(*p++);
282273 if (n == 0)
283274 goto out;
284
- if (n > ULONG_MAX / sizeof(*args->devs)) {
285
- status = htonl(NFS4ERR_BADXDR);
286
- goto out;
287
- }
288275
289276 args->devs = kmalloc_array(n, sizeof(*args->devs), GFP_KERNEL);
290277 if (!args->devs) {
....@@ -296,7 +283,8 @@
296283 for (i = 0; i < n; i++) {
297284 struct cb_devicenotifyitem *dev = &args->devs[i];
298285
299
- p = read_buf(xdr, (4 * sizeof(uint32_t)) + NFS4_DEVICEID4_SIZE);
286
+ p = xdr_inline_decode(xdr, (4 * sizeof(uint32_t)) +
287
+ NFS4_DEVICEID4_SIZE);
300288 if (unlikely(p == NULL)) {
301289 status = htonl(NFS4ERR_BADXDR);
302290 goto err;
....@@ -327,7 +315,7 @@
327315 p += XDR_QUADLEN(NFS4_DEVICEID4_SIZE);
328316
329317 if (dev->cbd_layout_type == NOTIFY_DEVICEID4_CHANGE) {
330
- p = read_buf(xdr, sizeof(uint32_t));
318
+ p = xdr_inline_decode(xdr, sizeof(uint32_t));
331319 if (unlikely(p == NULL)) {
332320 status = htonl(NFS4ERR_BADXDR);
333321 goto err;
....@@ -359,7 +347,7 @@
359347 {
360348 __be32 *p;
361349
362
- p = read_buf(xdr, NFS4_MAX_SESSIONID_LEN);
350
+ p = xdr_inline_decode(xdr, NFS4_MAX_SESSIONID_LEN);
363351 if (unlikely(p == NULL))
364352 return htonl(NFS4ERR_RESOURCE);
365353
....@@ -379,13 +367,13 @@
379367 goto out;
380368
381369 status = htonl(NFS4ERR_RESOURCE);
382
- p = read_buf(xdr, sizeof(uint32_t));
370
+ p = xdr_inline_decode(xdr, sizeof(uint32_t));
383371 if (unlikely(p == NULL))
384372 goto out;
385373
386374 rc_list->rcl_nrefcalls = ntohl(*p++);
387375 if (rc_list->rcl_nrefcalls) {
388
- p = read_buf(xdr,
376
+ p = xdr_inline_decode(xdr,
389377 rc_list->rcl_nrefcalls * 2 * sizeof(uint32_t));
390378 if (unlikely(p == NULL))
391379 goto out;
....@@ -418,7 +406,7 @@
418406 if (status)
419407 return status;
420408
421
- p = read_buf(xdr, 5 * sizeof(uint32_t));
409
+ p = xdr_inline_decode(xdr, 5 * sizeof(uint32_t));
422410 if (unlikely(p == NULL))
423411 return htonl(NFS4ERR_RESOURCE);
424412
....@@ -461,7 +449,7 @@
461449 uint32_t bitmap[2];
462450 __be32 *p, status;
463451
464
- p = read_buf(xdr, 4);
452
+ p = xdr_inline_decode(xdr, 4);
465453 if (unlikely(p == NULL))
466454 return htonl(NFS4ERR_BADXDR);
467455 args->craa_objs_to_keep = ntohl(*p++);
....@@ -480,7 +468,7 @@
480468 struct cb_recallslotargs *args = argp;
481469 __be32 *p;
482470
483
- p = read_buf(xdr, 4);
471
+ p = xdr_inline_decode(xdr, 4);
484472 if (unlikely(p == NULL))
485473 return htonl(NFS4ERR_BADXDR);
486474 args->crsa_target_highest_slotid = ntohl(*p++);
....@@ -492,14 +480,14 @@
492480 __be32 *p;
493481 unsigned int len;
494482
495
- p = read_buf(xdr, 12);
483
+ p = xdr_inline_decode(xdr, 12);
496484 if (unlikely(p == NULL))
497485 return htonl(NFS4ERR_BADXDR);
498486
499487 p = xdr_decode_hyper(p, &args->cbnl_owner.clientid);
500488 len = be32_to_cpu(*p);
501489
502
- p = read_buf(xdr, len);
490
+ p = xdr_inline_decode(xdr, len);
503491 if (unlikely(p == NULL))
504492 return htonl(NFS4ERR_BADXDR);
505493
....@@ -537,7 +525,7 @@
537525 __be32 *p;
538526
539527 /* skip the always zero field */
540
- p = read_buf(xdr, 4);
528
+ p = xdr_inline_decode(xdr, 4);
541529 if (unlikely(!p))
542530 goto out;
543531 p++;
....@@ -577,7 +565,7 @@
577565 return status;
578566
579567 /* decode status */
580
- p = read_buf(xdr, 4);
568
+ p = xdr_inline_decode(xdr, 4);
581569 if (unlikely(!p))
582570 goto out;
583571 args->error = ntohl(*p++);
....@@ -636,7 +624,7 @@
636624 return 0;
637625 }
638626
639
-static __be32 encode_attr_time(struct xdr_stream *xdr, const struct timespec *time)
627
+static __be32 encode_attr_time(struct xdr_stream *xdr, const struct timespec64 *time)
640628 {
641629 __be32 *p;
642630
....@@ -648,14 +636,14 @@
648636 return 0;
649637 }
650638
651
-static __be32 encode_attr_ctime(struct xdr_stream *xdr, const uint32_t *bitmap, const struct timespec *time)
639
+static __be32 encode_attr_ctime(struct xdr_stream *xdr, const uint32_t *bitmap, const struct timespec64 *time)
652640 {
653641 if (!(bitmap[1] & FATTR4_WORD1_TIME_METADATA))
654642 return 0;
655643 return encode_attr_time(xdr,time);
656644 }
657645
658
-static __be32 encode_attr_mtime(struct xdr_stream *xdr, const uint32_t *bitmap, const struct timespec *time)
646
+static __be32 encode_attr_mtime(struct xdr_stream *xdr, const uint32_t *bitmap, const struct timespec64 *time)
659647 {
660648 if (!(bitmap[1] & FATTR4_WORD1_TIME_MODIFY))
661649 return 0;
....@@ -943,10 +931,11 @@
943931 };
944932 unsigned int nops = 0;
945933
946
- xdr_init_decode(&xdr_in, &rqstp->rq_arg, rqstp->rq_arg.head[0].iov_base);
934
+ xdr_init_decode(&xdr_in, &rqstp->rq_arg,
935
+ rqstp->rq_arg.head[0].iov_base, NULL);
947936
948937 p = (__be32*)((char *)rqstp->rq_res.head[0].iov_base + rqstp->rq_res.head[0].iov_len);
949
- xdr_init_encode(&xdr_out, &rqstp->rq_res, p);
938
+ xdr_init_encode(&xdr_out, &rqstp->rq_res, p, NULL);
950939
951940 status = decode_compound_hdr_arg(&xdr_in, &hdr_arg);
952941 if (status == htonl(NFS4ERR_RESOURCE))
....@@ -954,9 +943,13 @@
954943
955944 if (hdr_arg.minorversion == 0) {
956945 cps.clp = nfs4_find_client_ident(SVC_NET(rqstp), hdr_arg.cb_ident);
957
- if (!cps.clp || !check_gss_callback_principal(cps.clp, rqstp)) {
958
- if (cps.clp)
959
- nfs_put_client(cps.clp);
946
+ if (!cps.clp) {
947
+ trace_nfs_cb_no_clp(rqstp->rq_xid, hdr_arg.cb_ident);
948
+ goto out_invalidcred;
949
+ }
950
+ if (!check_gss_callback_principal(cps.clp, rqstp)) {
951
+ trace_nfs_cb_badprinc(rqstp->rq_xid, hdr_arg.cb_ident);
952
+ nfs_put_client(cps.clp);
960953 goto out_invalidcred;
961954 }
962955 }