0

I am working on an encryption project and I am making a simple test that takes a file name from terminal and runs my encryption. I have the following encryption code but I get the following segmentation fault:

terminate called after throwing an instance of 'std::logic_error'
  what():  basic_string::_M_construct null not valid<br><br>
Program received signal SIGABRT, Aborted.
0x00007ffff74ab428 in __GI_raise (sig=sig@entry=6)
    at ../sysdeps/unix/sysv/linux/raise.c:54
54  ../sysdeps/unix/sysv/linux/raise.c: No such file or directory.

After running a trace with gdb I have confirmed that this fault is triggered after the following loc:

string plain(reinterpret_cast(fileContents), fileLength);

My main function below calls this piece of code:

#include <iostream>
#include <stdlib.h>
#include <stdio.h>
#include <string>
#include <fstream>
#include <limits>
#include <sstream>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include "rc4_enc.c"
#include "rc4_skey.c"

using namespace std;
void foo(int);

int main(int argc, char * argv[]){
    if(argc!=2){
        cout << "Please enter the filename that you want to encrypt or decrypt\n";
        exit(2);
    }
    int fd;
    fd = open(argv[1], O_RDONLY);
    cout << "The file descriptor is " << fd << endl;
    //close(fd);// Can I modify it if it's closed?
    foo(fd);

    return 0;
}

And the function is as follows:

void foo(int fd) {

     int fileLength = lseek(fd, 0, SEEK_END);
     unsigned char* fileContents;
     fileContents = (unsigned char*) calloc(fileLength, sizeof(char));
     pread(fd, fileContents, fileLength, 0);
     string plain(reinterpret_cast<char*>(fileContents), fileLength); // Segfault happens here. But why? 
        RC4_KEY key;
        int length = plain.size();
        unsigned char *buf = (unsigned char*)malloc(length+1);
        memset(buf, 0, length+1);

        ifstream pass;
        pass.open("pass.txt");
        if(!pass.good()){
            return;
        }
        else{
            string password;
            getline(pass,password);
            RC4_set_key(&key, password.length(), (const unsigned char*)password.c_str());
        }
        RC4(&key, length, (const unsigned char*)plain.c_str(), buf);
        string result((char*)buf, length);
        free(buf);
        const char *outputBuf = result.c_str();
        pwrite(fd, outputBuf, result.length(), 0);
        ftruncate(fd, result.length());
    }
Callat
  • 2,928
  • 5
  • 30
  • 47
  • 1
    Why are you #including .c files? –  Apr 14 '17 at 16:12
  • 1
    try `filecontents[filelength-1] = '\0';` right after the pread; just for a try; I suppose your `filecontents` is not terminated correctly; if it works you'll have to correct the length by 1 as well. – Stephan Lechner Apr 14 '17 at 16:12
  • @NeilButterworth those .c files contain all the required dependancies to use the `RC4_set_key()` & `RC4()` functions from openssl which I've already integrated. – Callat Apr 14 '17 at 16:14
  • @StephanLechner ok, I'll test that. – Callat Apr 14 '17 at 16:15
  • 1
    You should be linking to them, not including them. Including .c or .c++ files is very bad practice. –  Apr 14 '17 at 16:17
  • @StephanLechner This throws a different segmentation fault at the point that you suggested I include it, the fault is the following: `Program received signal SIGSEGV, Segmentation fault. 0x0000000000401dd8 in foo (fd=3) at main.cpp:72 72 fileContents[fileLength-1] = '\0'; ` – Callat Apr 14 '17 at 16:18
  • @NeilButterworth thanks I'll keep that in mind for the actual implementation, this is only testing right now as there is no way for me to show the full version of the project. It's far too huge. – Callat Apr 14 '17 at 16:25

1 Answers1

1

I would leave this as a comment, but do not have enough reputation.

How large is the file? Could calloc be failing and returning NULL? Even if it's not that, might be wise to check calloc's return value. Or use the new operator, with try/catch.

Cl9
  • 46
  • 3
  • The file is short, 6 bytes but I have a range of files to test it against before I integrate it into my filesystem project. This faults out on 6 bytes. I'll examine calloc's return – Callat Apr 14 '17 at 16:22
  • Yup that's it! Thanks for the walkthrough. – Callat Apr 14 '17 at 16:23