Why am I not getting a segmentation error with this code? (Bus error)

I had an error in my code that was like that.

char desc[25]; char name[20]; char address[20]; sprintf (desc, "%s %s", name, address); 

Ideally, this should give segfault. However, I saw that this leads to a bus error. Wikipedia says that something in the order of “Bus Error” is when a program tries to access an unaccepted memory location or when you try to access a physical (not virtual) memory location that does not exist or is not allowed.

The second part of the above statement is similar to seg error. So my question is: when do you get SIGBUS and when is SIGSEGV?

EDIT: - Many people mentioned this. I'm not sure what context is needed, but this is a buffer overflow lying inside a static class function called from a number of other class functions. If there is anything more specific that I can give that will help, ask.

In any case, someone commented that I should just write better code. My guess is that the question was “Can an application developer do anything from SIGBUS compared to SIGSEGV?” (selected from this blog post below)

+4
source share
6 answers

As you probably understand, the main reason is undefined behavior in your program. In this case, this leads to an error detected by the hardware, which is captured by the OS and displayed on the signal. The exact mapping is not really indicated (and I saw the integral division by zero in SIGFPE ), but usually: SIGSEGV occurs when you access from, SIGBUS for other access errors and SIGILL for illegal instruction. In this case, the most likely explanation is that your bounds error rewrote the return address on the stack. If the return address is not correctly aligned, you will probably get SIGBUS , and if so, you will start to do whatever it is that could lead to SIGILL . (But the ability to execute random bytes as code is what the standards committee had in mind when they defined “undefined behavior.” Especially on machines without memory, protection is where you could go directly to the OS.)

+4
source

Segmentation error is never guaranteed when you make fish stuff with memory. It all depends on many factors (how the compiler sets out the program in memory, optimization, etc.).

What may be illegal for a C ++ program may not be illegal for the program as a whole. For example, the OS does not care if you go beyond the array. He doesn't even know what an array is. However, it doesn’t matter if you touch a memory that does not belong to you.

+4
source

In this particular case, you do not know what kind of garbage you have in the format string. This garbage can potentially lead to other arguments being treated as "aligned" data types (for example, int or double ). Treating an unaligned region as a consistent argument definitely causes SIGBUS for some systems.

+1
source

A segmentation error occurs if you try to access virtual address data that is not tied to your process. On most operating systems, memory is displayed on pages of several kilobytes; this means that you often will not get an error if you write off the end of the array, because there are other reliable data on the memory page.

A bus error indicates a lower level error; as you say, there are two reasons: incorrect access or missing physical address. However, the first of these does not occur here, since you are dealing with bytes that have no alignment restrictions; and I think the second can only happen when accessing data, when the memory is completely exhausted, which probably does not happen.

However, I think you can also get a bus error if you try to execute code from an invalid virtual address. This may be what happens here - by writing off the end of the local array, you will overwrite important parts of the stack frame, such as the function return address. This will cause the function to return to the wrong address, which (I think) will give a bus error. This is my best guess about what a special undefined taste you have here.

In general, you cannot rely on segmentation errors to intercept buffers; The best tool I know is valgrind , although it still won't be able to catch some kind of overspending. The best way to avoid overflow when working with strings is to use std::string , rather than pretending that you are writing C.

+1
source

Given that your line consists of two lines, each of which has a length of not more than 20 characters, but you put it in a field containing 25 characters, that is your first problem. You have good potential to transcend your boundaries.

The desc variable must contain at least 41 characters (20 + 20 + 1 [for the place you insert]).

Use valgrind or gdb to find out why you get a seg error.

0
source
 char desc[25]; char name[20]; char address[20]; sprintf (desc, "%s %s", name, address); 

Just by looking at this code, I can assume that name and address can be long 20 . If so, does that not mean that desc should be a minimum 20+20+1 long symbol? ( 1 char for the space between name and address , as stated in sprintf ).

This may be one of the reasons segfault. There may be other reasons. For example, what if name longer than 20 characters?

So it’s better that you use std::string :

 std::string name; std::string address; std::string desc = name + " " + address; char const *char_desc = desc.str(); //if at all you need this 
0
source

Source: https://habr.com/ru/post/1400258/