27 Jul 2007

Linux on Nintendo DS

After getting my own DSX memory card for running homebrews (see previous blog entry), it's time to fire up Linux. Getting Linux to run on the NDS was no problem at all, but it's still quite limited. At least when using the memory card DSX.

The Linux distribution for NDS is called DSLinux and is under active development. To run it, use the following procedure:

  1. Connect the DSX to the USB.
  2. Download http://kineox.free.fr/DS/dslinux.nds and put it in the "apps/" folder. This version has wireless support.
  3. Since the DSX own application launcher are unable to launch DSLinux for some reason, another launcher has to load Linux. The launcher DSChannel can do the work. Unpack http://gtamp.com/DS/dschannels_beta5b_DS-X.7z to the root of your DSX.
  4. From DSX, start DSChannel. From DSChannel start DSLinux. If you try to launch DSLinux from DSX own application launcher, you'll just be presented with to white screens.
  5. When starting DSLinux, the top-screen (console) is garbled. Just tap "Enter" to redraw the screen.
  6. Login with user name: root and password: uClinux.

From here, get the wireless interface up and running:

# iwconfig nds channel 2 essid gatekeeper key off
# ifconfig nds 192.168.1.42 up
# route add default gw 192.168.1.1

Read more here: http://www.dslinux.org/wiki/Using_DSLinux

Oh, and the wireless is just legacy 802.11 (no 802.11b or 820.11g), so it's limited to 2Mbit/s data rate. And only WEP is supported, no 802.11i (WPA/WPA2).

Unfortunate, the DSX (file system) is not supported by DSLinux, so it's really limited what can be done. The file system is read-only so the rest of DSLinux is inaccessible. Only the most elementary programs are available like "busybox, "cat", "ls" and so on. Both "telnetd" and "dropbear" (ssh) refuses to start. I suspect that's because the read-only file system. And since no "netcat" or "socat" is present, it limits the remote accessibility further. Fortunate, support for DSX is on the TODO list.

So I'll guess I just have to wait until it's supported before I can play more with DSLinux.

Useful links:

Memory card "DS-Xtreme" (DSX) for the Nintendo DS (NDS)

As of June 2007, 47 million Nintendo DS units has been sold. That's quite an impressive number, and has been the fastest selling platform in Europe. As soon as I got my hands on one of these units, I started looking for ways to use "homebrews" (= software written for the NDS usually published for free).

There are a lot of great homebrews for the NDS, but a "memory card" (solid state ROM) is required to use homebrews. You must have a way of putting the homebrew onto the NDS. A lot of different memory cards exists. After poking around, I found that DS Xtreme card (DSX) looked to be a good choice.

Several reasons why I preferred DSX:
  • Comes in sizes up to 2GB.
  • The pysical size is no larger than ordinary game cards.
  • No need to patch/modify the NDS, the DSX works as an ordinary "game card".
  • USB interface directly onto the card which works flawlessly.
  • Support (which I found out where excellent) and forums.
  • A large and active community.
Okay, so how do I get hold of one of these cards? I found a Norwegian shop modnet.no which had the 2 GB in in stock.

The device arrived the next day. Great! Inside it was only a USB-cable and the DSX itself. I had read that the 2GB devices need a mandatory update, due to some firmware bugs. The firmware update was a breeze, but unfortunate a Windows only procedure.

When connected it's deteced as any ordinary USB-stick:

$ dmesg
...
[17185651.468000] usbcore: registered new driver usb-storage
[17185651.468000] USB Mass Storage support registered.
[17185651.468000] usb-storage: device found at 7
[17185651.468000] usb-storage: waiting for device to settle before scanning
[17185656.468000] usb-storage: device scan complete
[17185656.468000]   Vendor: DS-Xtrem  Model: e      isk        Rev:    
[17185656.468000]   Type:   Direct-Access                      ANSI SCSI revision: 00
[17185656.472000] SCSI device sdb: 4071424 512-byte hdwr sectors (2085 MB)
[17185656.472000] sdb: Write Protect is off
[17185656.472000] sdb: Mode Sense: 33 00 00 00
[17185656.472000] sdb: assuming drive cache: write through
[17185656.476000] SCSI device sdb: 4071424 512-byte hdwr sectors (2085 MB)
[17185656.476000] sdb: Write Protect is off
[17185656.476000] sdb: Mode Sense: 33 00 00 00
[17185656.476000] sdb: assuming drive cache: write through
[17185656.476000]  sdb: unknown partition table
[17185656.476000] sd 2:0:0:0: Attached scsi removable disk sdb
[17185656.476000] sd 2:0:0:0: Attached scsi generic sg1 type 0
[17185657.096000] FAT: utf8 is not a recommended IO charset for FAT filesystems, filesystem will be case sensitive!

$ df -h
...
/dev/sdb              2.0G  1.4G  639M  68% /media/DSX

After fiddling around with the DSX I needed to reset the DSX. I peeled off the label on the DSX and in the tiny hole there was two individual contacts. By connecting these two, the DSX was reset. Se picture to the right. After that I just needed to run the firmware upgrade utility and I was back on track.

So now it's time to find some good homebrews! A nice place to start:

http://www.ds-xtra.com/DS_Homebrew_Directory

25 Jul 2007

Less typing with enviroment variable CDPATH

The BASH shell has several environment variables that can be manipulated. The PATH variable is well known. Another useful variable is CDPATH. As PATH is a list of search paths for commands, so is CDPATH a list of directories used as search path for the "cd" command.

Example: At one ftp server we serve a lot of software, including several of the most popular Linux distributions. The local path to these distributions involves a lot of typing:

  larsks@spheniscus:~$ cd /usit/spheniscus/ftp/linux/
  larsks@spheniscus:/usit/spheniscus/ftp/linux$

From here, I can jump into "slackware/", "centos/", "debian/" and so on. But it's simpler when using CDPATH:

  larsks@spheniscus:~$ export CDPATH="/usit/spheniscus/ftp/linux"
  larsks@spheniscus:~$ cd slackware
  /usit/spheniscus/ftp/linux/slackware
  larsks@spheniscus:/usit/spheniscus/ftp/linux/slackware$

Nice huh?

An even lazier method (involving less typing) is to use alias:

  larsks@spheniscus:~$ alias s="cd /usit/spheniscus/ftp/linux/slackware"
  larsks@spheniscus:~$ s
  larsks@spheniscus:/usit/spheniscus/ftp/linux/slackware$

But then I have to create one alias for each directory. Oh the choices!

24 Jul 2007

Fork bomb, or how to take down a Linux server in matter of seconds

A particular nasty local denial of service attack is a fork bomb. It's dead simple: A program just replicate itself, which again replicate itself and so on until all resources are exhausted. Fortunately, protection against fork bombs are easy - but rarely used at all.

Fork bomb? Doesn't sound familiar? To understand fork bomb, you must understand "fork()". Fork is a system call, which creates an exact copy of the running process. The new process is called "child", and the invoking process "parent". If you've taken any sort of programming class I'm sure you know all about forking. If not, you can read about it in "man 2 fork" or Wikipedias entry on fork.

To create a fork bomb, you usually make some kind of misbehaving piece of software that spawns new child processes endlessly. This can be written in any language, but a one-liner bourne shell script is perhaps the most simple one:

  #/bin/sh
  $0 &
  $0


Save this as "forkbomb.sh", execute it and see what happens. I'll bet within seconds the system is unresponsive. Here "$0" is the name of the script (forkbomb.sh) and the "&" puts the new invocation in the background. Last the script is executed a second time and this time it's in the foreground waiting for the new invocation of itself to complete (which it never does..) thus effectively holding on to resources..

You can restrict the number of processes by the built-in bash command "ulimit". Option "-u" shows/controls number of processes you're allowed to run:

  $ ulimit -u
  unlimited

Unlimited number of processes? Thats nice. Restrict it by:

  $ ulimit -u 20
  $ ulimit -u
  20

Here "20" is the maximum number of processes available to the shell and processes started by it. Try it, and you'll soon see the restriction come to play:

  $ ulimit -u 20
  $ ./forkbomb.sh
  ./forkbomb.sh: fork: Resource temporarily unavailable
  ./forkbomb.sh: fork: Resource temporarily unavailable
  ./forkbomb.sh: fork: Resource temporarily unavailable
  ....

Good. Unfortunate, we do not trust our users. So we need this setting permanent. This an be done in /etc/security/limits.conf:

  # cat /etc/security/limits.conf
  ....
  lars    hard    nproc 20

Logout and back in, to see the restriction in effect.

  $ ulimit -u
  20

And I can of course not increase the limits beyond the level set in limits.conf:

  $ ulimit -u 100
  -bash: ulimit: max user processes: cannot modify limit: Operation not permitted

But do beware - the root account (or any account with UID 0) is not bound by limits.conf.