1 |
+ |
/* $MidnightBSD$ */ |
2 |
|
/*- |
3 |
|
* Copyright (c) 1999-2001 Robert N. M. Watson |
4 |
|
* All rights reserved. |
28 |
|
*/ |
29 |
|
|
30 |
|
#include <sys/cdefs.h> |
31 |
< |
__FBSDID("$MidnightBSD$"); |
31 |
> |
__FBSDID("$FreeBSD: stable/10/sys/kern/vfs_extattr.c 280258 2015-03-19 13:37:36Z rwatson $"); |
32 |
|
|
33 |
|
#include <sys/param.h> |
34 |
|
#include <sys/systm.h> |
35 |
< |
#include <sys/capability.h> |
35 |
> |
#include <sys/capsicum.h> |
36 |
|
#include <sys/lock.h> |
37 |
|
#include <sys/mount.h> |
38 |
|
#include <sys/mutex.h> |
70 |
|
struct nameidata nd; |
71 |
|
struct mount *mp, *mp_writable; |
72 |
|
char attrname[EXTATTR_MAXNAMELEN]; |
73 |
< |
int vfslocked, fnvfslocked, error; |
73 |
> |
int error; |
74 |
|
|
75 |
|
AUDIT_ARG_CMD(uap->cmd); |
76 |
|
AUDIT_ARG_VALUE(uap->attrnamespace); |
86 |
|
} |
87 |
|
AUDIT_ARG_TEXT(attrname); |
88 |
|
|
88 |
– |
vfslocked = fnvfslocked = 0; |
89 |
|
mp = NULL; |
90 |
|
filename_vp = NULL; |
91 |
|
if (uap->filename != NULL) { |
92 |
< |
NDINIT(&nd, LOOKUP, MPSAFE | FOLLOW | AUDITVNODE2, |
92 |
> |
NDINIT(&nd, LOOKUP, FOLLOW | AUDITVNODE2, |
93 |
|
UIO_USERSPACE, uap->filename, td); |
94 |
|
error = namei(&nd); |
95 |
|
if (error) |
96 |
|
return (error); |
97 |
– |
fnvfslocked = NDHASGIANT(&nd); |
97 |
|
filename_vp = nd.ni_vp; |
98 |
|
NDFREE(&nd, NDF_NO_VP_RELE); |
99 |
|
} |
100 |
|
|
101 |
|
/* uap->path is always defined. */ |
102 |
< |
NDINIT(&nd, LOOKUP, MPSAFE | FOLLOW | LOCKLEAF | AUDITVNODE1, |
102 |
> |
NDINIT(&nd, LOOKUP, FOLLOW | LOCKLEAF | AUDITVNODE1, |
103 |
|
UIO_USERSPACE, uap->path, td); |
104 |
|
error = namei(&nd); |
105 |
|
if (error) |
106 |
|
goto out; |
108 |
– |
vfslocked = NDHASGIANT(&nd); |
107 |
|
mp = nd.ni_vp->v_mount; |
108 |
|
error = vfs_busy(mp, 0); |
109 |
|
if (error) { |
143 |
|
*/ |
144 |
|
if (filename_vp != NULL) |
145 |
|
vrele(filename_vp); |
148 |
– |
VFS_UNLOCK_GIANT(fnvfslocked); |
149 |
– |
VFS_UNLOCK_GIANT(vfslocked); |
146 |
|
return (error); |
147 |
|
} |
148 |
|
|
166 |
|
ssize_t cnt; |
167 |
|
int error; |
168 |
|
|
173 |
– |
VFS_ASSERT_GIANT(vp->v_mount); |
169 |
|
error = vn_start_write(vp, &mp, V_WAIT | PCATCH); |
170 |
|
if (error) |
171 |
|
return (error); |
217 |
|
{ |
218 |
|
struct file *fp; |
219 |
|
char attrname[EXTATTR_MAXNAMELEN]; |
220 |
< |
int vfslocked, error; |
220 |
> |
cap_rights_t rights; |
221 |
> |
int error; |
222 |
|
|
223 |
|
AUDIT_ARG_FD(uap->fd); |
224 |
|
AUDIT_ARG_VALUE(uap->attrnamespace); |
227 |
|
return (error); |
228 |
|
AUDIT_ARG_TEXT(attrname); |
229 |
|
|
230 |
< |
error = getvnode(td->td_proc->p_fd, uap->fd, CAP_EXTATTR_SET, &fp); |
230 |
> |
error = getvnode(td->td_proc->p_fd, uap->fd, |
231 |
> |
cap_rights_init(&rights, CAP_EXTATTR_SET), &fp); |
232 |
|
if (error) |
233 |
|
return (error); |
234 |
|
|
238 |
– |
vfslocked = VFS_LOCK_GIANT(fp->f_vnode->v_mount); |
235 |
|
error = extattr_set_vp(fp->f_vnode, uap->attrnamespace, |
236 |
|
attrname, uap->data, uap->nbytes, td); |
237 |
|
fdrop(fp, td); |
242 |
– |
VFS_UNLOCK_GIANT(vfslocked); |
238 |
|
|
239 |
|
return (error); |
240 |
|
} |
252 |
|
{ |
253 |
|
struct nameidata nd; |
254 |
|
char attrname[EXTATTR_MAXNAMELEN]; |
255 |
< |
int vfslocked, error; |
255 |
> |
int error; |
256 |
|
|
257 |
|
AUDIT_ARG_VALUE(uap->attrnamespace); |
258 |
|
error = copyinstr(uap->attrname, attrname, EXTATTR_MAXNAMELEN, NULL); |
260 |
|
return (error); |
261 |
|
AUDIT_ARG_TEXT(attrname); |
262 |
|
|
263 |
< |
NDINIT(&nd, LOOKUP, MPSAFE | FOLLOW | AUDITVNODE1, UIO_USERSPACE, |
263 |
> |
NDINIT(&nd, LOOKUP, FOLLOW | AUDITVNODE1, UIO_USERSPACE, |
264 |
|
uap->path, td); |
265 |
|
error = namei(&nd); |
266 |
|
if (error) |
267 |
|
return (error); |
268 |
|
NDFREE(&nd, NDF_ONLY_PNBUF); |
269 |
|
|
275 |
– |
vfslocked = NDHASGIANT(&nd); |
270 |
|
error = extattr_set_vp(nd.ni_vp, uap->attrnamespace, attrname, |
271 |
|
uap->data, uap->nbytes, td); |
272 |
|
|
273 |
|
vrele(nd.ni_vp); |
280 |
– |
VFS_UNLOCK_GIANT(vfslocked); |
274 |
|
return (error); |
275 |
|
} |
276 |
|
|
287 |
|
{ |
288 |
|
struct nameidata nd; |
289 |
|
char attrname[EXTATTR_MAXNAMELEN]; |
290 |
< |
int vfslocked, error; |
290 |
> |
int error; |
291 |
|
|
292 |
|
AUDIT_ARG_VALUE(uap->attrnamespace); |
293 |
|
error = copyinstr(uap->attrname, attrname, EXTATTR_MAXNAMELEN, NULL); |
295 |
|
return (error); |
296 |
|
AUDIT_ARG_TEXT(attrname); |
297 |
|
|
298 |
< |
NDINIT(&nd, LOOKUP, MPSAFE | NOFOLLOW | AUDITVNODE1, UIO_USERSPACE, |
298 |
> |
NDINIT(&nd, LOOKUP, NOFOLLOW | AUDITVNODE1, UIO_USERSPACE, |
299 |
|
uap->path, td); |
300 |
|
error = namei(&nd); |
301 |
|
if (error) |
302 |
|
return (error); |
303 |
|
NDFREE(&nd, NDF_ONLY_PNBUF); |
304 |
|
|
312 |
– |
vfslocked = NDHASGIANT(&nd); |
305 |
|
error = extattr_set_vp(nd.ni_vp, uap->attrnamespace, attrname, |
306 |
|
uap->data, uap->nbytes, td); |
307 |
|
|
308 |
|
vrele(nd.ni_vp); |
317 |
– |
VFS_UNLOCK_GIANT(vfslocked); |
309 |
|
return (error); |
310 |
|
} |
311 |
|
|
329 |
|
size_t size, *sizep; |
330 |
|
int error; |
331 |
|
|
341 |
– |
VFS_ASSERT_GIANT(vp->v_mount); |
332 |
|
vn_lock(vp, LK_SHARED | LK_RETRY); |
333 |
|
|
334 |
|
/* |
392 |
|
{ |
393 |
|
struct file *fp; |
394 |
|
char attrname[EXTATTR_MAXNAMELEN]; |
395 |
< |
int vfslocked, error; |
395 |
> |
cap_rights_t rights; |
396 |
> |
int error; |
397 |
|
|
398 |
|
AUDIT_ARG_FD(uap->fd); |
399 |
|
AUDIT_ARG_VALUE(uap->attrnamespace); |
402 |
|
return (error); |
403 |
|
AUDIT_ARG_TEXT(attrname); |
404 |
|
|
405 |
< |
error = getvnode(td->td_proc->p_fd, uap->fd, CAP_EXTATTR_GET, &fp); |
405 |
> |
error = getvnode(td->td_proc->p_fd, uap->fd, |
406 |
> |
cap_rights_init(&rights, CAP_EXTATTR_GET), &fp); |
407 |
|
if (error) |
408 |
|
return (error); |
409 |
|
|
418 |
– |
vfslocked = VFS_LOCK_GIANT(fp->f_vnode->v_mount); |
410 |
|
error = extattr_get_vp(fp->f_vnode, uap->attrnamespace, |
411 |
|
attrname, uap->data, uap->nbytes, td); |
412 |
|
|
413 |
|
fdrop(fp, td); |
423 |
– |
VFS_UNLOCK_GIANT(vfslocked); |
414 |
|
return (error); |
415 |
|
} |
416 |
|
|
427 |
|
{ |
428 |
|
struct nameidata nd; |
429 |
|
char attrname[EXTATTR_MAXNAMELEN]; |
430 |
< |
int vfslocked, error; |
430 |
> |
int error; |
431 |
|
|
432 |
|
AUDIT_ARG_VALUE(uap->attrnamespace); |
433 |
|
error = copyinstr(uap->attrname, attrname, EXTATTR_MAXNAMELEN, NULL); |
435 |
|
return (error); |
436 |
|
AUDIT_ARG_TEXT(attrname); |
437 |
|
|
438 |
< |
NDINIT(&nd, LOOKUP, MPSAFE | FOLLOW | AUDITVNODE1, UIO_USERSPACE, |
449 |
< |
uap->path, td); |
438 |
> |
NDINIT(&nd, LOOKUP, FOLLOW | AUDITVNODE1, UIO_USERSPACE, uap->path, td); |
439 |
|
error = namei(&nd); |
440 |
|
if (error) |
441 |
|
return (error); |
442 |
|
NDFREE(&nd, NDF_ONLY_PNBUF); |
443 |
|
|
455 |
– |
vfslocked = NDHASGIANT(&nd); |
444 |
|
error = extattr_get_vp(nd.ni_vp, uap->attrnamespace, attrname, |
445 |
|
uap->data, uap->nbytes, td); |
446 |
|
|
447 |
|
vrele(nd.ni_vp); |
460 |
– |
VFS_UNLOCK_GIANT(vfslocked); |
448 |
|
return (error); |
449 |
|
} |
450 |
|
|
461 |
|
{ |
462 |
|
struct nameidata nd; |
463 |
|
char attrname[EXTATTR_MAXNAMELEN]; |
464 |
< |
int vfslocked, error; |
464 |
> |
int error; |
465 |
|
|
466 |
|
AUDIT_ARG_VALUE(uap->attrnamespace); |
467 |
|
error = copyinstr(uap->attrname, attrname, EXTATTR_MAXNAMELEN, NULL); |
469 |
|
return (error); |
470 |
|
AUDIT_ARG_TEXT(attrname); |
471 |
|
|
472 |
< |
NDINIT(&nd, LOOKUP, MPSAFE | NOFOLLOW | AUDITVNODE1, UIO_USERSPACE, |
473 |
< |
uap->path, td); |
472 |
> |
NDINIT(&nd, LOOKUP, NOFOLLOW | AUDITVNODE1, UIO_USERSPACE, uap->path, |
473 |
> |
td); |
474 |
|
error = namei(&nd); |
475 |
|
if (error) |
476 |
|
return (error); |
477 |
|
NDFREE(&nd, NDF_ONLY_PNBUF); |
478 |
|
|
492 |
– |
vfslocked = NDHASGIANT(&nd); |
479 |
|
error = extattr_get_vp(nd.ni_vp, uap->attrnamespace, attrname, |
480 |
|
uap->data, uap->nbytes, td); |
481 |
|
|
482 |
|
vrele(nd.ni_vp); |
497 |
– |
VFS_UNLOCK_GIANT(vfslocked); |
483 |
|
return (error); |
484 |
|
} |
485 |
|
|
500 |
|
struct mount *mp; |
501 |
|
int error; |
502 |
|
|
518 |
– |
VFS_ASSERT_GIANT(vp->v_mount); |
503 |
|
error = vn_start_write(vp, &mp, V_WAIT | PCATCH); |
504 |
|
if (error) |
505 |
|
return (error); |
536 |
|
{ |
537 |
|
struct file *fp; |
538 |
|
char attrname[EXTATTR_MAXNAMELEN]; |
539 |
< |
int vfslocked, error; |
539 |
> |
cap_rights_t rights; |
540 |
> |
int error; |
541 |
|
|
542 |
|
AUDIT_ARG_FD(uap->fd); |
543 |
|
AUDIT_ARG_VALUE(uap->attrnamespace); |
546 |
|
return (error); |
547 |
|
AUDIT_ARG_TEXT(attrname); |
548 |
|
|
549 |
< |
error = getvnode(td->td_proc->p_fd, uap->fd, CAP_EXTATTR_DELETE, |
550 |
< |
&fp); |
549 |
> |
error = getvnode(td->td_proc->p_fd, uap->fd, |
550 |
> |
cap_rights_init(&rights, CAP_EXTATTR_DELETE), &fp); |
551 |
|
if (error) |
552 |
|
return (error); |
553 |
|
|
569 |
– |
vfslocked = VFS_LOCK_GIANT(fp->f_vnode->v_mount); |
554 |
|
error = extattr_delete_vp(fp->f_vnode, uap->attrnamespace, |
555 |
|
attrname, td); |
556 |
|
fdrop(fp, td); |
573 |
– |
VFS_UNLOCK_GIANT(vfslocked); |
557 |
|
return (error); |
558 |
|
} |
559 |
|
|
568 |
|
{ |
569 |
|
struct nameidata nd; |
570 |
|
char attrname[EXTATTR_MAXNAMELEN]; |
571 |
< |
int vfslocked, error; |
571 |
> |
int error; |
572 |
|
|
573 |
|
AUDIT_ARG_VALUE(uap->attrnamespace); |
574 |
|
error = copyinstr(uap->attrname, attrname, EXTATTR_MAXNAMELEN, NULL); |
576 |
|
return(error); |
577 |
|
AUDIT_ARG_TEXT(attrname); |
578 |
|
|
579 |
< |
NDINIT(&nd, LOOKUP, MPSAFE | FOLLOW | AUDITVNODE1, UIO_USERSPACE, |
597 |
< |
uap->path, td); |
579 |
> |
NDINIT(&nd, LOOKUP, FOLLOW | AUDITVNODE1, UIO_USERSPACE, uap->path, td); |
580 |
|
error = namei(&nd); |
581 |
|
if (error) |
582 |
|
return(error); |
583 |
|
NDFREE(&nd, NDF_ONLY_PNBUF); |
584 |
|
|
603 |
– |
vfslocked = NDHASGIANT(&nd); |
585 |
|
error = extattr_delete_vp(nd.ni_vp, uap->attrnamespace, attrname, td); |
586 |
|
vrele(nd.ni_vp); |
606 |
– |
VFS_UNLOCK_GIANT(vfslocked); |
587 |
|
return(error); |
588 |
|
} |
589 |
|
|
598 |
|
{ |
599 |
|
struct nameidata nd; |
600 |
|
char attrname[EXTATTR_MAXNAMELEN]; |
601 |
< |
int vfslocked, error; |
601 |
> |
int error; |
602 |
|
|
603 |
|
AUDIT_ARG_VALUE(uap->attrnamespace); |
604 |
|
error = copyinstr(uap->attrname, attrname, EXTATTR_MAXNAMELEN, NULL); |
606 |
|
return(error); |
607 |
|
AUDIT_ARG_TEXT(attrname); |
608 |
|
|
609 |
< |
NDINIT(&nd, LOOKUP, MPSAFE | NOFOLLOW | AUDITVNODE1, UIO_USERSPACE, |
630 |
< |
uap->path, td); |
609 |
> |
NDINIT(&nd, LOOKUP, NOFOLLOW | AUDITVNODE1, UIO_USERSPACE, uap->path, td); |
610 |
|
error = namei(&nd); |
611 |
|
if (error) |
612 |
|
return(error); |
613 |
|
NDFREE(&nd, NDF_ONLY_PNBUF); |
614 |
|
|
636 |
– |
vfslocked = NDHASGIANT(&nd); |
615 |
|
error = extattr_delete_vp(nd.ni_vp, uap->attrnamespace, attrname, td); |
616 |
|
vrele(nd.ni_vp); |
639 |
– |
VFS_UNLOCK_GIANT(vfslocked); |
617 |
|
return(error); |
618 |
|
} |
619 |
|
|
637 |
|
ssize_t cnt; |
638 |
|
int error; |
639 |
|
|
663 |
– |
VFS_ASSERT_GIANT(vp->v_mount); |
640 |
|
vn_lock(vp, LK_EXCLUSIVE | LK_RETRY); |
641 |
|
|
642 |
|
auiop = NULL; |
693 |
|
} */ *uap; |
694 |
|
{ |
695 |
|
struct file *fp; |
696 |
< |
int vfslocked, error; |
696 |
> |
cap_rights_t rights; |
697 |
> |
int error; |
698 |
|
|
699 |
|
AUDIT_ARG_FD(uap->fd); |
700 |
|
AUDIT_ARG_VALUE(uap->attrnamespace); |
701 |
< |
error = getvnode(td->td_proc->p_fd, uap->fd, CAP_EXTATTR_LIST, &fp); |
701 |
> |
error = getvnode(td->td_proc->p_fd, uap->fd, |
702 |
> |
cap_rights_init(&rights, CAP_EXTATTR_LIST), &fp); |
703 |
|
if (error) |
704 |
|
return (error); |
705 |
|
|
728 |
– |
vfslocked = VFS_LOCK_GIANT(fp->f_vnode->v_mount); |
706 |
|
error = extattr_list_vp(fp->f_vnode, uap->attrnamespace, uap->data, |
707 |
|
uap->nbytes, td); |
708 |
|
|
709 |
|
fdrop(fp, td); |
733 |
– |
VFS_UNLOCK_GIANT(vfslocked); |
710 |
|
return (error); |
711 |
|
} |
712 |
|
|
721 |
|
} */ *uap; |
722 |
|
{ |
723 |
|
struct nameidata nd; |
724 |
< |
int vfslocked, error; |
724 |
> |
int error; |
725 |
|
|
726 |
|
AUDIT_ARG_VALUE(uap->attrnamespace); |
727 |
< |
NDINIT(&nd, LOOKUP, MPSAFE | FOLLOW | AUDITVNODE1, UIO_USERSPACE, |
752 |
< |
uap->path, td); |
727 |
> |
NDINIT(&nd, LOOKUP, FOLLOW | AUDITVNODE1, UIO_USERSPACE, uap->path, td); |
728 |
|
error = namei(&nd); |
729 |
|
if (error) |
730 |
|
return (error); |
731 |
|
NDFREE(&nd, NDF_ONLY_PNBUF); |
732 |
|
|
758 |
– |
vfslocked = NDHASGIANT(&nd); |
733 |
|
error = extattr_list_vp(nd.ni_vp, uap->attrnamespace, uap->data, |
734 |
|
uap->nbytes, td); |
735 |
|
|
736 |
|
vrele(nd.ni_vp); |
763 |
– |
VFS_UNLOCK_GIANT(vfslocked); |
737 |
|
return (error); |
738 |
|
} |
739 |
|
|
748 |
|
} */ *uap; |
749 |
|
{ |
750 |
|
struct nameidata nd; |
751 |
< |
int vfslocked, error; |
751 |
> |
int error; |
752 |
|
|
753 |
|
AUDIT_ARG_VALUE(uap->attrnamespace); |
754 |
< |
NDINIT(&nd, LOOKUP, MPSAFE | NOFOLLOW | AUDITVNODE1, UIO_USERSPACE, |
755 |
< |
uap->path, td); |
754 |
> |
NDINIT(&nd, LOOKUP, NOFOLLOW | AUDITVNODE1, UIO_USERSPACE, uap->path, |
755 |
> |
td); |
756 |
|
error = namei(&nd); |
757 |
|
if (error) |
758 |
|
return (error); |
759 |
|
NDFREE(&nd, NDF_ONLY_PNBUF); |
760 |
|
|
788 |
– |
vfslocked = NDHASGIANT(&nd); |
761 |
|
error = extattr_list_vp(nd.ni_vp, uap->attrnamespace, uap->data, |
762 |
|
uap->nbytes, td); |
763 |
|
|
764 |
|
vrele(nd.ni_vp); |
793 |
– |
VFS_UNLOCK_GIANT(vfslocked); |
765 |
|
return (error); |
766 |
|
} |