Tuesday, January 25, 2011

Access any memory by using kernel module

If you write a user program, it cannot read all the memory.

userprogram:
    virtualAddr = 0xc0010203 // randomly define virtual address
    for(i = 0; i< SIZE; i++)
    printf("%x", *(char*)(virtualAddr+i));

This program will give your segmentation fault when you run it.
Remember, CPU only understand virtual address.

Solution, write a kernel module to access any memory

#include <linux/module.h>
#include <linux/init.h>
#include <asm/io.h>

// 1G = 0x40000000
// trusted OS kernel code physical address is (0x400000, 0x620de5)
// add 1G, then test if it could access from this untrusted OS
#define PHYSTARTADDR 0x40400000
#define PHYENDADDR 0x40620de5
// this is the virtual address of kernel code
#define VIRSTARTADDR 0xc0400000
#define VIRENDADDR 0xc0620de5
#define SIZE 100

MODULE_LICENSE("Dual BSD/GPL");

static int hello_init(void)
{
    char mem[SIZE];
    int i;
    void *virtualAddr ;
//  if we want to access the memory range beyond current DIMM
//  we could use ioremap to create the pagetables, so cpu will understand
//  this virtual address.
//  virtualAddr = ioremap(PHYSTARTADDR, SIZE);
//  this case, we just want to read all the current memory range, 
//  which is DIMM has been initialized.
    virtualAddr = VIRSTARTADDR;

    for(i = 0; i< SIZE; i++)
    printk("%x", *(char*)(virtualAddr+i));
 
    printk("\nhello, world\n");
    return 0;
}
static void hello_exit(void)
{
    printk("Goodbye, crule world\n");
}
module_init(hello_init);
module_exit(hello_exit);

Monday, January 24, 2011

TIme of encryption and decryption of 500MB ramdisk using 256-bit AES in CBC mode

Benchmark
$openssl speed

Here is the script to calculate how long the encryption and decryption will take:
#!/bin/bash
ENCSTART=$(date +%s:%N)
echo "start = $ENCSTART"
openssl enc -aes-256-cbc -salt -in /dev/ram0 -out ramdisk.enc -pass pass:password
ENCEND=$(date +%s:%N)
echo "end = $ENCEND"
DECSTART=$(date +%s:%N)
echo "start = $DECSTART"
openssl enc -d -aes-256-cbc -in ramdisk.enc -out ramdisk -pass pass:password
DECEND=$(date +%s:%N)
echo "end = $DECEND"


More info, please see:
http://www.madboa.com/geek/openssl/

Sunday, January 23, 2011

AUFS HOWTO

Also see aufs+ramdisk setup at: another article

For AUFS2: 
http://aufs.sourceforge.net/

For AUFS1:
http://aufs.sourceforge.net/README.aufs1

Download aufs, configure and compile it. Then install the module.

Usage example:
$ mkdir /tmp/rw /tmp/aufs
$ mount -t aufs -o dirs=/tmp/rw:${HOME}=ro none /tmp/aufs
Or 
$ mount -t aufs -o br:/tmp/rw:${HOME}=ro none /tmp/aufs
/tmp/aufs = $HOME + /tmp/rw
if you touch a file in /tmp/aufs, this file will be show up in /tmp/rw, not in $HOME, because $HOME is read only

AUFS1 + ramdisk setup

OS environment: Cent OS 5.5

1. compile and install linux kernel 2.6.18
$ wget http://www.kernel.org/pub/linux/kernel/v2.6/linux-2.6.18.tar.bz2
$ make menuconfig /*remember to install ncurses-devel*/
$ make -j4
$ make modules_install
$ make install
Add new kernel to menulist and reboot

2. set the menu.list to initialize about 500MB ramdisk ( add ramdisk_size=500000 )
kernel /vmlinuz-2.6.18 ro root=LABEL=/ hdc=ide-scsi ramdisk_size=500000


3. format this ramdisk and mount ramdisk to mountpoint /ramdisk
$ mke2fs -m 0 /dev/ram0   
$ mkdir /ramdisk
$ mount /dev/ram0 /ramdisk


4. compile and install aufs1 module. more info: http://aufs.sourceforge.net/README.aufs1
$ cd /your/linux/kernel/source (/lib/module/2.6.18/source/)
$ make menuconfig
$ make include/linux/version.h include/linux/utsrelease.h

$ cd aufs.wcvs/aufs
$ rm fs/aufs/Kconfig
$ make -f local.mk kconfig

$ make -f local.mk /* compile aufs module */

$ install -m 500 -p mount.aufs umount.aufs auplink aulchown auchk /sbin (recommended)
$ install -m 644 -p etc_default_aufs /etc/default/aufs (recommended)
$ echo FLUSH=ALL > /etc/default/auplink (recommended)
$ insmod ./aufs.ko /* install aufs module, you need to do this everytime after reboot */


5. mount /home /root /tmp ... directory to ramdisk
$ mkdir /ramdisk/home
$ mount -t aufs -o dirs=/ramdisk/home:/home=ro none /home /* home directory is read only, all the files written to home folder will be written into /ramdisk/home */

Get Linux kernel Souce Code

1. use wget (you could get any version you want):
$ wget http://www.kernel.org/pub/linux/kernel/v2.6/linux-2.6.18.3.tar.bz2
or
$ wget http://www.kernel.org/pub/linux/kernel/v2.6/linux-2.6.18.tar.gz

2. use git
$ git clone git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6.git
$ cd linux-2.6
$ git reset --hard v2.6.17 /* Change current branch to 2.6.17 */
more details: http://www.kernel.org/pub/software/scm/git/docs/user-manual.html

Saturday, January 22, 2011

idea

talked it with one of my friend.. exciting.... Go for it!!

An idea

Build a roommate money sharing website in China, it must be popular

Friday, January 21, 2011

How to use git

check out file:
git clone URL CurentFileName

more on: http://git-scm.com/

This is the tutorial of using git to check out linux kernel source:
http://www.kernel.org/pub/software/scm/git/docs/user-manual.html

install git on Cent OS 5.5

1. install webtatic: rpm -ivh http://repo.webtatic.com/yum/centos/5/`uname -i`/webtatic-release-5-0.noarch.rpm
2. continue with yum install: yum install --enablerepo=webtatic git-all
more detailed, please see following link: 
http://genomewiki.ucsc.edu/index.php/Installing_git

Thursday, January 20, 2011

create RAMDISK HOWTO

OS: Cent OS 5.5
1. set up the size you want to create
$vim /boot/grub/menu.lst
set the ramdisk size as 128 MB
Add ramdisk_size = 128000 to kernel line
kernel /vmlinuz-2.4.20-20.9 ro root=LABEL=/ hdc=ide-scsi ramdisk_size=128000
$reboot

2. Format the ramdisk
$ mke2fs -m 0 /dev/ram0

3. Create a mount point to mount the ramdisk
$ mkdir /mnt/ramdisk
$ mount /dev/ram0 mnt/ramdisk


More detailed: http://www.vanemery.com/Linux/Ramdisk/ramdisk.html

Monday, January 17, 2011

Movie: The Social Network

Do what you feel passion on;
It's OK to fail, you could fail thousands times as soon as you love you are doing;
If you want to gain something, you have to give up something first;
Be brave, follow your heart!

Sunday, January 16, 2011

Memory System Configuration

OS: Cent OS 5.5
Chipset: AMDK8

you could get memory system configuration from following file:
/sys/bus/pci/devices/0000\:00\:18.0/  /* this is bus 0, device 18, function 0 registers */

E.g.
/* This is use hexdump to see the memory configuration */ 
hexdump /sys/bus/pci/devices/0000\:00\:18.0/config -v > ~/f0_conf
hexdump /sys/bus/pci/devices/0000\:00\:18.1/config -v > ~/f1_conf
hexdump /sys/bus/pci/devices/0000\:00\:18.2/config -v > ~/f2_conf
hexdump /sys/bus/pci/devices/0000\:00\:18.3/config -v > ~/f3_conf

For the meaning of these 256 bytes, please read the BIOS Kernel Development Guide(BKDG). There is another article about this

PCI programming

use a example to explain PCI programming:
access the memory controller register in AMD K8 machine

1. read the BKDG (BIOS and Kernel Developer's Guide), then you know what PCI device you are going to access(bus, dev, fun). Each 32 bit is a register, the first 32 bit is: vendor ID and device ID. E.g. memory system configuration register(function 2) in AMDK8 BKDG is: 1102h 1022h. From the vendor ID, and the device ID, you will know which one is high bit(31), which one is low bit(0).

2. write a program to read/write PCI device. This is an example to write memory system configuration registers.
#define DOMAIN (0x0)
#define BUS    (0x0)
#define DEV    (0x18)
#define FUNC   (0x2)

void writeMemConfig(int flag)
{
    struct pci_access *pacc;
    struct pci_dev    *dev;
    pacc = pci_alloc();
    pci_init(pacc);
   
    dev = pci_get_dev(pacc, DOMAIN, BUS, DEV, FUNC);

    printf("DRAM CS mask reg:\n");
    val1 = pci_read_long(dev, 0x60);
    printf("val is 0x%x\n", val1);

    u32 data;        
    printf("write to DRAM CS MASK 0 reg, offset 0x60\n");
    data = 0x00783fe0;
    pci_write_long(dev, 0x60, data);

    pci_cleanup(pacc); /* close everything */
}

3. this PCI register is 256 bytes, you could use PCI API access which byte you want. For AMD K8, you have to read/wirite as double word.

4. compile the program with -lpci

Friday, January 14, 2011

Use command line install on Mac

Download macport from website, install dmg file

Then you could do:
$sudo port search toolname
$sudo port install toolname

Wednesday, January 12, 2011

openVPN

openVPN use SSL/TSL to implement the VPN mechanism
We also could implement VPN by using the IPsec

need more information for this article. confused.

iptables and ipfw

iptables is the firewall in linux
$iptables --list

ipfw is the firewall on mac
$sudo ipfw list

see man page for more info.
remember both iptables and ipfw could set stateful rules

SSH into a computer behind NAT

Go to your router settings page, e.g 192.168.1.1
Go to the port forwarding setting page, configure following settings


External Port
2225
Internal Port
22
Protocol
tcp/udp
To IP Address
192.168.1.102


You may want to set a normal port, because attacked cannot guess that. If you set 22 to 22, you may have may brute force attacks from outside. Set external port as normal port is more secure. 

Then: 
ssh username(AT)corsairxxv(DOT)gotdns(DOT)com -p 2225
or
scp -r -P 2225 username(AT)corsairxxv(DOT)gotdns(DOT)com:~/work/workspace/ChestTest ~/
scp -P 2225 file.zip corsairxxv.gotdns.com:~/


enable ls color highlighting on mac, change color scheme in vim

$ mvim ~/.profile
 
copy paste following lines to .profile
export CLICOLOR=1
export LSCOLORS=Gxfxcxdxbxegedabagacad
or you could see man ls for more information
For the color scheme in vim, you could put following line to .vimrc or .gvimrc
colors koehler