1 // SPDX-License-Identifier: GPL-2.0
3 * Copyright (C) 2014-2021 Junjiro R. Okajima
5 * This program, aufs is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
20 * handling xattr functions
24 #include <linux/posix_acl_xattr.h>
25 #include <linux/xattr.h>
28 static int au_xattr_ignore(int err
, char *name
, unsigned int ignore_flags
)
38 if ((ignore_flags
& AuBrAttr_ICEX
) == AuBrAttr_ICEX
) {
43 #define cmp(brattr, prefix) do { \
44 if (!strncmp(name, XATTR_##prefix##_PREFIX, \
45 XATTR_##prefix##_PREFIX_LEN)) { \
46 if (ignore_flags & AuBrAttr_ICEX_##brattr) \
58 if (ignore_flags
& AuBrAttr_ICEX_OTH
)
65 static const int au_xattr_out_of_list
= AuBrAttr_ICEX_OTH
<< 1;
67 static int au_do_cpup_xattr(struct path
*h_dst
, struct path
*h_src
,
68 char *name
, char **buf
, unsigned int ignore_flags
,
74 struct dentry
*h_dst_dentry
, *h_src_dentry
;
75 struct user_namespace
*h_dst_userns
, *h_src_userns
;
77 h_src_userns
= mnt_user_ns(h_src
->mnt
);
78 h_src_dentry
= h_src
->dentry
;
79 ssz
= vfs_getxattr_alloc(h_src_userns
, h_src_dentry
, name
, buf
, 0,
82 if (unlikely(err
<= 0)) {
84 || (err
== -EOPNOTSUPP
85 && ((ignore_flags
& au_xattr_out_of_list
)
86 || (au_test_nfs_noacl(d_inode(h_src_dentry
))
87 && (!strcmp(name
, XATTR_NAME_POSIX_ACL_ACCESS
)
89 XATTR_NAME_POSIX_ACL_DEFAULT
))))
92 if (err
&& (verbose
|| au_debug_test()))
93 pr_err("%s, err %d\n", name
, err
);
97 /* unlock it temporary */
98 h_dst_userns
= mnt_user_ns(h_dst
->mnt
);
99 h_dst_dentry
= h_dst
->dentry
;
100 h_idst
= d_inode(h_dst_dentry
);
101 inode_unlock(h_idst
);
102 err
= vfsub_setxattr(h_dst_userns
, h_dst_dentry
, name
, *buf
, ssz
,
104 inode_lock_nested(h_idst
, AuLsc_I_CHILD2
);
106 if (verbose
|| au_debug_test())
107 pr_err("%s, err %d\n", name
, err
);
108 err
= au_xattr_ignore(err
, name
, ignore_flags
);
115 int au_cpup_xattr(struct path
*h_dst
, struct path
*h_src
, int ignore_flags
,
116 unsigned int verbose
)
118 int err
, unlocked
, acl_access
, acl_default
;
120 struct dentry
*h_dst_dentry
, *h_src_dentry
;
121 struct inode
*h_isrc
, *h_idst
;
122 char *value
, *p
, *o
, *e
;
124 /* try stopping to update the source inode while we are referencing */
125 /* there should not be the parent-child relationship between them */
126 h_dst_dentry
= h_dst
->dentry
;
127 h_idst
= d_inode(h_dst_dentry
);
128 h_src_dentry
= h_src
->dentry
;
129 h_isrc
= d_inode(h_src_dentry
);
130 inode_unlock(h_idst
);
131 inode_lock_shared_nested(h_isrc
, AuLsc_I_CHILD
);
132 inode_lock_nested(h_idst
, AuLsc_I_CHILD2
);
135 /* some filesystems don't list POSIX ACL, for example tmpfs */
136 ssz
= vfs_listxattr(h_src_dentry
, NULL
, 0);
138 if (unlikely(err
< 0)) {
141 || err
== -EOPNOTSUPP
)
142 err
= 0; /* ignore */
151 p
= kmalloc(ssz
, GFP_NOFS
);
155 err
= vfs_listxattr(h_src_dentry
, p
, ssz
);
157 inode_unlock_shared(h_isrc
);
159 AuDbg("err %d, ssz %zd\n", err
, ssz
);
160 if (unlikely(err
< 0))
168 while (!err
&& p
< e
) {
169 acl_access
|= !strncmp(p
, XATTR_NAME_POSIX_ACL_ACCESS
,
170 sizeof(XATTR_NAME_POSIX_ACL_ACCESS
) - 1);
171 acl_default
|= !strncmp(p
, XATTR_NAME_POSIX_ACL_DEFAULT
,
172 sizeof(XATTR_NAME_POSIX_ACL_DEFAULT
)
174 err
= au_do_cpup_xattr(h_dst
, h_src
, p
, &value
, ignore_flags
,
179 ignore_flags
|= au_xattr_out_of_list
;
180 if (!err
&& !acl_access
) {
181 err
= au_do_cpup_xattr(h_dst
, h_src
,
182 XATTR_NAME_POSIX_ACL_ACCESS
, &value
,
183 ignore_flags
, verbose
);
186 if (!err
&& !acl_default
) {
187 err
= au_do_cpup_xattr(h_dst
, h_src
,
188 XATTR_NAME_POSIX_ACL_DEFAULT
, &value
,
189 ignore_flags
, verbose
);
193 au_kfree_try_rcu(value
);
199 inode_unlock_shared(h_isrc
);
204 /* ---------------------------------------------------------------------- */
206 static int au_smack_reentering(struct super_block
*sb
)
208 #if IS_ENABLED(CONFIG_SECURITY_SMACK) || IS_ENABLED(CONFIG_SECURITY_SELINUX)
210 * as a part of lookup, smack_d_instantiate() is called, and it calls
211 * i_op->getxattr(). ouch.
213 return si_pid_test(sb
);
239 static ssize_t
au_lgxattr(struct dentry
*dentry
, struct inode
*inode
,
240 struct au_lgxattr
*arg
)
245 struct super_block
*sb
;
248 reenter
= au_smack_reentering(sb
);
250 err
= si_read_lock(sb
, AuLock_FLUSH
| AuLock_NOPLM
);
254 err
= au_h_path_getattr(dentry
, inode
, /*force*/1, &h_path
, reenter
);
257 if (unlikely(!h_path
.dentry
))
258 /* illegally overlapped or something */
259 goto out_di
; /* pretending success */
261 /* always topmost entry only */
264 err
= vfs_listxattr(h_path
.dentry
,
265 arg
->u
.list
.list
, arg
->u
.list
.size
);
268 AuDebugOn(d_is_negative(h_path
.dentry
));
269 err
= vfs_getxattr(mnt_user_ns(h_path
.mnt
), h_path
.dentry
,
270 arg
->u
.get
.name
, arg
->u
.get
.value
,
277 di_read_unlock(dentry
, AuLock_IR
);
286 ssize_t
aufs_listxattr(struct dentry
*dentry
, char *list
, size_t size
)
288 struct au_lgxattr arg
= {
289 .type
= AU_XATTR_LIST
,
296 return au_lgxattr(dentry
, /*inode*/NULL
, &arg
);
299 static ssize_t
au_getxattr(struct dentry
*dentry
, struct inode
*inode
,
300 const char *name
, void *value
, size_t size
)
302 struct au_lgxattr arg
= {
303 .type
= AU_XATTR_GET
,
311 return au_lgxattr(dentry
, inode
, &arg
);
314 static int au_setxattr(struct dentry
*dentry
, struct inode
*inode
,
315 const char *name
, const void *value
, size_t size
,
318 struct au_sxattr arg
= {
319 .type
= AU_XATTR_SET
,
328 return au_sxattr(dentry
, inode
, &arg
);
331 /* ---------------------------------------------------------------------- */
333 static int au_xattr_get(const struct xattr_handler
*handler
,
334 struct dentry
*dentry
, struct inode
*inode
,
335 const char *name
, void *buffer
, size_t size
)
337 return au_getxattr(dentry
, inode
, name
, buffer
, size
);
340 static int au_xattr_set(const struct xattr_handler
*handler
,
341 struct user_namespace
*userns
,
342 struct dentry
*dentry
, struct inode
*inode
,
343 const char *name
, const void *value
, size_t size
,
346 return au_setxattr(dentry
, inode
, name
, value
, size
, flags
);
349 static const struct xattr_handler au_xattr_handler
= {
356 static const struct xattr_handler
*au_xattr_handlers
[] = {
357 #ifdef CONFIG_FS_POSIX_ACL
358 &posix_acl_access_xattr_handler
,
359 &posix_acl_default_xattr_handler
,
361 &au_xattr_handler
, /* must be last */
365 void au_xattr_init(struct super_block
*sb
)
367 sb
->s_xattr
= au_xattr_handlers
;