[PATCH 19/22] shell: Add mode, UID and GID to shell commands

Sebastian Huber sebastian.huber at embedded-brains.de
Tue Nov 18 14:37:25 UTC 2014


Use this information to determine if a command is visible to the current
user and if the current user is allowed to execute this command.
---
 cpukit/libmisc/shell/cmds.c         |  4 +---
 cpukit/libmisc/shell/internal.h     |  2 ++
 cpukit/libmisc/shell/main_alias.c   | 11 +++++-----
 cpukit/libmisc/shell/main_help.c    | 17 ++++++++------
 cpukit/libmisc/shell/main_time.c    | 11 +++++-----
 cpukit/libmisc/shell/shell.h        |  4 ++++
 cpukit/libmisc/shell/shell_cmdset.c | 44 ++++++++++++++++++++++++++++++++-----
 7 files changed, 66 insertions(+), 27 deletions(-)

diff --git a/cpukit/libmisc/shell/cmds.c b/cpukit/libmisc/shell/cmds.c
index 7c9e21d..6e3e0c1 100644
--- a/cpukit/libmisc/shell/cmds.c
+++ b/cpukit/libmisc/shell/cmds.c
@@ -50,15 +50,13 @@ static bool rtems_shell_register_command(const rtems_monitor_command_entry_t *e,
   /* Exclude EXIT (alias quit)*/
   if (strcmp("exit", e->command) != 0) {
     rtems_shell_cmd_t *shell_cmd =
-      (rtems_shell_cmd_t *) malloc(sizeof(rtems_shell_cmd_t));
+      (rtems_shell_cmd_t *) calloc(1, sizeof(*shell_cmd));
 
     if (shell_cmd != NULL) {
       shell_cmd->name    = e->command;
       shell_cmd->topic   = "monitor";
       shell_cmd->usage   = e->usage;
       shell_cmd->command = rtems_shell_main_monitor;
-      shell_cmd->alias   = NULL;
-      shell_cmd->next    = NULL;
 
       if (rtems_shell_add_cmd_struct(shell_cmd) == NULL) {
         free(shell_cmd);
diff --git a/cpukit/libmisc/shell/internal.h b/cpukit/libmisc/shell/internal.h
index e6d0ef1..0187e5f 100644
--- a/cpukit/libmisc/shell/internal.h
+++ b/cpukit/libmisc/shell/internal.h
@@ -25,6 +25,8 @@ extern rtems_shell_topic_t * rtems_shell_first_topic;
 
 rtems_shell_topic_t * rtems_shell_lookup_topic(const char *topic);
 
+bool rtems_shell_can_see_cmd(const rtems_shell_cmd_t *shell_cmd);
+
 int rtems_shell_execute_cmd(const char *cmd, int argc, char *argv[]);
 
 extern void rtems_shell_register_monitor_commands(void);
diff --git a/cpukit/libmisc/shell/main_alias.c b/cpukit/libmisc/shell/main_alias.c
index 3ca0cb0..63a808c 100644
--- a/cpukit/libmisc/shell/main_alias.c
+++ b/cpukit/libmisc/shell/main_alias.c
@@ -34,10 +34,9 @@ static int rtems_shell_rtems_main_alias(int argc, char **argv)
 }
 
 rtems_shell_cmd_t rtems_shell_ALIAS_Command = {
-  "alias",                                /* name */
-  "alias old new",                        /* usage */
-  "misc",                                 /* topic */
-  rtems_shell_rtems_main_alias,           /* command */
-  NULL,                                   /* alias */
-  NULL                                    /* next */
+  .name = "alias",
+  .usage = "alias old new",
+  .topic = "misc",
+  .command = rtems_shell_rtems_main_alias,
+  .mode = S_IRUSR | S_IXUSR | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH
 };
diff --git a/cpukit/libmisc/shell/main_help.c b/cpukit/libmisc/shell/main_help.c
index 1933959..393d7e8 100644
--- a/cpukit/libmisc/shell/main_help.c
+++ b/cpukit/libmisc/shell/main_help.c
@@ -27,12 +27,16 @@
  * show the help for one command.
  */
 static int rtems_shell_help_cmd(
-  rtems_shell_cmd_t *shell_cmd
+  const rtems_shell_cmd_t *shell_cmd
 )
 {
   const char * pc;
   int    col,line;
 
+  if (!rtems_shell_can_see_cmd(shell_cmd)) {
+    return 0;
+  }
+
   printf("%-12.12s - ",shell_cmd->name);
   col = 14;
   line = 1;
@@ -149,10 +153,9 @@ static int rtems_shell_help(
 }
 
 rtems_shell_cmd_t rtems_shell_HELP_Command  =  {
-  "help",                                       /* name  */
-   "help [topic] # list of usage of commands",  /* usage */
-  "help",                                       /* topic */
-  rtems_shell_help,                             /* command */
-  NULL,                                         /* alias */
-  NULL                                          /* next */
+  .name = "help",
+  .usage = "help [topic] # list of usage of commands",
+  .topic = "help",
+  .command = rtems_shell_help,
+  .mode = S_IRUSR | S_IXUSR | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH
 };
diff --git a/cpukit/libmisc/shell/main_time.c b/cpukit/libmisc/shell/main_time.c
index 401186a..5ea1bf7 100644
--- a/cpukit/libmisc/shell/main_time.c
+++ b/cpukit/libmisc/shell/main_time.c
@@ -75,10 +75,9 @@ static int rtems_shell_main_time(
 }
 
 rtems_shell_cmd_t rtems_shell_TIME_Command = {
-  "time",                                     /* name */
-  "time command [arguments...]",              /* usage */
-  "misc",                                     /* topic */
-  rtems_shell_main_time,                      /* command */
-  NULL,                                       /* alias */
-  NULL                                        /* next */
+  .name = "time",
+  .usage = "time command [arguments...]",
+  .topic = "misc",
+  .command = rtems_shell_main_time,
+  .mode = S_IRUSR | S_IXUSR | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH
 };
diff --git a/cpukit/libmisc/shell/shell.h b/cpukit/libmisc/shell/shell.h
index c137378..657df77 100644
--- a/cpukit/libmisc/shell/shell.h
+++ b/cpukit/libmisc/shell/shell.h
@@ -18,6 +18,7 @@
 #define __RTEMS_SHELL_H__
 
 #include <sys/types.h>
+#include <sys/stat.h>
 #include <rtems.h>
 #include <stdio.h>
 #include <termios.h>
@@ -83,6 +84,9 @@ struct rtems_shell_cmd_tt {
   rtems_shell_command_t  command;
   rtems_shell_cmd_t     *alias;
   rtems_shell_cmd_t     *next;
+  mode_t                 mode;
+  uid_t                  uid;
+  gid_t                  gid;
 };
 
 typedef struct {
diff --git a/cpukit/libmisc/shell/shell_cmdset.c b/cpukit/libmisc/shell/shell_cmdset.c
index 07d37db..be64b83 100644
--- a/cpukit/libmisc/shell/shell_cmdset.c
+++ b/cpukit/libmisc/shell/shell_cmdset.c
@@ -29,6 +29,7 @@
 #include <rtems.h>
 #include <rtems/shell.h>
 #include <rtems/shellconfig.h>
+#include <rtems/libio_.h>
 #include "internal.h"
 
 /*
@@ -122,6 +123,9 @@ rtems_shell_cmd_t *rtems_shell_add_cmd_struct(
     next_ptr = &existing->next;
   }
 
+  /* Ensure that the user can read and execute commands */
+  shell_cmd->mode |= S_IRUSR | S_IXUSR;
+
   /* Append */
   *next_ptr = shell_cmd;
 
@@ -152,7 +156,7 @@ rtems_shell_cmd_t * rtems_shell_add_cmd(
   }
 
   /* Allocate command stucture */
-  shell_cmd = (rtems_shell_cmd_t *) malloc(sizeof(rtems_shell_cmd_t));
+  shell_cmd = (rtems_shell_cmd_t *) calloc(1, sizeof(*shell_cmd));
   if (shell_cmd == NULL) {
     return NULL;
   }
@@ -167,8 +171,6 @@ rtems_shell_cmd_t * rtems_shell_add_cmd(
   shell_cmd->topic   = my_topic;
   shell_cmd->usage   = my_usage;
   shell_cmd->command = command;
-  shell_cmd->alias   = NULL;
-  shell_cmd->next    = NULL;
 
   if (rtems_shell_add_cmd_struct(shell_cmd) == NULL) {
     /* Something is wrong, free allocated resources */
@@ -208,13 +210,37 @@ rtems_shell_cmd_t *rtems_shell_alias_cmd(
          shell_cmd->usage,
          shell_cmd->command
       );
-      if (shell_aux)
+      if (shell_aux) {
         shell_aux->alias = shell_cmd;
+        shell_aux->mode = shell_cmd->mode;
+        shell_aux->uid = shell_cmd->uid;
+        shell_aux->gid = shell_cmd->gid;
+      }
     }
   }
   return shell_aux;
 }
 
+bool rtems_shell_can_see_cmd(const rtems_shell_cmd_t *shell_cmd)
+{
+  return rtems_filesystem_check_access(
+    RTEMS_FS_PERMS_READ,
+    shell_cmd->mode,
+    shell_cmd->uid,
+    shell_cmd->gid
+  );
+}
+
+static bool rtems_shell_can_execute_cmd(const rtems_shell_cmd_t *shell_cmd)
+{
+  return rtems_filesystem_check_access(
+    RTEMS_FS_PERMS_EXEC,
+    shell_cmd->mode,
+    shell_cmd->uid,
+    shell_cmd->gid
+  );
+}
+
 int rtems_shell_execute_cmd(const char *cmd, int argc, char *argv[])
 {
   rtems_shell_cmd_t *shell_cmd;
@@ -225,9 +251,17 @@ int rtems_shell_execute_cmd(const char *cmd, int argc, char *argv[])
 
   shell_cmd = rtems_shell_lookup_cmd(argv[0]);
 
+  if (shell_cmd != NULL && !rtems_shell_can_see_cmd(shell_cmd)) {
+    shell_cmd = NULL;
+  }
+
   if (shell_cmd == NULL) {
     return rtems_shell_script_file(argc, argv);
-  } else {
+  } else if (rtems_shell_can_execute_cmd(shell_cmd)) {
     return shell_cmd->command(argc, argv);
+  } else {
+    fprintf(stderr, "%s: Permission denied\n", cmd);
+
+    return -1;
   }
 }
-- 
1.8.4.5




More information about the devel mailing list