Back to home page

LXR

 
 

    


File indexing completed on 2025-05-11 08:24:34

0001 /* SPDX-License-Identifier: BSD-2-Clause */
0002 
0003 /*
0004  * Copyright (C) 2014, 2019 embedded brains GmbH & Co. KG
0005  *
0006  * Redistribution and use in source and binary forms, with or without
0007  * modification, are permitted provided that the following conditions
0008  * are met:
0009  * 1. Redistributions of source code must retain the above copyright
0010  *    notice, this list of conditions and the following disclaimer.
0011  * 2. Redistributions in binary form must reproduce the above copyright
0012  *    notice, this list of conditions and the following disclaimer in the
0013  *    documentation and/or other materials provided with the distribution.
0014  *
0015  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
0016  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
0017  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
0018  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
0019  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
0020  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
0021  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
0022  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
0023  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
0024  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
0025  * POSSIBILITY OF SUCH DAMAGE.
0026  */
0027 
0028 #ifdef HAVE_CONFIG_H
0029 #include "config.h"
0030 #endif
0031 
0032 #include <sys/stat.h>
0033 #include <sys/types.h>
0034 #include <errno.h>
0035 #include <grp.h>
0036 #include <pwd.h>
0037 #include <stdio.h>
0038 #include <unistd.h>
0039 
0040 #include <rtems/imfs.h>
0041 #include <rtems/shell.h>
0042 #include <rtems/userenv.h>
0043 
0044 #include "tmacros.h"
0045 
0046 const char rtems_test_name[] = "SHELL 1";
0047 
0048 static const char etc_passwd[] =
0049   "moop:foo:1:3:blob:a::c\n"
0050   "no:*:2:4::::\n"
0051   "zero::3:5::::\n"
0052   "shadow:x:4:6::::\n"
0053   "invchroot::5:7:::/inv:\n"
0054   "chroot::6:8:::/chroot:\n";
0055 
0056 static const char etc_group[] =
0057   "A::1:moop,u,v,w,zero\n"
0058   "B::2:moop\n"
0059   "blub:bar:3:moop\n"
0060   "C::4:l,m,n,moop\n"
0061   "D::5:moop,moop\n"
0062   "E::6:x\n"
0063   "E::7:y,z\n"
0064   "F::8:s,moop,t\n";
0065 
0066 static const char joel_in[] =
0067   "#! joel\n"
0068   "jtst hello world\n"
0069   "jtst 1 2 3 4 5\n";
0070 
0071 static const char joel_out_1[] =
0072   " 3 'jtst hello world'\n"
0073   " 6 'jtst 1 2 3 4 5'\n";
0074 
0075 static const char joel_out_2[] =
0076   "\n"
0077   "RTEMS Shell on (null). Use 'help' to list commands.\n"
0078   " 3 'jtst hello world'\n"
0079   " 6 'jtst 1 2 3 4 5'\n";
0080 
0081 static int joel_test_command(int argc, char** argv)
0082 {
0083   int i;
0084   fprintf(stdout, "%2d '", argc);
0085   for (i = 0; i < argc; ++i) {
0086     fprintf(stdout, argv[i]);
0087     if (i < (argc - 1))
0088       fprintf(stdout, " ");
0089   }
0090   fprintf(stdout, "'\n");
0091   return 0;
0092 }
0093 
0094 static void test_joel(void)
0095 {
0096   /*
0097    * Running a joel script tests the shell main loop.
0098    */
0099   char buf[sizeof(joel_out_2) + 1];
0100   rtems_shell_cmd_t* cmd;
0101   FILE *in;
0102   FILE *out;
0103   FILE *current_stdout = stdout;
0104   FILE *current_stdin = stdin;
0105   size_t len;
0106   rtems_status_code sc;
0107 
0108   /*
0109    * Use a private command due to the way the testsuite maps printk onto printf.
0110    */
0111   cmd = rtems_shell_add_cmd("jtst", "misc", "joel test", joel_test_command);
0112   rtems_test_assert(cmd != NULL);
0113 
0114   len = strlen(joel_in);
0115 
0116   in = fopen("/jin", "w");
0117   rtems_test_assert(in != NULL);
0118   rtems_test_assert(fwrite(joel_in, sizeof(char), len, in) == len);
0119   rtems_test_assert(fclose(in) == 0);
0120 
0121   /*
0122    * The shell opens the input and output files.
0123    */
0124   sc = rtems_shell_script(
0125     "JTST",
0126     8 * 1024,
0127     1,
0128     "/jin",
0129     "/jout",
0130     false,
0131     true,
0132     false);
0133   rtems_test_assert(sc == RTEMS_SUCCESSFUL);
0134 
0135   out = fopen("/jout", "r");
0136   rtems_test_assert(out != NULL);
0137   rtems_test_assert(!feof(out));
0138   memset(buf, 0, sizeof(buf));
0139   len = fread(buf, sizeof(char), sizeof(buf), out);
0140   rtems_test_assert(len > 0);
0141   rtems_test_assert(strcmp(joel_out_1, buf) == 0);
0142   rtems_test_assert(fclose(out) == 0);
0143 
0144   /*
0145    * The shell task inherits the parent stdin and stdout
0146    */
0147   in = fopen("/jin", "r");
0148   rtems_test_assert(in != NULL);
0149   out = fopen("/jout", "w");
0150   rtems_test_assert(out != NULL);
0151 
0152   stdin = in;
0153   stdout = out;
0154 
0155   sc = rtems_shell_script(
0156     "JTST",
0157     8 * 1024,
0158     1,
0159     "stdin",
0160     "stdout",
0161     false,
0162     true,
0163     false);
0164   rtems_test_assert(sc == RTEMS_SUCCESSFUL);
0165 
0166   stdout = current_stdout;
0167   stdin = current_stdin;
0168 
0169   rtems_test_assert(fclose(in) == 0);
0170   rtems_test_assert(fclose(out) == 0);
0171 
0172   out = fopen("/jout", "r");
0173   rtems_test_assert(out != NULL);
0174   rtems_test_assert(!feof(out));
0175   memset(buf, 0, sizeof(buf));
0176   len = fread(buf, sizeof(char), sizeof(buf), out);
0177   rtems_test_assert(len > 0);
0178   rtems_test_assert(strcmp(joel_out_2, buf) == 0);
0179   rtems_test_assert(fclose(out) == 0);
0180 }
0181 
0182 static void test(void)
0183 {
0184   rtems_user_env_t *uenv;
0185   rtems_status_code sc;
0186   struct stat st_chroot;
0187   struct stat st_workdir;
0188   bool ok;
0189   int rv;
0190 
0191   rv = mkdir("/etc", S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH);
0192   rtems_test_assert(rv == 0);
0193 
0194   rv = mkdir("/chroot", S_IRWXU | S_IRWXG | S_IRWXO);
0195   rtems_test_assert(rv == 0);
0196 
0197   rv = lstat("/chroot", &st_chroot);
0198   rtems_test_assert(rv == 0);
0199 
0200   rv = IMFS_make_linearfile(
0201     "/etc/passwd",
0202     S_IWUSR | S_IRUSR | S_IRGRP | S_IROTH,
0203     etc_passwd,
0204     sizeof(etc_passwd)
0205   );
0206   rtems_test_assert(rv == 0);
0207 
0208   rv = IMFS_make_linearfile(
0209     "/etc/group",
0210     S_IWUSR | S_IRUSR | S_IRGRP | S_IROTH,
0211     etc_group,
0212     sizeof(etc_group)
0213   );
0214   rtems_test_assert(rv == 0);
0215 
0216   sc = rtems_libio_set_private_env();
0217   rtems_test_assert(sc == RTEMS_SUCCESSFUL);
0218 
0219   uenv = rtems_current_user_env_get();
0220 
0221   rv = setuid(0);
0222   rtems_test_assert(rv == 0);
0223 
0224   rv = seteuid(0);
0225   rtems_test_assert(rv == 0);
0226 
0227   ok = rtems_shell_login_check("inv", NULL);
0228   rtems_test_assert(!ok);
0229 
0230   ok = rtems_shell_login_check("no", NULL);
0231   rtems_test_assert(!ok);
0232 
0233   ok = rtems_shell_login_check("shadow", NULL);
0234   rtems_test_assert(!ok);
0235 
0236   ok = rtems_shell_login_check("moop", "false");
0237   rtems_test_assert(!ok);
0238 
0239   ok = rtems_shell_login_check("invchroot", NULL);
0240   rtems_test_assert(!ok);
0241 
0242   ok = rtems_shell_login_check("", NULL);
0243   rtems_test_assert(!ok);
0244 
0245   ok = rtems_shell_login_check(NULL, NULL);
0246   rtems_test_assert(!ok);
0247 
0248   rtems_test_assert(getuid() == 0);
0249   rtems_test_assert(geteuid() == 0);
0250   rtems_test_assert(getgid() == 0);
0251   rtems_test_assert(getegid() == 0);
0252   rtems_test_assert(uenv->ngroups == 0);
0253 
0254   ok = rtems_shell_login_check("zero", NULL);
0255   rtems_test_assert(ok);
0256   rtems_test_assert(getuid() == 3);
0257   rtems_test_assert(geteuid() == 3);
0258   rtems_test_assert(getgid() == 5);
0259   rtems_test_assert(getegid() == 5);
0260   rtems_test_assert(uenv->ngroups == 1);
0261   rtems_test_assert(uenv->groups[0] == 1);
0262 
0263   ok = rtems_shell_login_check("moop", "foo");
0264   rtems_test_assert(ok);
0265   rtems_test_assert(getuid() == 1);
0266   rtems_test_assert(geteuid() == 1);
0267   rtems_test_assert(getgid() == 3);
0268   rtems_test_assert(getegid() == 3);
0269   rtems_test_assert(uenv->ngroups == 5);
0270   rtems_test_assert(uenv->groups[0] == 1);
0271   rtems_test_assert(uenv->groups[1] == 2);
0272   rtems_test_assert(uenv->groups[2] == 4);
0273   rtems_test_assert(uenv->groups[3] == 5);
0274   rtems_test_assert(uenv->groups[4] == 8);
0275 
0276   rv = setuid(0);
0277   rtems_test_assert(rv == 0);
0278 
0279   rv = seteuid(0);
0280   rtems_test_assert(rv == 0);
0281 
0282   ok = rtems_shell_login_check("chroot", NULL);
0283   rtems_test_assert(ok);
0284   rtems_test_assert(getuid() == 6);
0285   rtems_test_assert(geteuid() == 6);
0286   rtems_test_assert(getgid() == 8);
0287   rtems_test_assert(getegid() == 8);
0288 
0289   rv = lstat(".", &st_workdir);
0290   rtems_test_assert(rv == 0);
0291   rtems_test_assert(memcmp(&st_chroot, &st_workdir, sizeof(st_chroot)) == 0);
0292 
0293   rtems_libio_use_global_env();
0294 }
0295 
0296 static void Init(rtems_task_argument arg)
0297 {
0298   TEST_BEGIN();
0299 
0300   test();
0301   test_joel();
0302 
0303   TEST_END();
0304   rtems_test_exit(0);
0305 }
0306 
0307 #define CONFIGURE_APPLICATION_DOES_NOT_NEED_CLOCK_DRIVER
0308 #define CONFIGURE_APPLICATION_NEEDS_SIMPLE_CONSOLE_DRIVER
0309 
0310 #define CONFIGURE_MAXIMUM_FILE_DESCRIPTORS 5
0311 
0312 #define CONFIGURE_MAXIMUM_TASKS 3
0313 #define CONFIGURE_MAXIMUM_POSIX_KEYS 2
0314 #define CONFIGURE_MAXIMUM_POSIX_KEY_VALUE_PAIRS 2
0315 
0316 #define CONFIGURE_INITIAL_EXTENSIONS RTEMS_TEST_INITIAL_EXTENSION
0317 
0318 #define CONFIGURE_RTEMS_INIT_TASKS_TABLE
0319 
0320 #define CONFIGURE_INIT
0321 
0322 #include <rtems/confdefs.h>
0323 
0324 #define CONFIGURE_SHELL_COMMANDS_INIT
0325 
0326 #include <rtems/shellconfig.h>