mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git
synced 2025-01-15 11:57:46 +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
|
This gets a reference on a live set of credentials, returning a pointer to
|
||||||
that set of credentials.
|
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
|
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);
|
fp = file_open_root(&root, filename, flags, mode);
|
||||||
path_put(&root);
|
path_put(&root);
|
||||||
|
|
||||||
revert_creds(old_cred);
|
put_cred(revert_creds(old_cred));
|
||||||
|
|
||||||
return fp;
|
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))
|
!(file->f_mode & FMODE_CAN_ODIRECT))
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
old_cred = override_creds_light(ctx->cred);
|
old_cred = override_creds(ctx->cred);
|
||||||
if (is_sync_kiocb(iocb)) {
|
if (is_sync_kiocb(iocb)) {
|
||||||
rwf_t rwf = iocb_to_rw_flags(flags);
|
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);
|
backing_aio_cleanup(aio, ret);
|
||||||
}
|
}
|
||||||
out:
|
out:
|
||||||
revert_creds_light(old_cred);
|
revert_creds(old_cred);
|
||||||
|
|
||||||
if (ctx->accessed)
|
if (ctx->accessed)
|
||||||
ctx->accessed(iocb->ki_filp);
|
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;
|
flags &= ~IOCB_DIO_CALLER_COMP;
|
||||||
|
|
||||||
old_cred = override_creds_light(ctx->cred);
|
old_cred = override_creds(ctx->cred);
|
||||||
if (is_sync_kiocb(iocb)) {
|
if (is_sync_kiocb(iocb)) {
|
||||||
rwf_t rwf = iocb_to_rw_flags(flags);
|
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);
|
backing_aio_cleanup(aio, ret);
|
||||||
}
|
}
|
||||||
out:
|
out:
|
||||||
revert_creds_light(old_cred);
|
revert_creds(old_cred);
|
||||||
|
|
||||||
return ret;
|
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)))
|
if (WARN_ON_ONCE(!(in->f_mode & FMODE_BACKING)))
|
||||||
return -EIO;
|
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);
|
ret = vfs_splice_read(in, &iocb->ki_pos, pipe, len, flags);
|
||||||
revert_creds_light(old_cred);
|
revert_creds(old_cred);
|
||||||
|
|
||||||
if (ctx->accessed)
|
if (ctx->accessed)
|
||||||
ctx->accessed(iocb->ki_filp);
|
ctx->accessed(iocb->ki_filp);
|
||||||
@ -310,11 +310,11 @@ ssize_t backing_file_splice_write(struct pipe_inode_info *pipe,
|
|||||||
if (ret)
|
if (ret)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
old_cred = override_creds_light(ctx->cred);
|
old_cred = override_creds(ctx->cred);
|
||||||
file_start_write(out);
|
file_start_write(out);
|
||||||
ret = out->f_op->splice_write(pipe, out, &iocb->ki_pos, len, flags);
|
ret = out->f_op->splice_write(pipe, out, &iocb->ki_pos, len, flags);
|
||||||
file_end_write(out);
|
file_end_write(out);
|
||||||
revert_creds_light(old_cred);
|
revert_creds(old_cred);
|
||||||
|
|
||||||
if (ctx->end_write)
|
if (ctx->end_write)
|
||||||
ctx->end_write(iocb, ret);
|
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);
|
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);
|
ret = call_mmap(vma->vm_file, vma);
|
||||||
revert_creds_light(old_cred);
|
revert_creds(old_cred);
|
||||||
|
|
||||||
if (ctx->accessed)
|
if (ctx->accessed)
|
||||||
ctx->accessed(user_file);
|
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);
|
int flags = nfsexp_flags(cred, exp);
|
||||||
|
|
||||||
/* discard any old override before preparing the new set */
|
/* 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();
|
new = prepare_creds();
|
||||||
if (!new)
|
if (!new)
|
||||||
return -ENOMEM;
|
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_effective = cap_raise_nfsd_set(new->cap_effective,
|
||||||
new->cap_permitted);
|
new->cap_permitted);
|
||||||
put_cred(override_creds(new));
|
put_cred(override_creds(new));
|
||||||
put_cred(new);
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
oom:
|
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,
|
beres = nfsd_file_do_acquire(NULL, net, cred, client,
|
||||||
fhp, may_flags, NULL, pnf, true);
|
fhp, may_flags, NULL, pnf, true);
|
||||||
revert_creds(save_cred);
|
put_cred(revert_creds(save_cred));
|
||||||
return beres;
|
return beres;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -82,14 +82,13 @@ nfs4_save_creds(const struct cred **original_creds)
|
|||||||
new->fsuid = GLOBAL_ROOT_UID;
|
new->fsuid = GLOBAL_ROOT_UID;
|
||||||
new->fsgid = GLOBAL_ROOT_GID;
|
new->fsgid = GLOBAL_ROOT_GID;
|
||||||
*original_creds = override_creds(new);
|
*original_creds = override_creds(new);
|
||||||
put_cred(new);
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
nfs4_reset_creds(const struct cred *original)
|
nfs4_reset_creds(const struct cred *original)
|
||||||
{
|
{
|
||||||
revert_creds(original);
|
put_cred(revert_creds(original));
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
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,
|
cap_raise_nfsd_set(new->cap_effective,
|
||||||
new->cap_permitted);
|
new->cap_permitted);
|
||||||
put_cred(override_creds(new));
|
put_cred(override_creds(new));
|
||||||
put_cred(new);
|
|
||||||
} else {
|
} else {
|
||||||
error = nfsd_setuser_and_check_port(rqstp, cred, exp);
|
error = nfsd_setuser_and_check_port(rqstp, cred, exp);
|
||||||
if (error)
|
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)
|
static const struct cred *access_override_creds(void)
|
||||||
{
|
{
|
||||||
const struct cred *old_cred;
|
|
||||||
struct cred *override_cred;
|
struct cred *override_cred;
|
||||||
|
|
||||||
override_cred = prepare_creds();
|
override_cred = prepare_creds();
|
||||||
@ -447,13 +446,7 @@ static const struct cred *access_override_creds(void)
|
|||||||
* freeing.
|
* freeing.
|
||||||
*/
|
*/
|
||||||
override_cred->non_rcu = 1;
|
override_cred->non_rcu = 1;
|
||||||
|
return override_creds(override_cred);
|
||||||
old_cred = override_creds(override_cred);
|
|
||||||
|
|
||||||
/* override_cred() gets its own ref */
|
|
||||||
put_cred(override_cred);
|
|
||||||
|
|
||||||
return old_cred;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static long do_faccessat(int dfd, const char __user *filename, int mode, int flags)
|
static long do_faccessat(int dfd, const char __user *filename, int mode, int flags)
|
||||||
@ -523,7 +516,7 @@ out_path_release:
|
|||||||
}
|
}
|
||||||
out:
|
out:
|
||||||
if (old_cred)
|
if (old_cred)
|
||||||
revert_creds(old_cred);
|
put_cred(revert_creds(old_cred));
|
||||||
|
|
||||||
return res;
|
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.
|
* referenec on the returned creds.
|
||||||
* We must be called with creator creds already, otherwise we risk
|
* We must be called with creator creds already, otherwise we risk
|
||||||
* leaking creds.
|
* 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));
|
WARN_ON_ONCE(old_cred != ovl_creds(dentry->d_sb));
|
||||||
|
|
||||||
return override_cred;
|
return override_cred;
|
||||||
|
@ -65,12 +65,12 @@ const struct cred *ovl_override_creds(struct super_block *sb)
|
|||||||
{
|
{
|
||||||
struct ovl_fs *ofs = OVL_FS(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)
|
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);
|
WARN_ON(work->saved_cred);
|
||||||
work->saved_cred = override_creds(cred);
|
work->saved_cred = override_creds(cred);
|
||||||
if (!work->saved_cred) {
|
|
||||||
abort_creds(cred);
|
|
||||||
return -EINVAL;
|
|
||||||
}
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -796,13 +792,11 @@ int ksmbd_override_fsids(struct ksmbd_work *work)
|
|||||||
void ksmbd_revert_fsids(struct ksmbd_work *work)
|
void ksmbd_revert_fsids(struct ksmbd_work *work)
|
||||||
{
|
{
|
||||||
const struct cred *cred;
|
const struct cred *cred;
|
||||||
|
|
||||||
WARN_ON(!work->saved_cred);
|
WARN_ON(!work->saved_cred);
|
||||||
|
|
||||||
cred = current_cred();
|
cred = revert_creds(work->saved_cred);
|
||||||
revert_creds(work->saved_cred);
|
|
||||||
put_cred(cred);
|
|
||||||
work->saved_cred = NULL;
|
work->saved_cred = NULL;
|
||||||
|
put_cred(cred);
|
||||||
}
|
}
|
||||||
|
|
||||||
__le32 smb_map_generic_desired_access(__le32 daccess)
|
__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 struct cred *prepare_exec_creds(void);
|
||||||
extern int commit_creds(struct cred *);
|
extern int commit_creds(struct cred *);
|
||||||
extern void abort_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 struct cred *prepare_kernel_cred(struct task_struct *);
|
||||||
extern int set_security_override(struct cred *, u32);
|
extern int set_security_override(struct cred *, u32);
|
||||||
extern int set_security_override_from_ctx(struct cred *, const char *);
|
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));
|
cred->cap_inheritable));
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
static inline const struct cred *override_creds(const struct cred *override_cred)
|
||||||
* 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)
|
|
||||||
{
|
{
|
||||||
const struct cred *old = current->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;
|
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);
|
rcu_assign_pointer(current->cred, revert_cred);
|
||||||
}
|
return override_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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -236,7 +206,8 @@ static inline const struct cred *get_cred_many(const struct cred *cred, int nr)
|
|||||||
if (!cred)
|
if (!cred)
|
||||||
return cred;
|
return cred;
|
||||||
nonconst_cred->non_rcu = 0;
|
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);
|
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.
|
* cred_fscmp - Compare two credentials with respect to filesystem access.
|
||||||
* @a: The first credential
|
* @a: The first credential
|
||||||
|
Loading…
x
Reference in New Issue
Block a user