This assignment is worth 125 points. Partial credit will be given for all questions — it is in your best interest to not leave any blank. Some of these questions may require you to conduct research beyond what we learned in class. You are free to leverage any public resources you'd like to complete this assignment, but make sure to cite your sources in your answers. Refer to this course's honor code policy for more information on what is appropriate reuse.

For this assignment, record your responses to the following activities in the README.md file in the homework05 folder of your assignments GitLab repository and push your work (including any code you developed) by 11:59 PM Thursday, April 2.

Activity 0: Branching

As discussed in class, each homework assignment must be completed in its own git branch; this will allow you to separate the work of each assignment and for you to use the merge request workflow.

First, follow these instructions to setup your git environment.

To create a homework05 branch in your local repository, follow the instructions below:

$ cd path/to/cse-40567-sp20-assignments   # Go to assignments repository

$ git checkout master                     # Make sure we are in master branch

$ git pull --rebase                       # Make sure we are up-to-date with GitLab

$ git checkout -b homework05              # Create homework05 branch and check it out

$ cd homework05                           # Go into homework05 folder

Once these commands have been successfully performed, you are now ready to add, commit, and push any work required for this assignment.

Activity 1: Code auditing, static buffers (15 points)

Does the following code contain any static memory-related bugs that could lead to a security hole? If so, describe the problem and re-write the code so it is bug free. Provide any input strings you used to verify the correctness or incorrectness of this code.

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define DELIM ";"

void parser(char *str, int num_fields)
{
   int i;
   char *input[24];

   for (i = 0; i < num_fields; i++)
   {
       if (i == 0)
           input[i] = strtok(str, DELIM);
       else
           input[i] = strtok(NULL, DELIM);

       printf("%s\n", input[i]);
   }
}

int main(int args, char **argv)
{
    parser(argv[1], atoi(argv[2]));
    return(0);
}

Activity 2: Code auditing, static buffers (15 Points)

Does the following code contain any static memory-related bugs that could lead to a security hole? If so, describe the problem and re-write the code so it is bug free. Provide any input strings you used to verify the correctness or incorrectness of this code.

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

void length_check(char *str)
{
   printf("The combined input length is: %d\n", (int) strlen(str));
}

int main(int args, char **argv)
{
   char input[48];
   memset(input, '\0', 48);
   strncpy(input, argv[1], 24);
   strncat(input, argv[2], 48);
   length_check(input);

   return(0);
}

Activity 3: Code auditing, static buffers (15 Points)

Does the following code contain any static memory-related bugs that could lead to a security hole? If so, describe the problem and re-write the code so it is bug free. Provide any input strings you used to verify the correctness or incorrectness of this code.

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

void copy(char *str)
{
   char input[48];
   memset(input, '\0', 48);
   strcpy(input, str);
   printf("The input string is: %s\n", input);
}

int main(int args, char **argv)
{
   if (strlen(argv[1]) < 48)
   {
       copy(argv[1]);
   }

   return(0);
}

Activity 4: Code auditing, dynamic buffers (16 Points)

Does the following code contain any dynamic memory-related bugs that could lead to a security hole? If so, describe the problem and re-write the code so it is bug free. Provide any input strings you used to verify the correctness or incorrectness of this code.

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define MAX_SIZE 48

char* combine(int num_A, int num_B)
{
   char *combined;
   int i, j;

   combined = malloc(2 * MAX_SIZE);
   memset(combined, '\0', 2 * MAX_SIZE);

   if (!combined)
       exit(-1);

   for (i = 0; i < num_A && MAX_SIZE >= i; i++)
       combined[i] = 'A';

   for (j = 0; j < num_B && MAX_SIZE >= j; j++)
       combined[i + j] = 'B';

   return combined;
}

int main(int argc, char **argv)
{
   char *str;

   str = combine(atoi(argv[1]), atoi(argv[2]));
   printf("Output string: %s\n", str);
   free(str);

   return 0;
}

Activity 5: Code auditing, dynamic buffers (16 Points)

Does the following code contain any dynamic memory-related bugs that could lead to a security hole? If so, describe the problem and re-write the code so it is bug free. Provide any input strings you used to verify the correctness or incorrectness of this code.

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main(int argc, char **argv)
{
   char *input;

   input = malloc(atoi(argv[1]));
   memset(input, '\0', atoi(argv[1]));

   printf("Enter the input here: ");
   scanf ("%s", input);
   printf("The input is: %s\n", input);
   free(input);

   return 0;
}

Activity 6: Code auditing, dynamic buffers (16 Points)

Does the following code contain any dynamic memory-related bugs that could lead to a security hole? If so, describe the problem and re-write the code so it is bug free. Provide any input strings you used to verify the correctness or incorrectness of this code.

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define LEN 48

char* release(char *str)
{
   free(str);
   return str;
}

char* copy(char *str)
{
   char *input;
   input = malloc(LEN);
   memset(input, '\0', LEN);

   return (strlen(str) <= LEN - 1) ? strncpy(input, str, LEN - 1) : release(input);
}

int main(int argc, char **argv)
{
   char *input;

   input = copy(argv[1]);
   if (input != NULL)
       printf("The input string is: %s\n", input);
   release(input);

   return 0;
}

Activity 7: Code auditing, formatted output (16 Points)

Does the following code contain any format string bugs that could lead to a security hole? If so, describe the problem and re-write the code so it is bug free. Provide any input strings you used to verify the correctness or incorrectness of this code.

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main(int argc, char **argv)
{
   if (argc < 3)
   {
       printf("error: a buffer size and string must be provided as input\n");
       exit(-1);
   }

   char input[atoi(argv[1])];

   memset(input, '\0', atoi(argv[1]));
   strlcpy(input, argv[2], atoi(argv[1]));
   printf(input);

   return 0;
}

Activity 8: Code auditing, formatted output (16 Points)

Does the following code contain any format string bugs that could lead to a security hole? If so, describe the problem and re-write the code so it is bug free. Provide any input strings you used to verify the correctness or incorrectness of this code.

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main(int argc, char **argv)
{
   char input[16];
   int mem_marker = 1;
   snprintf(input, sizeof(input), argv[1]);
   input[sizeof(input) - 1] = 0;
   printf("The buffer size is: (%d) \nInput: %s \n", (int) strlen(input), input);
   printf("mem_marker equals: %d / in hex: %#x\nThe memory address for mem_marker: (%p)\n", mem_marker, mem_marker, &mem_marker);

   return 0;
}


Feedback

If you have any questions, comments, or concerns regarding the course, please provide your feedback at the end of your README.md.

Submission

Remember to put your name in the README.md file. To submit your assignment, please commit your work to the homework05 folder of your homework05 branch in your assignment's GitLab repository:

$ cd path/to/cse-40567-sp20-assignments   # Go to assignments repository
$ git checkout master                     # Make sure we are in master branch
$ git pull --rebase                       # Make sure we are up-to-date with GitLab
$ git checkout -b homework05              # Create homework05 branch and check it out
$ cd homework05                           # Go to homework05 directory
...
$ $EDITOR README.md                       # Edit appropriate README.md
$ git add README.md                       # Mark changes for commit
$ git commit -m "homework05: complete"    # Record changes
...
$ git push -u origin homework05           # Push branch to GitLab

Procedure for submitting your work: create a merge request by the process that is described here, but make sure to change the target branch from wscheirer/cse-40567-sp20-assignments to your personal fork's master branch so that your code is not visible to other students. Additionally, assign this merge request to our TA (sabraha2) and add wscheirer as an approver (so all class staff can track your submission).