Skip to content

Commit 1d18101

Browse files
committed
Merge tag 'kernel-6.19-rc1.cred' of git://git.kernel.org/pub/scm/linux/kernel/git/vfs/vfs
Pull cred guard updates from Christian Brauner: "This contains substantial credential infrastructure improvements adding guard-based credential management that simplifies code and eliminates manual reference counting in many subsystems. Features: - Kernel Credential Guards Add with_kernel_creds() and scoped_with_kernel_creds() guards that allow using the kernel credentials without allocating and copying them. This was requested by Linus after seeing repeated prepare_kernel_creds() calls that duplicate the kernel credentials only to drop them again later. The new guards completely avoid the allocation and never expose the temporary variable to hold the kernel credentials anywhere in callers. - Generic Credential Guards Add scoped_with_creds() guards for the common override_creds() and revert_creds() pattern. This builds on earlier work that made override_creds()/revert_creds() completely reference count free. - Prepare Credential Guards Add prepare credential guards for the more complex pattern of preparing a new set of credentials and overriding the current credentials with them: - prepare_creds() - modify new creds - override_creds() - revert_creds() - put_cred() Cleanups: - Make init_cred static since it should not be directly accessed - Add kernel_cred() helper to properly access the kernel credentials - Fix scoped_class() macro that was introduced two cycles ago - coredump: split out do_coredump() from vfs_coredump() for cleaner credential handling - coredump: move revert_cred() before coredump_cleanup() - coredump: mark struct mm_struct as const - coredump: pass struct linux_binfmt as const - sev-dev: use guard for path" * tag 'kernel-6.19-rc1.cred' of git://git.kernel.org/pub/scm/linux/kernel/git/vfs/vfs: (36 commits) trace: use override credential guard trace: use prepare credential guard coredump: use override credential guard coredump: use prepare credential guard coredump: split out do_coredump() from vfs_coredump() coredump: mark struct mm_struct as const coredump: pass struct linux_binfmt as const coredump: move revert_cred() before coredump_cleanup() sev-dev: use override credential guards sev-dev: use prepare credential guard sev-dev: use guard for path cred: add prepare credential guard net/dns_resolver: use credential guards in dns_query() cgroup: use credential guards in cgroup_attach_permissions() act: use credential guards in acct_write_process() smb: use credential guards in cifs_get_spnego_key() nfs: use credential guards in nfs_idmap_get_key() nfs: use credential guards in nfs_local_call_write() nfs: use credential guards in nfs_local_call_read() erofs: use credential guards ...
2 parents f2e74ec + c8e00cd commit 1d18101

24 files changed

Lines changed: 326 additions & 365 deletions

File tree

drivers/base/firmware_loader/main.c

Lines changed: 25 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -829,8 +829,6 @@ _request_firmware(const struct firmware **firmware_p, const char *name,
829829
size_t offset, u32 opt_flags)
830830
{
831831
struct firmware *fw = NULL;
832-
struct cred *kern_cred = NULL;
833-
const struct cred *old_cred;
834832
bool nondirect = false;
835833
int ret;
836834

@@ -871,45 +869,38 @@ _request_firmware(const struct firmware **firmware_p, const char *name,
871869
* called by a driver when serving an unrelated request from userland, we use
872870
* the kernel credentials to read the file.
873871
*/
874-
kern_cred = prepare_kernel_cred(&init_task);
875-
if (!kern_cred) {
876-
ret = -ENOMEM;
877-
goto out;
878-
}
879-
old_cred = override_creds(kern_cred);
872+
scoped_with_kernel_creds() {
873+
ret = fw_get_filesystem_firmware(device, fw->priv, "", NULL);
880874

881-
ret = fw_get_filesystem_firmware(device, fw->priv, "", NULL);
882-
883-
/* Only full reads can support decompression, platform, and sysfs. */
884-
if (!(opt_flags & FW_OPT_PARTIAL))
885-
nondirect = true;
875+
/* Only full reads can support decompression, platform, and sysfs. */
876+
if (!(opt_flags & FW_OPT_PARTIAL))
877+
nondirect = true;
886878

887879
#ifdef CONFIG_FW_LOADER_COMPRESS_ZSTD
888-
if (ret == -ENOENT && nondirect)
889-
ret = fw_get_filesystem_firmware(device, fw->priv, ".zst",
890-
fw_decompress_zstd);
880+
if (ret == -ENOENT && nondirect)
881+
ret = fw_get_filesystem_firmware(device, fw->priv, ".zst",
882+
fw_decompress_zstd);
891883
#endif
892884
#ifdef CONFIG_FW_LOADER_COMPRESS_XZ
893-
if (ret == -ENOENT && nondirect)
894-
ret = fw_get_filesystem_firmware(device, fw->priv, ".xz",
895-
fw_decompress_xz);
885+
if (ret == -ENOENT && nondirect)
886+
ret = fw_get_filesystem_firmware(device, fw->priv, ".xz",
887+
fw_decompress_xz);
896888
#endif
897-
if (ret == -ENOENT && nondirect)
898-
ret = firmware_fallback_platform(fw->priv);
889+
if (ret == -ENOENT && nondirect)
890+
ret = firmware_fallback_platform(fw->priv);
899891

900-
if (ret) {
901-
if (!(opt_flags & FW_OPT_NO_WARN))
902-
dev_warn(device,
903-
"Direct firmware load for %s failed with error %d\n",
904-
name, ret);
905-
if (nondirect)
906-
ret = firmware_fallback_sysfs(fw, name, device,
907-
opt_flags, ret);
908-
} else
909-
ret = assign_fw(fw, device);
910-
911-
revert_creds(old_cred);
912-
put_cred(kern_cred);
892+
if (ret) {
893+
if (!(opt_flags & FW_OPT_NO_WARN))
894+
dev_warn(device,
895+
"Direct firmware load for %s failed with error %d\n",
896+
name, ret);
897+
if (nondirect)
898+
ret = firmware_fallback_sysfs(fw, name, device,
899+
opt_flags, ret);
900+
} else {
901+
ret = assign_fw(fw, device);
902+
}
903+
}
913904

914905
out:
915906
if (ret < 0) {

drivers/block/nbd.c

Lines changed: 21 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,6 @@
5252
static DEFINE_IDR(nbd_index_idr);
5353
static DEFINE_MUTEX(nbd_index_mutex);
5454
static struct workqueue_struct *nbd_del_wq;
55-
static struct cred *nbd_cred;
5655
static int nbd_total_devices = 0;
5756

5857
struct nbd_sock {
@@ -555,7 +554,6 @@ static int __sock_xmit(struct nbd_device *nbd, struct socket *sock, int send,
555554
int result;
556555
struct msghdr msg = {} ;
557556
unsigned int noreclaim_flag;
558-
const struct cred *old_cred;
559557

560558
if (unlikely(!sock)) {
561559
dev_err_ratelimited(disk_to_dev(nbd->disk),
@@ -564,33 +562,32 @@ static int __sock_xmit(struct nbd_device *nbd, struct socket *sock, int send,
564562
return -EINVAL;
565563
}
566564

567-
old_cred = override_creds(nbd_cred);
568-
569565
msg.msg_iter = *iter;
570566

571567
noreclaim_flag = memalloc_noreclaim_save();
572-
do {
573-
sock->sk->sk_allocation = GFP_NOIO | __GFP_MEMALLOC;
574-
sock->sk->sk_use_task_frag = false;
575-
msg.msg_flags = msg_flags | MSG_NOSIGNAL;
576-
577-
if (send)
578-
result = sock_sendmsg(sock, &msg);
579-
else
580-
result = sock_recvmsg(sock, &msg, msg.msg_flags);
581-
582-
if (result <= 0) {
583-
if (result == 0)
584-
result = -EPIPE; /* short read */
585-
break;
586-
}
587-
if (sent)
588-
*sent += result;
589-
} while (msg_data_left(&msg));
590568

591-
memalloc_noreclaim_restore(noreclaim_flag);
569+
scoped_with_kernel_creds() {
570+
do {
571+
sock->sk->sk_allocation = GFP_NOIO | __GFP_MEMALLOC;
572+
sock->sk->sk_use_task_frag = false;
573+
msg.msg_flags = msg_flags | MSG_NOSIGNAL;
592574

593-
revert_creds(old_cred);
575+
if (send)
576+
result = sock_sendmsg(sock, &msg);
577+
else
578+
result = sock_recvmsg(sock, &msg, msg.msg_flags);
579+
580+
if (result <= 0) {
581+
if (result == 0)
582+
result = -EPIPE; /* short read */
583+
break;
584+
}
585+
if (sent)
586+
*sent += result;
587+
} while (msg_data_left(&msg));
588+
}
589+
590+
memalloc_noreclaim_restore(noreclaim_flag);
594591

595592
return result;
596593
}
@@ -2683,15 +2680,7 @@ static int __init nbd_init(void)
26832680
return -ENOMEM;
26842681
}
26852682

2686-
nbd_cred = prepare_kernel_cred(&init_task);
2687-
if (!nbd_cred) {
2688-
destroy_workqueue(nbd_del_wq);
2689-
unregister_blkdev(NBD_MAJOR, "nbd");
2690-
return -ENOMEM;
2691-
}
2692-
26932683
if (genl_register_family(&nbd_genl_family)) {
2694-
put_cred(nbd_cred);
26952684
destroy_workqueue(nbd_del_wq);
26962685
unregister_blkdev(NBD_MAJOR, "nbd");
26972686
return -EINVAL;
@@ -2746,7 +2735,6 @@ static void __exit nbd_cleanup(void)
27462735
/* Also wait for nbd_dev_remove_work() completes */
27472736
destroy_workqueue(nbd_del_wq);
27482737

2749-
put_cred(nbd_cred);
27502738
idr_destroy(&nbd_index_idr);
27512739
unregister_blkdev(NBD_MAJOR, "nbd");
27522740
}

drivers/crypto/ccp/sev-dev.c

Lines changed: 5 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -259,27 +259,20 @@ static int sev_cmd_buffer_len(int cmd)
259259

260260
static struct file *open_file_as_root(const char *filename, int flags, umode_t mode)
261261
{
262-
struct file *fp;
263-
struct path root;
264-
struct cred *cred;
265-
const struct cred *old_cred;
262+
struct path root __free(path_put) = {};
266263

267264
task_lock(&init_task);
268265
get_fs_root(init_task.fs, &root);
269266
task_unlock(&init_task);
270267

271-
cred = prepare_creds();
268+
CLASS(prepare_creds, cred)();
272269
if (!cred)
273270
return ERR_PTR(-ENOMEM);
274-
cred->fsuid = GLOBAL_ROOT_UID;
275-
old_cred = override_creds(cred);
276271

277-
fp = file_open_root(&root, filename, flags, mode);
278-
path_put(&root);
279-
280-
put_cred(revert_creds(old_cred));
272+
cred->fsuid = GLOBAL_ROOT_UID;
281273

282-
return fp;
274+
scoped_with_creds(cred)
275+
return file_open_root(&root, filename, flags, mode);
283276
}
284277

285278
static int sev_read_init_ex_file(void)

drivers/target/target_core_configfs.c

Lines changed: 2 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -3670,8 +3670,6 @@ static int __init target_core_init_configfs(void)
36703670
{
36713671
struct configfs_subsystem *subsys = &target_core_fabrics;
36723672
struct t10_alua_lu_gp *lu_gp;
3673-
struct cred *kern_cred;
3674-
const struct cred *old_cred;
36753673
int ret;
36763674

36773675
pr_debug("TARGET_CORE[0]: Loading Generic Kernel Storage"
@@ -3748,16 +3746,8 @@ static int __init target_core_init_configfs(void)
37483746
if (ret < 0)
37493747
goto out;
37503748

3751-
/* We use the kernel credentials to access the target directory */
3752-
kern_cred = prepare_kernel_cred(&init_task);
3753-
if (!kern_cred) {
3754-
ret = -ENOMEM;
3755-
goto out;
3756-
}
3757-
old_cred = override_creds(kern_cred);
3758-
target_init_dbroot();
3759-
revert_creds(old_cred);
3760-
put_cred(kern_cred);
3749+
scoped_with_kernel_creds()
3750+
target_init_dbroot();
37613751

37623752
return 0;
37633753

fs/aio.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1640,10 +1640,10 @@ static int aio_write(struct kiocb *req, const struct iocb *iocb,
16401640
static void aio_fsync_work(struct work_struct *work)
16411641
{
16421642
struct aio_kiocb *iocb = container_of(work, struct aio_kiocb, fsync.work);
1643-
const struct cred *old_cred = override_creds(iocb->fsync.creds);
16441643

1645-
iocb->ki_res.res = vfs_fsync(iocb->fsync.file, iocb->fsync.datasync);
1646-
revert_creds(old_cred);
1644+
scoped_with_creds(iocb->fsync.creds)
1645+
iocb->ki_res.res = vfs_fsync(iocb->fsync.file, iocb->fsync.datasync);
1646+
16471647
put_cred(iocb->fsync.creds);
16481648
iocb_put(iocb);
16491649
}

0 commit comments

Comments
 (0)