mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git
synced 2025-01-15 02:05:33 +00:00
Merge branch 'kernel-6.14.cred' into vfs.all
This commit is contained in:
commit
b3ffcb5635
@ -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…
x
Reference in New Issue
Block a user