Tuesday, August 13, 2013

How to extract a single function from a ELF file

Simple bash script to disassemble a single function from a ELF file:
#!/bin/bash

SECTION=$1
IN=$2

i=`nm -S --size-sort $IN | grep "\<$SECTION\>" | \
        awk '{print toupper($1),toupper($2)}'`
echo "$i" | while read line; do
        start=${line%% *}
        size=${line##* }
        end=`echo "obase=16; ibase=16; $start + $size" | bc -l`
        objdump -d --section=.text \
                   --start-address="0x$start" \
                   --stop-address="0x$end" $IN
done
We may also want to generate a "binary" dump of the function (i.e., to do a binary copy of the function to a separate file); in this case the script becomes the following:
#!/bin/bash

SECTION=$1
IN=$2

i=`nm -S --size-sort $IN | grep "\<$SECTION\>" |
        awk '{print toupper($1),toupper($2)}'`
echo "$i" | while read line; do
        start=${line%% *}
        size=${line##* }
        end=`echo "obase=16; ibase=16; $start + $size" | bc -l`
        objdump -d --section=.text \
                   --start-address="0x$start" \
                   --stop-address="0x$end" $IN | \
                grep '[0-9a-f]:' | \
                cut -f2 -d: | \
                cut -f1-7 -d' ' | \
                tr -s ' ' | \
                tr '\t' ' ' | \
                sed 's/ $//g' | \
                sed 's/ /\\x/g' | \
                paste -d '' -s | \
                sed 's/^/"/' | \
                sed 's/$/"/g' | \
                sed 's:.*:echo -ne &:' | /bin/bash
done
Enjoy!

Wednesday, May 15, 2013

Linux PERF_EVENTS root exploit - CVE-2013-2094 (quick way to fix it)

Recently a quite critical flaw has been found in the PERF_EVENT code in Linux.

The problem is a failure at checking a 64-bits variable (cast to a 32-bits int) passed by user space, resulting to out-of-bounds access of an array in kernel space.

Here is the exploit: http://packetstormsecurity.com/files/121616/semtex.c

The bug has been already fixed mainstream: http://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/commit/?id=8176cced706b5e5d15887584150764894e94e02f

But lots of distro kernels are affected by this bug, so they're vulnerable to the root exploit (like all the RH / CentOS 2.6.32-based kernels).

A temporary solution, waiting for a new kernel to come out, can be to create a kernel module to "inject" the fix into the kernel at runtime, using the kprobe framework.

Here is the source code of the module:
https://www.develer.com/~arighi/linux/fix/CVE-2013-2094/perf-bug-fix.tar.gz

This module injects the fix by wrapping the buggy function perf_swevent_init() using the kprobe framework.

This would allow to provide a fix really soon, and it works with any kernel affected by this bug.

To compile it (on CentOS - instructions are almost identical in other distro):

  $ sudo yum install kernel-devel
  $ tar xvzf perf-bug-fix.tar.gz
  $ cd perf-bug-fix
  $ make

How to load the module and apply the fix:

 $ sudo insmod wrapper.ko

That's it. Now let's test the exploit.

Without wrapper.ko loaded:

cpuser1@testdomain1.com [/dev/shm]# id -u
521
cpuser1@testdomain1.com [/dev/shm]# ./a.out
...
 -sh-4.1# id -u
0

With wrapper.ko:

cpuser1@testdomain1.com [/dev/shm]# ./a.out
a.out: test.c:51: sheep: Assertion `!close(fd)' failed.
Aborted (core dumped)
cpuser1@testdomain1.com [/dev/shm]# id -u
521

Tuesday, August 30, 2011

install busybox from source on Samsung GT-I9100

If you want a complete set of unix tools in your phone, here are the steps to cross-compile and install busybox from source (there's no need to root the phone and/or install everything using the busybox installer from the market).

Download the latest ARM gnueabi toolchain from codesourcery.

Get the busybox source code from the git repository:
  $ git clone git://busybox.net/busybox.git

Copy my busybox config file (or use your own config if you prefer, this can be just a starting point):

$ cd busybox
$ wget -O .config http://www.develer.com/~arighi/android/busybox/config

[optional] Change the busybox config if you want by running:
$ make menuconfig

Cross-compile busybox:
$ make oldconfig && make

At the end of the build the busybox binary should be available as a statically linked ELF for ARM:
$ file busybox
busybox: ELF 32-bit LSB executable, ARM, version 1 (SYSV), statically linked, for GNU/Linux 2.6.16, stripped

Upload the busybox binary to the device (you don't need root access to your phone):
$ adb push busybox /data/local/tmp/

Now busybox it's ready to be used:
$ adb shell /data/local/tmp/busybox CMD

Example:
$ adb shell /data/local/tmp/busybox lsusb
Bus 001 Device 001: ID 1d6b:0002
Bus 001 Device 002: ID 1519:0020

=== NOTE: all the following steps are optional ===

If you have enabled the adb root shell access to your phone (i.e., by rooting the phone or by installing my custom kernel), you can also install busybox in the /system partition and have all the commands available in the $PATH.

Remount the /system partition in read-write mode on your phone:
$ adb shell "mount -oremount,rw /dev/block/mmcblk0p9 /system

Upload the busybox binary to the /system partition:
$ adb push busybox /system/xbin/busybox

Install busybox by using busybox itself:
$ adb shell "chmod 755 /system/xbin/busybox"
$ adb shell "/system/xbin/busybox --install -s /system/xbin"

Remount /system in read-only:
$ adb shell "mount -oremount,ro /dev/block/mmcblk0p9 /system"

Now all the busybox applets are in your $PATH:

$ adb shell lsusb
Bus 001 Device 001: ID 1d6b:0002
Bus 001 Device 002: ID 1519:0020

HOWTO: custom kernel on Samsung Galaxy S II I9100

Recently I've replaced my Bravo HTC Desire with a new Android phone: a Samsung Galaxy S II I-9100. I couldn't resist too much with the stock kernel, so finally I've found some spare time to cook a custom kernel starting from the original Samsung kernel source code GT-I9100_OpenSource_Update2.

In this post I report (for me to remember later and for those who are interested) all the steps that I did to setup the build environment, cross compile the custom kernel and flash it into the phone.

DISCLAIMER: I take no responsibility for anything that may go wrong by you following these instructions. Proceed at your own risk!

=== Requirements ===

- A Samsung Galaxy S II (not necessarily rooted! you'll get a root shell when you'll flash the new kernel)
- The latest android SDK
- The arm-none-eabi cross-compile toolchain (you can get it from the CodeSourcery website)

=== HOWTO ===

Download and install the arm toolchain from the CodeSourcery website: be sure that arm-none-eabi-gcc is in your $PATH.

Get the autobuild script:
 $ git clone git://github.com/arighi/gt-i9100.git

Run the script:
 $ ./build-kernel.sh

The script downloads the "-arighi" kernel source code, a initramfs template and builds a new kernel ready to be flashed into the device.

At the end of the autobuild process the file kernel-gt-i9100-arighi.tar can be used to flash the new kernel to the phone using Odin (search on the web or in the xda-developers forum, there are tons of howtos/tutorials for this).

=== Results ===

The score with Quadrant benchmark is not bad at all, I got always > 4000, but remember that we're cheating during the IO test, due to the fsync-disable patch.

Anyway overall result looks good enough.


== Additional notes ===

- All the custom *.ko files are included into the initramfs to avoid potential errors/problems with the original kernel modules (so it is always possible to flash back the original kernel later, all the old kernel modules are still there, untouched).

- After you've flashed the -arighi kernel the first time you will also have root access to your device. The initramfs template enables adb root shell (ro.secure == 0), so an adb shell will immediately drop you to a root shell. This means you can also re-flash your device from Linux directly using the flash-kernel.sh script.

- For the complete list of all the patches applied to this kernel have a look at the git log here.

- IMPORTANT: the fsync-disable patch (enabled in the kernel by default) can increase performance and battery life, but it is dangerous, because it might eat your data!! It makes the software no longer crash safe, so if you start to randomly kill your apps you may lose some data


[UPDATE: the fsync-disable patch is no more enabled by default in the kernel, to enable it just set CONFIG_FILE_SYNC_DISABLE=y in the kernel .config)]

Thursday, January 20, 2011

Android: automated per-uid task group

Android is a privilege-separated operating system, in which each application runs with a distinct system identity: the Linux user ID (uid).

With this patch (sched-automated-per-uid-task-groups.patch) the kernel automatically creates a distinct task group for each uid (when a process calls set_user()) and places all the tasks that belong to a single uid into the same task group. In this way each application can get a fair amount of the CPU bandwidth (guaranteed by the CFS scheduler), independently by the number of task/threads spawned.

The patch is against the CyanogenMod's 6.1.1 kernel (2.6.35.10) and I tested it successfully on my HTC Desire (Bravo).

I've used the following testcase:
  - run 4 cpu hogs in background as user app_35 (com.android.email in my case):

 # su - app_35
 $ for i in `seq 4`; do yes >/dev/null & done

  - run the Quadrant benchmark in parallel and measure the result with and without the patch applied

Without the patch (output of top):
  PID  PPID USER     STAT   VSZ %MEM CPU %CPU COMMAND
 6533   123 10070    R     202m 48.6   0 20.0 com.aurorasoftworks.quadrant.ui.st
 6506     1 10035    R     1128  0.2   0 20.0 yes
 6507     1 10035    R     1128  0.2   0 20.0 yes
 6508     1 10035    R     1128  0.2   0 20.0 yes
 6509     1 10035    R     1128  0.2   0 20.0 yes

Benchmark result: 676

  uid 10035 (cpu hog)  : 60.0 % cpu quota
 uid 10070 (benchmark): 20.0 % cpu quota

With automated per-uid task group (output of top):
  PID  PPID USER     STAT   VSZ %MEM CPU %CPU COMMAND
 6784   123 10070    S     209m 51.4   0 50.0 com.aurorasoftworks.quadrant.ui.st
 6852     1 10035    R     1128  0.2   0 12.5 yes
 6853     1 10035    R     1128  0.2   0 12.5 yes
 6854     1 10035    R     1128  0.2   0 12.5 yes
 6855     1 10035    R     1128  0.2   0 12.5 yes

Benchmark result: 816

 uid 10035 (cpu hog)  : 50.0 % cpu quota
 uid 10070 (benchmark): 50.0 % cpu quota

Total speedup: ~1.2 (the benchmark is about 20% faster in this case), because in the last case the benchmark gets ~50% of the CPU time and in the other case it gets only ~20%, despite the fact that there are 2 "pair" applications that should be correctly considered as equal from the user's perspective.

This patch is based on the patch "sched: automated per tty task groups" by Mike Galbraith.

Monday, January 10, 2011

HOWTO: install a custom kernel on HTC Desire

=== Disclaimer ===

I take no responsibility for anything that may go wrong by you following these instructions. Proceed at your own risk!

I tested this howto with a Bravo HTC Desire, rooted with Unrevoked 3.22.

=== Requirements ===

- A rooted HTC Desire (Bravo)

- The android SDK + NDK (to get the cross-compile toolchain):

- The latest HTC Desire kernel (choose "HTC Desire - Froyo MR - 2.6.32 kernel source code")

- The koush's AnyKernel template (to generate the update.zip at the end of the build process)

=== HOWTO ===

- Prepare the cross-compiler environment (replace /opt/android with the path where you have installed the Andorid NDK):

$ export PATH=/opt/android/android-ndk-r5/toolchains/arm-eabi-4.4.0/prebuilt/linux-x86/bin:$PATH

At this point arm-eabi-gcc, as well as other binutils and compiler binaries, should be in your $PATH.

- Untar the kernel

- save the kernel config (if you want to restore the original kernel config):
$ adb pull /proc/config.gz

- [optional] Apply the following patches to the kernel:
   - 0001-sync-disable-fsync-fdatasync-sync_file_range-syscall
   - 0002-writeback-change-default-dirty-memory-settings
   - 0003-sched-replace-CFS-with-the-BFS-scheduler

- [optional] Take my kernel configuration:
$ wget -O bravo-2.6.32-gd96f2c0/.config http://www.develer.com/~arighi/android/linux/config

Or use the previously saved config.gz either.

- Build the kernel:
$ cd bravo-2.6.32-gd96f2c0/
$ make ARCH=arm CROSS_COMPILE=arm-eabi- oldconfig
$ make ARCH=arm CROSS_COMPILE=arm-eabi-

Now you should find the fresh new kernel, ready to be flashed on your HTC Desire, in arch/arm/boot/zImage.

- Apply the following patch to the koush's AnyKernel source (to fix a syntax error when trying to flash update.zip from ClockworkMod):
   - 0001-updater-script-specify-the-mount-options-for-the-sys

- Replace the zImage in the AnyKernel template with your zImage:
$ cp bravo-2.6.32-gd96f2c0/arch/arm/boot/zImage AnyKernel/kernel/zImage

- Go back to the template directory (you will see three subdirectories: META-INF, kernel & system) and generate the update.zip:
$ zip -r ../update.zip *

- Connect your phone via a USB cable (be sure to turn on USB debugging on your phone: Settings -> Applications -> Development -> USB debugging)

- Push update.zip and the wireless module to the SD card of your phone:
$ adb push update.zip /sdcard/update.zip
$ adb push bravo-2.6.32-gd96f2c0/drivers/net/wireless/bcm4329_204/bcm4329.ko /sdcard/bcm4329.ko

- Reboot your phone in ClockworkMod recovery (power-on while holding Volume down key and select RECOVERY)

- In ClockworkMod select "apply sdcard:update.zip" (confirm: choose Yes)

- Reboot your phone via "reboot system now"

At this point your custom new kernel should boot.

=== Fix the bcm4329 wireless module loading without S-OFF ===

The bcm4329.ko module can't be properly overwritten in the /system partition without S-OFF the device and so give access in read-write to the /system partition. However, we can enforce the usage of our new module binding any other writable directory to /system/lib/modules (i.e., /data/local).

Prerequisites:
- the latest ARM toolchain downloadable from the CodeSourcery site

Download and install the ARM toolchain and be sure that arm-none-linux-gnueabi-gcc is in your $PATH.

- get the latest version of busybox from git (or download a recent stable version if you prefer):
$ git clone git://busybox.net/busybox.git

Howto:
- use my busybox config file:
$ cd busybox
$ wget -O .config http://www.develer.com/~arighi/android/busybox/config

- cross-compile busybox:
$ make ARCH=arm CROSS_COMPILE=arm-none-linux-gnueabi- oldconfig
$ make ARCH=arm CROSS_COMPILE=arm-none-linux-gnueabi-

- copy the busybox binary into the /data/local directory on your phone:
$ adb push busybox /data/local/busybox

- bind the directory /system/lib/modules with /data/local:
$ adb shell
$ su
# cat /sdcard/bcm4329.ko > /data/local/bcm4329.ko
# /data/local/busybox mount --bind /data/local /system/lib/modules

After this trick go on your phone check Settings -> Wireless & networks -> Wi-Fi. The wireless connection should start normally.

=== Results ===

Here is my score with this kernel using the Quadrant benchmark: 1370!

Friday, September 11, 2009

Linux kernel hacking: file notification system with kernel tracepoints

An example of how to use kernel tracepoints to create a simple real-time backup / file change notification system. The article (only in italian, sorry) is available at stacktrace.it.

Friday, June 26, 2009

mutt + gmail notifier

I really enjoy the power of mutt, and I've to say that I've not too far from reaching the email Nirvana with it :). OK, it's not the email client for everybody, it's just for the people that prefer the keyboard to the mouse and love the command line interfaces.

There's only one missing feature in mutt: a nice way to notifiy new emails. The problem with mutt is that I need to periodically switch to the mutt shell to check for new emails. And I don't even like the crappy notification balloons that cover the useful part of the desktop (e.g., thunderbird). A small tray icon could be a solution (and I did it this way for a while, patching mutt), but with the icon I don't see immediately the message that I receive.

This led me to notice a large unused area in the gnome panel at the top (recently I moved from Fluxbox to Gnome, yeah! :) now I've a ultra-very-fast SSD I can also use a fancy desktop environment). So, why not to use the top panel to notify the subject of the last email I received in my mailbox? ta-da! the solution: a small python gnome applet that periodically fetches the last unread email from a generic IMAPS folder in gmail and prints the subject to the panel.

Here's the code: gmail-check, very minimalist and designed just for my particular desktop environment, so it may not work in some cases...

Monday, June 8, 2009

New SSD disk

I just got one new SSD disk MTRON MOBI 3000 for my Dell Latitude D430 notebook. It's very small, only 32GB, but it definitely ROCKS!!! I can boot in about 12 seconds, without any deep tuning of the kernel and boot services, but the _responsiveness_ is the most relevant thing, apart the read/write 100MB/s throughput (that is not so important for a desktop system). The impressive part is the ~5500 iops (IO operations per second) obtained using a workload of 4KB random reads/writes!

Thursday, May 14, 2009