All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 1/2] libselinux: accept const fromcon in get_context API
@ 2021-01-08 16:00 Christian Göttsche
  2021-01-08 16:00 ` [PATCH 2/2] libselinux: update getseuser Christian Göttsche
  0 siblings, 1 reply; 4+ messages in thread
From: Christian Göttsche @ 2021-01-08 16:00 UTC (permalink / raw)
  To: selinux

Rework the APIs in <selinux/get_context_list.h> to take a constant
string as from context.

The passed string is not modified currently but not declared const,
which is restricting callers (who care about const-correctness).

Signed-off-by: Christian Göttsche <cgzones@googlemail.com>
---
 libselinux/include/selinux/get_context_list.h | 12 ++---
 .../man/man3/get_ordered_context_list.3       | 12 ++---
 libselinux/src/get_context_list.c             | 49 +++++++++----------
 3 files changed, 36 insertions(+), 37 deletions(-)

diff --git a/libselinux/include/selinux/get_context_list.h b/libselinux/include/selinux/get_context_list.h
index db8641a4..6b2f14f3 100644
--- a/libselinux/include/selinux/get_context_list.h
+++ b/libselinux/include/selinux/get_context_list.h
@@ -17,14 +17,14 @@ extern "C" {
    If 'fromcon' is NULL, defaults to current context.
    Caller must free via freeconary. */
 	extern int get_ordered_context_list(const char *user,
-					    char * fromcon,
+					    const char *fromcon,
 					    char *** list);
 
 /* As above, but use the provided MLS level rather than the
    default level for the user. */
 	extern int get_ordered_context_list_with_level(const char *user,
 						       const char *level,
-						       char * fromcon,
+						       const char *fromcon,
 						       char *** list);
 
 /* Get the default security context for a user session for 'user'
@@ -35,14 +35,14 @@ extern "C" {
    Returns 0 on success or -1 otherwise.
    Caller must free via freecon. */
 	extern int get_default_context(const char *user,
-				       char * fromcon,
+				       const char *fromcon,
 				       char ** newcon);
 
 /* As above, but use the provided MLS level rather than the
    default level for the user. */
 	extern int get_default_context_with_level(const char *user,
 						  const char *level,
-						  char * fromcon,
+						  const char *fromcon,
 						  char ** newcon);
 
 /* Same as get_default_context, but only return a context
@@ -50,7 +50,7 @@ extern "C" {
    for the user with that role, then return -1. */
 	extern int get_default_context_with_role(const char *user,
 						 const char *role,
-						 char * fromcon,
+						 const char *fromcon,
 						 char ** newcon);
 
 /* Same as get_default_context, but only return a context
@@ -59,7 +59,7 @@ extern "C" {
 	extern int get_default_context_with_rolelevel(const char *user,
 						      const char *role,
 						      const char *level,
-						      char * fromcon,
+						      const char *fromcon,
 						      char ** newcon);
 
 /* Given a list of authorized security contexts for the user, 
diff --git a/libselinux/man/man3/get_ordered_context_list.3 b/libselinux/man/man3/get_ordered_context_list.3
index 3ed14a96..2a1e08f0 100644
--- a/libselinux/man/man3/get_ordered_context_list.3
+++ b/libselinux/man/man3/get_ordered_context_list.3
@@ -7,17 +7,17 @@ get_ordered_context_list, get_ordered_context_list_with_level, get_default_conte
 .br
 .B #include <selinux/get_context_list.h>
 .sp
-.BI "int get_ordered_context_list(const char *" user ", char *" fromcon ", char ***" list );
+.BI "int get_ordered_context_list(const char *" user ", const char *" fromcon ", char ***" list );
 .sp
-.BI "int get_ordered_context_list_with_level(const char *" user ", const char *" level ", char *" fromcon ", char ***" list );
+.BI "int get_ordered_context_list_with_level(const char *" user ", const char *" level ", const char *" fromcon ", char ***" list );
 .sp
-.BI "int get_default_context(const char *" user ", char *" fromcon ", char **" newcon );
+.BI "int get_default_context(const char *" user ", const char *" fromcon ", char **" newcon );
 .sp
-.BI "int get_default_context_with_level(const char *" user ", const char *" level ", char *" fromcon ", char **" newcon );
+.BI "int get_default_context_with_level(const char *" user ", const char *" level ", const char *" fromcon ", char **" newcon );
 .sp
-.BI "int get_default_context_with_role(const char *" user ", const char *" role ", char *" fromcon ", char **" newcon ");
+.BI "int get_default_context_with_role(const char *" user ", const char *" role ", const char *" fromcon ", char **" newcon ");
 .sp
-.BI "int get_default_context_with_rolelevel(const char *" user ", const char *" role ", const char *" level ", char *" fromcon ", char **" newcon ");
+.BI "int get_default_context_with_rolelevel(const char *" user ", const char *" role ", const char *" level ", const char *" fromcon ", char **" newcon ");
 .sp
 .BI "int query_user_context(char **" list ", char **" newcon );
 .sp
diff --git a/libselinux/src/get_context_list.c b/libselinux/src/get_context_list.c
index b43652ff..cfe38e59 100644
--- a/libselinux/src/get_context_list.c
+++ b/libselinux/src/get_context_list.c
@@ -13,7 +13,7 @@
 
 int get_default_context_with_role(const char *user,
 				  const char *role,
-				  char * fromcon,
+				  const char *fromcon,
 				  char ** newcon)
 {
 	char **conary;
@@ -56,23 +56,24 @@ int get_default_context_with_role(const char *user,
 int get_default_context_with_rolelevel(const char *user,
 				       const char *role,
 				       const char *level,
-				       char * fromcon,
+				       const char *fromcon,
 				       char ** newcon)
 {
 
-	int rc = 0;
-	int freefrom = 0;
+	int rc;
+	char *backup_fromcon = NULL;
 	context_t con;
-	char *newfromcon;
+	const char *newfromcon;
+
 	if (!level)
 		return get_default_context_with_role(user, role, fromcon,
 						     newcon);
 
 	if (!fromcon) {
-		rc = getcon(&fromcon);
+		rc = getcon(&backup_fromcon);
 		if (rc < 0)
 			return rc;
-		freefrom = 1;
+		fromcon = backup_fromcon;
 	}
 
 	rc = -1;
@@ -91,14 +92,13 @@ int get_default_context_with_rolelevel(const char *user,
 
       out:
 	context_free(con);
-	if (freefrom)
-		freecon(fromcon);
+	freecon(backup_fromcon);
 	return rc;
 
 }
 
 int get_default_context(const char *user,
-			char * fromcon, char ** newcon)
+			const char *fromcon, char ** newcon)
 {
 	char **conary;
 	int rc;
@@ -128,7 +128,7 @@ static int is_in_reachable(char **reachable, const char *usercon_str)
 }
 
 static int get_context_user(FILE * fp,
-			     char * fromcon,
+			     const char * fromcon,
 			     const char * user,
 			     char ***reachable,
 			     unsigned int *nreachable)
@@ -345,22 +345,22 @@ static int get_failsafe_context(const char *user, char ** newcon)
 
 int get_ordered_context_list_with_level(const char *user,
 					const char *level,
-					char * fromcon,
+					const char *fromcon,
 					char *** list)
 {
 	int rc;
-	int freefrom = 0;
+	char *backup_fromcon = NULL;
 	context_t con;
-	char *newfromcon;
+	const char *newfromcon;
 
 	if (!level)
 		return get_ordered_context_list(user, fromcon, list);
 
 	if (!fromcon) {
-		rc = getcon(&fromcon);
+		rc = getcon(&backup_fromcon);
 		if (rc < 0)
 			return rc;
-		freefrom = 1;
+		fromcon = backup_fromcon;
 	}
 
 	rc = -1;
@@ -379,15 +379,14 @@ int get_ordered_context_list_with_level(const char *user,
 
       out:
 	context_free(con);
-	if (freefrom)
-		freecon(fromcon);
+	freecon(backup_fromcon);
 	return rc;
 }
 
 
 int get_default_context_with_level(const char *user,
 				   const char *level,
-				   char * fromcon,
+				   const char *fromcon,
 				   char ** newcon)
 {
 	char **conary;
@@ -405,12 +404,13 @@ int get_default_context_with_level(const char *user,
 }
 
 int get_ordered_context_list(const char *user,
-			     char * fromcon,
+			     const char *fromcon,
 			     char *** list)
 {
 	char **reachable = NULL;
 	int rc = 0;
-	unsigned nreachable = 0, freefrom = 0;
+	unsigned nreachable = 0;
+	char *backup_fromcon = NULL;
 	FILE *fp;
 	char *fname = NULL;
 	size_t fname_len;
@@ -418,10 +418,10 @@ int get_ordered_context_list(const char *user,
 
 	if (!fromcon) {
 		/* Get the current context and use it for the starting context */
-		rc = getcon(&fromcon);
+		rc = getcon(&backup_fromcon);
 		if (rc < 0)
 			return rc;
-		freefrom = 1;
+		fromcon = backup_fromcon;
 	}
 
 	/* Determine the ordering to apply from the optional per-user config
@@ -469,8 +469,7 @@ int get_ordered_context_list(const char *user,
 	else
 		freeconary(reachable);
 
-	if (freefrom)
-		freecon(fromcon);
+	freecon(backup_fromcon);
 
 	return rc;
 
-- 
2.30.0


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

* [PATCH 2/2] libselinux: update getseuser
  2021-01-08 16:00 [PATCH 1/2] libselinux: accept const fromcon in get_context API Christian Göttsche
@ 2021-01-08 16:00 ` Christian Göttsche
  2021-01-20 16:06   ` Nicolas Iooss
  0 siblings, 1 reply; 4+ messages in thread
From: Christian Göttsche @ 2021-01-08 16:00 UTC (permalink / raw)
  To: selinux

- Bail out if not running on a SELinux enabled system
- Check whether the passed context is valid
- Do not report a get_ordered_context_list_with_level failure on zero
  found contexts

Signed-off-by: Christian Göttsche <cgzones@googlemail.com>
---
 libselinux/utils/getseuser.c | 47 +++++++++++++++++++++++++-----------
 1 file changed, 33 insertions(+), 14 deletions(-)

diff --git a/libselinux/utils/getseuser.c b/libselinux/utils/getseuser.c
index 9193fe0a..ce1b7b27 100644
--- a/libselinux/utils/getseuser.c
+++ b/libselinux/utils/getseuser.c
@@ -9,32 +9,51 @@ int main(int argc, char **argv)
 {
 	char *seuser = NULL, *level = NULL;
 	char **contextlist;
-	int rc, n, i;
+	int rc, n;
 
 	if (argc != 3) {
 		fprintf(stderr, "usage:  %s linuxuser fromcon\n", argv[0]);
-		exit(1);
+		return 1;
+	}
+
+	if (!is_selinux_enabled()) {
+		fprintf(stderr, "%s may be used only on a SELinux enabled kernel.\n", argv[0]);
+		return 4;
 	}
 
 	rc = getseuserbyname(argv[1], &seuser, &level);
 	if (rc) {
-		fprintf(stderr, "getseuserbyname failed:  %s\n",
-			strerror(errno));
-		exit(2);
+		fprintf(stderr, "getseuserbyname failed:  %s\n", strerror(errno));
+		return 2;
 	}
 	printf("seuser:  %s, level %s\n", seuser, level);
-	n = get_ordered_context_list_with_level(seuser, level, argv[2],
-						&contextlist);
-	if (n <= 0) {
-		fprintf(stderr,
-			"get_ordered_context_list_with_level failed:  %s\n",
-			strerror(errno));
-		exit(3);
+
+	rc = security_check_context(argv[2]);
+	if (rc) {
+		fprintf(stderr, "context '%s' is invalid\n", argv[2]);
+		free(seuser);
+		free(level);
+		return 5;
+	}
+
+	n = get_ordered_context_list_with_level(seuser, level, argv[2], &contextlist);
+	if (n < 0) {
+		fprintf(stderr, "get_ordered_context_list_with_level failed:  %s\n", strerror(errno));
+		free(seuser);
+		free(level);
+		return 3;
 	}
+
 	free(seuser);
 	free(level);
-	for (i = 0; i < n; i++)
+
+	if (n == 0)
+		printf("no valid context found\n");
+
+	for (int i = 0; i < n; i++)
 		printf("Context %d\t%s\n", i, contextlist[i]);
+
 	freeconary(contextlist);
-	exit(EXIT_SUCCESS);
+
+	return EXIT_SUCCESS;
 }
-- 
2.30.0


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

* Re: [PATCH 2/2] libselinux: update getseuser
  2021-01-08 16:00 ` [PATCH 2/2] libselinux: update getseuser Christian Göttsche
@ 2021-01-20 16:06   ` Nicolas Iooss
  2021-01-21 21:24     ` Nicolas Iooss
  0 siblings, 1 reply; 4+ messages in thread
From: Nicolas Iooss @ 2021-01-20 16:06 UTC (permalink / raw)
  To: Christian Göttsche; +Cc: SElinux list

On Fri, Jan 8, 2021 at 5:02 PM Christian Göttsche
<cgzones@googlemail.com> wrote:
>
> - Bail out if not running on a SELinux enabled system
> - Check whether the passed context is valid
> - Do not report a get_ordered_context_list_with_level failure on zero
>   found contexts
>
> Signed-off-by: Christian Göttsche <cgzones@googlemail.com>
> ---
>  libselinux/utils/getseuser.c | 47 +++++++++++++++++++++++++-----------
>  1 file changed, 33 insertions(+), 14 deletions(-)
>
> diff --git a/libselinux/utils/getseuser.c b/libselinux/utils/getseuser.c
> index 9193fe0a..ce1b7b27 100644
> --- a/libselinux/utils/getseuser.c
> +++ b/libselinux/utils/getseuser.c
> @@ -9,32 +9,51 @@ int main(int argc, char **argv)
>  {
>         char *seuser = NULL, *level = NULL;
>         char **contextlist;
> -       int rc, n, i;
> +       int rc, n;
>
>         if (argc != 3) {
>                 fprintf(stderr, "usage:  %s linuxuser fromcon\n", argv[0]);
> -               exit(1);
> +               return 1;
> +       }
> +
> +       if (!is_selinux_enabled()) {
> +               fprintf(stderr, "%s may be used only on a SELinux enabled kernel.\n", argv[0]);
> +               return 4;
>         }
>
>         rc = getseuserbyname(argv[1], &seuser, &level);
>         if (rc) {
> -               fprintf(stderr, "getseuserbyname failed:  %s\n",
> -                       strerror(errno));
> -               exit(2);
> +               fprintf(stderr, "getseuserbyname failed:  %s\n", strerror(errno));
> +               return 2;
>         }
>         printf("seuser:  %s, level %s\n", seuser, level);
> -       n = get_ordered_context_list_with_level(seuser, level, argv[2],
> -                                               &contextlist);
> -       if (n <= 0) {
> -               fprintf(stderr,
> -                       "get_ordered_context_list_with_level failed:  %s\n",
> -                       strerror(errno));
> -               exit(3);
> +
> +       rc = security_check_context(argv[2]);
> +       if (rc) {
> +               fprintf(stderr, "context '%s' is invalid\n", argv[2]);
> +               free(seuser);
> +               free(level);
> +               return 5;
> +       }
> +
> +       n = get_ordered_context_list_with_level(seuser, level, argv[2], &contextlist);
> +       if (n < 0) {
> +               fprintf(stderr, "get_ordered_context_list_with_level failed:  %s\n", strerror(errno));
> +               free(seuser);
> +               free(level);
> +               return 3;
>         }
> +
>         free(seuser);
>         free(level);
> -       for (i = 0; i < n; i++)
> +
> +       if (n == 0)
> +               printf("no valid context found\n");
> +
> +       for (int i = 0; i < n; i++)
>                 printf("Context %d\t%s\n", i, contextlist[i]);
> +
>         freeconary(contextlist);
> -       exit(EXIT_SUCCESS);
> +
> +       return EXIT_SUCCESS;
>  }
> --
> 2.30.0

Thanks for your patch! Sorry for the delay: I wanted to test things
and I have been to busy in the past few days to boot my test machine,
and now I see that your patch greatly improves the usability of
getseuser! Many thanks!

As an example of the improvement, before (on a non-MLS system):

$ getseuser myadmin system_u:system_r:sshd_t
seuser:  unconfined_u, level (null)
Context 0 unconfined_u:unconfined_r:unconfined_t
$ getseuser myadmin sshd_t
seuser:  unconfined_u, level (null)
get_ordered_context_list:  error in processing configuration file
/etc/selinux/refpolicy-git/contexts/users/unconfined_u
get_ordered_context_list:  error in processing configuration file
/etc/selinux/refpolicy-git/contexts/default_contexts
get_ordered_context_list_with_level failed:  Invalid argument

With your patch, the first command did not change, but the second one
now returns:

$ getseuser myadmin sshd_t
seuser:  unconfined_u, level (null)
context 'sshd_t' is invalid

... which is much more helpful, in my humble opinion.

So for both your patches: Acked-by: Nicolas Iooss <nicolas.iooss@m4x.org>

I will merge the 2 patches tomorrow if nobody complains.

Nicolas


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

* Re: [PATCH 2/2] libselinux: update getseuser
  2021-01-20 16:06   ` Nicolas Iooss
@ 2021-01-21 21:24     ` Nicolas Iooss
  0 siblings, 0 replies; 4+ messages in thread
From: Nicolas Iooss @ 2021-01-21 21:24 UTC (permalink / raw)
  To: Christian Göttsche; +Cc: SElinux list

On Wed, Jan 20, 2021 at 5:06 PM Nicolas Iooss <nicolas.iooss@m4x.org> wrote:
>
> On Fri, Jan 8, 2021 at 5:02 PM Christian Göttsche
> <cgzones@googlemail.com> wrote:
> >
> > - Bail out if not running on a SELinux enabled system
> > - Check whether the passed context is valid
> > - Do not report a get_ordered_context_list_with_level failure on zero
> >   found contexts
> >
> > Signed-off-by: Christian Göttsche <cgzones@googlemail.com>
> > ---
> >  libselinux/utils/getseuser.c | 47 +++++++++++++++++++++++++-----------
> >  1 file changed, 33 insertions(+), 14 deletions(-)
> >
> > diff --git a/libselinux/utils/getseuser.c b/libselinux/utils/getseuser.c
> > index 9193fe0a..ce1b7b27 100644
> > --- a/libselinux/utils/getseuser.c
> > +++ b/libselinux/utils/getseuser.c
> > @@ -9,32 +9,51 @@ int main(int argc, char **argv)
> >  {
> >         char *seuser = NULL, *level = NULL;
> >         char **contextlist;
> > -       int rc, n, i;
> > +       int rc, n;
> >
> >         if (argc != 3) {
> >                 fprintf(stderr, "usage:  %s linuxuser fromcon\n", argv[0]);
> > -               exit(1);
> > +               return 1;
> > +       }
> > +
> > +       if (!is_selinux_enabled()) {
> > +               fprintf(stderr, "%s may be used only on a SELinux enabled kernel.\n", argv[0]);
> > +               return 4;
> >         }
> >
> >         rc = getseuserbyname(argv[1], &seuser, &level);
> >         if (rc) {
> > -               fprintf(stderr, "getseuserbyname failed:  %s\n",
> > -                       strerror(errno));
> > -               exit(2);
> > +               fprintf(stderr, "getseuserbyname failed:  %s\n", strerror(errno));
> > +               return 2;
> >         }
> >         printf("seuser:  %s, level %s\n", seuser, level);
> > -       n = get_ordered_context_list_with_level(seuser, level, argv[2],
> > -                                               &contextlist);
> > -       if (n <= 0) {
> > -               fprintf(stderr,
> > -                       "get_ordered_context_list_with_level failed:  %s\n",
> > -                       strerror(errno));
> > -               exit(3);
> > +
> > +       rc = security_check_context(argv[2]);
> > +       if (rc) {
> > +               fprintf(stderr, "context '%s' is invalid\n", argv[2]);
> > +               free(seuser);
> > +               free(level);
> > +               return 5;
> > +       }
> > +
> > +       n = get_ordered_context_list_with_level(seuser, level, argv[2], &contextlist);
> > +       if (n < 0) {
> > +               fprintf(stderr, "get_ordered_context_list_with_level failed:  %s\n", strerror(errno));
> > +               free(seuser);
> > +               free(level);
> > +               return 3;
> >         }
> > +
> >         free(seuser);
> >         free(level);
> > -       for (i = 0; i < n; i++)
> > +
> > +       if (n == 0)
> > +               printf("no valid context found\n");
> > +
> > +       for (int i = 0; i < n; i++)
> >                 printf("Context %d\t%s\n", i, contextlist[i]);
> > +
> >         freeconary(contextlist);
> > -       exit(EXIT_SUCCESS);
> > +
> > +       return EXIT_SUCCESS;
> >  }
> > --
> > 2.30.0
>
> Thanks for your patch! Sorry for the delay: I wanted to test things
> and I have been to busy in the past few days to boot my test machine,
> and now I see that your patch greatly improves the usability of
> getseuser! Many thanks!
>
> As an example of the improvement, before (on a non-MLS system):
>
> $ getseuser myadmin system_u:system_r:sshd_t
> seuser:  unconfined_u, level (null)
> Context 0 unconfined_u:unconfined_r:unconfined_t
> $ getseuser myadmin sshd_t
> seuser:  unconfined_u, level (null)
> get_ordered_context_list:  error in processing configuration file
> /etc/selinux/refpolicy-git/contexts/users/unconfined_u
> get_ordered_context_list:  error in processing configuration file
> /etc/selinux/refpolicy-git/contexts/default_contexts
> get_ordered_context_list_with_level failed:  Invalid argument
>
> With your patch, the first command did not change, but the second one
> now returns:
>
> $ getseuser myadmin sshd_t
> seuser:  unconfined_u, level (null)
> context 'sshd_t' is invalid
>
> ... which is much more helpful, in my humble opinion.
>
> So for both your patches: Acked-by: Nicolas Iooss <nicolas.iooss@m4x.org>
>
> I will merge the 2 patches tomorrow if nobody complains.
>
> Nicolas

Merged. Thanks!
Nicolas


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

end of thread, other threads:[~2021-01-21 21:26 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-01-08 16:00 [PATCH 1/2] libselinux: accept const fromcon in get_context API Christian Göttsche
2021-01-08 16:00 ` [PATCH 2/2] libselinux: update getseuser Christian Göttsche
2021-01-20 16:06   ` Nicolas Iooss
2021-01-21 21:24     ` Nicolas Iooss

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.