mirror of
				git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
				synced 2025-10-31 08:44:41 +00:00 
			
		
		
		
	kernel-6.14-rc1.cred
-----BEGIN PGP SIGNATURE-----
 
 iHUEABYKAB0WIQRAhzRXHqcMeLMyaSiRxhvAZXjcogUCZ4pRuAAKCRCRxhvAZXjc
 okEiAP4wZOkUGX+d3FUXxM1DJfCsBssoYh01S4LE+s+hkq81vgD8D7PRZk7d12Jw
 zaS6/cLt12UDz1v6Ez103S9AQ5E6ywg=
 =Sknj
 -----END PGP SIGNATURE-----
Merge tag 'kernel-6.14-rc1.cred' of git://git.kernel.org/pub/scm/linux/kernel/git/vfs/vfs
Pull cred refcount updates from Christian Brauner:
 "For the v6.13 cycle we switched overlayfs to a variant of
  override_creds() that doesn't take an extra reference. To this end the
  {override,revert}_creds_light() helpers were introduced.
  This generalizes the idea behind {override,revert}_creds_light() to
  the {override,revert}_creds() helpers. Afterwards overriding and
  reverting credentials is reference count free unless the caller
  explicitly takes a reference.
  All callers have been appropriately ported"
* tag 'kernel-6.14-rc1.cred' of git://git.kernel.org/pub/scm/linux/kernel/git/vfs/vfs: (30 commits)
  cred: fold get_new_cred_many() into get_cred_many()
  cred: remove unused get_new_cred()
  nfsd: avoid pointless cred reference count bump
  cachefiles: avoid pointless cred reference count bump
  dns_resolver: avoid pointless cred reference count bump
  trace: avoid pointless cred reference count bump
  cgroup: avoid pointless cred reference count bump
  acct: avoid pointless reference count bump
  io_uring: avoid pointless cred reference count bump
  smb: avoid pointless cred reference count bump
  cifs: avoid pointless cred reference count bump
  cifs: avoid pointless cred reference count bump
  ovl: avoid pointless cred reference count bump
  open: avoid pointless cred reference count bump
  nfsfh: avoid pointless cred reference count bump
  nfs/nfs4recover: avoid pointless cred reference count bump
  nfs/nfs4idmap: avoid pointless reference count bump
  nfs/localio: avoid pointless cred reference count bumps
  coredump: avoid pointless cred reference count bump
  binfmt_misc: avoid pointless cred reference count bump
  ...
			
			
This commit is contained in:
		
						commit
						37c12fcb3c
					
				
					 13 changed files with 29 additions and 129 deletions
				
			
		|  | @ -527,11 +527,6 @@ There are some functions to help manage credentials: | |||
|      This gets a reference on a live set of credentials, returning a pointer to | ||||
|      that set of credentials. | ||||
| 
 | ||||
|  - ``struct cred *get_new_cred(struct cred *cred);`` | ||||
| 
 | ||||
|      This gets a reference on a set of credentials that is under construction | ||||
|      and is thus still mutable, returning a pointer to that set of credentials. | ||||
| 
 | ||||
| 
 | ||||
| Open File Credentials | ||||
| ===================== | ||||
|  |  | |||
|  | @ -249,7 +249,7 @@ static struct file *open_file_as_root(const char *filename, int flags, umode_t m | |||
| 	fp = file_open_root(&root, filename, flags, mode); | ||||
| 	path_put(&root); | ||||
| 
 | ||||
| 	revert_creds(old_cred); | ||||
| 	put_cred(revert_creds(old_cred)); | ||||
| 
 | ||||
| 	return fp; | ||||
| } | ||||
|  |  | |||
|  | @ -176,7 +176,7 @@ ssize_t backing_file_read_iter(struct file *file, struct iov_iter *iter, | |||
| 	    !(file->f_mode & FMODE_CAN_ODIRECT)) | ||||
| 		return -EINVAL; | ||||
| 
 | ||||
| 	old_cred = override_creds_light(ctx->cred); | ||||
| 	old_cred = override_creds(ctx->cred); | ||||
| 	if (is_sync_kiocb(iocb)) { | ||||
| 		rwf_t rwf = iocb_to_rw_flags(flags); | ||||
| 
 | ||||
|  | @ -197,7 +197,7 @@ ssize_t backing_file_read_iter(struct file *file, struct iov_iter *iter, | |||
| 			backing_aio_cleanup(aio, ret); | ||||
| 	} | ||||
| out: | ||||
| 	revert_creds_light(old_cred); | ||||
| 	revert_creds(old_cred); | ||||
| 
 | ||||
| 	if (ctx->accessed) | ||||
| 		ctx->accessed(iocb->ki_filp); | ||||
|  | @ -233,7 +233,7 @@ ssize_t backing_file_write_iter(struct file *file, struct iov_iter *iter, | |||
| 	 */ | ||||
| 	flags &= ~IOCB_DIO_CALLER_COMP; | ||||
| 
 | ||||
| 	old_cred = override_creds_light(ctx->cred); | ||||
| 	old_cred = override_creds(ctx->cred); | ||||
| 	if (is_sync_kiocb(iocb)) { | ||||
| 		rwf_t rwf = iocb_to_rw_flags(flags); | ||||
| 
 | ||||
|  | @ -264,7 +264,7 @@ ssize_t backing_file_write_iter(struct file *file, struct iov_iter *iter, | |||
| 			backing_aio_cleanup(aio, ret); | ||||
| 	} | ||||
| out: | ||||
| 	revert_creds_light(old_cred); | ||||
| 	revert_creds(old_cred); | ||||
| 
 | ||||
| 	return ret; | ||||
| } | ||||
|  | @ -281,9 +281,9 @@ ssize_t backing_file_splice_read(struct file *in, struct kiocb *iocb, | |||
| 	if (WARN_ON_ONCE(!(in->f_mode & FMODE_BACKING))) | ||||
| 		return -EIO; | ||||
| 
 | ||||
| 	old_cred = override_creds_light(ctx->cred); | ||||
| 	old_cred = override_creds(ctx->cred); | ||||
| 	ret = vfs_splice_read(in, &iocb->ki_pos, pipe, len, flags); | ||||
| 	revert_creds_light(old_cred); | ||||
| 	revert_creds(old_cred); | ||||
| 
 | ||||
| 	if (ctx->accessed) | ||||
| 		ctx->accessed(iocb->ki_filp); | ||||
|  | @ -310,11 +310,11 @@ ssize_t backing_file_splice_write(struct pipe_inode_info *pipe, | |||
| 	if (ret) | ||||
| 		return ret; | ||||
| 
 | ||||
| 	old_cred = override_creds_light(ctx->cred); | ||||
| 	old_cred = override_creds(ctx->cred); | ||||
| 	file_start_write(out); | ||||
| 	ret = out->f_op->splice_write(pipe, out, &iocb->ki_pos, len, flags); | ||||
| 	file_end_write(out); | ||||
| 	revert_creds_light(old_cred); | ||||
| 	revert_creds(old_cred); | ||||
| 
 | ||||
| 	if (ctx->end_write) | ||||
| 		ctx->end_write(iocb, ret); | ||||
|  | @ -338,9 +338,9 @@ int backing_file_mmap(struct file *file, struct vm_area_struct *vma, | |||
| 
 | ||||
| 	vma_set_file(vma, file); | ||||
| 
 | ||||
| 	old_cred = override_creds_light(ctx->cred); | ||||
| 	old_cred = override_creds(ctx->cred); | ||||
| 	ret = call_mmap(vma->vm_file, vma); | ||||
| 	revert_creds_light(old_cred); | ||||
| 	revert_creds(old_cred); | ||||
| 
 | ||||
| 	if (ctx->accessed) | ||||
| 		ctx->accessed(user_file); | ||||
|  |  | |||
|  | @ -27,7 +27,7 @@ int nfsd_setuser(struct svc_cred *cred, struct svc_export *exp) | |||
| 	int flags = nfsexp_flags(cred, exp); | ||||
| 
 | ||||
| 	/* discard any old override before preparing the new set */ | ||||
| 	revert_creds(get_cred(current_real_cred())); | ||||
| 	put_cred(revert_creds(get_cred(current_real_cred()))); | ||||
| 	new = prepare_creds(); | ||||
| 	if (!new) | ||||
| 		return -ENOMEM; | ||||
|  | @ -80,7 +80,6 @@ int nfsd_setuser(struct svc_cred *cred, struct svc_export *exp) | |||
| 		new->cap_effective = cap_raise_nfsd_set(new->cap_effective, | ||||
| 							new->cap_permitted); | ||||
| 	put_cred(override_creds(new)); | ||||
| 	put_cred(new); | ||||
| 	return 0; | ||||
| 
 | ||||
| oom: | ||||
|  |  | |||
|  | @ -1248,7 +1248,7 @@ nfsd_file_acquire_local(struct net *net, struct svc_cred *cred, | |||
| 
 | ||||
| 	beres = nfsd_file_do_acquire(NULL, net, cred, client, | ||||
| 				     fhp, may_flags, NULL, pnf, true); | ||||
| 	revert_creds(save_cred); | ||||
| 	put_cred(revert_creds(save_cred)); | ||||
| 	return beres; | ||||
| } | ||||
| 
 | ||||
|  |  | |||
|  | @ -82,14 +82,13 @@ nfs4_save_creds(const struct cred **original_creds) | |||
| 	new->fsuid = GLOBAL_ROOT_UID; | ||||
| 	new->fsgid = GLOBAL_ROOT_GID; | ||||
| 	*original_creds = override_creds(new); | ||||
| 	put_cred(new); | ||||
| 	return 0; | ||||
| } | ||||
| 
 | ||||
| static void | ||||
| nfs4_reset_creds(const struct cred *original) | ||||
| { | ||||
| 	revert_creds(original); | ||||
| 	put_cred(revert_creds(original)); | ||||
| } | ||||
| 
 | ||||
| static void | ||||
|  |  | |||
|  | @ -222,7 +222,6 @@ static __be32 nfsd_set_fh_dentry(struct svc_rqst *rqstp, struct net *net, | |||
| 			cap_raise_nfsd_set(new->cap_effective, | ||||
| 					   new->cap_permitted); | ||||
| 		put_cred(override_creds(new)); | ||||
| 		put_cred(new); | ||||
| 	} else { | ||||
| 		error = nfsd_setuser_and_check_port(rqstp, cred, exp); | ||||
| 		if (error) | ||||
|  |  | |||
							
								
								
									
										11
									
								
								fs/open.c
									
										
									
									
									
								
							
							
						
						
									
										11
									
								
								fs/open.c
									
										
									
									
									
								
							|  | @ -402,7 +402,6 @@ static bool access_need_override_creds(int flags) | |||
| 
 | ||||
| static const struct cred *access_override_creds(void) | ||||
| { | ||||
| 	const struct cred *old_cred; | ||||
| 	struct cred *override_cred; | ||||
| 
 | ||||
| 	override_cred = prepare_creds(); | ||||
|  | @ -447,13 +446,7 @@ static const struct cred *access_override_creds(void) | |||
| 	 * freeing. | ||||
| 	 */ | ||||
| 	override_cred->non_rcu = 1; | ||||
| 
 | ||||
| 	old_cred = override_creds(override_cred); | ||||
| 
 | ||||
| 	/* override_cred() gets its own ref */ | ||||
| 	put_cred(override_cred); | ||||
| 
 | ||||
| 	return old_cred; | ||||
| 	return override_creds(override_cred); | ||||
| } | ||||
| 
 | ||||
| static long do_faccessat(int dfd, const char __user *filename, int mode, int flags) | ||||
|  | @ -523,7 +516,7 @@ out_path_release: | |||
| 	} | ||||
| out: | ||||
| 	if (old_cred) | ||||
| 		revert_creds(old_cred); | ||||
| 		put_cred(revert_creds(old_cred)); | ||||
| 
 | ||||
| 	return res; | ||||
| } | ||||
|  |  | |||
|  | @ -575,12 +575,12 @@ static const struct cred *ovl_setup_cred_for_create(struct dentry *dentry, | |||
| 	} | ||||
| 
 | ||||
| 	/*
 | ||||
| 	 * Caller is going to match this with revert_creds_light() and drop | ||||
| 	 * Caller is going to match this with revert_creds() and drop | ||||
| 	 * referenec on the returned creds. | ||||
| 	 * We must be called with creator creds already, otherwise we risk | ||||
| 	 * leaking creds. | ||||
| 	 */ | ||||
| 	old_cred = override_creds_light(override_cred); | ||||
| 	old_cred = override_creds(override_cred); | ||||
| 	WARN_ON_ONCE(old_cred != ovl_creds(dentry->d_sb)); | ||||
| 
 | ||||
| 	return override_cred; | ||||
|  |  | |||
|  | @ -65,12 +65,12 @@ const struct cred *ovl_override_creds(struct super_block *sb) | |||
| { | ||||
| 	struct ovl_fs *ofs = OVL_FS(sb); | ||||
| 
 | ||||
| 	return override_creds_light(ofs->creator_cred); | ||||
| 	return override_creds(ofs->creator_cred); | ||||
| } | ||||
| 
 | ||||
| void ovl_revert_creds(const struct cred *old_cred) | ||||
| { | ||||
| 	revert_creds_light(old_cred); | ||||
| 	revert_creds(old_cred); | ||||
| } | ||||
| 
 | ||||
| /*
 | ||||
|  |  | |||
|  | @ -781,10 +781,6 @@ int __ksmbd_override_fsids(struct ksmbd_work *work, | |||
| 
 | ||||
| 	WARN_ON(work->saved_cred); | ||||
| 	work->saved_cred = override_creds(cred); | ||||
| 	if (!work->saved_cred) { | ||||
| 		abort_creds(cred); | ||||
| 		return -EINVAL; | ||||
| 	} | ||||
| 	return 0; | ||||
| } | ||||
| 
 | ||||
|  | @ -796,13 +792,11 @@ int ksmbd_override_fsids(struct ksmbd_work *work) | |||
| void ksmbd_revert_fsids(struct ksmbd_work *work) | ||||
| { | ||||
| 	const struct cred *cred; | ||||
| 
 | ||||
| 	WARN_ON(!work->saved_cred); | ||||
| 
 | ||||
| 	cred = current_cred(); | ||||
| 	revert_creds(work->saved_cred); | ||||
| 	put_cred(cred); | ||||
| 	cred = revert_creds(work->saved_cred); | ||||
| 	work->saved_cred = NULL; | ||||
| 	put_cred(cred); | ||||
| } | ||||
| 
 | ||||
| __le32 smb_map_generic_desired_access(__le32 daccess) | ||||
|  |  | |||
|  | @ -155,8 +155,6 @@ extern struct cred *prepare_creds(void); | |||
| extern struct cred *prepare_exec_creds(void); | ||||
| extern int commit_creds(struct cred *); | ||||
| extern void abort_creds(struct cred *); | ||||
| extern const struct cred *override_creds(const struct cred *); | ||||
| extern void revert_creds(const struct cred *); | ||||
| extern struct cred *prepare_kernel_cred(struct task_struct *); | ||||
| extern int set_security_override(struct cred *, u32); | ||||
| extern int set_security_override_from_ctx(struct cred *, const char *); | ||||
|  | @ -172,12 +170,7 @@ static inline bool cap_ambient_invariant_ok(const struct cred *cred) | |||
| 					  cred->cap_inheritable)); | ||||
| } | ||||
| 
 | ||||
| /*
 | ||||
|  * Override creds without bumping reference count. Caller must ensure | ||||
|  * reference remains valid or has taken reference. Almost always not the | ||||
|  * interface you want. Use override_creds()/revert_creds() instead. | ||||
|  */ | ||||
| static inline const struct cred *override_creds_light(const struct cred *override_cred) | ||||
| static inline const struct cred *override_creds(const struct cred *override_cred) | ||||
| { | ||||
| 	const struct cred *old = current->cred; | ||||
| 
 | ||||
|  | @ -185,35 +178,12 @@ static inline const struct cred *override_creds_light(const struct cred *overrid | |||
| 	return old; | ||||
| } | ||||
| 
 | ||||
| static inline void revert_creds_light(const struct cred *revert_cred) | ||||
| static inline const struct cred *revert_creds(const struct cred *revert_cred) | ||||
| { | ||||
| 	const struct cred *override_cred = current->cred; | ||||
| 
 | ||||
| 	rcu_assign_pointer(current->cred, revert_cred); | ||||
| } | ||||
| 
 | ||||
| /**
 | ||||
|  * get_new_cred_many - Get references on a new set of credentials | ||||
|  * @cred: The new credentials to reference | ||||
|  * @nr: Number of references to acquire | ||||
|  * | ||||
|  * Get references on the specified set of new credentials.  The caller must | ||||
|  * release all acquired references. | ||||
|  */ | ||||
| static inline struct cred *get_new_cred_many(struct cred *cred, int nr) | ||||
| { | ||||
| 	atomic_long_add(nr, &cred->usage); | ||||
| 	return cred; | ||||
| } | ||||
| 
 | ||||
| /**
 | ||||
|  * get_new_cred - Get a reference on a new set of credentials | ||||
|  * @cred: The new credentials to reference | ||||
|  * | ||||
|  * Get a reference on the specified set of new credentials.  The caller must | ||||
|  * release the reference. | ||||
|  */ | ||||
| static inline struct cred *get_new_cred(struct cred *cred) | ||||
| { | ||||
| 	return get_new_cred_many(cred, 1); | ||||
| 	return override_cred; | ||||
| } | ||||
| 
 | ||||
| /**
 | ||||
|  | @ -236,7 +206,8 @@ static inline const struct cred *get_cred_many(const struct cred *cred, int nr) | |||
| 	if (!cred) | ||||
| 		return cred; | ||||
| 	nonconst_cred->non_rcu = 0; | ||||
| 	return get_new_cred_many(nonconst_cred, nr); | ||||
| 	atomic_long_add(nr, &nonconst_cred->usage); | ||||
| 	return cred; | ||||
| } | ||||
| 
 | ||||
| /*
 | ||||
|  |  | |||
|  | @ -476,56 +476,6 @@ void abort_creds(struct cred *new) | |||
| } | ||||
| EXPORT_SYMBOL(abort_creds); | ||||
| 
 | ||||
| /**
 | ||||
|  * override_creds - Override the current process's subjective credentials | ||||
|  * @new: The credentials to be assigned | ||||
|  * | ||||
|  * Install a set of temporary override subjective credentials on the current | ||||
|  * process, returning the old set for later reversion. | ||||
|  */ | ||||
| const struct cred *override_creds(const struct cred *new) | ||||
| { | ||||
| 	const struct cred *old; | ||||
| 
 | ||||
| 	kdebug("override_creds(%p{%ld})", new, | ||||
| 	       atomic_long_read(&new->usage)); | ||||
| 
 | ||||
| 	/*
 | ||||
| 	 * NOTE! This uses 'get_new_cred()' rather than 'get_cred()'. | ||||
| 	 * | ||||
| 	 * That means that we do not clear the 'non_rcu' flag, since | ||||
| 	 * we are only installing the cred into the thread-synchronous | ||||
| 	 * '->cred' pointer, not the '->real_cred' pointer that is | ||||
| 	 * visible to other threads under RCU. | ||||
| 	 */ | ||||
| 	get_new_cred((struct cred *)new); | ||||
| 	old = override_creds_light(new); | ||||
| 
 | ||||
| 	kdebug("override_creds() = %p{%ld}", old, | ||||
| 	       atomic_long_read(&old->usage)); | ||||
| 	return old; | ||||
| } | ||||
| EXPORT_SYMBOL(override_creds); | ||||
| 
 | ||||
| /**
 | ||||
|  * revert_creds - Revert a temporary subjective credentials override | ||||
|  * @old: The credentials to be restored | ||||
|  * | ||||
|  * Revert a temporary set of override subjective credentials to an old set, | ||||
|  * discarding the override set. | ||||
|  */ | ||||
| void revert_creds(const struct cred *old) | ||||
| { | ||||
| 	const struct cred *override = current->cred; | ||||
| 
 | ||||
| 	kdebug("revert_creds(%p{%ld})", old, | ||||
| 	       atomic_long_read(&old->usage)); | ||||
| 
 | ||||
| 	revert_creds_light(old); | ||||
| 	put_cred(override); | ||||
| } | ||||
| EXPORT_SYMBOL(revert_creds); | ||||
| 
 | ||||
| /**
 | ||||
|  * cred_fscmp - Compare two credentials with respect to filesystem access. | ||||
|  * @a: The first credential | ||||
|  |  | |||
		Loading…
	
	Add table
		
		Reference in a new issue
	
	 Linus Torvalds
						Linus Torvalds