Is this usage of mlockall correct?

你说的曾经没有我的故事 提交于 2019-12-14 04:09:21

问题


The program below XORs 2 files to create an output file using one time pad encryption. I have attempted to use mlockall in order to avoid any traces of the keyfile being left on the hard drive when getting the keyfile from external memory sources.

From the mlockall man page:

mlock() and mlockall() respectively lock part or all of the calling process's virtual address space into RAM, preventing that memory from being paged to the swap area.

How I do check if it is working and have I used mlockall correctly?

#include <stdio.h>
#include <stdlib.h>
#include <sys/stat.h>
#include <sys/mman.h>

int main(int argc, char **argv)
{
struct stat statbuf;
struct stat keybuf;

char buffer [20];
int key;
int data;
int output;
int count;
char ans;
int * buf;
FILE * keyfile;
FILE * sourcefile;
FILE * destfile;

if(geteuid() !=0)
{
printf("Root access is required to run this program\n\n");
exit(0);
}

if(argc<4)
{
printf("OTP-Bunny 1.0\n");
printf("USAGE: OTP <source file> <output file> <keyfile>\n");
return (0);
}

/* Check number of arguments. */
if(argc>4)
{
printf("Too many arguments.\n");
printf("USAGE: OTP <source file> <output file> <keyfile>\n");
exit(1);
}

/* Allocate memory required by processes */
buf = (int*) malloc (sizeof(int));
if (buf == NULL)
{
perror("Error");
exit(1);
}

/* Lock down pages mapped to processes */
printf("Locking down processes\n");
if(mlockall (MCL_CURRENT | MCL_FUTURE) < 0)
{
perror("mlockall");
exit (1);
}


/* Check if sourcefile can be opened. */
if((sourcefile = fopen(argv[1], "rb"))== NULL)
{
printf("Can't open source file\n");
perror("Error");
printf("USAGE: OTP <source file> <output file> <keyfile>\n");
exit (1);
}

/* Get size of sourcefile */
fstat(fileno(sourcefile), &statbuf); 

/* Check if keyfile can be opened. */
if((keyfile = fopen(argv[3], "rb"))== NULL)
{
printf("Can't open keyfile.\n");
perror("Error");
printf("USAGE: OTP <source file> <output file> <keyfile>\n");
exit(1);
}                               

/* Get size of keyfile */
fstat(fileno(keyfile), &keybuf);

/* Check if keyfile is the same size as, or bigger than the sourcefile */
if((keybuf.st_size) < (statbuf.st_size))
{
printf("Source file is larger than keyfile.\n");
printf("This significantly reduces cryptographic strength.\n");
printf("Do you wish to continue? (Y/N)\n");
fgets(buffer, 20, stdin);
sscanf(buffer, "%c", &ans);
if(ans == 'n' || ans == 'N')
{
exit (1);
}
if(ans == 'y' || ans == 'Y')
{
    printf("Proceeding with Encryption/Decryption.\n");
    }
else
{
printf("No option selected. Exiting...\n");
exit (1);
}
}   

/* Check if destfile can be opened. */
if((destfile = fopen(argv[2], "wb"))== NULL)
{
printf("Can't open output file.\n");
perror("Error");
exit(1);                    
}    

/* Encrypt/Decrypt and write to output file. */
while(count < (statbuf.st_size))
{
key=fgetc(keyfile);
data=fgetc(sourcefile);

output=(key^data);

fputc(output,destfile);
count++;
}

/* Close files. */
fclose(keyfile);
fclose(sourcefile);
fclose(destfile);

printf("Encryption/Decryption Complete.\n\n");

/* delete keyfile option. */
printf("Do you wish to delete the keyfile? (Y/N)\n");
fgets(buffer, 20, stdin);
sscanf(buffer, "%c", &ans);
if(ans == 'y' || ans == 'Y')
{
    if ( remove(argv[3]) == 0)
    {
    printf("File deleted successfully.\n");
    }
    else
    {
    printf("Unable to delete the file.\n");
    perror("Error");
    exit(1);
    }
}

/* cleanup */
printf("Releasing memory\n");
free (buf);
return(0);
}

回答1:


Your usage of mlockall is probably correct. Since you gave MCL_FUTURE any indirect malloc (e.g. by fopen) would also be concerned - but these malloc-s might need to mmap (and these mmap syscalls might fail, e.g. because of lack of RAM).

But why don't you make your buf a local int variable?

And I don't understand why using mlockall would "avoid any traces of the keyfile being left on the hard drive"; the keyfile is surely in a filesystem (and probably in some kernel file cache), which leave traces on some disk (unless you use e.g. a tmpfs filesystem for it). mlopckall(2) deals with the process' (virtual memory) address space, but files are related to the file systems, which on Linux usually have kernel buffers and cache.

Because of lack of indentation, I tend to find your program hard to read, and I don't understand exactly what it does and what is the relevance of mlockall. It would be nice to edit your question to explain the intended purpose of your program.

You really should read a good book like e.g. Advanced Linux Programming and Advanced Unix Programming. It seems that you are missing some basic concepts; I don't understand why you are using mlockall.

Perhaps you might use lower-level syscalls like mmap(2) to access your sensitive data (and munmap(2) it as soon as possible, perhaps clearing it before). You don't know exactly what fopen or fgetc are doing, they are adding another buffer, which will keep your secret data, perhaps even after fclose.

Also, you might want to define (at least in your head and in explicit comments) what is your trusted computing base.

Also, cryptography is a very difficult science. Please use existing cryptographic library instead of inventing your own encryption (which is really a child's play). If you want to become a cryptographer, please get a PhD on that domain. (I do recommend using some cryptographic library with your one time pad, not just an xor).



来源:https://stackoverflow.com/questions/12990214/is-this-usage-of-mlockall-correct

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!