2015年10月12日 星期一

How to taint a hibernation snapshot image in a qemu swap disk file

For testing hibernation signature verification, I need try to taint the hibernation snapshot image in swap partition. Using qemu to test to taint snapshot image is more convenient than the real swap partition.

First, I created a qemu raw disk file to be the /dev/sdb swap partition to guest OS:

  qemu-img create ./swap.image 1G

Please be sure the format of file is raw but not qcow2, otherwise the swap header will not in the first page of swap file. I didn't investigate the detail of qcow2 format, but looks the magic string, SWAPSPACE2, is in the position after 5M offset but not the first page:

00050ff0  53 50 41 43 45 32 53 57  41 50 53 50 41 43 45 32  |SPACE2SWAPSPACE2|

The position of magic string in raw format file is in the first page:

00000fe0  01 00 00 00 00 00 00 00  03 00 00 00 53 57 41 50  |............SWAP|
00000ff0  53 50 41 43 45 32 53 57  41 50 53 50 41 43 45 32  |SPACE2SWAPSPACE2|

My whole investigation is base on the raw format disk file.

After create a disk file, then add it to guest OS to be the swap partition. My guest OS is openSUSE:

a. Add the new disk file to be the hdb of guest OS in qemu command:
  -hdb /home/joeyli/qemu-vm/swap.image

b. Launch guest OS, format the sdb disk to be swap:
  mkswap /dev/sdb

c. Add to /etc/fstab
  /dev/sdb swap swap defaults 0 0

d. Add kernel parameter to indicate sdb to be the resume partition:
  resume=/dev/sdb

e. Add the following kernel parameter to grub2 conf for testing hibernation:
earlyprintk=ttyS0,115200 console=tty0 console=ttyS0,115200 debug no_console_suspend=1 loglevel=9 nomodeset earlyprintk=efi hibernate=nocompress

Using hibernate=nocompress to avoid crc32 check, anyway, it's just for testing hibernation verification mechanism. We will taint a snapshot image in swap, then CRC checking maybe failed before hibernation verification.

After /dev/sdb show in guest OS, then trying hibernation. Before hibernation, you should find the magic string of swap parition:

00000fe0  01 00 00 00 00 00 00 00  03 00 00 00 53 57 41 50  |............SWAP|
00000ff0  53 50 41 43 45 32 53 57  41 50 53 50 41 43 45 32  |SPACE2SWAPSPACE2|

The declaration of swap header in kernel source is the swap_header union in swap.h header:

include/linux/swap.h
/*
 * Magic header for a swap area. The first part of the union is
 * what the swap magic looks like for the old (limited to 128MB)
 * swap area format, the second part of the union adds - in the
 * old reserved area - some extra information. Note that the first
 * kilobyte is reserved for boot loader or disk label stuff...
 *
 * Having the magic at the end of the PAGE_SIZE makes detecting swap
 * areas somewhat tricky on machines that support multiple page sizes.
 * For 2.5 we'll probably want to move the magic to just beyond the
 * bootbits...
 */
union swap_header {
        struct {
                char reserved[PAGE_SIZE - 10];
                char magic[10];                 /* SWAP-SPACE or SWAPSPACE2 */
        } magic;
        struct {
                char            bootbits[1024]; /* Space for disklabel etc. */
                __u32           version;
                __u32           last_page;
                __u32           nr_badpages;
                unsigned char   sws_uuid[16];
                unsigned char   sws_volume[16];
                __u32           padding[117];
                __u32           badpages[1];
        } info;
};

So, the magic string is in the end of the first page of partition. On the other hand, other meta-datas are written to the first page from top-down.

After launched hibernation, the magic string will be changed to S1SUSPEND:

00000fe0  01 00 00 00 00 00 00 00  05 00 00 00 53 57 41 50  |............SWAP|
00000ff0  53 50 41 43 45 32 53 31  53 55 53 50 45 4e 44 00  |SPACE2S1SUSPEND.|

After hibernation resuming, either success or fail, the magic string will be changed back to SWAPSPACE2.

The hibernation verification mechanism is calculating the signature of data pages in snapshot image. To test the mechanism is to taint the content in data pages:


Find out the position of data pages is the most important thing to taint data pages in snapshot image. The snapshot image header is swsusp_info, it's in the first page of snapshot. The hibernation mechanism uses the reserved space from bottom-up of the first page of swap partition:

kernel/power/swap.c
struct swsusp_header {      /* 1 page, 4096 bytes */
char reserved[PAGE_SIZE - 20 - sizeof(sector_t) - sizeof(int) -
sizeof(u32)]; /* 4096 - 20 - 8 - 4 - 4 = 4060 */
u32     crc32;             /* 4 bytes */
sector_t image;          /* sector_t of snapshot image, unsigned long 8 bytes */
unsigned int flags;      /* unsigned int, 4 bytes */
char    orig_sig[10];   /* 10 bytes */
char    sig[10];           /* 10 bytes *//* SWAPSPACE2 or S1SUSPEND */
} __attribute__((packed));

The swsusp_header actually is also mapping to the first page of swap, in the same space of swap_header:
The main field of swsusp_header to find the position snapshot image is "image", it's a number of sector_t, the size the same with page on swap. For example, if image = 1, then means the offset of snapshot image in swap is:
    offest = (swap header + image sector) * PAGE_SIZE = (1 + 1) * 4096

Then follow this offset, we can find out the snapshoti image header, swsusp_info:

kernel/power/power.h
struct swsusp_info {
        struct new_utsname      uts;     /* on x86, struct restore_data_record, 24 bytes */
                                                         /* 0x0123456789ABCDEFUL */
        u32                     version_code;
        unsigned long     num_physpages;
        int                       cpus;
        unsigned long      image_pages;    /* data pages number */
        unsigned long      pages;               /* total pages number that are in snapshot */
        unsigned long      size;
} __aligned(PAGE_SIZE);

I want to taint the content of data pages to emulate someone modified the image data. There have some important field in swsusp_info structure, pages and image_pages. So the offset of the beginning of data pages area is: 
    data pages offset = (swap header + image sector) * PAGE_SIZE + (pages - image_pages) * PAGE_SIZE

Then, using printf and dd command to modify the content of data pages. For example, this is the command to modify one byte in 5242848 offset:
    printf '\x32' | dd conv=notrunc of=./swap.image bs=1 seek=5242848

Here is a simple C program to check the swap header and swsusp header in qemu swap raw file, and taint 3 bytes in 3 different position for testing.

2015年5月25日 星期一

Attended GNOME.Asia 2015 in Indonesia

I am really happy have a chance to attend GNOME.Asia 2015 summit in Indonesia. This is my first time join to GNOME conference, it's also my first time visit to Indonesia. I really appreciate for GNOME Taiwan community and openSUSE Indonesia community friends' help in Depok. And I very think for GNOME.Asia and openSUSE's sponsor to my air ticket and hotel. It's a wonderful experience to me.

The location of GNOME.Asia 2015 venue is at University of Indonesia, Depok. It's a beautiful university:

The GNOME workship in day 0:

David King's session: "Writing your first GNOME application"

Speakers from more than 10 different countries:

Team discussion in workshop:


This special building is library in University of Indonesia:


There has a beautiful lake in university. GNOME.Asia venues are just around this lake:

The front door of Balairung, the main space of start/end and lighting talk:

Setting up the booth of of openSUSE ID. It's just simple in day 0. But it will have a big chance after openSUSE Indonesia community friends' help in day 1 and day2:

The openSUSE material and posters:


Banner, openSUSE is the silver sponsor of GNOME.Asia 2015:

The front door of venue:

There have 4 rooms for sessions:

My session is in latest day, about hibernate signature checking:

There have many banners on front door:

Show the different Linux distro:


openSUSE Indonesia friends setup computer, Raspberry pi to demo openSUSE. And also they provide interesting questionnaire for earning openSUSE T-shirt:

openSUSE Indonesia friends. Edwin, Yan, Adnan, Andi. Without them, it's impossible to setup wonderful booth to openSUSE. They also handle a amazing project to promote OSS in schools:

Many people visit to openSUSE booth:

The big hall for start/end and lighten talking:

Sesions start at the day 1 afternoon...
Join to the session "Open Source Software in Shoes Industry", Iwan S. Tahari. He is from shoes manufacture "Fans" to present their status of using OSS in the company. "Fans" is also the sponsor of GNOME.Aisa shoes:

"Fans" is using OSS on desktop and server for their designing and making shoes:


The second session that I joined is Chen Shing Yuan's presentation "Promote FOSS Education to Remote Areas in Taiwan and China":

The Aletheia University in Taiwan have a project to promoting OSS, English and Culture to the school in Xinjiang, China. It's far and less resource for the children in school:

The third session I joined is Anton Siswo Raharjo Ansori's "An Overview, Maximize The Ability of The GNU/Linux Operating System Using "In Memory Computation" for Academic, Business and Government":

The lighten talk of day one:

Talking with GNOME contributor:

The local GNOME user raised questions to experts:


I join to Edwin's session at afternoon on day 2:

The subject of Edwin's session is "Using Linux for Basic Education, Is it Feasible?":

Their project is promoting OSS to schools:


It's amazing for Edwin's project already promote and setup OSS to 500 schools. Cool!

It's really not easy to promoting OSS to teachers and students. openSUSE Indonesia community show us their tough working:

Then I join to Matthew Waters's session: "gtkgst: Video in your Widgets!"

Then Bin Li's interesting session "GNOME-Shell on Nexus 7". I think the only problem is need to find out the official kernel of Nexus 7 that's announced by Google:

Then, join to Franklin Weng & Eric Sun's "The evolution of ezgo development & Why Do We Insist Promoting FOSS in Taiwan's Campus?":

The ezgo is also a excellent project in Taiwan launched for education:

Sorry for I didn't take the picture for my own presentation, but my slides is here:

The lightening talk at the afternoon in day 2:

Ending of conference:

GNOME.Asia people done a great job to host GNOME.Asia 2015 (Max, Haris...):

openSUSE sponsor to GNOME.Asia 2015. And also thanks for GNOME.Asia sponsor to openSUSE.Asia at last year:

We all got the GNOME.Asia shoes from "Fans":

Thanks for very body's join, it's a wonderful conference:

The final picture is a note for anyone want to trip to Indonesia. The type of power socket the same with Europe, just feel free to take Europe type power adapter to Indonesia:

I am really happy to join GNOME.Asia 2015 summit. Not just to meet GNOME community friends from many different counties, but also I meet openSUSE community friends in Indonesia. I hope there have chance openSUSE.Asia can go to Indonesia, then I can trip to this good country again.

More pictures are here: https://www.flickr.com/photos/104068895@N07/sets/72157653462172002