Safe Ch
Ch was designed with the ease of use and security in mind.

The pointer and memory allocation/deallocation make C/C++ powerful, but they are not easy to handle for an inexperienced programmer. The inappropriate handling of the pointer and memory can lead to buffer overflow. We have noticed that a very high percentage of programs that crash suffer from the mishandling of the string.

Ch recognizes this shortcoming and has a built-in string type with automatic memory management to resolve this problem. It can work seamlessly with the type char* and char []. Users are encouraged to use this feature for rapid application development without concerns for memory handling and pointers. Furthermore, Ch checks array bounds automatically to avoid memory corruption.

Safe Ch is introduced to address the security concerns for C-based applets to run across the Internet or as a restricted shell. Safe Ch disables the use of C pointer and reduces the potential security risk while taking advantage of pointers in other applications such as real-time control of machinery and data acquisition. Safe Ch has a sandbox and limits a malicious applet from gaining privilege to take full control of the computer.

Program chs is safe Ch shell. If the -S flag is present when the Ch language environment is invoked as ch -S , the Ch shell is a safe shell. The macro _SCH_ is predefined with value 1 for a safe shell. The execution environments of a safe shell are more controlled than those of the regular shell and restricted shell. Ch -S and Ch run similarly, except that the following features are disabled in safe shell:

  • changing directory by cd and chdir
  • specifying path or command names containing character '/' in input command, command statement, and command substitution.
  • specifying path or command names containing characters '/' or '\' in a dot command statement.
  • specifying path with first character of '/' or '\' in file #include <file>.
  • #include "file" is treated as #include <file>
  • redirecting input and output (<, <<, >, >|, and >>)
  • built-in function system()
  • using built-in variables _path, _fpath, _ipath, _user, _home, _cwd, _shell, _host as lvalue. To the safe shell user, these system variables have value of NULL. To test setup, you may print the values of these system variables inside startup file .chsrc in Unix and _chsrc in Windows in the user's home directory.
  • use shell commands parse and run in interactive mode.
  • specifying path or command names containing ; (will be Ok in future)
  • specifying path or command names containing | (will be Ok in future)
  • Lvalue of pointer type. For example, char *p, **p2; p = malloc(90); p2 = &p; But, array type can be used as lvalue. For example, int a[2]={1,2}; a[1] =90;
  • Casting a non-pointer value to a pointer. For example, char *p; p = (char *)16;
  • Pointer arithmetic. For example, char *p; p = p+128; int a[15]; *(a+10)=12;
  • Generic functions _execv(), _execvp(), _fopen(), _fork(), _fstat(), _lstat(), _pipe(), _popen(), _remove(), _rename(), _socket(), _socketpair(), _stat(), _utime(), _system(), ccess(), getenv(). open(), putenv(), setrlimit(), umask().
  • Functions or function files with return type qualified with type qualifier restrict are called restricted functions as shown below.
       #!/bin/ch -S
       restrict void funct(void) {
          printf("This function cannot be called by Safe Ch program.\n");
       }
       funct(); // Eerror: call restricted functions
    
    The following restricted functions cannot be called by safe Ch programs: accept(), chdir(), chown(), chroot(), creat(), execl(), execv(), execle(), execve(), execlp(), execvp(), fchdir(), fchown(), fchroot(), fdopen(), fopen(), fstat(), gethostname(), kill(), lchown(), link(), lstat(), mkdir(), pipe(), popen(), remove(), rename(), rmdir(), socket(), socketpair(), stat(), system(), unlink().
  • Macro offsetof().
  • No command and file name completion in a command shell.
The restrictions above are enforced after .chsrc in the home directory is interpreted. For maximum security, a system administrator may take the ownership of .chsrc and change the mode of the file to readable only. The CPU resource in safe shell for each process can also be restricted by modifying .chsrc file. If Ch is invoked with option -S, option -f will be ignored. These additional restrictions are relaxed for function files located in a client. Therefore, an important safety guidance is to not use arguments from a function file as input to restricted functions directly. The memory outside the array boundary is guaranteed to not be contaminated. if an array is used as a pointer to void or pointer to char in the following functions: fgets(), fread(), gets(), memcpy(), memmove(), memset(), read(), recv(), sprintf() strcat(), strcpy(), strncat(), strncpy(). The contaminated memory by functions fscanf(), scanf(), and sscanf() are set to null character to close a possible security hole. If a program tries to write to the memory outside the array boundary, an error message will be generated. Since variables of pointer type cannot be invoked in safe shell, these functions will be safe to use.

When a command to be executed is found to be a Ch program, the safe shell invokes ch -S to execute it. If a Ch program is invoked with shell identification #!/bin/ch without option -S, the safe shell invokes ch to execute it. Thus, it is possible to provide to the end-user Ch programs that have access to the full power of the regular shell, while imposing a limited number of commands; this scheme assumes that the end-user does not have write and execute permissions in a directory containing commands. Therefore, the writer of the .chsrc has complete control over user actions, by performing guaranteed setup actions and leaving the user in an appropriate directory (probably not the login directory). A default directory CHHOME/sbin has been setup for putting binary and Ch commands, respectively, that can be safely invoked by safe shell. Applications of safe Ch are illustrated by Ch applet-based network computing.