Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-doc
Path: blob/main/website/static/security/patches/EN-07:01/nfs60.patch
18096 views
1
Index: sys/nfsserver/nfs_serv.c
2
===================================================================
3
RCS file: /home/ncvs/src/sys/nfsserver/nfs_serv.c,v
4
retrieving revision 1.156
5
diff -u -r1.156 nfs_serv.c
6
--- sys/nfsserver/nfs_serv.c 17 Apr 2005 16:25:36 -0000 1.156
7
+++ sys/nfsserver/nfs_serv.c 13 Feb 2007 20:43:09 -0000
8
@@ -569,6 +569,10 @@
9
10
error = lookup(&ind);
11
ind.ni_dvp = NULL;
12
+ if (ind.ni_cnd.cn_flags & GIANTHELD) {
13
+ mtx_unlock(&Giant);
14
+ ind.ni_cnd.cn_flags &= ~GIANTHELD;
15
+ }
16
17
if (error == 0) {
18
/*
19
@@ -599,15 +603,9 @@
20
}
21
}
22
23
- if (dirp) {
24
- vrele(dirp);
25
- dirp = NULL;
26
- }
27
-
28
/*
29
* Resources at this point:
30
* ndp->ni_vp may not be NULL
31
- *
32
*/
33
34
if (error) {
35
@@ -621,15 +619,6 @@
36
}
37
38
/*
39
- * Clear out some resources prior to potentially blocking. This
40
- * is not as critical as ni_dvp resources in other routines, but
41
- * it helps.
42
- */
43
- vrele(ndp->ni_startdir);
44
- ndp->ni_startdir = NULL;
45
- NDFREE(&nd, NDF_ONLY_PNBUF);
46
-
47
- /*
48
* Get underlying attribute, then release remaining resources ( for
49
* the same potential blocking reason ) and reply.
50
*/
51
@@ -641,8 +630,12 @@
52
error = VOP_GETATTR(vp, vap, cred, td);
53
54
vput(vp);
55
- mtx_unlock(&Giant); /* VFS */
56
+ vrele(ndp->ni_startdir);
57
+ vrele(dirp);
58
ndp->ni_vp = NULL;
59
+ ndp->ni_startdir = NULL;
60
+ dirp = NULL;
61
+ mtx_unlock(&Giant); /* VFS */
62
NFSD_LOCK();
63
nfsm_reply(NFSX_SRVFH(v3) + NFSX_POSTOPORFATTR(v3) + NFSX_POSTOPATTR(v3));
64
if (error) {
65
@@ -662,17 +655,19 @@
66
67
nfsmout:
68
NFSD_LOCK_ASSERT();
69
- NFSD_UNLOCK();
70
- mtx_lock(&Giant); /* VFS */
71
- if (dirp)
72
- vrele(dirp);
73
+ if (ndp->ni_vp || dirp || ndp->ni_startdir) {
74
+ NFSD_UNLOCK();
75
+ mtx_lock(&Giant); /* VFS */
76
+ if (ndp->ni_vp)
77
+ vput(ndp->ni_vp);
78
+ if (dirp)
79
+ vrele(dirp);
80
+ if (ndp->ni_startdir)
81
+ vrele(ndp->ni_startdir);
82
+ mtx_unlock(&Giant); /* VFS */
83
+ NFSD_LOCK();
84
+ }
85
NDFREE(&nd, NDF_ONLY_PNBUF);
86
- if (ndp->ni_startdir)
87
- vrele(ndp->ni_startdir);
88
- if (ndp->ni_vp)
89
- vput(ndp->ni_vp);
90
- mtx_unlock(&Giant); /* VFS */
91
- NFSD_LOCK();
92
return (error);
93
}
94
95
@@ -1924,6 +1919,10 @@
96
97
error = lookup(&nd);
98
nd.ni_dvp = NULL;
99
+ if (nd.ni_cnd.cn_flags & GIANTHELD) {
100
+ mtx_unlock(&Giant);
101
+ nd.ni_cnd.cn_flags &= ~GIANTHELD;
102
+ }
103
if (error)
104
goto ereply;
105
106
@@ -2004,13 +2003,6 @@
107
NFSD_LOCK_ASSERT();
108
NFSD_UNLOCK();
109
mtx_lock(&Giant); /* VFS */
110
- if (nd.ni_startdir) {
111
- vrele(nd.ni_startdir);
112
- nd.ni_startdir = NULL;
113
- }
114
- if (dirp)
115
- vrele(dirp);
116
- NDFREE(&nd, NDF_ONLY_PNBUF);
117
if (nd.ni_dvp) {
118
if (nd.ni_dvp == nd.ni_vp)
119
vrele(nd.ni_dvp);
120
@@ -2019,6 +2011,13 @@
121
}
122
if (nd.ni_vp)
123
vput(nd.ni_vp);
124
+ if (nd.ni_startdir) {
125
+ vrele(nd.ni_startdir);
126
+ nd.ni_startdir = NULL;
127
+ }
128
+ if (dirp)
129
+ vrele(dirp);
130
+ NDFREE(&nd, NDF_ONLY_PNBUF);
131
vn_finished_write(mp);
132
mtx_unlock(&Giant); /* VFS */
133
NFSD_LOCK();
134
@@ -2092,6 +2091,8 @@
135
tl = nfsm_dissect_nonblock(u_int32_t *, NFSX_UNSIGNED);
136
vtyp = nfsv3tov_type(*tl);
137
if (vtyp != VCHR && vtyp != VBLK && vtyp != VSOCK && vtyp != VFIFO) {
138
+ NFSD_UNLOCK();
139
+ mtx_lock(&Giant); /* VFS */
140
error = NFSERR_BADTYPE;
141
goto out;
142
}
143
@@ -2108,6 +2109,8 @@
144
* Iff doesn't exist, create it.
145
*/
146
if (nd.ni_vp) {
147
+ NFSD_UNLOCK();
148
+ mtx_lock(&Giant); /* VFS */
149
error = EEXIST;
150
goto out;
151
}
152
@@ -2146,6 +2149,10 @@
153
154
error = lookup(&nd);
155
nd.ni_dvp = NULL;
156
+ if (nd.ni_cnd.cn_flags & GIANTHELD) {
157
+ mtx_unlock(&Giant);
158
+ nd.ni_cnd.cn_flags &= ~GIANTHELD;
159
+ }
160
161
if (error)
162
goto out;
163
@@ -2158,18 +2165,6 @@
164
*/
165
out:
166
NFSD_UNLOCK_ASSERT();
167
- if (nd.ni_startdir) {
168
- vrele(nd.ni_startdir);
169
- nd.ni_startdir = NULL;
170
- }
171
- NDFREE(&nd, NDF_ONLY_PNBUF);
172
- if (nd.ni_dvp) {
173
- if (nd.ni_dvp == nd.ni_vp)
174
- vrele(nd.ni_dvp);
175
- else
176
- vput(nd.ni_dvp);
177
- nd.ni_dvp = NULL;
178
- }
179
vp = nd.ni_vp;
180
if (!error) {
181
bzero((caddr_t)fhp, sizeof(nfh));
182
@@ -2178,11 +2173,23 @@
183
if (!error)
184
error = VOP_GETATTR(vp, vap, cred, td);
185
}
186
+ if (nd.ni_dvp) {
187
+ if (nd.ni_dvp == nd.ni_vp)
188
+ vrele(nd.ni_dvp);
189
+ else
190
+ vput(nd.ni_dvp);
191
+ nd.ni_dvp = NULL;
192
+ }
193
if (vp) {
194
vput(vp);
195
vp = NULL;
196
nd.ni_vp = NULL;
197
}
198
+ if (nd.ni_startdir) {
199
+ vrele(nd.ni_startdir);
200
+ nd.ni_startdir = NULL;
201
+ }
202
+ NDFREE(&nd, NDF_ONLY_PNBUF);
203
if (dirp) {
204
vn_lock(dirp, LK_EXCLUSIVE | LK_RETRY, td);
205
diraft_ret = VOP_GETATTR(dirp, &diraft, cred, td);
206
@@ -2210,11 +2217,6 @@
207
NFSD_LOCK_ASSERT();
208
NFSD_UNLOCK();
209
mtx_lock(&Giant); /* VFS */
210
- if (dirp)
211
- vrele(dirp);
212
- if (nd.ni_startdir)
213
- vrele(nd.ni_startdir);
214
- NDFREE(&nd, NDF_ONLY_PNBUF);
215
if (nd.ni_dvp) {
216
if (nd.ni_dvp == nd.ni_vp)
217
vrele(nd.ni_dvp);
218
@@ -2223,6 +2225,11 @@
219
}
220
if (nd.ni_vp)
221
vput(nd.ni_vp);
222
+ if (dirp)
223
+ vrele(dirp);
224
+ if (nd.ni_startdir)
225
+ vrele(nd.ni_startdir);
226
+ NDFREE(&nd, NDF_ONLY_PNBUF);
227
vn_finished_write(mp);
228
mtx_unlock(&Giant); /* VFS */
229
NFSD_LOCK();
230
@@ -2519,8 +2526,8 @@
231
tond.ni_dvp = NULL;
232
tond.ni_vp = NULL;
233
if (error) {
234
- fromnd.ni_cnd.cn_flags &= ~HASBUF;
235
- tond.ni_cnd.cn_flags &= ~HASBUF;
236
+ NDFREE(&fromnd, NDF_ONLY_PNBUF);
237
+ NDFREE(&tond, NDF_ONLY_PNBUF);
238
}
239
} else {
240
if (error == -1)
241
@@ -2573,11 +2580,6 @@
242
NFSD_LOCK_ASSERT();
243
NFSD_UNLOCK();
244
mtx_lock(&Giant); /* VFS */
245
- if (tdirp)
246
- vrele(tdirp);
247
- if (tond.ni_startdir)
248
- vrele(tond.ni_startdir);
249
- NDFREE(&tond, NDF_ONLY_PNBUF);
250
if (tond.ni_dvp) {
251
if (tond.ni_dvp == tond.ni_vp)
252
vrele(tond.ni_dvp);
253
@@ -2586,7 +2588,11 @@
254
}
255
if (tond.ni_vp)
256
vput(tond.ni_vp);
257
-
258
+ if (tdirp)
259
+ vrele(tdirp);
260
+ if (tond.ni_startdir)
261
+ vrele(tond.ni_startdir);
262
+ NDFREE(&tond, NDF_ONLY_PNBUF);
263
/*
264
* Clear out fromnd related fields
265
*/
266
@@ -2747,8 +2753,6 @@
267
NFSD_UNLOCK();
268
mtx_lock(&Giant); /* VFS */
269
NDFREE(&nd, NDF_ONLY_PNBUF);
270
- if (dirp)
271
- vrele(dirp);
272
if (vp)
273
vput(vp);
274
if (nd.ni_dvp) {
275
@@ -2757,6 +2761,8 @@
276
else
277
vput(nd.ni_dvp);
278
}
279
+ if (dirp)
280
+ vrele(dirp);
281
if (nd.ni_vp)
282
vrele(nd.ni_vp);
283
vn_finished_write(mp);
284
@@ -2815,6 +2821,12 @@
285
nd.ni_cnd.cn_flags = LOCKPARENT | SAVESTART;
286
error = nfs_namei(&nd, fhp, len, slp, nam, &md, &dpos,
287
&dirp, v3, &dirfor, &dirfor_ret, td, FALSE);
288
+ if (error == 0) {
289
+ VATTR_NULL(vap);
290
+ if (v3)
291
+ nfsm_srvsattr(vap);
292
+ nfsm_srvpathsiz(len2);
293
+ }
294
NFSD_UNLOCK();
295
mtx_lock(&Giant); /* VFS */
296
if (dirp && !v3) {
297
@@ -2824,10 +2836,6 @@
298
if (error)
299
goto out;
300
301
- VATTR_NULL(vap);
302
- if (v3)
303
- nfsm_srvsattr(vap);
304
- nfsm_srvpathsiz(len2);
305
MALLOC(pathcp, caddr_t, len2 + 1, M_TEMP, M_WAITOK);
306
iv.iov_base = pathcp;
307
iv.iov_len = len2;
308
@@ -2884,6 +2892,10 @@
309
310
error = lookup(&nd);
311
nd.ni_dvp = NULL;
312
+ if (nd.ni_cnd.cn_flags & GIANTHELD) {
313
+ mtx_unlock(&Giant);
314
+ nd.ni_cnd.cn_flags &= ~GIANTHELD;
315
+ }
316
317
if (error == 0) {
318
bzero((caddr_t)fhp, sizeof(nfh));
319
@@ -3113,8 +3125,6 @@
320
NFSD_LOCK_ASSERT();
321
NFSD_UNLOCK();
322
mtx_lock(&Giant); /* VFS */
323
- if (dirp)
324
- vrele(dirp);
325
if (nd.ni_dvp) {
326
NDFREE(&nd, NDF_ONLY_PNBUF);
327
if (nd.ni_dvp == nd.ni_vp && vpexcl)
328
@@ -3128,6 +3138,8 @@
329
else
330
vrele(nd.ni_vp);
331
}
332
+ if (dirp)
333
+ vrele(dirp);
334
vn_finished_write(mp);
335
mtx_unlock(&Giant); /* VFS */
336
NFSD_LOCK();
337
@@ -3255,8 +3267,6 @@
338
NFSD_UNLOCK();
339
mtx_lock(&Giant); /* VFS */
340
NDFREE(&nd, NDF_ONLY_PNBUF);
341
- if (dirp)
342
- vrele(dirp);
343
if (nd.ni_dvp) {
344
if (nd.ni_dvp == nd.ni_vp)
345
vrele(nd.ni_dvp);
346
@@ -3265,6 +3275,8 @@
347
}
348
if (nd.ni_vp)
349
vput(nd.ni_vp);
350
+ if (dirp)
351
+ vrele(dirp);
352
353
vn_finished_write(mp);
354
mtx_unlock(&Giant); /* VFS */
355
Index: sys/nfsserver/nfs_srvsubs.c
356
===================================================================
357
RCS file: /home/ncvs/src/sys/nfsserver/nfs_srvsubs.c,v
358
retrieving revision 1.136
359
diff -u -r1.136 nfs_srvsubs.c
360
--- sys/nfsserver/nfs_srvsubs.c 28 Mar 2005 18:51:58 -0000 1.136
361
+++ sys/nfsserver/nfs_srvsubs.c 13 Feb 2007 20:43:09 -0000
362
@@ -875,6 +875,10 @@
363
}
364
if (!lockleaf)
365
cnp->cn_flags &= ~LOCKLEAF;
366
+ if (cnp->cn_flags & GIANTHELD) {
367
+ mtx_unlock(&Giant);
368
+ cnp->cn_flags &= ~GIANTHELD;
369
+ }
370
371
/*
372
* nfs_namei() guarentees that fields will not contain garbage
373
@@ -1331,6 +1335,24 @@
374
return 0;
375
}
376
377
+int
378
+nfsm_srvnamesiz0_xx(int *s, int m, struct mbuf **md, caddr_t *dpos)
379
+{
380
+ u_int32_t *tl;
381
+
382
+ NFSD_LOCK_DONTCARE();
383
+
384
+ tl = nfsm_dissect_xx_nonblock(NFSX_UNSIGNED, md, dpos);
385
+ if (tl == NULL)
386
+ return EBADRPC;
387
+ *s = fxdr_unsigned(int32_t, *tl);
388
+ if (*s > m)
389
+ return NFSERR_NAMETOL;
390
+ if (*s < 0)
391
+ return EBADRPC;
392
+ return 0;
393
+}
394
+
395
void
396
nfsm_clget_xx(u_int32_t **tl, struct mbuf *mb, struct mbuf **mp,
397
char **bp, char **be, caddr_t bpos, int droplock)
398
Index: sys/nfsserver/nfsm_subs.h
399
===================================================================
400
RCS file: /home/ncvs/src/sys/nfsserver/nfsm_subs.h,v
401
retrieving revision 1.37
402
diff -u -r1.37 nfsm_subs.h
403
--- sys/nfsserver/nfsm_subs.h 7 Jan 2005 01:45:51 -0000 1.37
404
+++ sys/nfsserver/nfsm_subs.h 13 Feb 2007 20:43:09 -0000
405
@@ -74,6 +74,7 @@
406
407
int nfsm_srvstrsiz_xx(int *s, int m, struct mbuf **md, caddr_t *dpos);
408
int nfsm_srvnamesiz_xx(int *s, int m, struct mbuf **md, caddr_t *dpos);
409
+int nfsm_srvnamesiz0_xx(int *s, int m, struct mbuf **md, caddr_t *dpos);
410
int nfsm_srvmtofh_xx(fhandle_t *f, struct nfsrv_descript *nfsd,
411
struct mbuf **md, caddr_t *dpos);
412
int nfsm_srvsattr_xx(struct vattr *a, struct mbuf **md, caddr_t *dpos);
413
@@ -101,7 +102,7 @@
414
#define nfsm_srvpathsiz(s) \
415
do { \
416
int t1; \
417
- t1 = nfsm_srvnamesiz_xx(&(s), NFS_MAXPATHLEN, &md, &dpos); \
418
+ t1 = nfsm_srvnamesiz0_xx(&(s), NFS_MAXPATHLEN, &md, &dpos); \
419
if (t1) { \
420
error = t1; \
421
nfsm_reply(0); \
422
423