aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/cred.c
diff options
context:
space:
mode:
authorNeilBrown <neilb@suse.com>2018-12-02 19:30:30 -0500
committerAnna Schumaker <Anna.Schumaker@Netapp.com>2018-12-19 13:52:44 -0500
commitd89b22d46a40da3a1630ecea111beaf3ef10bc21 (patch)
tree532cce487be9e4d08f4d20c2362c08043311ed4a /kernel/cred.c
parent8e2e5b7c492639109b1137c286dbad529c2b35e1 (diff)
cred: add cred_fscmp() for comparing creds.
NFS needs to compare to credentials, to see if they can be treated the same w.r.t. filesystem access. Sometimes an ordering is needed when credentials are used as a key to an rbtree. NFS currently has its own private credential management from before 'struct cred' existed. To move it over to more consistent use of 'struct cred' we need a comparison function. This patch adds that function. Signed-off-by: NeilBrown <neilb@suse.com> Signed-off-by: Anna Schumaker <Anna.Schumaker@Netapp.com>
Diffstat (limited to 'kernel/cred.c')
-rw-r--r--kernel/cred.c55
1 files changed, 55 insertions, 0 deletions
diff --git a/kernel/cred.c b/kernel/cred.c
index ecf03657e71c..0b3ac72bd717 100644
--- a/kernel/cred.c
+++ b/kernel/cred.c
@@ -19,6 +19,7 @@
19#include <linux/security.h> 19#include <linux/security.h>
20#include <linux/binfmts.h> 20#include <linux/binfmts.h>
21#include <linux/cn_proc.h> 21#include <linux/cn_proc.h>
22#include <linux/uidgid.h>
22 23
23#if 0 24#if 0
24#define kdebug(FMT, ...) \ 25#define kdebug(FMT, ...) \
@@ -564,6 +565,60 @@ void revert_creds(const struct cred *old)
564} 565}
565EXPORT_SYMBOL(revert_creds); 566EXPORT_SYMBOL(revert_creds);
566 567
568/**
569 * cred_fscmp - Compare two credentials with respect to filesystem access.
570 * @a: The first credential
571 * @b: The second credential
572 *
573 * cred_cmp() will return zero if both credentials have the same
574 * fsuid, fsgid, and supplementary groups. That is, if they will both
575 * provide the same access to files based on mode/uid/gid.
576 * If the credentials are different, then either -1 or 1 will
577 * be returned depending on whether @a comes before or after @b
578 * respectively in an arbitrary, but stable, ordering of credentials.
579 *
580 * Return: -1, 0, or 1 depending on comparison
581 */
582int cred_fscmp(const struct cred *a, const struct cred *b)
583{
584 struct group_info *ga, *gb;
585 int g;
586
587 if (a == b)
588 return 0;
589 if (uid_lt(a->fsuid, b->fsuid))
590 return -1;
591 if (uid_gt(a->fsuid, b->fsuid))
592 return 1;
593
594 if (gid_lt(a->fsgid, b->fsgid))
595 return -1;
596 if (gid_gt(a->fsgid, b->fsgid))
597 return 1;
598
599 ga = a->group_info;
600 gb = b->group_info;
601 if (ga == gb)
602 return 0;
603 if (ga == NULL)
604 return -1;
605 if (gb == NULL)
606 return 1;
607 if (ga->ngroups < gb->ngroups)
608 return -1;
609 if (ga->ngroups > gb->ngroups)
610 return 1;
611
612 for (g = 0; g < ga->ngroups; g++) {
613 if (gid_lt(ga->gid[g], gb->gid[g]))
614 return -1;
615 if (gid_gt(ga->gid[g], gb->gid[g]))
616 return 1;
617 }
618 return 0;
619}
620EXPORT_SYMBOL(cred_fscmp);
621
567/* 622/*
568 * initialise the credentials stuff 623 * initialise the credentials stuff
569 */ 624 */