Truth, Computing and Fail

  • Home
  • About

Resource limits – Part II (hard limits)

anomit | June 26, 2009

So much for late night coding. Yesterday I missed out on a very important part about setting the hard limits on resources. But you need to have a superuser process to achieve this. Referring to the code of exec.c in the previous post, put in this after line no. 18.

limit.rlim_max =1;

This is actually the hard limit and as the man page says, it acts as a ceiling for the soft limit i.e. rlim_cur. The advantage being that if the process exceeds the limit and yet continues running such as by handling the SIGXCPU signal in the previous example, this time a SIGKILL will be issued which would force it to terminate.

Now compile exec.c as usual and run it as root. You won’t see any output as we set the hard limit equal to the soft limit.

  • Soft limit reached, SIGXCPU sent
  • Process tries to handle it
  • At the same time the hard limit i.e. the ceiling for soft limit is reached too. So a SIGKILL is sent and the process terminates before any output.

References


setrlimit(2) man page

Comments
No Comments »
Categories
Coding, GNU/Linux
Tags
ipc, linux, syscall
Comments rss Comments rss
Trackback Trackback

Resource limits on an exec()-ed process

anomit | June 25, 2009

This might seem trivial at first sight but you have no idea how darn happy I’m to see this works :D . So happy that I decided to blog about it. I already hear trumpets blowing in the distance.

Here is what I was worried about:

Normally, exec() is carried out in a forked process. Setting resource limits on a forked process is straightforward using setrlimit(). But I was apprehensive whether those limits would hold once I exec() another binary image within that forked process, and it wouldn’t be overstating it if I said I was about to front kick my laptop in joy :P .

I tested by limiting the amount of CPU time(RLIMIT_CPU) that a running process is allocated since this would be the easiest to test IMO. The signal delivered to the process when it exceeds the CPU time limit is SIGXCPU.

Since this is all that is to it, wasting no more words, let’s get our hands dirty.

The program in which a process is forked and exec() is run (exec.c):

#include <stdio.h>
#include <stdlib.h>
#include <sys/resource.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>

int main()
{
    int pid;
    int rv;

    if (!( pid=fork() ))
    {
        struct rlimit limit;
        getrlimit(RLIMIT_CPU, &limit);

        limit.rlim_cur = 1;

        setrlimit(RLIMIT_CPU, &limit);

        execl("./inf","inf",NULL);
    }
    else if(pid)
    {
        wait(&rv);
    }
    else
        printf("Error forking\n");

    return 0;
}

The program whose binary image is specified in exec() (inf.c):

#include <stdio.h>
#include <stdlib.h>
#include <signal.h>

void handler(int signum)
{
    if (signum == SIGXCPU)
        printf("Caught SIGXCPU signal, exec in peace\n");
}

int main()
{
signal(SIGXCPU, handler);
while(1);
return 0;
}

Now compile
$gcc -Wall exec.c -o exec
$gcc -Wall inf.c -o inf

and run
$./exec

You’ll see SIGXCPU being handled which means the resource limit is working!

Comments
No Comments »
Categories
Coding, GNU/Linux
Tags
linux, syscall, unix
Comments rss Comments rss
Trackback Trackback

Adding a new system call to the linux kernel

anomit | April 6, 2009

I tried this thing last semester too but I wasn’t too serious about it. I had decided to go for gentoo for obvious benefits that’d support the frequent rebuilding of the kernel. Somewhere down the line gentoo got caught in a cyclic dependency error and I forgot about the whole thing. But I am digressing.

Anyway, I built gentoo from scratch and got things working. This step by step guide is quite good to get started. Note that this is about adding system calls to the kernel, not implementing them.

The guide is a bit old though, and just one thing needs to be changed. Step #16 mentions the use of the _syscallN macro. Don’t use it. From the man page of _syscall

NAME

_syscall – invoking a system call without library support (OBSOLETE)

NOTES

Starting around kernel 2.6.18, the _syscall macros were removed from header files supplied to user space. Use syscall(2) instead.

The _syscall() macros do not produce a prototype. You may have to create one, especially for C++ users.

Instead use a function wrapper like this:

long mycall(int i, int * result)

{

	return syscall(__NR_mycall, i, result);

}

i and result are the arguments I used for my syscall and quite obviously it would vary according to whatever you decide to write.

There are quite a few other guides too on this topic but they are generally old and not updated. So in any case you do need to poke around quite a bit to get things working.

Some really good reading material:

  • Kernel command using Linux system calls ( uses the _syscallN macro in examples )
  • Playing with the cr0 register. This is a bit advanced for my current knowledge level and I’m in the process of fully understanding how the register works. Try at your own risk.
Comments
No Comments »
Categories
Coding, GNU/Linux
Tags
hacking, kernel, linux, syscall
Comments rss Comments rss
Trackback Trackback

Basic file operations with NASM

anomit | April 17, 2008

This is meant for NASM running on a linux machine. First things first: everything in UNIX is a file. A device is a file, a network socket is a file and everything else you can imagine is a file. Each file has a file descriptor attached to it. Some standard file descriptors are 0 for STDIN (standard input), 1 for STDOUT (standard output) and 2 for STDERR (standard error output). Since everything is a file, you can read() and write() on them provided you have the file descriptor.

read(), write() and open() are some of the very important syscalls in linux that would allow you to manipulate any file (that is, provided you have the permissions). There are some 150+ of them if you are really interested to find out. For syscalls, you need to pass the necessary parameters in the ebx, ecx, edx registers and so on, depending upon the number of parameters. You can also call libc functions by declaring them as extern printf for example and pushing the necessary parameters on the stack, the last parameter to be pushed first. To understand what kind of parameters need to be passed for the syscalls, read the developer man pages. Like man 2 write for write(). Use this for any other syscall like read() or open() and also keep the list of syscalls mentioned earlier in this post handy.

Regarding passing arguments to the program, they are stored in the stack as

    argc
    argv[0]
    argv[1]
    argv[2]

and so on…
argv[0] is the program name itself, so we can pop and discard it safely.

The following is a small program in NASM that takes a filename as an argument and reads 8kB from the file and displays it on the screen.

section .data
buf times 8 db 0
bufsize db 8192

section .text
global _start

_start:
pop ebx
pop ebx
pop ebx
mov eax,5
mov ecx,2	;the read mode
int 80h

test eax,eax
jns file_read

mov ebx,eax
mov eax,1
int 80h
ret

file_read:
mov ebx,eax	;move the file descriptor
mov eax,3	;3 for read()
mov ecx,buf	;the buffer
mov edx,bufsize	;the buffer size
int 80h

mov edx,eax	;move the number of bytes read from the previous syscall to edx
mov eax,4	;4 for write()
mov ebx,1	;1, the STDOUT file descriptor
int 80h

mov eax,1
mov ebx,0
int 80h		;exit with error code 0
ret

To assemble: nasm -f elf filename.asm
To link: ld -s -o executable-name filename.o

To know more about the read and write modes, the file descriptors and some increased masochistic behavior, start with reading the /usr/include/unistd.h and /usr/include/fcntl.h files. Poke around that directory for some more knowledge.

Comments
No Comments »
Categories
Coding, GNU/Linux
Tags
assembly, NASM, syscall, unix
Comments rss Comments rss
Trackback Trackback

What’s in

  • Symlinks in a libfs virtual file system: The Pains
  • Small rant on the FUSE API reference
  • Kernel module debugging: a simple technique
  • Vim/Cscope quickie
  • PyCon India or Code Jam?

Blogroll

  • Akshay Kothari
  • Ankur Shrivastav (OS)
  • Ankur Sinha
  • Harsh J
  • Hullap
  • LUG manipal
  • Swap

Tags

aircrack airfail airtel assembly blues build c Coding college country cryptography dean faculty file systems fuckery gnuplot hacking India kernel linux mangalore manipal mpd music NASM plugin plugins politicians pub culture python rant rock sam scheduler simulation SSFNet stupidity supernatural suppression syscall syscalls unix vim xchat xml

Archives

  • January 2010
  • December 2009
  • November 2009
  • October 2009
  • September 2009
  • July 2009
  • June 2009
  • May 2009
  • April 2009
  • March 2009
  • January 2009
  • November 2008
  • September 2008
  • August 2008
  • July 2008
  • June 2008
  • May 2008
  • April 2008
  • March 2008
  • February 2008
  • January 2008
  • October 2007
  • September 2007
  • July 2007
  • June 2007
  • May 2007
  • April 2007
  • March 2007

License

Creative Commons License
This work by Anomit Ghosh is licensed under a Creative Commons Attribution-Noncommercial-Share Alike 2.5 India License.
rss Comments rss valid xhtml 1.1 design by jide powered by Wordpress get firefox