473,396 Members | 2,024 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,396 software developers and data experts.

Code causes segfault on exit

For some reason, I get a segmentation fault when I exit this program I made.
Most of the time when I have seen this it has occured in the middle of the
program and the program terminates. However, in this instance, the program
gets a segmentation fault on exit.

I already posted this question, but people were asking for some code, so
here it is:
#define DWORD unsigned long
/* called from main() */
int extract(struct tm *date) {
FILE *journ;
DWORD full_date;
DWORD tmp_date;
DWORD index_size;
DWORD index_offset;
DWORD sear_size;
DWORD *index;
DWORD *bsear;
DWORD *esear;
DWORD *psear;
DWORD header[2];
size_t pwd_len;
int extra;
char *raw_buf;
char *clear_buf;
char **pwd;
char *zerout;
char chk[16];

full_date = ((date->tm_year) << 16) | ((date->tm_mon) << 8)
| (date->tm_mday);
journ = fopen(FNAME, "r");
if (fread(chk, 1, 16, journ) == 0)
return FILE_ERROR;
if (memcmp(chk, "EncryptedJournal", 16))
return FILE_ERROR;
fread(&index_offset, sizeof(index_offset), 1, journ);
fseek(journ, index_offset, SEEK_SET);
fread(&index_size, sizeof(index_size), 1, journ);
if ((index = malloc((index_size) * sizeof(*index))) == NULL)
return ERROR;
fread(index, sizeof(*index), index_size, journ);

bsear = index;
esear = index + (index_size - 1);
if (index_size == 1) {
psear = index;
fseek(journ, *psear, SEEK_SET);
fread(&tmp_date, sizeof(tmp_date), 1, journ);
}
for (sear_size = index_size; sear_size > 2;
sear_size = (esear - bsear) + 1) {

if (tmp_date < full_date)
psear = bsear + (sear_size / 2);
else
psear = esear - (sear_size/2);

fseek(journ, *psear, SEEK_SET);
fread(&tmp_date, sizeof(tmp_date), 1, journ);
if (tmp_date == full_date) {
break;
} else if (tmp_date < full_date) {
bsear = psear;
} else if (tmp_date > full_date) {
esear = psear;
}
}
if (sear_size == 2) {
fseek(journ, *bsear, SEEK_SET);
fread(&tmp_date, sizeof(tmp_date), 1, journ);
if (tmp_date != full_date) {
fseek(journ, *esear, SEEK_SET);
fread(&tmp_date, sizeof(tmp_date), 1, journ);
}
}
if (tmp_date != full_date)
return DATE_ERROR;
fread(header, sizeof(*header), 2, journ);
if ((raw_buf = malloc(header[0])) == NULL)
return ERROR;
fread(raw_buf, sizeof(*raw_buf), header[0], journ);

if ((pwd = malloc(1)) == NULL)
return ERROR;
*pwd = NULL;
if ((pwd_len = get_pwd(pwd)) == ERROR) {
printf("Passwords don't match\nSorry =(\n");
free(*pwd);
free(pwd);
return ERROR;
}
if (initialize_blowfish(*pwd, pwd_len) == ERROR) {
zerout = calloc(pwd_len + 1, 1);
memcpy(*pwd, zerout, pwd_len + 1);
free(zerout);
free(*pwd);
free(pwd);
return ERROR;
}
zerout = calloc(pwd_len + 1, 1);
memcpy(*pwd, zerout, pwd_len + 1);
free(zerout);
free(*pwd);
free(pwd);

extra = decipher(raw_buf, header[0]);
header[0] -= extra;
if ((raw_buf = realloc(raw_buf, header[0])) == NULL)
return ERROR;
if ((clear_buf = malloc(header[1])) == NULL)
return ERROR;
uncompress(clear_buf, (header + 1), raw_buf, header[0]);
fwrite(clear_buf, 1, header[1], stdout);
free(raw_buf);
free(clear_buf);
free(index);
return SUCCESS;
}

/* called from main() */
int conv_str_date(struct tm *result, char *date)
{
char *number;
long int tmp;

//month
if ((number = strtok(date, "/")) == NULL)
return ERROR;
tmp = strtol(number, NULL, 10);
if ((tmp < 0) || (tmp > 12))
return ERROR;
result->tm_mon = tmp - 1;
//day
if ((number = strtok(NULL, "/")) == NULL)
return ERROR;
tmp = strtol(number, NULL, 10);
if ((tmp < 1) || (tmp > 31))
return ERROR;
result->tm_mday = tmp;
//year
if ((number = strtok(NULL, "\0")) == NULL)
return ERROR;
tmp = strtol(number, NULL, 10);
tmp-=1900;
if (tmp < 0)
return ERROR;
result->tm_year = tmp;
return 1;
}

/* called from extract() */
int get_pwd(char **pwd)
{
struct termios old, new;
char **check;
char *s;
char *zerout;
int i;
size_t scheck = 0;
size_t spwd = 0;

if ((check = malloc(1)) == NULL)
return ERROR;
*check = NULL;
if (tcgetattr(fileno(stdin), &old) != 0)
return ERROR;
new = old;
new.c_lflag &= ~ECHO;
if (tcsetattr(fileno(stdin), TCSAFLUSH, &new) != 0)
return ERROR;
for (i = 0; i < 3; i++) {
printf("Password: ");
getline(pwd, &spwd, stdin);
printf("\nAgain: ");
getline(check, &scheck, stdin);
if (!strcmp(*pwd, *check))
break;
printf("\nPasswords don't match\n");
}
tcsetattr(fileno(stdin), TCSAFLUSH, &old);
if ((zerout = calloc(scheck, 1)) == NULL)
return ERROR;
printf("\n");
memcpy(*check, zerout, scheck);
scheck = 0;
free(*check);
free(check);
free(zerout);
if (i == 3) {
if ((zerout = calloc(spwd, 1)) == NULL)
return ERROR;
memcpy(*pwd, zerout, spwd);
return ERROR;
free(zerout);
}
assert((s = strchr(*pwd, (int)'\n')) != NULL);
*s = 0; //we don't want the newlinet in our password!!
return strlen(*pwd);
}

void decipher_dword(void *al, void *ar)
{
DWORD *temp, *xl, *xr;
int i;

xl = al;
xr = ar;
for (i = N + 1; i > 1; i--) {
*xl = *xl ^ P[i];
*xr = f(xl) ^ *xr;
SWAP(*xl, *xr, *temp);
}

SWAP(*xl, *xr, *temp);

*xr = *xr ^ P[1];
*xl = *xl ^ P[0];
}

int decipher(char *buf, size_t size)
{
div_t fix;
int i;
char *pbuf;
DWORD value;

fix = div(size, 8);
assert (fix.rem == 0);
for (i = 0; i < fix.quot; i++) {
pbuf = buf + (i * 8);
decipher_dword(pbuf, pbuf + 4);
}
if ((value = buf[size -1]) < 8)
return value;
return 0;
}

I know it's a lot, that is why I did not want to post it in the first place.

Thanks again,
James Leddy
Nov 13 '05 #1
7 5921
James Leddy wrote:
#define DWORD unsigned long


Isn't a typedef more appropriate?

Nov 13 '05 #2
James Leddy wrote:

For some reason, I get a segmentation fault when I exit this program I made.
Most of the time when I have seen this it has occured in the middle of the
program and the program terminates. However, in this instance, the program
gets a segmentation fault on exit.

I already posted this question, but people were asking for some code, so
here it is: [heavily snipped]
#define DWORD unsigned long
/* called from main() */
int extract(struct tm *date) {
[...]
journ = fopen(FNAME, "r");
You probably want "rb" there, since you appear to be
reading binary data as opposed to text.
if ((pwd = malloc(1)) == NULL)
return ERROR;
*pwd = NULL;
Here's one problem, at any rate. `pwd' is a `char**',
and unless sizeof(char*) happens to be 1 on your system
you're storing more data than you've allocated space for.
It's likely that you'll get away with this error, though,
because malloc() implementations usually round up the
requested size to a convenient multiple of some "atom"
size, and that'll probably be enough to hold the extra
data. Risky, though, and you should fix it.
if (initialize_blowfish(*pwd, pwd_len) == ERROR) {
zerout = calloc(pwd_len + 1, 1);
memcpy(*pwd, zerout, pwd_len + 1);
free(zerout);
Why fool around with this `zerout' area, when a simple
`memset(*pwd, 0, pwd_len + 1)' does the same thing with
less bother and without risking calloc() failure?
uncompress(clear_buf, (header + 1), raw_buf, header[0]);
You haven't shown us what uncompress() looks like, but that
second argument looks peculiar. Are you sure you didn't mean
`*(header + 1)' or more simply `header[1]'? If it's actually
an output from uncompress() it may be right, but check it.
/* called from extract() */
int get_pwd(char **pwd)
{
[...]
if ((check = malloc(1)) == NULL)
return ERROR;
*check = NULL;


This is the same error you made with `pwd' in extract().

If I were trying to debug this, my next step would be
to sprinkle a bunch of

fprintf (stderr, "Made it to line %d\n", __LINE__);

statements at strategic places, particularly in the latter
stages of the program where the problem appears (which is not
necessarily where it actually occurs). This technique is
surprisingly effective in helping narrow in on the actual
point of failure, but beware: if the problem arises from a
"wild pointer" stomping on unpredictable memory locations,
adding a few function calls may move things around enough
that the problem disappears or changes its manifestation.
Still, it remains a useful, if non-sexy, technique.

Another thing I'd do is check for failure of those I/O
functions. It really makes me nervous to see all that
blind trust in a number that may or may not have actually
been read ...

--
Er*********@sun.com
Nov 13 '05 #3
In article <3f**********************@news.free.fr>,
Nudge <de*****@kma.eu.org> wrote:
James Leddy wrote:
#define DWORD unsigned long


Isn't a typedef more appropriate?


DWORD (abbreviation for "double word") is not appropriate, whether you
use a #define or a typedef. On the majority of current computers,
"unsigned long" is a word and not a double word; on a small but growing
number of computers "unsigned long" is a half word.
Nov 13 '05 #4
James Leddy <jl*****@binghamton.edu> wrote:
For some reason, I get a segmentation fault when I exit this program I made.
Most of the time when I have seen this it has occured in the middle of the
program and the program terminates. However, in this instance, the program
gets a segmentation fault on exit.

I already posted this question, but people were asking for some code, so
here it is:
Fine, but it would heve been better to post your code in the thread you
already started, after cutting it down to a minimal version exhibiting
your problem.
#define DWORD unsigned long
typedef unsigned long DWORD;

<SNIP> char **pwd; <SNIP> if ((pwd = malloc(1)) == NULL) Ouch! One byte is most certainly insufficient to hold a char *.
All bets off. No further checking applied.

<SNIP>
I know it's a lot, that is why I did not want to post it in the first place.


Why didn't you reduce it?

Regards
--
Irrwahn
(ir*******@freenet.de)
Nov 13 '05 #5
Irrwahn Grausewitz wrote:
James Leddy <jl*****@binghamton.edu> wrote:
I know it's a lot, that is why I did not want to post it in the first
place.
Why didn't you reduce it?


I would have if I could have tracked down the runtime error to a line or
function. But because the error occured upon exit, I had no idea what
function the malicious code was in. So, I included all the code that was
called during the course of running this program in the erroneous case.

Regards


Nov 13 '05 #6
On Wed, 15 Oct 2003 17:11:29 -0400
James Leddy <jl*****@binghamton.edu> wrote:
For some reason, I get a segmentation fault when I exit this program I
made. Most of the time when I have seen this it has occured in the
middle of the program and the program terminates. However, in this
instance, the program gets a segmentation fault on exit.

I already posted this question, but people were asking for some code,
so here it is:
You missed at least the following includes. However, even with them
added this does not come anywhere near compiling and therefor is NOT
your source code.

#include <time.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define DWORD unsigned long
You should use a typedef rather than a #define. Look in your C reference
for the syntax.
/* called from main() */
int extract(struct tm *date) {
FILE *journ;
DWORD full_date;
DWORD tmp_date;
DWORD index_size;
DWORD index_offset;
DWORD sear_size;
DWORD *index;
DWORD *bsear;
DWORD *esear;
DWORD *psear;
DWORD header[2];
size_t pwd_len;
int extra;
char *raw_buf;
char *clear_buf;
char **pwd;
char *zerout;
char chk[16];

full_date = ((date->tm_year) << 16) | ((date->tm_mon) << 8)
| (date->tm_mday);
journ = fopen(FNAME, "r");
t.c:30: error: `FNAME' undeclared (first use in this function)

The first of many.

<snip>
I know it's a lot, that is why I did not want to post it in the first
place.


Then try deleting bits to cut it down to the minimum COMPILABLE example
that exhibits your problem. Even if I took guesses at how identifiers
should be declared, you have not included a definition of main so I
don't know how you use the functions.

Amongst the things you should delete (or replace with suitable stubs)
are all the OS dependant things such as getline (a GNU extension),
tcsetattr which is a UNIX function etc.

I also suggest you look up in your compiler manual on how to turn up the
warning level then deal with all the many warning you will get.

I also suggest you look up the definition of malloc and then check your
usage since the following is also an error
char **pwd;
if ((pwd = malloc(1)) == NULL)
return ERROR;
*pwd = NULL;

Finally I suggest you go back to something far simpler such as working
your way through the examples in a GOO C text book such as K&R2.
--
Mark Gordon
Paid to be a Geek & a Senior Software Developer
Although my email address says spamtrap, it is real and I read it.
Nov 13 '05 #7
James Leddy <jl*****@binghamton.edu> wrote:
Irrwahn Grausewitz wrote:
James Leddy <jl*****@binghamton.edu> wrote:
I know it's a lot, that is why I did not want to post it in the first
place.


Why didn't you reduce it?


I would have if I could have tracked down the runtime error to a line or
function. But because the error occured upon exit, I had no idea what
function the malicious code was in. So, I included all the code that was
called during the course of running this program in the erroneous case.


Well, you could replace functions with dummy versions (one at a time)
and check whether the error goes away.

Furthermore, if you'd pumped up the warning level of your compiler, it'd
given you several hints to flaws in your code.

Finally, to track down errors, the use of a debugger has been reported
to be somewhat helpful. ;-)

Regards
--
Irrwahn
(ir*******@freenet.de)
Nov 13 '05 #8

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

23
by: James Aguilar | last post by:
Someone showed me something today that I didn't understand. This doesn't seem like it should be valid C++. Specifically, I don't understand how the commas are accepted after the function...
1
by: Daveyk0 | last post by:
Hello there, I have a front end database that I have recently made very many changes to to allow off-line use. I keep copies of the databases on my hard drive and link to them rather than the...
12
by: Vijay Kumar R Zanvar | last post by:
Hi, I invite reviews for the following code: #include <stdio.h> #include <string.h> #include <stdlib.h> int main ( void )
9
by: Narendran Kumaraguru Nathan | last post by:
Hi all, I am fairly experianced in C. I am writing a program in which I'm getting a segmentation fault. The problem is that it is getting the segmentation fault when executing calloc. I tried...
32
by: fatted | last post by:
I've written a function (clean_string) to remove characters from a string, but it looks clunky to me, and I'm sure there's a more 'C' like way of doing it (still learning), comments and advice...
165
by: Dieter | last post by:
Hi. In the snippet of code below, I'm trying to understand why when the struct dirent ** namelist is declared with "file" scope, I don't have a problem freeing the allocated memory. But...
12
by: comp.lang.php | last post by:
index.php: // STUFF // STEP 1: imagecreatetruecolor ONLY IF GD 2.0+ SUPPORTED AND FOUND if ($this->isSuccessful && !$hasMogrified && $image && !$newImage &&...
41
by: SkyBlue | last post by:
Hi, can someone explain why the following simple C code segfaulted? I've stared it for 30mins but couldn't find the problem. Thx in advance #include <stdio.h> int main() { char *one; char...
49
by: comp.lang.php | last post by:
/** * Class for grayscaling image * * @author Phil Powell * @version 1.2.1 * @package IMAGE_CATALOG::IMAGE */ class ImageGrayscaleGenerator extends ImageResizeComponents { /
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
0
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...
0
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.