Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

replace do_setxattr() with saner helpers.

io_uring setxattr logics duplicates stuff from fs/xattr.c; provide
saner helpers (filename_setxattr() and file_setxattr() resp.) and
use them.

NB: putname(ERR_PTR()) is a no-op

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>

Al Viro 66d7ac6b a10c4c5e

+54 -62
+3 -3
fs/internal.h
··· 285 285 struct dentry *d, 286 286 struct kernel_xattr_ctx *ctx); 287 287 288 + int file_setxattr(struct file *file, struct kernel_xattr_ctx *ctx); 289 + int filename_setxattr(int dfd, struct filename *filename, 290 + unsigned int lookup_flags, struct kernel_xattr_ctx *ctx); 288 291 int setxattr_copy(const char __user *name, struct kernel_xattr_ctx *ctx); 289 - int do_setxattr(struct mnt_idmap *idmap, struct dentry *dentry, 290 - struct kernel_xattr_ctx *ctx); 291 - 292 292 int import_xattr_name(struct xattr_name *kname, const char __user *name); 293 293 294 294 int may_write_xattr(struct mnt_idmap *idmap, struct inode *inode);
+44 -25
fs/xattr.c
··· 626 626 return error; 627 627 } 628 628 629 - int do_setxattr(struct mnt_idmap *idmap, struct dentry *dentry, 629 + static int do_setxattr(struct mnt_idmap *idmap, struct dentry *dentry, 630 630 struct kernel_xattr_ctx *ctx) 631 631 { 632 632 if (is_posix_acl_xattr(ctx->kname->name)) ··· 635 635 636 636 return vfs_setxattr(idmap, dentry, ctx->kname->name, 637 637 ctx->kvalue, ctx->size, ctx->flags); 638 + } 639 + 640 + int file_setxattr(struct file *f, struct kernel_xattr_ctx *ctx) 641 + { 642 + int error = mnt_want_write_file(f); 643 + 644 + if (!error) { 645 + audit_file(f); 646 + error = do_setxattr(file_mnt_idmap(f), f->f_path.dentry, ctx); 647 + mnt_drop_write_file(f); 648 + } 649 + return error; 650 + } 651 + 652 + /* unconditionally consumes filename */ 653 + int filename_setxattr(int dfd, struct filename *filename, 654 + unsigned int lookup_flags, struct kernel_xattr_ctx *ctx) 655 + { 656 + struct path path; 657 + int error; 658 + 659 + retry: 660 + error = filename_lookup(dfd, filename, lookup_flags, &path, NULL); 661 + if (error) 662 + goto out; 663 + error = mnt_want_write(path.mnt); 664 + if (!error) { 665 + error = do_setxattr(mnt_idmap(path.mnt), path.dentry, ctx); 666 + mnt_drop_write(path.mnt); 667 + } 668 + path_put(&path); 669 + if (retry_estale(error, lookup_flags)) { 670 + lookup_flags |= LOOKUP_REVAL; 671 + goto retry; 672 + } 673 + 674 + out: 675 + putname(filename); 676 + return error; 638 677 } 639 678 640 679 static int path_setxattr(const char __user *pathname, ··· 688 649 .kname = &kname, 689 650 .flags = flags, 690 651 }; 691 - struct path path; 692 652 int error; 693 653 694 654 error = setxattr_copy(name, &ctx); 695 655 if (error) 696 656 return error; 697 657 698 - retry: 699 - error = user_path_at(AT_FDCWD, pathname, lookup_flags, &path); 700 - if (error) 701 - goto out; 702 - error = mnt_want_write(path.mnt); 703 - if (!error) { 704 - error = do_setxattr(mnt_idmap(path.mnt), path.dentry, &ctx); 705 - mnt_drop_write(path.mnt); 706 - } 707 - path_put(&path); 708 - if (retry_estale(error, lookup_flags)) { 709 - lookup_flags |= LOOKUP_REVAL; 710 - goto retry; 711 - } 712 - 713 - out: 658 + error = filename_setxattr(AT_FDCWD, getname(pathname), lookup_flags, 659 + &ctx); 714 660 kvfree(ctx.kvalue); 715 661 return error; 716 662 } ··· 731 707 732 708 if (fd_empty(f)) 733 709 return -EBADF; 734 - audit_file(fd_file(f)); 710 + 735 711 error = setxattr_copy(name, &ctx); 736 712 if (error) 737 713 return error; 738 714 739 - error = mnt_want_write_file(fd_file(f)); 740 - if (!error) { 741 - error = do_setxattr(file_mnt_idmap(fd_file(f)), 742 - fd_file(f)->f_path.dentry, &ctx); 743 - mnt_drop_write_file(fd_file(f)); 744 - } 715 + error = file_setxattr(fd_file(f), &ctx); 745 716 kvfree(ctx.kvalue); 746 717 return error; 747 718 }
+7 -34
io_uring/xattr.c
··· 187 187 path = u64_to_user_ptr(READ_ONCE(sqe->addr3)); 188 188 189 189 ix->filename = getname(path); 190 - if (IS_ERR(ix->filename)) { 191 - ret = PTR_ERR(ix->filename); 192 - ix->filename = NULL; 193 - } 190 + if (IS_ERR(ix->filename)) 191 + return PTR_ERR(ix->filename); 194 192 195 - return ret; 193 + return 0; 196 194 } 197 195 198 196 int io_fsetxattr_prep(struct io_kiocb *req, const struct io_uring_sqe *sqe) ··· 198 200 return __io_setxattr_prep(req, sqe); 199 201 } 200 202 201 - static int __io_setxattr(struct io_kiocb *req, unsigned int issue_flags, 202 - const struct path *path) 203 + int io_fsetxattr(struct io_kiocb *req, unsigned int issue_flags) 203 204 { 204 205 struct io_xattr *ix = io_kiocb_to_cmd(req, struct io_xattr); 205 206 int ret; 206 207 207 - ret = mnt_want_write(path->mnt); 208 - if (!ret) { 209 - ret = do_setxattr(mnt_idmap(path->mnt), path->dentry, &ix->ctx); 210 - mnt_drop_write(path->mnt); 211 - } 212 - 213 - return ret; 214 - } 215 - 216 - int io_fsetxattr(struct io_kiocb *req, unsigned int issue_flags) 217 - { 218 - int ret; 219 - 220 208 WARN_ON_ONCE(issue_flags & IO_URING_F_NONBLOCK); 221 209 222 - ret = __io_setxattr(req, issue_flags, &req->file->f_path); 210 + ret = file_setxattr(req->file, &ix->ctx); 223 211 io_xattr_finish(req, ret); 224 212 return IOU_OK; 225 213 } ··· 213 229 int io_setxattr(struct io_kiocb *req, unsigned int issue_flags) 214 230 { 215 231 struct io_xattr *ix = io_kiocb_to_cmd(req, struct io_xattr); 216 - unsigned int lookup_flags = LOOKUP_FOLLOW; 217 - struct path path; 218 232 int ret; 219 233 220 234 WARN_ON_ONCE(issue_flags & IO_URING_F_NONBLOCK); 221 235 222 - retry: 223 - ret = filename_lookup(AT_FDCWD, ix->filename, lookup_flags, &path, NULL); 224 - if (!ret) { 225 - ret = __io_setxattr(req, issue_flags, &path); 226 - path_put(&path); 227 - if (retry_estale(ret, lookup_flags)) { 228 - lookup_flags |= LOOKUP_REVAL; 229 - goto retry; 230 - } 231 - } 232 - 236 + ret = filename_setxattr(AT_FDCWD, ix->filename, LOOKUP_FOLLOW, &ix->ctx); 237 + ix->filename = NULL; 233 238 io_xattr_finish(req, ret); 234 239 return IOU_OK; 235 240 }