Lines 892-903
Link Here
|
892 |
static int |
892 |
static int |
893 |
unionfs_vn_create_on_upper(struct vnode **vpp, struct vnode *udvp, |
893 |
unionfs_vn_create_on_upper(struct vnode **vpp, struct vnode *udvp, |
894 |
struct unionfs_node *unp, struct vattr *uvap, |
894 |
struct unionfs_node *unp, struct vattr *uvap, |
895 |
struct thread *td) |
895 |
struct ucred *cred, struct thread *td) |
896 |
{ |
896 |
{ |
897 |
struct unionfs_mount *ump; |
897 |
struct unionfs_mount *ump; |
898 |
struct vnode *vp; |
898 |
struct vnode *vp; |
899 |
struct vnode *lvp; |
899 |
struct vnode *lvp; |
900 |
struct ucred *cred; |
|
|
901 |
struct vattr lva; |
900 |
struct vattr lva; |
902 |
int fmode; |
901 |
int fmode; |
903 |
int error; |
902 |
int error; |
Lines 906-912
Link Here
|
906 |
ump = MOUNTTOUNIONFSMOUNT(UNIONFSTOV(unp)->v_mount); |
905 |
ump = MOUNTTOUNIONFSMOUNT(UNIONFSTOV(unp)->v_mount); |
907 |
vp = NULLVP; |
906 |
vp = NULLVP; |
908 |
lvp = unp->un_lowervp; |
907 |
lvp = unp->un_lowervp; |
909 |
cred = td->td_ucred; |
908 |
if (unp->un_path == NULL) |
|
|
909 |
panic("unionfs: un_path is null"); |
910 |
|
910 |
fmode = FFLAGS(O_WRONLY | O_CREAT | O_TRUNC | O_EXCL); |
911 |
fmode = FFLAGS(O_WRONLY | O_CREAT | O_TRUNC | O_EXCL); |
911 |
error = 0; |
912 |
error = 0; |
Lines 914-922
Link Here
|
914 |
return (error); |
915 |
return (error); |
915 |
unionfs_create_uppervattr_core(ump, &lva, uvap, td); |
916 |
unionfs_create_uppervattr_core(ump, &lva, uvap, td); |
916 |
if (unp->un_path == NULL) |
|
|
917 |
panic("unionfs: un_path is null"); |
918 |
|
919 |
cn.cn_namelen = strlen(unp->un_path); |
917 |
cn.cn_namelen = strlen(unp->un_path); |
920 |
cn.cn_pnbuf = uma_zalloc(namei_zone, M_WAITOK); |
918 |
cn.cn_pnbuf = uma_zalloc(namei_zone, M_WAITOK); |
921 |
bcopy(unp->un_path, cn.cn_pnbuf, cn.cn_namelen + 1); |
919 |
bcopy(unp->un_path, cn.cn_pnbuf, cn.cn_namelen + 1); |
Lines 1053-1058
Link Here
|
1053 |
struct vnode *lvp; |
1051 |
struct vnode *lvp; |
1054 |
struct vnode *uvp; |
1052 |
struct vnode *uvp; |
1055 |
struct vattr uva; |
1053 |
struct vattr uva; |
|
|
1054 |
struct uidinfo *rootinfo; |
1056 |
lvp = unp->un_lowervp; |
1055 |
lvp = unp->un_lowervp; |
1057 |
uvp = NULLVP; |
1056 |
uvp = NULLVP; |
Lines 1069-1084
Link Here
|
1069 |
if ((udvp->v_mount->mnt_flag & MNT_RDONLY)) |
1068 |
if ((udvp->v_mount->mnt_flag & MNT_RDONLY)) |
1070 |
return (EROFS); |
1069 |
return (EROFS); |
|
|
1070 |
/* Authority change to root */ |
1071 |
rootinfo = uifind((uid_t)0); |
1072 |
cred = crdup(cred); |
1073 |
/* |
1074 |
* The calls to chgproccnt() are needed to compensate for change_ruid() |
1075 |
* calling chgproccnt(). |
1076 |
*/ |
1077 |
chgproccnt(cred->cr_ruidinfo, 1, 0); |
1078 |
change_euid(cred, rootinfo); |
1079 |
change_ruid(cred, rootinfo); |
1080 |
change_svuid(cred, (uid_t)0); |
1081 |
uifree(rootinfo); |
1082 |
|
1083 |
/* we changed to root here, so no need to check again |
1071 |
error = VOP_ACCESS(lvp, VREAD, cred, td); |
1084 |
error = VOP_ACCESS(lvp, VREAD, cred, td); |
1072 |
if (error != 0) |
1085 |
if (error != 0) |
1073 |
return (error); |
1086 |
goto unionfs_copyfile_abort; |
|
|
1087 |
*/ |
1074 |
if ((error = vn_start_write(udvp, &mp, V_WAIT | PCATCH)) != 0) |
1088 |
if ((error = vn_start_write(udvp, &mp, V_WAIT | PCATCH)) != 0) |
1075 |
return (error); |
1089 |
goto unionfs_copyfile_abort; |
1076 |
error = unionfs_vn_create_on_upper(&uvp, udvp, unp, &uva, td); |
1090 |
error = unionfs_vn_create_on_upper(&uvp, udvp, unp, &uva, cred, td); |
1077 |
if (error != 0) { |
1091 |
if (error != 0) { |
1078 |
vn_finished_write(mp); |
1092 |
vn_finished_write(mp); |
1079 |
return (error); |
1093 |
goto unionfs_copyfile_abort; |
1080 |
} |
1094 |
} |
1081 |
if (docopy != 0) { |
1095 |
if (docopy != 0) { |
Lines 1095-1108
Link Here
|
1095 |
vn_finished_write(mp); |
1109 |
vn_finished_write(mp); |
1096 |
if (error == 0) { |
|
|
1097 |
/* Reset the attributes. Ignore errors. */ |
1098 |
uva.va_type = VNON; |
1099 |
VOP_SETATTR(uvp, &uva, cred); |
1100 |
} |
1101 |
|
1102 |
unionfs_node_update(unp, uvp, td); |
1110 |
unionfs_node_update(unp, uvp, td); |
|
|
1111 |
unionfs_copyfile_abort: |
1112 |
chgproccnt(cred->cr_ruidinfo, -1, 0); |
1113 |
crfree(cred); |
1114 |
|
1103 |
return (error); |
1115 |
return (error); |
1104 |
} |
1116 |
} |