vfs_extattr.c (762e6b856c64ee48f286a7f0b45d0067e556b252) | vfs_extattr.c (91f37dcba1648b1f24e2913c3ab78fc4eae35991) |
---|---|
1/* 2 * Copyright (c) 1989, 1993 3 * The Regents of the University of California. All rights reserved. 4 * (c) UNIX System Laboratories, Inc. 5 * All or some portions of this file are derived from material licensed 6 * to the University of California by American Telephone and Telegraph 7 * Co. or Unix System Laboratories, Inc. and are reproduced herein with 8 * the permission of UNIX System Laboratories, Inc. --- 46 unchanged lines hidden (view full) --- 55#include <sys/fcntl.h> 56#include <sys/file.h> 57#include <sys/linker.h> 58#include <sys/stat.h> 59#include <sys/unistd.h> 60#include <sys/vnode.h> 61#include <sys/proc.h> 62#include <sys/dirent.h> | 1/* 2 * Copyright (c) 1989, 1993 3 * The Regents of the University of California. All rights reserved. 4 * (c) UNIX System Laboratories, Inc. 5 * All or some portions of this file are derived from material licensed 6 * to the University of California by American Telephone and Telegraph 7 * Co. or Unix System Laboratories, Inc. and are reproduced herein with 8 * the permission of UNIX System Laboratories, Inc. --- 46 unchanged lines hidden (view full) --- 55#include <sys/fcntl.h> 56#include <sys/file.h> 57#include <sys/linker.h> 58#include <sys/stat.h> 59#include <sys/unistd.h> 60#include <sys/vnode.h> 61#include <sys/proc.h> 62#include <sys/dirent.h> |
63#include <sys/extattr.h> |
|
63 | 64 |
65#include <machine/limits.h> |
|
64#include <miscfs/union/union.h> | 66#include <miscfs/union/union.h> |
65 | 67#include <sys/sysctl.h> |
66#include <vm/vm.h> 67#include <vm/vm_object.h> 68#include <vm/vm_zone.h> | 68#include <vm/vm.h> 69#include <vm/vm_object.h> 70#include <vm/vm_zone.h> |
69#include <sys/sysctl.h> | |
70 71static int change_dir __P((struct nameidata *ndp, struct proc *p)); 72static void checkdirs __P((struct vnode *olddp)); 73static int chroot_refuse_vdir_fds __P((struct filedesc *fdp)); 74static int getutimes __P((const struct timeval *, struct timespec *)); 75static int setfown __P((struct proc *, struct vnode *, uid_t, gid_t)); 76static int setfmode __P((struct proc *, struct vnode *, int)); 77static int setfflags __P((struct proc *, struct vnode *, int)); --- 3279 unchanged lines hidden (view full) --- 3357 sp->f_flags = mp->mnt_flag & MNT_VISFLAGMASK; 3358 if (suser_xxx(p->p_ucred, 0, 0)) { 3359 bcopy((caddr_t)sp, (caddr_t)&sb, sizeof(sb)); 3360 sb.f_fsid.val[0] = sb.f_fsid.val[1] = 0; 3361 sp = &sb; 3362 } 3363 return (copyout(sp, SCARG(uap, buf), sizeof(*sp))); 3364} | 71 72static int change_dir __P((struct nameidata *ndp, struct proc *p)); 73static void checkdirs __P((struct vnode *olddp)); 74static int chroot_refuse_vdir_fds __P((struct filedesc *fdp)); 75static int getutimes __P((const struct timeval *, struct timespec *)); 76static int setfown __P((struct proc *, struct vnode *, uid_t, gid_t)); 77static int setfmode __P((struct proc *, struct vnode *, int)); 78static int setfflags __P((struct proc *, struct vnode *, int)); --- 3279 unchanged lines hidden (view full) --- 3358 sp->f_flags = mp->mnt_flag & MNT_VISFLAGMASK; 3359 if (suser_xxx(p->p_ucred, 0, 0)) { 3360 bcopy((caddr_t)sp, (caddr_t)&sb, sizeof(sb)); 3361 sb.f_fsid.val[0] = sb.f_fsid.val[1] = 0; 3362 sp = &sb; 3363 } 3364 return (copyout(sp, SCARG(uap, buf), sizeof(*sp))); 3365} |
3366 3367/* 3368 * Syscall to push extended attribute configuration information into the 3369 * VFS. Accepts a path, which it converts to a mountpoint, as well as 3370 * a command (int cmd), and attribute name and misc data. For now, the 3371 * attribute name is left in userspace for consumption by the VFS_op. 3372 * It will probably be changed to be copied into sysspace by the 3373 * syscall in the future, once issues with various consumers of the 3374 * attribute code have raised their hands. 3375 * 3376 * Currently this is used only by UFS Extended Attributes. 3377 */ 3378int 3379extattrctl(p, uap) 3380 struct proc *p; 3381 struct extattrctl_args *uap; 3382{ 3383 struct nameidata nd; 3384 struct mount *mp; 3385 int error; 3386 3387 NDINIT(&nd, LOOKUP, FOLLOW, UIO_USERSPACE, SCARG(uap, path), p); 3388 if ((error = namei(&nd)) != 0) 3389 return (error); 3390 mp = nd.ni_vp->v_mount; 3391 NDFREE(&nd, 0); 3392 return (VFS_EXTATTRCTL(mp, SCARG(uap, cmd), SCARG(uap, attrname), 3393 SCARG(uap, arg), p)); 3394} 3395 3396/* 3397 * Syscall to set a named extended attribute on a file or directory. 3398 * Accepts attribute name, and a uio structure pointing to the data to set. 3399 * The uio is consumed in the style of writev(). The real work happens 3400 * in VOP_SETEXTATTR(). 3401 */ 3402int 3403extattr_set_file(p, uap) 3404 struct proc *p; 3405 struct extattr_set_file_args *uap; 3406{ 3407 struct nameidata nd; 3408 struct uio auio; 3409 struct iovec *iov, *needfree = NULL, aiov[UIO_SMALLIOV]; 3410 char attrname[EXTATTR_MAXNAMELEN]; 3411 u_int iovlen, cnt; 3412 int error, i; 3413 3414 error = copyin(SCARG(uap, attrname), attrname, EXTATTR_MAXNAMELEN); 3415 if (error) 3416 return (error); 3417 NDINIT(&nd, LOOKUP, LOCKLEAF | FOLLOW, UIO_USERSPACE, SCARG(uap, path), 3418 p); 3419 if ((error = namei(&nd)) != 0) 3420 return(error); 3421 iovlen = uap->iovcnt * sizeof(struct iovec); 3422 if (uap->iovcnt > UIO_SMALLIOV) { 3423 if (uap->iovcnt > UIO_MAXIOV) { 3424 error = EINVAL; 3425 goto done; 3426 } 3427 MALLOC(iov, struct iovec *, iovlen, M_IOV, M_WAITOK); 3428 needfree = iov; 3429 } else 3430 iov = aiov; 3431 auio.uio_iov = iov; 3432 auio.uio_iovcnt = uap->iovcnt; 3433 auio.uio_rw = UIO_WRITE; 3434 auio.uio_segflg = UIO_USERSPACE; 3435 auio.uio_procp = p; 3436 auio.uio_offset = 0; 3437 if ((error = copyin((caddr_t)uap->iovp, (caddr_t)iov, iovlen))) 3438 goto done; 3439 auio.uio_resid = 0; 3440 for (i = 0; i < uap->iovcnt; i++) { 3441 if (iov->iov_len > INT_MAX - auio.uio_resid) { 3442 error = EINVAL; 3443 goto done; 3444 } 3445 auio.uio_resid += iov->iov_len; 3446 iov++; 3447 } 3448 cnt = auio.uio_resid; 3449 error = VOP_SETEXTATTR(nd.ni_vp, attrname, &auio, p->p_cred->pc_ucred, 3450 p); 3451 if (auio.uio_resid != cnt && (error == ERESTART || 3452 error == EINTR || error == EWOULDBLOCK)) 3453 error = 0; 3454 cnt -= auio.uio_resid; 3455 p->p_retval[0] = cnt; 3456done: 3457 if (needfree) 3458 FREE(needfree, M_IOV); 3459 NDFREE(&nd, 0); 3460 return (error); 3461} 3462 3463/* 3464 * Syscall to get a named extended attribute on a file or directory. 3465 * Accepts attribute name, and a uio structure pointing to a buffer for the 3466 * data. The uio is consumed in the style of readv(). The real work 3467 * happens in VOP_GETEXTATTR(); 3468 */ 3469int 3470extattr_get_file(p, uap) 3471 struct proc *p; 3472 struct extattr_get_file_args *uap; 3473{ 3474 struct nameidata nd; 3475 struct uio auio; 3476 struct iovec *iov, *needfree, aiov[UIO_SMALLIOV]; 3477 char attrname[EXTATTR_MAXNAMELEN]; 3478 u_int iovlen, cnt; 3479 int error, i; 3480 3481 error = copyin(SCARG(uap, attrname), attrname, EXTATTR_MAXNAMELEN); 3482 if (error) 3483 return (error); 3484 NDINIT(&nd, LOOKUP, FOLLOW, UIO_USERSPACE, SCARG(uap, path), p); 3485 if ((error = namei(&nd)) != 0) 3486 return (error); 3487 iovlen = uap->iovcnt * sizeof (struct iovec); 3488 if (uap->iovcnt > UIO_SMALLIOV) { 3489 if (uap->iovcnt > UIO_MAXIOV) { 3490 NDFREE(&nd, 0); 3491 return (EINVAL); 3492 } 3493 MALLOC(iov, struct iovec *, iovlen, M_IOV, M_WAITOK); 3494 needfree = iov; 3495 } else { 3496 iov = aiov; 3497 needfree = NULL; 3498 } 3499 auio.uio_iov = iov; 3500 auio.uio_iovcnt = uap->iovcnt; 3501 auio.uio_rw = UIO_READ; 3502 auio.uio_segflg = UIO_USERSPACE; 3503 auio.uio_procp = p; 3504 auio.uio_offset = 0; 3505 if ((error = copyin((caddr_t)uap->iovp, (caddr_t)iov, iovlen))) 3506 goto done; 3507 auio.uio_resid = 0; 3508 for (i = 0; i < uap->iovcnt; i++) { 3509 if (iov->iov_len > INT_MAX - auio.uio_resid) { 3510 error = EINVAL; 3511 goto done; 3512 } 3513 auio.uio_resid += iov->iov_len; 3514 iov++; 3515 } 3516 cnt = auio.uio_resid; 3517 error = VOP_GETEXTATTR(nd.ni_vp, attrname, &auio, p->p_cred->pc_ucred, 3518 p); 3519 if (auio.uio_resid != cnt && (error == ERESTART || 3520 error == EINTR || error == EWOULDBLOCK)) 3521 error = 0; 3522 cnt -= auio.uio_resid; 3523 p->p_retval[0] = cnt; 3524done: 3525 if (needfree) 3526 FREE(needfree, M_IOV); 3527 NDFREE(&nd, 0); 3528 return(error); 3529} 3530 3531/* 3532 * Syscall to delete a named extended attribute from a file or directory. 3533 * Accepts attribute name. The real work happens in VOP_SETEXTATTR(). 3534 */ 3535int 3536extattr_delete_file(p, uap) 3537 struct proc *p; 3538 struct extattr_delete_file_args *uap; 3539{ 3540 struct nameidata nd; 3541 char attrname[EXTATTR_MAXNAMELEN]; 3542 int error; 3543 3544 error = copyin(SCARG(uap, attrname), attrname, EXTATTR_MAXNAMELEN); 3545 if (error) 3546 return(error); 3547 NDINIT(&nd, LOOKUP, LOCKLEAF | FOLLOW, UIO_USERSPACE, SCARG(uap, path), 3548 p); 3549 if ((error = namei(&nd)) != 0) 3550 return(error); 3551 error = VOP_SETEXTATTR(nd.ni_vp, attrname, NULL, p->p_cred->pc_ucred, 3552 p); 3553 NDFREE(&nd, 0); 3554 return(error); 3555} |
|