linux-nfs.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [md PATCH 0/4] Minor 'cred' improvements prepare for NFS conversion
@ 2018-01-31  5:15 NeilBrown
  2018-01-31  5:15 ` [PATCH 2/4] cred: add get_cred_rcu() NeilBrown
                   ` (4 more replies)
  0 siblings, 5 replies; 6+ messages in thread
From: NeilBrown @ 2018-01-31  5:15 UTC (permalink / raw)
  To: David Howells, Andrew Morton, Ingo Molnar, Anna Schumaker; +Cc: NFS, lkml

Hi,
 NFS and SUNRPC have an internal "rpc_cred" which plays two distinct
 roles, one of which is much the same as 'struct cred' (which didn't
 exist when rpc_cred was created).
 I want to replace that usage of rpc_cred with 'struct cred'.
 Doing so requires some minor improvements to cred.c and cred.h as
 follows.

 It isn't clear to me who "maintains" cred.c and cred.h, so I'm hoping
 that Andrew Morton will take these (if no-one complains).
 Alternately if I got one or two credible "Acked-by"s, they could go
 upstream through the NFS tree when the rest of the patches are ready.

Thanks,
NeilBrown


---

NeilBrown (4):
      cred: add cred_fscmp() for comparing creds.
      cred: add get_cred_rcu()
      cred: export get_task_cred().
      cred: allow get_cred() and put_cred() to be given NULL.


 include/linux/cred.h |   26 ++++++++++++++++++----
 kernel/cred.c        |   58 +++++++++++++++++++++++++++++++++++++++++++++++++-
 2 files changed, 78 insertions(+), 6 deletions(-)

--
Signature


^ permalink raw reply	[flat|nested] 6+ messages in thread

* [PATCH 4/4] cred: allow get_cred() and put_cred() to be given NULL.
  2018-01-31  5:15 [md PATCH 0/4] Minor 'cred' improvements prepare for NFS conversion NeilBrown
  2018-01-31  5:15 ` [PATCH 2/4] cred: add get_cred_rcu() NeilBrown
@ 2018-01-31  5:15 ` NeilBrown
  2018-01-31  5:15 ` [PATCH 1/4] cred: add cred_fscmp() for comparing creds NeilBrown
                   ` (2 subsequent siblings)
  4 siblings, 0 replies; 6+ messages in thread
From: NeilBrown @ 2018-01-31  5:15 UTC (permalink / raw)
  To: David Howells, Andrew Morton, Ingo Molnar, Anna Schumaker; +Cc: NFS, lkml

It is common practice of helps like this so silently,
accept a NULL pointer.
get_rpccred() and put_rpccred() used by NFS act this way
and using the same interface will ease the conversion
for NFS, and simplify the resulting code.

Signed-off-by: NeilBrown <neilb@suse.com>
---
 include/linux/cred.h |   14 +++++++++-----
 1 file changed, 9 insertions(+), 5 deletions(-)

diff --git a/include/linux/cred.h b/include/linux/cred.h
index 69ed76f7d49f..c9ba3c8747e9 100644
--- a/include/linux/cred.h
+++ b/include/linux/cred.h
@@ -232,7 +232,7 @@ static inline struct cred *get_new_cred(struct cred *cred)
  * @cred: The credentials to reference
  *
  * Get a reference on the specified set of credentials.  The caller must
- * release the reference.
+ * release the reference.  If %NULL is passed, it is returned with no action.
  *
  * This is used to deal with a committed set of credentials.  Although the
  * pointer is const, this will temporarily discard the const and increment the
@@ -243,6 +243,8 @@ static inline struct cred *get_new_cred(struct cred *cred)
 static inline const struct cred *get_cred(const struct cred *cred)
 {
 	struct cred *nonconst_cred = (struct cred *) cred;
+	if (!cred)
+		return cred;
 	validate_creds(cred);
 	return get_new_cred(nonconst_cred);
 }
@@ -263,7 +265,7 @@ static inline const struct cred *get_cred_rcu(const struct cred *cred)
  * @cred: The credentials to release
  *
  * Release a reference to a set of credentials, deleting them when the last ref
- * is released.
+ * is released.  If %NULL is passed, nothing is done.
  *
  * This takes a const pointer to a set of credentials because the credentials
  * on task_struct are attached by const pointers to prevent accidental
@@ -273,9 +275,11 @@ static inline void put_cred(const struct cred *_cred)
 {
 	struct cred *cred = (struct cred *) _cred;
 
-	validate_creds(cred);
-	if (atomic_dec_and_test(&(cred)->usage))
-		__put_cred(cred);
+	if (cred) {
+		validate_creds(cred);
+		if (atomic_dec_and_test(&(cred)->usage))
+			__put_cred(cred);
+	}
 }
 
 /**



^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [PATCH 3/4] cred: export get_task_cred().
  2018-01-31  5:15 [md PATCH 0/4] Minor 'cred' improvements prepare for NFS conversion NeilBrown
                   ` (2 preceding siblings ...)
  2018-01-31  5:15 ` [PATCH 1/4] cred: add cred_fscmp() for comparing creds NeilBrown
@ 2018-01-31  5:15 ` NeilBrown
  2018-03-21 14:49 ` [md PATCH 0/4] Minor 'cred' improvements prepare for NFS conversion Anna Schumaker
  4 siblings, 0 replies; 6+ messages in thread
From: NeilBrown @ 2018-01-31  5:15 UTC (permalink / raw)
  To: David Howells, Andrew Morton, Ingo Molnar, Anna Schumaker; +Cc: NFS, lkml

There is no reason that modules should not be able
to use this, and NFS will need it when converted to
use 'struct cred'.

Signed-off-by: NeilBrown <neilb@suse.com>
---
 kernel/cred.c |    1 +
 1 file changed, 1 insertion(+)

diff --git a/kernel/cred.c b/kernel/cred.c
index f11aa4e0d2b9..3e43bde1fd3c 100644
--- a/kernel/cred.c
+++ b/kernel/cred.c
@@ -200,6 +200,7 @@ const struct cred *get_task_cred(struct task_struct *task)
 	rcu_read_unlock();
 	return cred;
 }
+EXPORT_SYMBOL(get_task_cred);
 
 /*
  * Allocate blank credentials, such that the credentials can be filled in at a



^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [PATCH 2/4] cred: add get_cred_rcu()
  2018-01-31  5:15 [md PATCH 0/4] Minor 'cred' improvements prepare for NFS conversion NeilBrown
@ 2018-01-31  5:15 ` NeilBrown
  2018-01-31  5:15 ` [PATCH 4/4] cred: allow get_cred() and put_cred() to be given NULL NeilBrown
                   ` (3 subsequent siblings)
  4 siblings, 0 replies; 6+ messages in thread
From: NeilBrown @ 2018-01-31  5:15 UTC (permalink / raw)
  To: David Howells, Andrew Morton, Ingo Molnar, Anna Schumaker; +Cc: NFS, lkml

Sometimes we want to opportunistically get a
ref to a cred in an rcu_read_lock protected section.
get_task_cred() does this, and NFS does as similar thing
with its own credential structures.
To prepare for NFS converting to use 'struct cred' more
uniformly, define get_cred_rcu(), and use it in
get_task_cred().

Signed-off-by: NeilBrown <neilb@suse.com>
---
 include/linux/cred.h |   11 +++++++++++
 kernel/cred.c        |    2 +-
 2 files changed, 12 insertions(+), 1 deletion(-)

diff --git a/include/linux/cred.h b/include/linux/cred.h
index 6dd51e503f23..69ed76f7d49f 100644
--- a/include/linux/cred.h
+++ b/include/linux/cred.h
@@ -247,6 +247,17 @@ static inline const struct cred *get_cred(const struct cred *cred)
 	return get_new_cred(nonconst_cred);
 }
 
+static inline const struct cred *get_cred_rcu(const struct cred *cred)
+{
+	struct cred *nonconst_cred = (struct cred *) cred;
+	if (!cred)
+		return NULL;
+	if (!atomic_inc_not_zero(&nonconst_cred->usage))
+		return NULL;
+	validate_creds(cred);
+	return cred;
+}
+
 /**
  * put_cred - Release a reference to a set of credentials
  * @cred: The credentials to release
diff --git a/kernel/cred.c b/kernel/cred.c
index 4ce75c6fb752..f11aa4e0d2b9 100644
--- a/kernel/cred.c
+++ b/kernel/cred.c
@@ -195,7 +195,7 @@ const struct cred *get_task_cred(struct task_struct *task)
 	do {
 		cred = __task_cred((task));
 		BUG_ON(!cred);
-	} while (!atomic_inc_not_zero(&((struct cred *)cred)->usage));
+	} while (!get_cred_rcu(cred));
 
 	rcu_read_unlock();
 	return cred;



^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [PATCH 1/4] cred: add cred_fscmp() for comparing creds.
  2018-01-31  5:15 [md PATCH 0/4] Minor 'cred' improvements prepare for NFS conversion NeilBrown
  2018-01-31  5:15 ` [PATCH 2/4] cred: add get_cred_rcu() NeilBrown
  2018-01-31  5:15 ` [PATCH 4/4] cred: allow get_cred() and put_cred() to be given NULL NeilBrown
@ 2018-01-31  5:15 ` NeilBrown
  2018-01-31  5:15 ` [PATCH 3/4] cred: export get_task_cred() NeilBrown
  2018-03-21 14:49 ` [md PATCH 0/4] Minor 'cred' improvements prepare for NFS conversion Anna Schumaker
  4 siblings, 0 replies; 6+ messages in thread
From: NeilBrown @ 2018-01-31  5:15 UTC (permalink / raw)
  To: David Howells, Andrew Morton, Ingo Molnar, Anna Schumaker; +Cc: NFS, lkml

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 current 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>
---
 include/linux/cred.h |    1 +
 kernel/cred.c        |   55 ++++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 56 insertions(+)

diff --git a/include/linux/cred.h b/include/linux/cred.h
index 631286535d0f..6dd51e503f23 100644
--- a/include/linux/cred.h
+++ b/include/linux/cred.h
@@ -164,6 +164,7 @@ extern int change_create_files_as(struct cred *, struct inode *);
 extern int set_security_override(struct cred *, u32);
 extern int set_security_override_from_ctx(struct cred *, const char *);
 extern int set_create_files_as(struct cred *, struct inode *);
+extern int cred_fscmp(const struct cred *, const struct cred *);
 extern void __init cred_init(void);
 
 /*
diff --git a/kernel/cred.c b/kernel/cred.c
index ecf03657e71c..4ce75c6fb752 100644
--- a/kernel/cred.c
+++ b/kernel/cred.c
@@ -19,6 +19,7 @@
 #include <linux/security.h>
 #include <linux/binfmts.h>
 #include <linux/cn_proc.h>
+#include <linux/uidgid.h>
 
 #if 0
 #define kdebug(FMT, ...)						\
@@ -564,6 +565,60 @@ void revert_creds(const struct cred *old)
 }
 EXPORT_SYMBOL(revert_creds);
 
+/**
+ * cred_fscmp - Compare to credentials with respect to filesystem access.
+ * @a: The first credential
+ * @b: The second credential
+ *
+ * cred_cmp() will return zero if both credentials have the same
+ * fsuid, fsgid, and supplementary groups.  That is, if they will both
+ * provide the same access to files based on mode/uid/gid.
+ * If the credentials are different, then either -1 or 1 will
+ * be returned depending on whether @a comes before or after @b
+ * respectively in an arbitrary, but stable, ordering of credentials.
+ *
+ * Return: -1, 0, or 1 depending on comparison
+ */
+int cred_fscmp(const struct cred *a, const struct cred *b)
+{
+	struct group_info *ga, *gb;
+	int g;
+
+	if (a == b)
+		return 0;
+	if (uid_lt(a->fsuid, b->fsuid))
+		return -1;
+	if (uid_gt(a->fsuid, b->fsuid))
+		return 1;
+
+	if (gid_lt(a->fsgid, b->fsgid))
+		return -1;
+	if (gid_gt(a->fsgid, b->fsgid))
+		return 1;
+
+	ga = a->group_info;
+	gb = b->group_info;
+	if (ga == gb)
+		return 0;
+	if (ga == NULL)
+		return -1;
+	if (gb == NULL)
+		return 1;
+	if (ga->ngroups < gb->ngroups)
+		return -1;
+	if (ga->ngroups > gb->ngroups)
+		return 1;
+
+	for (g = 0; g < ga->ngroups; g++) {
+		if (gid_lt(ga->gid[g], gb->gid[g]))
+			return -1;
+		if (gid_gt(ga->gid[g], gb->gid[g]))
+			return 1;
+	}
+	return 0;
+}
+EXPORT_SYMBOL(cred_fscmp);
+
 /*
  * initialise the credentials stuff
  */



^ permalink raw reply related	[flat|nested] 6+ messages in thread

* Re: [md PATCH 0/4] Minor 'cred' improvements prepare for NFS conversion
  2018-01-31  5:15 [md PATCH 0/4] Minor 'cred' improvements prepare for NFS conversion NeilBrown
                   ` (3 preceding siblings ...)
  2018-01-31  5:15 ` [PATCH 3/4] cred: export get_task_cred() NeilBrown
@ 2018-03-21 14:49 ` Anna Schumaker
  4 siblings, 0 replies; 6+ messages in thread
From: Anna Schumaker @ 2018-03-21 14:49 UTC (permalink / raw)
  To: NeilBrown, David Howells, Andrew Morton, Ingo Molnar; +Cc: NFS, lkml



On 01/31/2018 12:15 AM, NeilBrown wrote:
> Hi,
>  NFS and SUNRPC have an internal "rpc_cred" which plays two distinct
>  roles, one of which is much the same as 'struct cred' (which didn't
>  exist when rpc_cred was created).
>  I want to replace that usage of rpc_cred with 'struct cred'.
>  Doing so requires some minor improvements to cred.c and cred.h as
>  follows.
> 
>  It isn't clear to me who "maintains" cred.c and cred.h, so I'm hoping
>  that Andrew Morton will take these (if no-one complains).
>  Alternately if I got one or two credible "Acked-by"s, they could go
>  upstream through the NFS tree when the rest of the patches are ready.

Neil sent these patches out a while ago, and I haven't heard any acks for them yet.  Does anybody have a problem with me taking them through the NFS tree for 4.17?

Anna

> 
> Thanks,
> NeilBrown
> 
> 
> ---
> 
> NeilBrown (4):
>       cred: add cred_fscmp() for comparing creds.
>       cred: add get_cred_rcu()
>       cred: export get_task_cred().
>       cred: allow get_cred() and put_cred() to be given NULL.
> 
> 
>  include/linux/cred.h |   26 ++++++++++++++++++----
>  kernel/cred.c        |   58 +++++++++++++++++++++++++++++++++++++++++++++++++-
>  2 files changed, 78 insertions(+), 6 deletions(-)
> 
> --
> Signature
> 

^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2018-03-21 14:49 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2018-01-31  5:15 [md PATCH 0/4] Minor 'cred' improvements prepare for NFS conversion NeilBrown
2018-01-31  5:15 ` [PATCH 2/4] cred: add get_cred_rcu() NeilBrown
2018-01-31  5:15 ` [PATCH 4/4] cred: allow get_cred() and put_cred() to be given NULL NeilBrown
2018-01-31  5:15 ` [PATCH 1/4] cred: add cred_fscmp() for comparing creds NeilBrown
2018-01-31  5:15 ` [PATCH 3/4] cred: export get_task_cred() NeilBrown
2018-03-21 14:49 ` [md PATCH 0/4] Minor 'cred' improvements prepare for NFS conversion Anna Schumaker

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).