Why segmentation fault ?

Rule *parse_file(FILE *fp) {
    // Implement this function and remove the stubbed return statement below.
    char *cmd_line = NULL;
    Rule *data_structure = malloc(sizeof(Rule));
    while(fgets(cmd_line, MAXLINE, fp) != NULL) {
        if(is_comment_or_empty(cmd_line) == 1) {
            continue;
        }
        if (cmd_line[0] != '\t' && cmd_line[0] != ' ') {
            char *curr_token = NULL;
            curr_token = strtok(cmd_line, " ");

            if(data_structure->target == NULL) {
                data_structure->target = curr_token;
            } else {
                Rule *curr_node = data_structure;
                while(curr_node->next_rule != NULL && curr_node->target != curr_token) {
                    curr_node = curr_node->next_rule;
                }
                if(curr_node->target != curr_token) {
                    Rule *new_rule = malloc(sizeof(Rule));
                    curr_node->next_rule = new_rule;
                    curr_node->next_rule->target = curr_token;
                }
            }
            

            while(curr_token != NULL) {
                curr_token = strtok(NULL, " ");
                if (strcmp(curr_token, ":") == 0) {
                    continue;
                }
                Rule *curr_node = data_structure;
                while(curr_node->next_rule != NULL && curr_node->target != curr_token) {
                    curr_node = curr_node->next_rule;
                }
                if(curr_node->target != curr_token) {
                    Rule *new_rule = malloc(sizeof(Rule));
                    curr_node->next_rule = new_rule;
                    curr_node->next_rule->target = curr_token;
                }
            }
        }
    }
    return data_structure;
}