Linux Namespaces

Starting from kernel 2.6.24, there are 6 different types of Linux namespaces. Namespaces are useful in isolating processes from the rest of the system, without needing to use full low level virtualization technology. CLONE_NEWIPC: IPC Namespaces: SystemV IPC and POSIX Message Queues can be isolated. CLONE_NEWPID: PID Namespaces: PIDs are isolated, meaning that a PID inside of the namespace can conflict with a PID outside of the namespace. PIDs inside the namespace will be mapped to other PIDs outside of the namespace. The first PID inside the namespace will be ‘1’ which outside of the namespace is assigned to init CLONE_NEWNET: Network Namespaces: Networking (/proc/net, IPs, interfaces and routes) are isolated. Services can be run on the same ports within namespaces, and “duplicate” virtual interfaces can be created. CLONE_NEWNS: Mount Namespaces. We have the ability to isolate mount points as they appear to processes. Using mount namespaces, we can achieve similar functionality to chroot() however with improved security. CLONE_NEWUTS: UTS Namespaces. This namespaces primary purpose is to isolate the hostname and NIS name. CLONE_NEWUSER: User Namespaces. Here, user and group IDs are different inside and outside of namespaces and can be duplicated. Let’s look first at the structure of a C program, required to demonstrate process namespaces. The following has been tested on Debian 6 and 7. First, we need to allocate a page of memory on the stack, and set a pointer to the end of that memory page. We use alloca to allocate stack memory rather than malloc which would allocate memory on the heap. void *mem = alloca(sysconf(_SC_PAGESIZE)) + sysconf(_SC_PAGESIZE); Next, we use clone to create a child process, passing the location of our child stack ‘mem’, as well as the required flags to specify a new namespace. We specify ‘callee’ as the function to execute within the child space: mypid = clone(callee, mem, SIGCHLD | CLONE_NEWIPC | CLONE_NEWPID | CLONE_NEWNS | CLONE_FILES, NULL); After calling clone we then wait for the child process to finish, before terminating the parent. If not, the parent execution flow will continue and terminate immediately after, clearing up the child with it: while (waitpid(mypid, &r, 0) < 0 && errno == EINTR) { continue; } Lastly, we’ll return to the shell with the exit code of the child: if (WIFEXITED(r)) { return WEXITSTATUS(r); } return EXIT_FAILURE; Now, let’s look at the callee function: static int callee() { int ret; mount("proc", "/proc", "proc", 0, ""); setgid(u); setgroups(0, NULL); setuid(u); ret = execl("/bin/bash", "/bin/bash", NULL); return ret; } Here, we mount a /proc filesystem, and then set the uid (User ID) and gid (Group ID) to the value of ‘u’ before spawning the /bin/bash shell. […]

By | November 23rd, 2014|BASH, C/C++, Linux, Networking, Security Consultant|1 Comment

Rebuilding the Robot

It had been a while since I’d worked on the robot, and I wanted to work on some movement algorithms. I’ve done some AI work lately on a separate project, and thought that this would help with the automated movement task. Unfortunately, the Robot had a little accident, namely falling out of the loft whilst I was bring it down. It’s been long overdue the removal of some of the excess hardware, and also needed some bugfixes that I now had no choice but to perform. […]

By | May 1st, 2011|C/C++, Development, Hardware, PHP, Robot, Technology|0 Comments

Embedded Linux Programmer

As an embedded linux programmer, I’ve had the opportunity to work on a number of different platforms, MIPS being one of my favorites. There are a few general limitations that you’ll find. You have limited CPU power available, you have very little RAM available, and for more advanced operations and optimizations, your CPU will generally have a limited function set. The usual good programming practices apply, but are of much greater importance. Specifically, don’t allocate memory that you don’t need, and dont put the CPU under undue stress with unnecessary or badly optimized loops. Taking C syntax and some pseudo code; […]

By | January 15th, 2010|C/C++, Development, Hardware, Technology|0 Comments

Easy Reverse Engineering

Compiling a program doesn’t protect it or necessarily hide the source. Take the following example C program. It serves no real life purpose and should never print anything to the console: #include <stdio.h> int main(void) { const char *password = “secretpassword”; const char *otherpassword = “othersecretpassword”; if(!strcmp(password, otherpassword)) { printf(“This will never get evaluated”); } return 0; } To assemble the code using gcc -S test.c leaves test.s. The important point being that all strings remain intact: […]

By | November 2nd, 2009|C/C++, Development, Linux|0 Comments

Linux C setuid setgid tutorial

Here’s a very brief example of how to use setuid() and setgid() functions in your C program. #include <stdio.h> #include <sys/types.h> #include <unistd.h> int main(void) { int current_uid = getuid(); printf("My UID is: %d. My GID is: %dn", current_uid, getgid()); system("/usr/bin/id"); if (setuid(0)) { perror("setuid"); return 1; } //I am now root! printf("My UID is: %d. My GID is: %dn", getuid(), getgid()); system("/usr/bin/id"); //Time to drop back to regular user privileges setuid(current_uid); printf("My UID is: %d. My GID is: %dn", getuid(), getgid()); system("/usr/bin/id"); return 0; } The program above should be pretty self explanatory, now: adam@staging:~$ gcc -O2 -ggdb -o setuid setuid.c adam@staging:~$ ls -al setuid -rwxr-xr-x 1 adam adam 9792 2009-10-03 18:09 setuid adam@staging:~$ […]

By | October 3rd, 2009|C/C++, Development, Linux|0 Comments