aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2016-06-16 23:16:56 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2016-06-16 23:16:56 -0400
commit9c514bedbe6948f31d29c53aceb9234c1484ae69 (patch)
tree09b2dd9e3a145e9baf0f8e5ada69e729e178dead /fs
parent38327424b40bcebe2de92d07312c89360ac9229a (diff)
parentd0e13f5bbe4be7c8f27736fc40503dcec04b7de0 (diff)
Merge branch 'overlayfs-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mszeredi/vfs
Pull overlayfs fixes from Miklos Szeredi: "This contains two regression fixes: one for the xattr API update and one for using the mounter's creds in file creation in overlayfs. There's also a fix for a bug in handling hard linked AF_UNIX sockets that's been there from day one. This fix is overlayfs only despite the fact that it touches code outside the overlay filesystem: d_real() is an identity function for all except overlay dentries" * 'overlayfs-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mszeredi/vfs: ovl: fix uid/gid when creating over whiteout ovl: xattr filter fix af_unix: fix hard linked sockets on overlay vfs: add d_real_inode() helper
Diffstat (limited to 'fs')
-rw-r--r--fs/overlayfs/dir.c13
-rw-r--r--fs/overlayfs/inode.c26
2 files changed, 17 insertions, 22 deletions
diff --git a/fs/overlayfs/dir.c b/fs/overlayfs/dir.c
index 22f0253a3567..c2a6b0894022 100644
--- a/fs/overlayfs/dir.c
+++ b/fs/overlayfs/dir.c
@@ -405,12 +405,21 @@ static int ovl_create_or_link(struct dentry *dentry, int mode, dev_t rdev,
405 err = ovl_create_upper(dentry, inode, &stat, link, hardlink); 405 err = ovl_create_upper(dentry, inode, &stat, link, hardlink);
406 } else { 406 } else {
407 const struct cred *old_cred; 407 const struct cred *old_cred;
408 struct cred *override_cred;
408 409
409 old_cred = ovl_override_creds(dentry->d_sb); 410 old_cred = ovl_override_creds(dentry->d_sb);
410 411
411 err = ovl_create_over_whiteout(dentry, inode, &stat, link, 412 err = -ENOMEM;
412 hardlink); 413 override_cred = prepare_creds();
414 if (override_cred) {
415 override_cred->fsuid = old_cred->fsuid;
416 override_cred->fsgid = old_cred->fsgid;
417 put_cred(override_creds(override_cred));
418 put_cred(override_cred);
413 419
420 err = ovl_create_over_whiteout(dentry, inode, &stat,
421 link, hardlink);
422 }
414 revert_creds(old_cred); 423 revert_creds(old_cred);
415 } 424 }
416 425
diff --git a/fs/overlayfs/inode.c b/fs/overlayfs/inode.c
index 0ed7c4012437..1dbeab6cf96e 100644
--- a/fs/overlayfs/inode.c
+++ b/fs/overlayfs/inode.c
@@ -238,41 +238,27 @@ out:
238 return err; 238 return err;
239} 239}
240 240
241static bool ovl_need_xattr_filter(struct dentry *dentry,
242 enum ovl_path_type type)
243{
244 if ((type & (__OVL_PATH_PURE | __OVL_PATH_UPPER)) == __OVL_PATH_UPPER)
245 return S_ISDIR(dentry->d_inode->i_mode);
246 else
247 return false;
248}
249
250ssize_t ovl_getxattr(struct dentry *dentry, struct inode *inode, 241ssize_t ovl_getxattr(struct dentry *dentry, struct inode *inode,
251 const char *name, void *value, size_t size) 242 const char *name, void *value, size_t size)
252{ 243{
253 struct path realpath; 244 struct dentry *realdentry = ovl_dentry_real(dentry);
254 enum ovl_path_type type = ovl_path_real(dentry, &realpath);
255 245
256 if (ovl_need_xattr_filter(dentry, type) && ovl_is_private_xattr(name)) 246 if (ovl_is_private_xattr(name))
257 return -ENODATA; 247 return -ENODATA;
258 248
259 return vfs_getxattr(realpath.dentry, name, value, size); 249 return vfs_getxattr(realdentry, name, value, size);
260} 250}
261 251
262ssize_t ovl_listxattr(struct dentry *dentry, char *list, size_t size) 252ssize_t ovl_listxattr(struct dentry *dentry, char *list, size_t size)
263{ 253{
264 struct path realpath; 254 struct dentry *realdentry = ovl_dentry_real(dentry);
265 enum ovl_path_type type = ovl_path_real(dentry, &realpath);
266 ssize_t res; 255 ssize_t res;
267 int off; 256 int off;
268 257
269 res = vfs_listxattr(realpath.dentry, list, size); 258 res = vfs_listxattr(realdentry, list, size);
270 if (res <= 0 || size == 0) 259 if (res <= 0 || size == 0)
271 return res; 260 return res;
272 261
273 if (!ovl_need_xattr_filter(dentry, type))
274 return res;
275
276 /* filter out private xattrs */ 262 /* filter out private xattrs */
277 for (off = 0; off < res;) { 263 for (off = 0; off < res;) {
278 char *s = list + off; 264 char *s = list + off;
@@ -302,7 +288,7 @@ int ovl_removexattr(struct dentry *dentry, const char *name)
302 goto out; 288 goto out;
303 289
304 err = -ENODATA; 290 err = -ENODATA;
305 if (ovl_need_xattr_filter(dentry, type) && ovl_is_private_xattr(name)) 291 if (ovl_is_private_xattr(name))
306 goto out_drop_write; 292 goto out_drop_write;
307 293
308 if (!OVL_TYPE_UPPER(type)) { 294 if (!OVL_TYPE_UPPER(type)) {