From 7eada71e1b8e707d5b97d4d0cf7d2ca73013e403 Mon Sep 17 00:00:00 2001 From: Sebastian Huber Date: Tue, 18 Nov 2014 07:35:30 +0100 Subject: shell: Add mode, UID and GID to shell commands 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 7c9e21dcfc..6e3e0c1ec2 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 e6d0ef1de4..0187e5f013 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 3ca0cb0abd..63a808c066 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 19339594dc..393d7e8172 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 401186aeb4..5ea1bf7498 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 c137378cbe..657df777e5 100644 --- a/cpukit/libmisc/shell/shell.h +++ b/cpukit/libmisc/shell/shell.h @@ -18,6 +18,7 @@ #define __RTEMS_SHELL_H__ #include +#include #include #include #include @@ -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 07d37dbda7..be64b83fe4 100644 --- a/cpukit/libmisc/shell/shell_cmdset.c +++ b/cpukit/libmisc/shell/shell_cmdset.c @@ -29,6 +29,7 @@ #include #include #include +#include #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; } } -- cgit v1.2.3