hc
2024-10-22 8ac6c7a54ed1b98d142dce24b11c6de6a1e239a5
kernel/kernel/cred.c
....@@ -1,12 +1,8 @@
1
+// SPDX-License-Identifier: GPL-2.0-or-later
12 /* Task credentials management - see Documentation/security/credentials.rst
23 *
34 * Copyright (C) 2008 Red Hat, Inc. All Rights Reserved.
45 * Written by David Howells (dhowells@redhat.com)
5
- *
6
- * This program is free software; you can redistribute it and/or
7
- * modify it under the terms of the GNU General Public Licence
8
- * as published by the Free Software Foundation; either version
9
- * 2 of the Licence, or (at your option) any later version.
106 */
117 #include <linux/export.h>
128 #include <linux/cred.h>
....@@ -19,6 +15,9 @@
1915 #include <linux/security.h>
2016 #include <linux/binfmts.h>
2117 #include <linux/cn_proc.h>
18
+#include <linux/uidgid.h>
19
+
20
+#include <trace/hooks/creds.h>
2221
2322 #if 0
2423 #define kdebug(FMT, ...) \
....@@ -176,6 +175,12 @@
176175 validate_creds(cred);
177176 alter_cred_subscribers(cred, -1);
178177 put_cred(cred);
178
+
179
+#ifdef CONFIG_KEYS_REQUEST_CACHE
180
+ key_put(tsk->cached_requested_key);
181
+ tsk->cached_requested_key = NULL;
182
+#endif
183
+ trace_android_vh_exit_creds(tsk, cred);
179184 }
180185
181186 /**
....@@ -197,11 +202,12 @@
197202 do {
198203 cred = __task_cred((task));
199204 BUG_ON(!cred);
200
- } while (!atomic_inc_not_zero(&((struct cred *)cred)->usage));
205
+ } while (!get_cred_rcu(cred));
201206
202207 rcu_read_unlock();
203208 return cred;
204209 }
210
+EXPORT_SYMBOL(get_task_cred);
205211
206212 /*
207213 * Allocate blank credentials, such that the credentials can be filled in at a
....@@ -312,6 +318,9 @@
312318 new->process_keyring = NULL;
313319 #endif
314320
321
+ new->suid = new->fsuid = new->euid;
322
+ new->sgid = new->fsgid = new->egid;
323
+
315324 return new;
316325 }
317326
....@@ -328,6 +337,10 @@
328337 {
329338 struct cred *new;
330339 int ret;
340
+
341
+#ifdef CONFIG_KEYS_REQUEST_CACHE
342
+ p->cached_requested_key = NULL;
343
+#endif
331344
332345 if (
333346 #ifdef CONFIG_KEYS
....@@ -466,9 +479,9 @@
466479
467480 /* alter the thread keyring */
468481 if (!uid_eq(new->fsuid, old->fsuid))
469
- key_fsuid_changed(task);
482
+ key_fsuid_changed(new);
470483 if (!gid_eq(new->fsgid, old->fsgid))
471
- key_fsgid_changed(task);
484
+ key_fsgid_changed(new);
472485
473486 /* do it
474487 * RLIMIT_NPROC limits on user->processes have already been checked
....@@ -479,6 +492,7 @@
479492 atomic_inc(&new->user->processes);
480493 rcu_assign_pointer(task->real_cred, new);
481494 rcu_assign_pointer(task->cred, new);
495
+ trace_android_vh_commit_creds(task, new);
482496 if (new->user != old->user)
483497 atomic_dec(&old->user->processes);
484498 alter_cred_subscribers(old, -2);
....@@ -556,6 +570,7 @@
556570 get_new_cred((struct cred *)new);
557571 alter_cred_subscribers(new, 1);
558572 rcu_assign_pointer(current->cred, new);
573
+ trace_android_vh_override_creds(current, new);
559574 alter_cred_subscribers(old, -1);
560575
561576 kdebug("override_creds() = %p{%d,%d}", old,
....@@ -584,10 +599,65 @@
584599 validate_creds(override);
585600 alter_cred_subscribers(old, 1);
586601 rcu_assign_pointer(current->cred, old);
602
+ trace_android_vh_revert_creds(current, old);
587603 alter_cred_subscribers(override, -1);
588604 put_cred(override);
589605 }
590606 EXPORT_SYMBOL(revert_creds);
607
+
608
+/**
609
+ * cred_fscmp - Compare two credentials with respect to filesystem access.
610
+ * @a: The first credential
611
+ * @b: The second credential
612
+ *
613
+ * cred_cmp() will return zero if both credentials have the same
614
+ * fsuid, fsgid, and supplementary groups. That is, if they will both
615
+ * provide the same access to files based on mode/uid/gid.
616
+ * If the credentials are different, then either -1 or 1 will
617
+ * be returned depending on whether @a comes before or after @b
618
+ * respectively in an arbitrary, but stable, ordering of credentials.
619
+ *
620
+ * Return: -1, 0, or 1 depending on comparison
621
+ */
622
+int cred_fscmp(const struct cred *a, const struct cred *b)
623
+{
624
+ struct group_info *ga, *gb;
625
+ int g;
626
+
627
+ if (a == b)
628
+ return 0;
629
+ if (uid_lt(a->fsuid, b->fsuid))
630
+ return -1;
631
+ if (uid_gt(a->fsuid, b->fsuid))
632
+ return 1;
633
+
634
+ if (gid_lt(a->fsgid, b->fsgid))
635
+ return -1;
636
+ if (gid_gt(a->fsgid, b->fsgid))
637
+ return 1;
638
+
639
+ ga = a->group_info;
640
+ gb = b->group_info;
641
+ if (ga == gb)
642
+ return 0;
643
+ if (ga == NULL)
644
+ return -1;
645
+ if (gb == NULL)
646
+ return 1;
647
+ if (ga->ngroups < gb->ngroups)
648
+ return -1;
649
+ if (ga->ngroups > gb->ngroups)
650
+ return 1;
651
+
652
+ for (g = 0; g < ga->ngroups; g++) {
653
+ if (gid_lt(ga->gid[g], gb->gid[g]))
654
+ return -1;
655
+ if (gid_gt(ga->gid[g], gb->gid[g]))
656
+ return 1;
657
+ }
658
+ return 0;
659
+}
660
+EXPORT_SYMBOL(cred_fscmp);
591661
592662 /*
593663 * initialise the credentials stuff
....@@ -614,8 +684,6 @@
614684 * The caller may change these controls afterwards if desired.
615685 *
616686 * Returns the new credentials or NULL if out of memory.
617
- *
618
- * Does not take, and does not return holding current->cred_replace_mutex.
619687 */
620688 struct cred *prepare_kernel_cred(struct task_struct *daemon)
621689 {
....@@ -730,19 +798,6 @@
730798 {
731799 if (cred->magic != CRED_MAGIC)
732800 return true;
733
-#ifdef CONFIG_SECURITY_SELINUX
734
- /*
735
- * cred->security == NULL if security_cred_alloc_blank() or
736
- * security_prepare_creds() returned an error.
737
- */
738
- if (selinux_is_enabled() && cred->security) {
739
- if ((unsigned long) cred->security < PAGE_SIZE)
740
- return true;
741
- if ((*(u32 *)cred->security & 0xffffff00) ==
742
- (POISON_FREE << 24 | POISON_FREE << 16 | POISON_FREE << 8))
743
- return true;
744
- }
745
-#endif
746801 return false;
747802 }
748803 EXPORT_SYMBOL(creds_are_invalid);