* 10 *

Software security

  1. Suppose that you are writing a program and you need to construct the full name of a file which you will open. The filename consists of a directory-path and the actual nodename. Nodenames are usually restricted to being no more than 255 characters long. Explain at least two things wrong with the following:
    char *BuildName(char *path, char *name)
    { char buffer[256];
    return buffer;
    First of all the lengths of path and name are unknown! They could be anything (much bigger than 256). We should check somehow, e.g.
    if (path == NULL || name == NULL)
       printf("Bad path or filename\n");
       return NULL;
    if (strlen(path)+strlen(name)+strlen("/")+strlen("\0") > 256)
       printf("Filename too long\n");
       return NULL;
    The other problem is that the function allocates local memory for the result and then tries to pass it back to the calling function. This cannot produce a sensible result. As soon as the function returns buffer ceases to exist, so the result will most likely be garbage. We solve this in two ways: either declare:
    static char buffer[256];
    buffer[0] = '\0';  // Clear static buffer for reuse
    or rewrite the function to that we send the address of an independent buffer which will be used:
    char buffer[1024];
    buffer = BuildName(path,name,buffer);
    if (buffer == NULL)
       /* error */
  2. Rewrite the function above so that it is secure. Hint, use strlen() to check lengths. See above.
  3. Suppose the path were the name of a user, and we intend to write to the file e.g.
    name = BuildName("/home/mark",".cshrc");
    fp = fopen(name,"w");
    Describe an explain a safe way to open the file for a system process. Describe what can go wrong in this kind of simple operation.
    Since we are writing to an area where an ordinary non-privileged user can write, using a privileged system process, we have to watch out for symbolic links and race conditions. See this week's lecture.