Core dump file name truncated - linux

Given the configuration in /proc/sys/kernel/core_pattern set to /cores/core.%e.%p, core dumps are named according to pattern, however for processes running executables with long names e.g. SampleCrashApplication, the generated core file will contain a truncated executable name: /cores/core.SampleCrashAppl.9933
What is causing this ? The man core page talks only about maximum size of the resulting core filename being 128 (64 for kernels before 2.6.19)

The code for this can be found in exec.c here.
The code is going to copy the corename based on the pattern up to the first percentage (giving /cores/core.). At the percentage it's going to increment and process the 'e'. The code for processing the 'e' part prints out the pattern using snprintf based on the current->comm structure.
This is the executable name (excluding path) TRUNCATED to the value TASK_COMM_LEN. Since this is defined as 16 characters (at least in the Kernel I found) then SampleCrashApplication is truncated to 15 + 1 characters (1 for the null byte at the end) which explains why you get your truncated core dump name.
At to why this structure truncates the name TASK_COMM_LEN, that's a deeper question, but it's something internal to the kernel and there's some discussion here.

Related

Stack Overflow (Shellcoder's Handbook)

I'm currently following the erratas for the Shellcoder's Handbook (2nd edition).
The book is a little outdated but pretty good still. My problem right now is that I can't guess how long my payload needs to be I tried to follow every step (and run gdb with the same arguments) and I tried to guess where the buffer starts, but I don't know exactly. I'm kind of new to this too so it makes sense.
I have a vulnerable program with strcpy() and a buffer[512]. I want to make the stack overflow, so I run some A's with the program (as the Erratas for the Shellcoders Handbook). I want to find how long the payload needs to be (no ASLR) so in theory I just need to find where the buffer is.
Since I'm new I can't post an image, but the preferred output from the book has a full 4 row of 'A's (0x41414141), and mine is like this:
(gdb) x/20xw $esp - 532
0xbffff968 : 0x0000000 0xbfffffa0e 0x41414141 0x41414141
0xbffff968 0x41414141 0x41414141 0x00004141 0x0804834
What address is that? How I know where this buffer starts? I want to do this so I can keep working with the book. I realize that the buffer is somewhere in there because of the A's that I ran. But if I want to find how long the payload needs to be I need the point where it starts.
I'm not sure that you copied the output of gdb correctly. You used the command x/20xw, this says you'd like to examine 20 32-bit words of memory, displayed as hex. As such, each item of data displayed should consist of 0x followed by 8 characters. You have some some with only 7, and some with 9. I'll assume that you copied out the text by hand and made a few mistakes.
The address is the first item displayed on the line, so, for the first line the address is 0xbffff968, this is the address of the first byte on the line. From there you can figure out the address of every other byte on the line by counting.
Your second line looks a little messed up, you have the same address, and also you're missing the : character, again, I'll assume this is just a result of the copy. I would expect the address of the second line to be 0xbffff978.
If the buffer starts with the first word of 0x41414141 then this is at address 0xbffff970, though an easier way to figure out the address of a variable is just to ask gdb for the address of the variable, so, in your case, once gdb is stopped at a place where buffer is in scope:
(gdb) p &buffer
$1 = (char (*)[512]) 0xbffff970
Metasploit has a nice tool to assist with calculating the offset. It will generate a string that contains unique patterns. Using this pattern (and the value of EIP or whatever other location after using the pattern), you can see how big the buffer should be to write exactly into EIP or whatever other location.
Open the tools folder in the metasploit framework3 folder (I’m using a linux version of metasploit 3). You should find a tool called pattern_create.rb. Create a pattern of 5000 characters and write it into a file:
root#bt:/pentest/exploits/framework3/tools# ./pattern_create.rb
Usage: pattern_create.rb length [set a] [set b] [set c]
root#bt:/pentest/exploits/framework3/tools# ./pattern_create.rb 5000
Then just replace the A's with the output of the tool.
Run the application and wait until the application dies again, and take note of the contents of EIP or whatever other location.
Then use a second metasploit tool to calculate the exact length of the buffer before writing into EIP or whatever other location, feed it with the value of EIP or whatever other location(based on the pattern file) and length of the buffer :
root#bt:/pentest/exploits/framework3/tools# ./pattern_offset.rb 0x356b4234 5000
1094
root#bt:/pentest/exploits/framework3/tools#
That’s the buffer length needed to overwrite EIP or whatever other location.

In order to obtain the size of ELF binary, what's the difference between size and ls?

Test is on 32bit x86 Linux.
In order to get the size of some ELF binaries, I tried these two commands:
ls -la sha512sum
size sha512sum
But the thing is that the size output are different:
ls -la sha512sum
-rwxrwxr-x 1 szw175 szw175 95856 Oct 10 07:50 sha512sum
size sha512sum
text data bss dec hex filename
89644 488 452 90584 161d8 sha512sum
So my question is, in order to evaluate the size of an ELF binary, which method is more reliable? Why are these two methods different?
size(1) tells you the sizes of the various sections within the file. ls(1) tells you the number of bytes the ELF file contains. They serve completely different purposes, and which one is more "reliable" depends completely upon what you're going to do with the file.
You could think of a elf-file contain various information about loading & linking the program at runtime. All information that is given as input (.text, .data, .bss, .rel.*, etc.) all are stored in various sections of the elf-file. These section are managed by a section-header table stored somewhere in the binary.
You get the size of contents of the sections by
size sha512sum
but, if you want to get the total size of the file (which includes along with section contents - elf-header, program-header table, and section-header table), then you will use
ls -la sha512sum
Note that when the program is loaded (at any address, namely base address), the contents of the sections are mapped at various offsets from the base address. The mapping may not be continous and the runtime-image of the program may be larger than the file-size. Also, note that some sections (like .bss which only contain zeros) are not even stored in the file. The program-loader maps a memory-region and fills zeros in them, instead of copying zeros from the file. This saves alot of disk space & reduces file size (and thus, the time to load the binary into memory).
So, the memory-image size of the program could be larger than the file-size.

when user types size command in linux/unix, what does the result mean?

I've been wandering about the size of bss, data or text that I have. So I typed size command.
The result is
text data bss dec hex filename
5461 580 24 ....
What does the number mean? Is the unit bits, Bytes, Kilobytes or Megabytes?
In addition, how to reduce the size of bss, data, text of the file? (Not using strip command.)
That command shows a list of the sections and their sizes in bytes found in an object file. The unit is decimal bytes, unless display of a different format was specified. And there most likely exists a man page for the size command too.
"reduce the size" - modify source code. Take things out.
As for the part about reducing segment size, you have some leeway in moving parts from data to bss by not initializing them. This is only an option if the program initializes the data in another way.
You can reduce data or bss by replacing arrays with dynamically allocated memory, using malloc and friends.
Note that the bss takes no space in the executable and reducing it just for the sake of having smaller numbers reported by size is probably not a good idea.

Getting length of /proc/self/exe symlink

As mentioned on SO, readlink on /proc/self/exe can be used to get the executable path on linux. man 2 readlink recommends that one should use lstat to extract the required length of a path. However, when I stat /proc/self/exe, the st_size member is set to 0. How can I get the length for allocating the buffer?
taken from man 2 lstat, under NOTES
For most files under the /proc directory, stat() does not return
the file size in the st_size field; instead the field is returned
with the value 0.
That's why it does not work
In practice, I would tend to use a reasonable size (e.g. 256 or 1024, or PATH_MAX) for readlink of /proc/*/exe (or /proc/self/exe)
The point is that almost always, executables are supposed to be started by humans, so either the PATH (for execvp(3) or some shell) or the entire file path is human friendly. I don't know any people who explicitly uses very long filenames (not fitting in width in some terminal screen). I never heard of executable programs (or scripts) whose filename exceeds a hundred of bytes.
So just use a local buffer of some reasonable size (and perhaps strdup it on success if so needed). And readlink(2) returns the number of meaningful bytes in its buffer (so if you really care, grow the buffer and make a loop till it fits).
For readlink of /proc/self/exe, I would do it into a 256 bytes buffer at initialization, and abort (with a meaningful error message) if it does not fit (or fail, e.g. because /proc/ is not mounted).

Where is OPEN_MAX defined for Linux systems?

OPEN_MAX is the constant that defines the maximum number of open files allowed for a single program.
According to Beginning Linux Programming 4th Edition, Page 101 :
The limit, usually defined by the constant OPEN_MAX in limits.h, varies from system to system, ...
In my system, the file limits.h in directory /usr/lib/gcc/x86_64-linux-gnu/4.6/include-fixed does not have this constant. Am i looking at the wrong limits.h or has the location of OPEN_MAX changed since 2008 ?
For what it's worth, the 4th edition of Beginning Linux Programming was published in 2007; parts of it may be a bit out of date. (That's not a criticism of the book, which I haven't read.)
It appears that OPEN_MAX is deprecated, at least on Linux systems. The reason appears to be that the maximum number of file that can be opened simultaneously is not fixed, so a macro that expands to an integer literal is not a good way to get that information.
There's another macro FOPEN_MAX that should be similar; I can't think of a reason why OPEN_MAX and FOPEN_MAX, if they're both defined, should have different values. But FOPEN_MAX is mandated by the C language standard, so system's don't have the option of not defining it. The C standard says that FOPEN_MAX
expands to an integer constant expression that is the minimum number of files that
the implementation guarantees can be open simultaneously
(If the word "minimum" is confusing, it's a guarantee that a program can open at least that many files at once.)
If you want the current maximum number of files that can be opened, take a look at the sysconf() function; on my system, sysconf(_SC_OPEN_MAX) returns 1024. (The sysconf() man page refers to a symbol OPEN_MAX. This is not a count, but a value recognized by sysconf(). And it's not defined on my system.)
I've searched for OPEN_MAX (word match, so excluding FOPEN_MAX) on my Ubuntu system, and found the following (these are obviously just brief excerpts):
/usr/include/X11/Xos.h:
# ifdef __GNU__
# define PATH_MAX 4096
# define MAXPATHLEN 4096
# define OPEN_MAX 256 /* We define a reasonable limit. */
# endif
/usr/include/i386-linux-gnu/bits/local_lim.h:
/* The kernel header pollutes the namespace with the NR_OPEN symbol
and defines LINK_MAX although filesystems have different maxima. A
similar thing is true for OPEN_MAX: the limit can be changed at
runtime and therefore the macro must not be defined. Remove this
after including the header if necessary. */
#ifndef NR_OPEN
# define __undef_NR_OPEN
#endif
#ifndef LINK_MAX
# define __undef_LINK_MAX
#endif
#ifndef OPEN_MAX
# define __undef_OPEN_MAX
#endif
#ifndef ARG_MAX
# define __undef_ARG_MAX
#endif
/usr/include/i386-linux-gnu/bits/xopen_lim.h:
/* We do not provide fixed values for
ARG_MAX Maximum length of argument to the `exec' function
including environment data.
ATEXIT_MAX Maximum number of functions that may be registered
with `atexit'.
CHILD_MAX Maximum number of simultaneous processes per real
user ID.
OPEN_MAX Maximum number of files that one process can have open
at anyone time.
PAGESIZE
PAGE_SIZE Size of bytes of a page.
PASS_MAX Maximum number of significant bytes in a password.
We only provide a fixed limit for
IOV_MAX Maximum number of `iovec' structures that one process has
available for use with `readv' or writev'.
if this is indeed fixed by the underlying system.
*/
Aside from the link given by cste, I would like to point out that there is a /proc/sys/fs/file-max entry that provides the number of files THE SYSTEM can have open at any given time.
Here's some docs:
https://access.redhat.com/knowledge/docs/en-US/Red_Hat_Directory_Server/8.2/html/Performance_Tuning_Guide/system-tuning.html
Note that this is not to say that there's a GUARANTEE you can open that many files - if the system runs out of some resource (e.g. "no more memory available"), then it may well fail.
The FOPEN_MAX indicates that the C library allows this many files to be opened (at least, as discussed), but there are other limits that may happen first. Say for example the SYSTEM limit is 4000 files, and some applications already running has 3990 files open. Then you won't be able to open more than 7 files [since stdin, stdout and stderr take up three slots too]. And if rlimit is set to 5, then you can only open 2 files of your own.
In my opinion, the best way to know if you can open a file is to open it. If that fails, you have to do something else. If you have some process that needs to open MANY files [e.g. a multithreaded search/compare on a machine with 256 cores and 8 threads per core and each thread uses three files (file "A", "B" and "diff") ], then you may need to ensure that your FOPEN_MAX allows for 3 * 8 * 256 files being opened before you start creating threads, as a thread that fails to open its files will be meaningless. But for most ordinary applications, just try to open the file, if it fails, tell the user (log, or something), and/or try again...
I suggest to use the magic of grep to find this constant on /usr/include:
grep -rn --col OPEN_MAX /usr/include
...
...
/usr/include/stdio.h:159: FOPEN_MAX Minimum number of files that can be open at once.
...
...
Hope it helps you

Resources