Creating a vDSO: the Colonel's Other Chicken
Compiling, Linking and Running
Wait, is that all there is to adding a vDSO? Um, yes. Of course, if the function was something supported by the C library (glibc, in our case), you can hack that to do the detection of vDSO and then the actual call. However, I mentioned we wouldn't be hacking glibc. And, you don't need to anyway, because getting the code to work is pretty simple. With the chunks described above all in place, it's time to start building. Just configure and compile your kernel as you typically would:
make menuconfig
make bzImage
make modules
make modules_install
Now, install and boot your new modified vDSO kernel. Once that is up and running, it's time to test a few things, mainly the vDSO stuff you just added. Let's compile a test case to exercise the vDSO call:
/* notb.c */
#include <stdio.h>
int main(void)
{
int notb = number_of_the_beast();
printf("His number is %d\n", notb);
return 0;
}
Then, compile the code above as:
gcc notb.c -o notb vdso.so
The file you link against is vdso.so, which provides the symbol resolution needed
to make the kernel call. The kernel version of
number_of_the_beast() is
called, even if the code for that function is completely different in vdso.so.
Where is vdso.so located? It's located in the kernel build directory
after building the kernel: linux-2.6.37/arch/x86/vdso/vdso.so.
At runtime, when a program executes
number_of_the_beast, the kernel code is
called and not the version of number_of_the_beast() in the vdso.so file.
If you modify the kernel and, say, have
number_of_the_beast() return
42,
then unless you load that kernel, you still will get
666. Even if you
compile the test example above with the newer modified-to-42 vdso.so.
Another way of getting the vdso.so file is by writing a program that extracts
the vDSO memory from a running executable. Numerous sources on-line
explain
how to do this, but I briefly describe it here.
The vDSO page, which is mapped
into the memory of every running process, can be in a non-deterministic memory
range of your executing process, thanks to Linux's address space layout
randomization (ASLR). To get this address, a running program can find its
memory information from the file /proc/self/maps. In there, a line with the
text [vdso] exists. That line contains the address range in the executing
process of the vDSO page. For example, you could run cat
/proc/self/maps.
Note that running this command multiple times produces different address
ranges for [vdso] thanks to (if your kernel supports
it) address space layout
randomization.
The output should look something similar to:
...
7fff40d71000-7fff40d72000 r-xp 00000000 00:00 0 [vdso]
...
The above range is showing for the cat process you just executed that the
address range for the vDSO page is located starting at
7fff40d71000 and ending
at 7fff40d7200. Subtracting the start and end
range, you get 0x1000 or 4096
bytes. 4096 is the page size often used in the kernel. Listing 1 shows
code for extracting the vDSO from a running kernel, and it is based on code
from the "Examining the Linux VDSO" article listed in
Resources.
A simple dumping of the dynamic object symbols can be conducted via:
objdump -T vdso.so
Because a shared library is also an elf, the readelf
tool also can be used on
vdso.so.
Listing 1. Extracting the vDSO from a Running Kernel
/* extract_vdso.c */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(int argc, char **argv)
{
char buf[256], *mem;
const char *range_name;
FILE *rd, *wr;
long long start_addr, end_addr;
/* Open file for writing the vdso data to */
if (argc != 3)
{
fprintf(stderr,
"Usage: %s <file> <string>\n"
"\t<file>: File to write the vdso data to.\n"
"\t<string>: Name of the mapped in region, e.g. vdso\n",
argv[0]);
abort();
}
range_name = argv[2];
if (!(wr = fopen(argv[1], "w")))
{
perror("Error: fopen() - output file");
abort();
}
/* Get this process' memory layout */
if (!(rd = fopen("/proc/self/maps", "r")))
{
perror("Error: fopen() - /proc/self/maps");
abort();
}
/* Find the line in /proc/self/maps that contains
the substring [vdso] * */
while (fgets(buf, sizeof(buf), rd))
{
if (strstr(buf, range_name))
break;
}
fclose(rd);
/* Locate the end memory range for [vdso] */
end_addr = strtoll((strchr(buf, '-') + 1), NULL, 16);
/* Terminate the string so we can get the start
address really easily * */
*(strchr(buf, '-')) = '\0';
start_addr = strtoll(buf, NULL, 16);
/* Open up the memory page and extract the vdso */
if (!(rd = fopen("/proc/self/mem", "r")))
{
perror("Error: fopen() - /proc/self/mem");
abort();
}
/* Hop to the vdso portion */
fseek(rd, start_addr, SEEK_SET);
/* Copy the memory locally and then move it to the file */
mem = malloc(end_addr - start_addr);
if (!fread(mem, 1, end_addr - start_addr, rd))
{
perror("Error: read() - /proc/self/mem");
abort();
}
/* Write the data to the specified output file */
if (!fwrite(mem, 1, end_addr - start_addr, wr))
{
perror("Error: fwrite() - output file");
abort();
}
free(mem);
fclose(rd);
fclose(wr);
printf("Start: %p\nEnd: %p\nBytes: %d\n",
(void *)start_addr, (void *)end_addr, (int)(end_addr -
↪start_addr));
return 0;
}
Security Implication
Anytime you dabble with the kernel, you should consider the security implications. If you think you can "own" someone by creating your own vDSO calls, you might want to think again. Because adding a vDSO requires users to bake their own kernels, the only people they could be compromising is their system and the users on their system. Of course, any dabbling with kernel resources should be done with much consideration. Remember, playing with vDSO goodies occurs in userland; however, your vDSOs can access kernel data. And, your kernel can read vDSO data. That can be a concern, but I'll leave that up to you as an exercise for finding anything exploitable.
Finally, this article is just a little one-two on how to cook up your own vDSO. Now go make yourself a smoking kernel.
Resources
GNU/Linux Kernel. 2.6.37: http://www.kernel.org
"6.30 Declaring Attributes of Functions" (GCC Manual): http://gcc.gnu.org/onlinedocs/gcc/Function-Attributes.html
"Weak Symbol" (Wikipedia): http://en.wikipedia.org/wiki/Weak_symbol
"Examining the Linux VDSO" (Truth, Computing and Fail): http://anomit.com/2010/04/18/examining-the-linux-vdso
Johan Peterson's "What is linux-gate.so.1?": http://www.trilithium.com/johan/2005/08/linux-gate
Matt Davis' "Linux syscall, vsyscall, and vDSO...Oh My!": http://davisdoesdownunder.blogspot.com/2011/02/linux-syscall-vsyscall-and-vdso-oh-my.html
- « first
- ‹ previous
- 1
- 2
- 3
Matt Davis is a software engineer on leave from his job in the US to pursue a PhD from the Computer Science Department at the University of Melbourne, where he is focusing his hackery toward the compiler field.
Realizing the promise of Apache® Hadoop® requires the effective deployment of compute, memory, storage and networking to achieve optimal results. With its flexibility and multitude of options, it is easy to over or under provision the server infrastructure, resulting in poor performance and high TCO. Join us for an in depth, technical discussion with industry experts from leading Hadoop and server companies who will provide insights into the key considerations for designing and deploying an optimal Hadoop cluster.
Sponsored by AMD
Built-in forensics, incident response, and security with Red Hat Enterprise Linux 6
Every security policy provides guidance and requirements for ensuring adequate protection of information and data, as well as high-level technical and administrative security requirements for a system in a given environment. Traditionally, providing security for a system focuses on the confidentiality of the information on it. However, protecting the data integrity and system and data availability is just as important. For example, when processing United States intelligence information, there are three attributes that require protection: confidentiality, integrity, and availability.
Learn more about catching the bad guy in this free white paper.
Sponsored by DLT Solutions
| Designing Electronics with Linux | May 22, 2013 |
| Dynamic DNS—an Object Lesson in Problem Solving | May 21, 2013 |
| Using Salt Stack and Vagrant for Drupal Development | May 20, 2013 |
| Making Linux and Android Get Along (It's Not as Hard as It Sounds) | May 16, 2013 |
| Drupal Is a Framework: Why Everyone Needs to Understand This | May 15, 2013 |
| Home, My Backup Data Center | May 13, 2013 |
- RSS Feeds
- Dynamic DNS—an Object Lesson in Problem Solving
- Making Linux and Android Get Along (It's Not as Hard as It Sounds)
- Designing Electronics with Linux
- Using Salt Stack and Vagrant for Drupal Development
- New Products
- A Topic for Discussion - Open Source Feature-Richness?
- Drupal Is a Framework: Why Everyone Needs to Understand This
- Validate an E-Mail Address with PHP, the Right Way
- What's the tweeting protocol?
- Kernel Problem
9 hours 58 min ago - BASH script to log IPs on public web server
14 hours 25 min ago - DynDNS
18 hours 1 min ago - Reply to comment | Linux Journal
18 hours 33 min ago - All the articles you talked
20 hours 57 min ago - All the articles you talked
21 hours 37 sec ago - All the articles you talked
21 hours 1 min ago - myip
1 day 1 hour ago - Keeping track of IP address
1 day 3 hours ago - Roll your own dynamic dns
1 day 8 hours ago
Enter to Win an Adafruit Pi Cobbler Breakout Kit for Raspberry Pi

It's Raspberry Pi month at Linux Journal. Each week in May, Adafruit will be giving away a Pi-related prize to a lucky, randomly drawn LJ reader. Winners will be announced weekly.
Fill out the fields below to enter to win this week's prize-- a Pi Cobbler Breakout Kit for Raspberry Pi.
Congratulations to our winners so far:
- 5-8-13, Pi Starter Pack: Jack Davis
- 5-15-13, Pi Model B 512MB RAM: Patrick Dunn
- 5-21-13, Prototyping Pi Plate Kit: Philip Kirby
- Next winner announced on 5-27-13!
Free Webinar: Hadoop
How to Build an Optimal Hadoop Cluster to Store and Maintain Unlimited Amounts of Data Using Microservers
Realizing the promise of Apache® Hadoop® requires the effective deployment of compute, memory, storage and networking to achieve optimal results. With its flexibility and multitude of options, it is easy to over or under provision the server infrastructure, resulting in poor performance and high TCO. Join us for an in depth, technical discussion with industry experts from leading Hadoop and server companies who will provide insights into the key considerations for designing and deploying an optimal Hadoop cluster.
Some of key questions to be discussed are:
- What is the “typical” Hadoop cluster and what should be installed on the different machine types?
- Why should you consider the typical workload patterns when making your hardware decisions?
- Are all microservers created equal for Hadoop deployments?
- How do I plan for expansion if I require more compute, memory, storage or networking?



Comments
----- http://ai.vc/zd
----- http://ai.vc/zd -----
Hi,Dear Ladies and Gentlemen,
1. sport shoes : Jordan ,Nike, adidas, Puma, Gucci, LV, UGG , etc. including women shoes and kids shoes.
2. T-Shirts : BBC T-Shirts, Bape T-Shirts, Armani T-Shirts, Polo T-Shirts,etc.
3. Hoodies : Bape hoody, hoody, AFF hoody, GGG hoody, ED hoody ,etc.
4. Jeans : Levis jeans , Gucci jeans, jeans, Bape jeans , DG jeans ,etc.
----- http://ai.vc/zd -----
----- http://ai.vc/zd -----
Service is our Lift.
enjoy yourself.
thank you!!
::∴★∵**☆.∴★∵**☆.∴★∵**☆.
█████.::∴★∵**☆.∴★∵**☆.
█田█田█::∴★∵**☆.∴★∵**☆.
█田█田█.∴★∵**☆.∴★∵**☆.
█田█田█∴★∵**☆.∴★∵**☆.
█田█田█.★∵**☆.∴★∵**☆.
█████.*******************
◢██□██◣.~~~~~*^_^*
Good content, I trust this is
Good content, I trust this is a good weblog about Wish to see refreshing content material next time. Thanks for sharing this publish with us. Keep it up.
hebergement audiotel voyance
Re : Creating a vDSO: the Colonel's Other Chicken
script code is my weakness and it is difficult for me to learn
but in this tutorial I will try hard to understand
thank you
why x86(32bit) does not have gettimeofday vdso
Very nice article. Thanks for explaining vdso concept.
Why x86(32bit) does not have gettimeofday vdso?
Only 64bit x86 has this call implemented. Why?
Does x86 32bit have limitations?