1 // SPDX-License-Identifier: GPL-2.0-only 2 3 #include <linux/fs.h> 4 #include <linux/xattr.h> 5 #include "overlayfs.h" 6 7 static bool ovl_is_escaped_xattr(struct super_block *sb, const char *name) 8 { 9 struct ovl_fs *ofs = sb->s_fs_info; 10 11 if (ofs->config.userxattr) 12 return strncmp(name, OVL_XATTR_ESCAPE_USER_PREFIX, 13 OVL_XATTR_ESCAPE_USER_PREFIX_LEN) == 0; 14 else 15 return strncmp(name, OVL_XATTR_ESCAPE_TRUSTED_PREFIX, 16 OVL_XATTR_ESCAPE_TRUSTED_PREFIX_LEN - 1) == 0; 17 } 18 19 static bool ovl_is_own_xattr(struct super_block *sb, const char *name) 20 { 21 struct ovl_fs *ofs = OVL_FS(sb); 22 23 if (ofs->config.userxattr) 24 return strncmp(name, OVL_XATTR_USER_PREFIX, 25 OVL_XATTR_USER_PREFIX_LEN) == 0; 26 else 27 return strncmp(name, OVL_XATTR_TRUSTED_PREFIX, 28 OVL_XATTR_TRUSTED_PREFIX_LEN) == 0; 29 } 30 31 bool ovl_is_private_xattr(struct super_block *sb, const char *name) 32 { 33 return ovl_is_own_xattr(sb, name) && !ovl_is_escaped_xattr(sb, name); 34 } 35 36 static int ovl_xattr_set(struct dentry *dentry, struct inode *inode, const char *name, 37 const void *value, size_t size, int flags) 38 { 39 int err; 40 struct ovl_fs *ofs = OVL_FS(dentry->d_sb); 41 struct dentry *upperdentry = ovl_i_dentry_upper(inode); 42 struct dentry *realdentry = upperdentry ?: ovl_dentry_lower(dentry); 43 struct path realpath; 44 45 if (!value && !upperdentry) { 46 ovl_path_lower(dentry, &realpath); 47 with_ovl_creds(dentry->d_sb) 48 err = vfs_getxattr(mnt_idmap(realpath.mnt), realdentry, name, NULL, 0); 49 if (err < 0) 50 goto out; 51 } 52 53 if (!upperdentry) { 54 err = ovl_copy_up(dentry); 55 if (err) 56 goto out; 57 58 realdentry = ovl_dentry_upper(dentry); 59 } 60 61 err = ovl_want_write(dentry); 62 if (err) 63 goto out; 64 65 with_ovl_creds(dentry->d_sb) { 66 if (value) { 67 err = ovl_do_setxattr(ofs, realdentry, name, value, size, flags); 68 } else { 69 WARN_ON(flags != XATTR_REPLACE); 70 err = ovl_do_removexattr(ofs, realdentry, name); 71 } 72 } 73 ovl_drop_write(dentry); 74 75 /* copy c/mtime */ 76 ovl_copyattr(inode); 77 out: 78 return err; 79 } 80 81 static int ovl_xattr_get(struct dentry *dentry, struct inode *inode, const char *name, 82 void *value, size_t size) 83 { 84 struct path realpath; 85 86 ovl_i_path_real(inode, &realpath); 87 with_ovl_creds(dentry->d_sb) 88 return vfs_getxattr(mnt_idmap(realpath.mnt), realpath.dentry, name, value, size); 89 } 90 91 static bool ovl_can_list(struct super_block *sb, const char *s) 92 { 93 /* Never list private (.overlay) */ 94 if (ovl_is_private_xattr(sb, s)) 95 return false; 96 97 /* List all non-trusted xattrs */ 98 if (strncmp(s, XATTR_TRUSTED_PREFIX, XATTR_TRUSTED_PREFIX_LEN) != 0) 99 return true; 100 101 /* list other trusted for superuser only */ 102 return ns_capable_noaudit(&init_user_ns, CAP_SYS_ADMIN); 103 } 104 105 ssize_t ovl_listxattr(struct dentry *dentry, char *list, size_t size) 106 { 107 struct dentry *realdentry = ovl_dentry_real(dentry); 108 struct ovl_fs *ofs = OVL_FS(dentry->d_sb); 109 ssize_t res; 110 size_t len; 111 char *s; 112 size_t prefix_len, name_len; 113 114 with_ovl_creds(dentry->d_sb) 115 res = vfs_listxattr(realdentry, list, size); 116 if (res <= 0 || size == 0) 117 return res; 118 119 prefix_len = ofs->config.userxattr ? 120 OVL_XATTR_USER_PREFIX_LEN : OVL_XATTR_TRUSTED_PREFIX_LEN; 121 122 /* filter out private xattrs */ 123 for (s = list, len = res; len;) { 124 size_t slen = strnlen(s, len) + 1; 125 126 /* underlying fs providing us with an broken xattr list? */ 127 if (WARN_ON(slen > len)) 128 return -EIO; 129 130 len -= slen; 131 if (!ovl_can_list(dentry->d_sb, s)) { 132 res -= slen; 133 memmove(s, s + slen, len); 134 } else if (ovl_is_escaped_xattr(dentry->d_sb, s)) { 135 res -= OVL_XATTR_ESCAPE_PREFIX_LEN; 136 name_len = slen - prefix_len - OVL_XATTR_ESCAPE_PREFIX_LEN; 137 s += prefix_len; 138 memmove(s, s + OVL_XATTR_ESCAPE_PREFIX_LEN, name_len + len); 139 s += name_len; 140 } else { 141 s += slen; 142 } 143 } 144 145 return res; 146 } 147 148 static char *ovl_xattr_escape_name(const char *prefix, const char *name) 149 { 150 size_t prefix_len = strlen(prefix); 151 size_t name_len = strlen(name); 152 size_t escaped_len; 153 char *escaped, *s; 154 155 escaped_len = prefix_len + OVL_XATTR_ESCAPE_PREFIX_LEN + name_len; 156 if (escaped_len > XATTR_NAME_MAX) 157 return ERR_PTR(-EOPNOTSUPP); 158 159 escaped = kmalloc(escaped_len + 1, GFP_KERNEL); 160 if (escaped == NULL) 161 return ERR_PTR(-ENOMEM); 162 163 s = escaped; 164 memcpy(s, prefix, prefix_len); 165 s += prefix_len; 166 memcpy(s, OVL_XATTR_ESCAPE_PREFIX, OVL_XATTR_ESCAPE_PREFIX_LEN); 167 s += OVL_XATTR_ESCAPE_PREFIX_LEN; 168 memcpy(s, name, name_len + 1); 169 170 return escaped; 171 } 172 173 static int ovl_own_xattr_get(const struct xattr_handler *handler, 174 struct dentry *dentry, struct inode *inode, 175 const char *name, void *buffer, size_t size) 176 { 177 char *escaped; 178 int r; 179 180 escaped = ovl_xattr_escape_name(handler->prefix, name); 181 if (IS_ERR(escaped)) 182 return PTR_ERR(escaped); 183 184 r = ovl_xattr_get(dentry, inode, escaped, buffer, size); 185 186 kfree(escaped); 187 188 return r; 189 } 190 191 static int ovl_own_xattr_set(const struct xattr_handler *handler, 192 struct mnt_idmap *idmap, 193 struct dentry *dentry, struct inode *inode, 194 const char *name, const void *value, 195 size_t size, int flags) 196 { 197 char *escaped; 198 int r; 199 200 escaped = ovl_xattr_escape_name(handler->prefix, name); 201 if (IS_ERR(escaped)) 202 return PTR_ERR(escaped); 203 204 r = ovl_xattr_set(dentry, inode, escaped, value, size, flags); 205 206 kfree(escaped); 207 208 return r; 209 } 210 211 static int ovl_other_xattr_get(const struct xattr_handler *handler, 212 struct dentry *dentry, struct inode *inode, 213 const char *name, void *buffer, size_t size) 214 { 215 return ovl_xattr_get(dentry, inode, name, buffer, size); 216 } 217 218 static int ovl_other_xattr_set(const struct xattr_handler *handler, 219 struct mnt_idmap *idmap, 220 struct dentry *dentry, struct inode *inode, 221 const char *name, const void *value, 222 size_t size, int flags) 223 { 224 return ovl_xattr_set(dentry, inode, name, value, size, flags); 225 } 226 227 static const struct xattr_handler ovl_own_trusted_xattr_handler = { 228 .prefix = OVL_XATTR_TRUSTED_PREFIX, 229 .get = ovl_own_xattr_get, 230 .set = ovl_own_xattr_set, 231 }; 232 233 static const struct xattr_handler ovl_own_user_xattr_handler = { 234 .prefix = OVL_XATTR_USER_PREFIX, 235 .get = ovl_own_xattr_get, 236 .set = ovl_own_xattr_set, 237 }; 238 239 static const struct xattr_handler ovl_other_xattr_handler = { 240 .prefix = "", /* catch all */ 241 .get = ovl_other_xattr_get, 242 .set = ovl_other_xattr_set, 243 }; 244 245 static const struct xattr_handler * const ovl_trusted_xattr_handlers[] = { 246 &ovl_own_trusted_xattr_handler, 247 &ovl_other_xattr_handler, 248 NULL 249 }; 250 251 static const struct xattr_handler * const ovl_user_xattr_handlers[] = { 252 &ovl_own_user_xattr_handler, 253 &ovl_other_xattr_handler, 254 NULL 255 }; 256 257 const struct xattr_handler * const *ovl_xattr_handlers(struct ovl_fs *ofs) 258 { 259 return ofs->config.userxattr ? ovl_user_xattr_handlers : 260 ovl_trusted_xattr_handlers; 261 } 262