1 // SPDX-License-Identifier: CDDL-1.0 2 /* 3 * CDDL HEADER START 4 * 5 * The contents of this file are subject to the terms of the 6 * Common Development and Distribution License (the "License"). 7 * You may not use this file except in compliance with the License. 8 * 9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10 * or https://opensource.org/licenses/CDDL-1.0. 11 * See the License for the specific language governing permissions 12 * and limitations under the License. 13 * 14 * When distributing Covered Code, include this CDDL HEADER in each 15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16 * If applicable, add the following below this CDDL HEADER, with the 17 * fields enclosed by brackets "[]" replaced with your own identifying 18 * information: Portions Copyright [yyyy] [name of copyright owner] 19 * 20 * CDDL HEADER END 21 */ 22 /* 23 * Copyright 2010 Sun Microsystems, Inc. All rights reserved. 24 * Use is subject to license terms. 25 */ 26 27 #include <sys/zfs_context.h> 28 #include <sys/vfs.h> 29 #include <sys/fs/zfs.h> 30 #include <sys/zfs_znode.h> 31 #include <sys/zfs_sa.h> 32 #include <sys/zfs_acl.h> 33 34 #ifndef _KERNEL 35 static 36 #endif 37 void 38 zfs_oldace_byteswap(ace_t *ace, int ace_cnt) 39 { 40 for (int i = 0; i != ace_cnt; i++, ace++) { 41 ace->a_who = BSWAP_32(ace->a_who); 42 ace->a_access_mask = BSWAP_32(ace->a_access_mask); 43 ace->a_flags = BSWAP_16(ace->a_flags); 44 ace->a_type = BSWAP_16(ace->a_type); 45 } 46 } 47 48 /* 49 * swap ace_t and ace_object_t 50 */ 51 #ifndef _KERNEL 52 static 53 #endif 54 void 55 zfs_ace_byteswap(void *buf, size_t size, boolean_t zfs_layout) 56 { 57 caddr_t end; 58 caddr_t ptr; 59 zfs_ace_t *zacep = NULL; 60 ace_t *acep; 61 uint16_t entry_type; 62 size_t entry_size; 63 int ace_type; 64 65 end = (caddr_t)buf + size; 66 ptr = buf; 67 68 while (ptr < end) { 69 if (zfs_layout) { 70 /* 71 * Avoid overrun. Embedded aces can have one 72 * of several sizes. We don't know exactly 73 * how many our present, only the size of the 74 * buffer containing them. That size may be 75 * larger than needed to hold the aces 76 * present. As long as we do not do any 77 * swapping beyond the end of our block we are 78 * okay. It is safe to swap any non-ace data 79 * within the block since it is just zeros. 80 */ 81 if (ptr + sizeof (zfs_ace_hdr_t) > end) { 82 break; 83 } 84 zacep = (zfs_ace_t *)ptr; 85 zacep->z_hdr.z_access_mask = 86 BSWAP_32(zacep->z_hdr.z_access_mask); 87 zacep->z_hdr.z_flags = BSWAP_16(zacep->z_hdr.z_flags); 88 ace_type = zacep->z_hdr.z_type = 89 BSWAP_16(zacep->z_hdr.z_type); 90 entry_type = zacep->z_hdr.z_flags & ACE_TYPE_FLAGS; 91 } else { 92 /* Overrun avoidance */ 93 if (ptr + sizeof (ace_t) > end) { 94 break; 95 } 96 acep = (ace_t *)ptr; 97 acep->a_access_mask = BSWAP_32(acep->a_access_mask); 98 acep->a_flags = BSWAP_16(acep->a_flags); 99 ace_type = acep->a_type = BSWAP_16(acep->a_type); 100 acep->a_who = BSWAP_32(acep->a_who); 101 entry_type = acep->a_flags & ACE_TYPE_FLAGS; 102 } 103 switch (entry_type) { 104 case ACE_OWNER: 105 case ACE_EVERYONE: 106 case (ACE_IDENTIFIER_GROUP | ACE_GROUP): 107 entry_size = zfs_layout ? 108 sizeof (zfs_ace_hdr_t) : sizeof (ace_t); 109 break; 110 case ACE_IDENTIFIER_GROUP: 111 default: 112 /* Overrun avoidance */ 113 if (zfs_layout) { 114 if (ptr + sizeof (zfs_ace_t) <= end) { 115 zacep->z_fuid = BSWAP_64(zacep->z_fuid); 116 } else { 117 entry_size = sizeof (zfs_ace_t); 118 break; 119 } 120 } 121 switch (ace_type) { 122 case ACE_ACCESS_ALLOWED_OBJECT_ACE_TYPE: 123 case ACE_ACCESS_DENIED_OBJECT_ACE_TYPE: 124 case ACE_SYSTEM_AUDIT_OBJECT_ACE_TYPE: 125 case ACE_SYSTEM_ALARM_OBJECT_ACE_TYPE: 126 entry_size = zfs_layout ? 127 sizeof (zfs_object_ace_t) : 128 sizeof (ace_object_t); 129 break; 130 default: 131 entry_size = zfs_layout ? sizeof (zfs_ace_t) : 132 sizeof (ace_t); 133 break; 134 } 135 } 136 ptr = ptr + entry_size; 137 } 138 } 139 140 void 141 zfs_oldacl_byteswap(void *buf, size_t size) 142 { 143 /* 144 * Arggh, since we don't know how many ACEs are in 145 * the array, we have to swap the entire block 146 */ 147 zfs_oldace_byteswap((ace_t *)buf, size / sizeof (ace_t)); 148 } 149 150 void 151 zfs_acl_byteswap(void *buf, size_t size) 152 { 153 zfs_ace_byteswap(buf, size, B_TRUE); 154 } 155 156 void 157 zfs_znode_byteswap(void *buf, size_t size) 158 { 159 znode_phys_t *zp = buf; 160 161 ASSERT(size >= sizeof (znode_phys_t)); 162 163 zp->zp_crtime[0] = BSWAP_64(zp->zp_crtime[0]); 164 zp->zp_crtime[1] = BSWAP_64(zp->zp_crtime[1]); 165 zp->zp_atime[0] = BSWAP_64(zp->zp_atime[0]); 166 zp->zp_atime[1] = BSWAP_64(zp->zp_atime[1]); 167 zp->zp_mtime[0] = BSWAP_64(zp->zp_mtime[0]); 168 zp->zp_mtime[1] = BSWAP_64(zp->zp_mtime[1]); 169 zp->zp_ctime[0] = BSWAP_64(zp->zp_ctime[0]); 170 zp->zp_ctime[1] = BSWAP_64(zp->zp_ctime[1]); 171 zp->zp_gen = BSWAP_64(zp->zp_gen); 172 zp->zp_mode = BSWAP_64(zp->zp_mode); 173 zp->zp_size = BSWAP_64(zp->zp_size); 174 zp->zp_parent = BSWAP_64(zp->zp_parent); 175 zp->zp_links = BSWAP_64(zp->zp_links); 176 zp->zp_xattr = BSWAP_64(zp->zp_xattr); 177 zp->zp_rdev = BSWAP_64(zp->zp_rdev); 178 zp->zp_flags = BSWAP_64(zp->zp_flags); 179 zp->zp_uid = BSWAP_64(zp->zp_uid); 180 zp->zp_gid = BSWAP_64(zp->zp_gid); 181 zp->zp_zap = BSWAP_64(zp->zp_zap); 182 zp->zp_pad[0] = BSWAP_64(zp->zp_pad[0]); 183 zp->zp_pad[1] = BSWAP_64(zp->zp_pad[1]); 184 zp->zp_pad[2] = BSWAP_64(zp->zp_pad[2]); 185 186 zp->zp_acl.z_acl_extern_obj = BSWAP_64(zp->zp_acl.z_acl_extern_obj); 187 zp->zp_acl.z_acl_size = BSWAP_32(zp->zp_acl.z_acl_size); 188 zp->zp_acl.z_acl_version = BSWAP_16(zp->zp_acl.z_acl_version); 189 zp->zp_acl.z_acl_count = BSWAP_16(zp->zp_acl.z_acl_count); 190 if (zp->zp_acl.z_acl_version == ZFS_ACL_VERSION) { 191 zfs_acl_byteswap((void *)&zp->zp_acl.z_ace_data[0], 192 ZFS_ACE_SPACE); 193 } else { 194 zfs_oldace_byteswap((ace_t *)&zp->zp_acl.z_ace_data[0], 195 ACE_SLOT_CNT); 196 } 197 } 198 199 #if defined(_KERNEL) 200 EXPORT_SYMBOL(zfs_oldacl_byteswap); 201 EXPORT_SYMBOL(zfs_acl_byteswap); 202 EXPORT_SYMBOL(zfs_znode_byteswap); 203 #endif 204