Singpolyma

's Profile

Author Archive

Writing a Simple OS Kernel — Part 3, Syscalls

Posted on

Updated 2012-33 to fix a bug in the context switch assumptions.
Edited for clarity, 2012-34.

Last time, we got our kernel to set up space for a task, and run that task in user mode. This time we’re going to add a facility for the user mode task to call back into the kernel.

Syscalls

But wait! Didn’t I say last time that one of the things user mode tasks cannot do is change the CPU mode? Well, yes, they can’t change it directly. What they can do is trigger an event that will make the CPU switch to supervisor mode and then jump to some predefined bit of code. That way, there’s no security problem, only kernel code is running in supervisor mode, but the user mode task can still ask the kernel to do things for it.

The instruction that lets us do this on an ARMv6 CPU is svc (used to be called swi). It takes an immediate value as an “argument”, which it actually does nothing with. If the kernel wants to use that number for something (like specifying what the user mode task wants done), it has to read the number right out of the instruction in RAM. This is doable, but not always ideal, and so some kernels (such as modern Linux) actually just always use a zero, and then store information they want to pass elsewhere.

Vector Interrupt Table

The svc instruction actually causes an interrupt. Interrupts are signals that (when they’re enabled) cause the CPU to switch modes and jump to some predefined instruction. What instruction will it jump to? Well, ARM CPUs have something called the vector interrupt table that is at the very start of RAM. These locations are where it will jump to (each word, starting at 0x0, is the location of a particular sort of interrupt, up until there are no more interrupt types).

That may not seem very useful. We can only execute one instruction? Well, yes, but that instruction can jump us to somewhere more useful. Now, your first thought may be to put a branch instruction there. Great idea, but it won’t work. Branch instructions are calculated relative to their position in the linked binary. If we copy one of them to another location in RAM, the offset will be wrong. We need to use a load instruction to load an absolute value into the program counter. What value should we load? The address of a function in our kernel, of course! It turns out that the assembler contains a syntax for including the address of a function directly, which is then an absolute value and so does not move when we copy it.

Here’s what the new bootstrap.s looks like:

.global _start
_start:
	mov r0, #
	ldr r1, =interrupt_table
	ldr r3, =interrupt_table_end
keep_loading:
	ldr r2, [r1, #]
	str r2, [r0, #]
	add r0, r0, #
	add r1, r1, #
	cmp r1, r3
	bne keep_loading

	ldr sp, =0x07FFFFFF
	bl main

interrupt_table:
	ldr pc, svc_entry_address
	svc_entry_address: .word svc_entry
interrupt_table_end:

Why do we need to copy two instructions? Well, even that load instruction is loading from a relative address. Luckily if we move them both then the relative position remains the same. This may look a bit complicated, and that’s because it is. You could just copy the two words directly across, but this way we have a loop that copies everything from our interrupt table section, so we can easily add other interrupt handlers to it later. You’ll note we started at 0x8 instead of 0x0, because that’s where the SVC handler is, so if we want to add ones that come before 0x8, we just have to remember to change the base address at the start. With some hacks we could do the copying part in C, but for this example I decided that keeping all the bits for this in assembly was easiest.

Syscall Wrapper

We need a way for our C code to call the svc instruction. Since we don’t have anything we really need to pass through, we’ll just add a dummy wrapper for now.

Create a new file called syscalls.s and add it to the Makefile as a dependency of kernel.elf. Put this in it:

.global syscall
syscall:
	svc 0
	bx lr

Pretty simple. It just activates the svc, and then when it comes back jumps to the caller (note that this assumes the registers it had before it called svc are reset before it comes back).

You’ll also need to add a line to asm.h:

void syscall(void);

Save Kernel State

Now, let’s think about what we want the kernel to do when it actually gets control back. We’d like to go back to the point in our kernel code we left off when calling activate in the first place. The problem is, we’ve not got any clue where that was! In loading the user mode task state, we did not keep around any information about what state the kernel was in. Let’s add that to activate now:

mov ip, sp
push {r4,r5,r6,r7,r8,r9,r10,fp,ip,lr}

Put that at the top of activate, before we begin messing about with the registers. That’s all the kernel state we need to save!

SVC Entry

Alright, we’re now ready to define our first version of the svc_entry function. All we really want to go at this point is get the kernel back into a state where it can run, and then return to our code. We’ll put this in context_switch.s:

.global svc_entry
svc_entry:
	pop {r4,r5,r6,r7,r8,r9,r10,fp,ip,lr}
	mov sp, ip
	bx lr

Just reverse the save we just did, and jump back to where we came from in the kernel. How is lr where we came from? Well, you’ll have noted that when we call functions (and the C compiler does this as well), we use bl, which saves the address of the instruction after itself in lr before jumping to the function.

Alright, add a call to syscall to the end of first and then add another bwputs call after the activate call in main, build, and run. You should see your new message printed last.

Code so far on GitHub

Heading Back to User Mode

Add another print and another syscall to first, and another print and call to activate to main. Compile and run your code. What do you see?

When we call activate again, the user mode task re-starts at the beginning! That’s not what we want, but it makes sense. We never saved our place inside the user mode task. In fact, we don’t even have a reference to where its stack was when it called the syscall, so we’re just going back with the stack from before. That’s not going to work. We need to add some code to our SVC entry to save the user mode task’s state. If you recall the way we set up the task before, you’ll now see why. The way the stack looks after we save our state on it is exactly the same as the way we set it up! Everything will be where activate expects it:

msr CPSR_c, # /* System mode */
push {r0,r1,r2,r3,r4,r5,r6,r7,r8,r9,r10,fp,ip,lr}
mov r0, sp
msr CPSR_c, # /* Supervisor mode */

mrs ip, SPSR
stmfd r0!, {ip,lr}

There, all the registers are on the user stack. We use stmfd which is just like push, but lets us operate on another register. You’ll note we had to save both versions of lr. One is state for the syscall wrapper to use, the other is the address inside the syscall wrapper we need to jump back to later. Now we just need some way to get the new location of the top of the stack back to the kernel.

Conveniently, our C code expects the return value of a function to be in r0, which is where I’ve put the user mode sp in this example. Just change the definition of activate in asm.h to return the right type, and then assign the return value somewhere and pass that to the next call to activate. You can now keep calling into your user mode task as many times as you want!

That’s It!

We now have a kernel that can start a user mode task, and switch back and forth between the kernel and the user mode task at will. Next time we’ll look at multitasking and maybe some other stuff.

Code for this post is on GitHub.

Writing a Simple OS Kernel — Part 2, User Mode

Posted on

Updated 2012-33 to fix a bug in the context switch assumptions.
Edited for clarity, 2012-34.

Last time, we got a basic bit of C code bootstrapped and running all by itself on QEMU. This is often called “bare-metal” programming. This time we’re going to add to that and do something a bit more complicated: we’re going to run a single user-mode program on our kernel.

What is User Mode?

User mode is the name given to the mode we put the computer in when running anything other than the kernel. This often has implications for memory protection and similar, but we don’t have any of that. For us it’s just going to be the CPU mode in which certain things (such as changing CPU modes) cannot be done.

User mode also often refers to the slices of the system resources given to different processes, etc, such that they can all be run on the same computer without interfering with each other.

First, some abstractions

We hard-coded some values and functionality last time to write to the serial port. That code was very simple for printing one statement, but we may want to clean it up a bit if we’re going to use the serial port a lot.

First, let’s pull out everything machine-specific from kernel.c and put it in a header file for the machine, call it versatilepb.h:

# UART0 ((volatile unsigned int*)0x101f1000)

So far we just throw the characters at the serial port as fast as we can, and hope they get caught. That will probably always work on QEMU, but will not work on real hardware, so let’s add the ability to check if the serial port can handle a byte right now. For that we’ll need two more constants:

# UARTFR 0x06
# UARTFR_TXFF 0x20

UARTFR is the offset (in words) from the UART0 base address of the flags for the serial port. UARTFR_TXFF is the mask that gets the bit representing if the transmit buffer is full.

Now you can put the following at the top of kernel.c:

# "versatilepb.h"

void bwputs(char *s) {
	while(*s) {
		while(*(UART0 + UARTFR) & UARTFR_TXFF);
		*UART0 = *s;
		s++;
	}
}

Now you can replace the big mess in main with bwputs("Hello, World!\n"); or any other message. Much cleaner!

Code so far on GitHub

Calling Into Assembly Code

Last time, we had a small piece of assembly code that called in to our C program. This time, we are going to want to call into assembly code from our C code. If you are on Ubuntu or some other systems, your C compiler may be defaulting to generating “thumb mode” instructions, which are not what we need to use for our assembly code. So we need to tell the C compiler to generate normal ARM instructions. To do this with gcc, add -marm to the end of your CFLAGS

A User Program

Create a simple “user program” in the form of a function in kernel.c called first that just prints and then hangs (since we will not build the ability to get out of user mode until later):

void first(void) {
	bwputs("In user mode\n");
	while(1);
}

Assembly stub

Create a new file called context_switch.s with the following:

.global activate
activate:

And a new file called asm.h with the following:

void activate(void);

Include this new header file into kernel.c so that you can call the assembly stub from your C code, then add a call to activate to your main.

Finally, add context_switch.o as a dependency to kernel.elf in your Makefile so that it will get built.

The Context Switch

Alright, what are the absolute minimum things we need our switch to user mode (called the “context switch”) to do? Well, it the very least we need a way to start running some function in user mode.

The way to switch an ARM system into user mode is to use the movs instruction to put some address to jump to (like the address of our function) into the pc register (the “program counter”, which is where the CPU is currently executing). But what mode will the CPU enter when we do this? The answer is that it will read the contents of a special register called SPSR (Saved Processor Status Register) and use that to change CPSR (Current Processor Status Register), and thus change modes. Couldn’t we just change CPSR directly? Because we’re not in user mode, we could, but since we want to jump into our function the moment we switch modes, this is the safest way to do it:

mov r0, #
msr SPSR, r0
ldr lr, =first
movs pc, lr

0x10 is just the value that sets the bit meaning “user mode”. We set that to SPSR, load the location of first and then movs there.

You can stick that at the start of activate and try to run that if you like, but it won’t work. Why is that? Remember how we had to set up the stack in order to jump into C code? Well, it turns out that one of the differences of user mode is that it uses a different sp register. This can be very handy later when we’re doing more complicated things, but for now we can just set the user mode stack to be the same as the kernel stack, by adding the following before the movs:

mov ip, sp
msr CPSR_c, # /* System mode */
mov sp, ip
msr CPSR_c, # /* Supervisor mode */

So what are we doing here? We copy our current sp to ip (because we’ll have a different sp in user mode, so we need to copy it somewhere), then we set a part of CPSR directly to enter “system mode”. What is system mode? It’s a special mode on the ARM processor that lets us access the registers as though we were in user mode, but still be able to do privileged things. We set user mode sp to our copy, then switch back to supervisor mode (which is where we normally operate in the kernel).

If you build the kernel now, and run it under QEMU, you should get “In user mode” printed out. Good job!

Code so far on GitHub

A Better Stack

Using the same kernel stack for our user mode program isn’t going to work very well if we want to be able to pause the program and go back to it, because other things will use the kernel stack in between, so we really want the program to have it’s own stack.

First, declare some space for your user stack:

unsigned int first_stack[256];

Then pass first_stack + 256 to activate, and change asm.h to have activate take an argument.

The first four arguments to an assembly call come in as r0-r3, so we can easily access this parameter inside activate:

msr CPSR_c, # /* System mode */
mov sp, r0
msr CPSR_c, # /* Supervisor mode */

One less line, since we can access r0 from user mode directly.

Less hardcoding

The program should still run, but now it’s using its own stack. We still have the value of SPSR and the name of the function we’re calling hardcoded into the assembly. We could pass these as parameters, but then we would have to remember them in a special way when it comes to being able to enter and re-enter the same user mode function multiple times (since the current stack, CPU mode, and entry point can change between calls), so it’s actually easiest to store these two additional values on the user mode program’s stack. We will store them in special positions so that all the user mode registers can be saved along with them easily.

We’ll want to move the calculation of the end of the stack up, so that we can put our data into in:

unsigned int *first_stack_start = first_stack + 256 - 16;
first_stack_start[0] = 0x10;
first_stack_start[1] = (unsigned int)&first;

You’ll note the cast to (unsigned int) of the function pointer. This is mostly to make the compiler not warn us about using a function pointer as data. You should now pass first_stack_start to activate. If you want to, you can test that it still works, but we aren’t actually using this new data yet.

We’ve done a lot of work on the assembly, and are about to change it quite a bit, so I’ll reproduce the whole context switch here with the changes to use these values:

.global activate
activate:
	ldmfd r0!, {ip,lr} /* Get SPSR and lr */
	msr SPSR, ip

	msr CPSR_c, # /* System mode */
	mov sp, r0
	pop {r0,r1,r2,r3,r4,r5,r6,r7,r8,r9,r10,fp,ip,lr}
	msr CPSR_c, # /* Supervisor mode */

	movs pc, lr

This loads the first two elements from the passed-in stack to SPSR and lr (ldmfd, when coupled with the ! on the first argument, is the same as pop, but works with any register instead of just sp), then we switch to usermode and set the stack to r0, as before. Finally we use the pop instruction to load the rest of the stuff into our registers. We have nothing in there just now, but we’ll use more later, and this also makes the stack skip over all that stuff so that the process can use all of the space.

You’ll note we had to set lr twice. This is because, like sp, lr has a different version used in user mode from the one used in supervisor mode.

That’s it!

We now have a kernel that sets up a user mode task and then switches to it. Next time: getting back out of user mode!

The code for this post is on GitHub.

Writing a Simple OS Kernel — Part 1

Posted on

This is the first of what I intend to be a series of posts detailing the specifics of writing and testing a simple OS kernel.

Because some parts of any kernel have to be platform-specific, I had to choose a platform to target for this example. In order to make the assembly code simple but still relevant, I chose ARMv6 for the architecture target. In order to make testing easy, I chose the versatilepb board as a target, which is very well supported by QEMU. As a result (unfortunately) the target is little-endian, but you can’t have everything. I will try to make sure I point out when something platform-specific is going on.

Setting up your system

First, you’ll need a build system for the ARM target. On Debian you’ll need to add the emdebian repository to get a cross-compiling toolchain. On Ubuntu it is already in the repositories. Instal the gcc-arm-linux-gnueabi package. Other systems may vary. This package adds all your standard tools (like gcc, ld, etc) but with as arm-linux-gnueabi- prefix.

Then, you’ll need the qemu-system package for use in testing your code.

Building code

Create a file called kernel.c containing the following:

int main(void) { return 0; }

It’s not very exciting, and we’ll revisit it in a minute, but we need something there or we can’t test our build.

One thing our build system is going to need to handle is running the arm-linux-gnueabi- prefixed commands instead of the normal toolchain. There are multiple ways you can choose to do this:

  1. Write a simple env shell script that you source in any terminal you cross-compile in. In this script, set aliases for all the standard commands to the cross-compiler commands.
  2. Write a simple env shell script that you source in any terminal you cross-compile in. In this script, set environment variables (like CC, LD, OBJCOPY) to point at the cross-compiler commands.
  3. Set the cross-compiler commands as the defaults for your make variables at the top of your Makefile.

Any of these ways, and probably many others, can work. I’m going to choose option 3 for this example, so I’ll start my Makefile off with:

CC=arm-linux-gnueabi-gcc

We’re going to need to send some options to the C compiler to get it to generate the right sort of output, so that means defining a CFLAGS make variable. We need to specify the target architecture, tell the compiler to emulate floating point in software and to generate position-independant code, and tell the assembler to generate complete stack frames. I also prefer to turn on lots of warnings, so my CFLAGS looks like:

CFLAGS=-ansi -pedantic -Wall -Wextra -march=armv6 -msoft-float -fPIC -mapcs-frame

If you don’t know what some of these options do, you can check the gcc man page.

Now run the following to build the object code:

make kernel.o

Linking an ELF file

Now we have some code compiled for our target, but we also need to link it. You may be used to invoking the C compiler in order to link programs, but that won’t work for us because it actually links in some extra things that we don’t want, so we’ll need direct access to the linker by adding this to the top of our Makefile:

LD=arm-linux-gnueabi-ld

Next we’re going to have to send some special flags to the linker. One to tell it not to do a bunch of formatting and dynamic linking, and another to tell it where to start the code (since our code will not be loaded by an OS, it needs to sit at a specific place in RAM. This will depend on your bootloader and hardware. The memory address for the loader we’re using with QEMU is 0x10000). My LDFLAGS looks like:

LDFLAGS=-N -Ttext=0x10000

Finally, we need to write a make rule to actually link *.o files into *.elf files. Here it is:

.SUFFIXES: .o .elf
.o.elf:
	$(LD) $(LDFLAGS) -o $@ $^

You should now be able to link your code with the following:

make kernel.elf

It probably gives you a warning about not being able to find the entry symbol. This is because the linker doesn’t actually expect to start in main, but rather in _start. We’ll deal with this in a bit.

Running the code

It turns out that qemu’s loader can actually load ELF files, so we now have something that we can run. Run the following:

qemu-system-arm -M versatilepb -cpu arm1176 -nographic -kernel kernel.elf

The switches just select the target and tell QEMU not to bother launching a video display. You will note that the program does not exit. This is because when you return 0; in our trivial code, you have nowhere to return to except QEMU’s loader, so the program just gets loaded again. Hit Ctrl-a and then hit x to quit.

Making the code do something interesting

Ok, now that we have some code building and running, lets make it do something. I’d like to emulate the good old “Hello, World!” program. Unfortunately, our code is everything running on the system. We have no standard out. We haven’t even initialised a video device. Are we going to have to write a whole video driver before we can even see anything?

Thankfully, serial ports come to our rescue. You may think serial ports are outdated, but they have one major adavtage: writing a serial port driver is trivial. When we run QEMU with -nographic, it is actually binding the first serial port of the emulated system to STDIN/STDOUT. Nice!

So, how does one talk to a serial port? Well, that is platform specific. If you look at the documentation for our target board, you’ll see that it uses reads and writes to special memory addresses in order to talk to devices. This is called memory-mapped I/O. The memory address we need to write to in order to send a byte over the first serial port (called UART0 in the documentation) is 0x101f1000. So let’s write a trivial C program to shove bytes into that memory address:

int main(void) {
	char *string = "Hello, World!\n";
	while(*string) {
		*(volatile char *)0x101f1000 = *string;
		string++;
	}

	while(1); /* We can't exit, there's nowhere to go */
	return 0;
}

Pretty simple. If you haven’t seen the volatile keyword before, it just tells the optomiser that this memory address needs to be treated like it is in RAM, otherwise the optomiser could decide to store it somewhere else, which wouldn’t work for us because we’re not actually storing a value, we’re talking to a device.

Notice that we also put an infinite loop at the end of the program, to keep it from going back to the QEMU loader.

Rebuild kernel.elf and run it with QEMU again. What happened? Nothing? Hmm, something’s not right.

Setting up the stack

C programs store their area on a stack in RAM. Unfortunately, we haven’t told anything where in RAM to put that, so our C program is not a happy camper. But how can we set things up if we can’t run code?

Well, we can run assembly code. This sounds more complicated than it is. All we need to do is set the stack pointer (which is a register that all C code defined for ARM knows about and uses to find the stack) and then call our main function. Here’s the code, saved as bootstrap.s:

.global _start
_start:
	ldr sp, =0x07FFFFFF
	bl main

Ah! There’s the _start symbol that our liker has been looking for! The first line just declares _start as visible to the linker. The ldr instruction sets the stack pointer to 0x07FFFFFF, which is the the address of the end of the 128MB of RAM that our QEMU system gives us. The bl instruction just jumps to our main function in the C program.

Building assembly code

We need to add some stuff to our Makefile so that we can build this new assembly file. Here’s the rule to build *.s files to *.o files:

.SUFFIXES: .s .o
.s.o:
	$(CC) $(CFLAGS) -o $@ -c $^

We also need to add a new rule for kernel.elf now, beacuse we’re linking multiple *.o files into it:

kernel.elf: bootstrap.o kernel.o

We’re done!

If you rebuild kernel.elf and run it with QEMU again, you should see “Hello, World!” printed in your terminal. Well done. I think that’s enough for one blog post, but I’ll be back with more.

The code from this post can be found on Github.

Dystoparx — Part 14

Posted on

Jack is still at the datacentre. He’s just brought all the machines running mailservers back up. The attackers kept trying at the other machines in the meantime, but it doesn’t seem like the attack was refocused. Maybe it’s largely automated?

No attacks on the— oh. The systems are starting to get attacked again, one by one. Annoying. His phone vibrates. It’s an email from his boss. Wants to know why there are still issues. Jack replies with a summary of what’s going on. Only a few of the machines he checked during the “security window” were compromised. He patched those and everything should be safe now. At this point the odds of the attackers compromising more is slim. If they were going to get in they’d have done so already. Either they’re just hoping someone on one of the boxes will majorly goof up, or else…

Or else the attack is a distraction. What else in the datacentre could they be after? Well, they’ve shown an attraction to communications services, mostly email. What can you do with a compromised mailserver?

You can send mail as the people whose accounts are on that server. No, that’s useless. Anyone can send email as anyone else quite easily, no need to hack a datacentre. What else?

You can read people’s email. Of course! Where else would it be really easy to read people’s email? The routers! The routers for the datacentre handle every single piece of data passing to any server, so reading emails from there would be easy.

Jack starts scanning the routers for unusual behaviour. While his scan is running, his phone rings. Who would be calling— oh, maybe it’s her? He is hopeful, but a quick glance at his display shows that it is not her. It’s her best friend.

“Hello?” Jack doesn’t know why she’s calling, but he hopes it is on her behalf.

“Ok,” she says, “it has now reached that point. You two have to talk.”

“I tried to call her last night,” Jack defends a little.

“Right. I know. I mean, like, not like that. Talk talk.”

Oh. “I don’t think she wants to see me.”

“See, that’s your problem. You’re dense. Of course she wants to see you.”

“What? But she specifically said—”

“Stop! Stop listening to what she says and start listening to what she needs!”

Jack has heard this kind of rhetoric before. It doesn’t make a lot of sense. Why should he interpret her when it’s much easier for her to just… oh. Because that’s part of the problem. She doesn’t always know what she needs. Just like he doesn’t know just quite why he wants her so badly.

“Has she said she wants to talk to me?”

“Sure, or, sort of. After last night, she knows she wants to fix this.”

“Tell me what to do.”

“Oh no. My meddling part is over. Your turn.”

With that, she hangs up.

His eyes turn to his laptop. Scan still running. Half of the routers have been checked and seem normal. He opens up a chat with Nicnus and Acklas.

09:30 <jjdavis> I called her last night. Her friend called me back this morning.

09:35 <acklas> So, she’s still not speaking to you? Or did you talk to her last night?

09:36 <jjdavis> nono, talked to voicemail. Sounded like a moron. friend thinks I need to meet with her

09:36 <acklas> Looks like nicnus is still asleep. lucky jerk

09:37 <acklas> With the friend? No, with your ex. To get her back.

09:37 <jjdavis> Yes.

09:40 <acklas> How?

09:40 <jjdavis> I don’t know.

The scan is done and Jack is going over the results. There. A single router claims to have been upgraded more recently than all the rest.

On investigation it turns out that someone, probably one of the ops, forgot to upgrade this specific router last time upgrades were done. He’ll have to track down whoever was in charge of that and scold them. The attackers have replaced the software on the router with some that functions normally, but also sends them a copy of everything that comes through.

“Gotcha.”

09:45 <jjdavis> Those shifty crackers were hiding a successful router exploit behind the noise of their constant attempts to get in everywhere else.

09:45 <acklas> That’s actually sort of smart.

09:45 <nicnus> acklas: yes, I am a lucky jerk 🙂

09:45 <nicnus> jjdavis: have enough to trace them with?

09:45 <nicnus> jjdavis: That sounds good for you. I would just show up wherever she’s staying.

09:47 <jjdavis> nicnus: I think so. I’ running some trace stuff now an d also posting their monitoring code some places. Others may also be compromised.

09:47 <jjdavis> nicnus: I could do that. She’s just over at her place, I’m pretty sure. I don’t think she’d slam the door in my face.

09:50 <acklas> jjdavis: her place? I thought you two shared an apartment?

09:51 <nicnus> jjdavis: Good idea. And yeah, that should work.

09:52 <jjdavis> acklas: no, we’ve never lived together. I work from home, and she’s over a lot. Some of her stuff used to be at my place.

09:55 <acklas> Interesting

10:00 <jjdavis> Uh, guys… this trace does not look good…

Acklas spins in his chair. He’s been at work for almost an hour and hasn’t really done anything yet. He’s not currently assigned to a project. The last team he was on has completed their project and dispersed. He’s not even sure who he’s reporting to just now, since his old team is no longer together.

09:55 <acklas> Interesting

He looks up from the chat to see a new email in his work inbox. The email is not from anyone he knows, but claims to be VP of something. The message has very few details. Setting up a meeting about… something. A new project? Probably.

Woah! This meeting is in five minutes! Why is he just getting this now? He grumbles something under his breath and walks off to find the room.

He eventually finds the meeting. It’s in a part of the building he hasn’t been to before. How big is this place? What time is it? He’s 3 minutes late. Ah, well, he’ll just slip in the back and see what’s up.

Acklas enters the room and it becomes immediately apparent that there will be no slipping in. The room has just two business people and his old manager, and they appear to be waiting for him.

“Nice of you to join us.” One of the suits smiles.

Acklas just nods, “Yeah, well, someone only decided to email me about this about ten minutes ago.”

The suits seem to be ignoring him now. One is looking through some papers.

Finally, “Sit down.”

Oh, right. Sitting. He sits. His old manager isn’t looking at him. Not in an evasive kind of way. More like a distracted kind of way. Acklas thinks about making conversation, but these meetings have a way of running themselves eventually. He doesn’t have anything better to be doing.

The suit with the papers looks up, “We’ve had a new contract come in to the company. Records indicate that you are currently unassigned, yes?”

This isn’t strictly true. He is assigned to the whole company right now, which means he could be called upon by any team to help out with small tasks or hunt down bugs. Really, though, “Yes.”

The suit smiles, “Good.” A pause, “The project involves some fairly sensitive government work. We can’t reveal the exact nature of this work to you, but you will be given adequate information to complete the project.”

“And who will I be working with?”

“This will be your manager,” the suit indicates his old manager.

“And?”

“And what? We’re assigning you, under him, to this project.”

“What, by myself?”

“Why? Do you require a team to operate?”

Acklas thinks about this. He certainly could work by himself. “No.”

“Good. The product ships in two weeks. We will, of course, be expecting regular status updates.” The man folds his papers into a binder.

Acklas is a bit confused now. “Two weeks? I don’t even know what it is yet.”

The other suit is smiling now, “Nor will you ever. The specification for what you are to build will be emailed to you. We will ship it in two weeks.”

This is not a completely new experience for Acklas. He’s been put on ridiculous deadlines before. Sometimes they meet them, sometimes they don’t, sometimes they just write terrible code so that they can come close. Just as he is considering this, though, the weight of dislike for his job comes crashing in. They figure him for a pushover! He’ll just take what they say and go do it. Not anymore. He’s had it with this. “Excuse me?”

The suits appeared ready to leave. Finally one asks, “Was there something unclear?”

Acklas stands up. “No, nothing unclear. Just let me get this straight. You need me for this new project. In fact, you seem to have no other resources to allocate to the project. You need it done very soon. Probably more soon than it can be done, but I can’t estimate that because you won’t tell me what it is. You waste my time by leaving me hanging and then setting up a meeting when all you had to do was have the spec in my inbox this morning. You want me to spend even more of my time updating you on the status of a project that needs to be done almost before I could make much of a status update anyway. And you expect that I’ll just do this? That I won’t have a problem with it? That it will get done and function properly?”

His old manager blinks at him. “Where is this coming from? I thought you liked it here.”

That’s the last straw. Acklas isn’t shouting yet, but he’s getting there. “Like it here! How could you think I like it here? Every feedback period I write about how much things could be improved. About how developers are being wasted and projects mishandled!”

His manager seems shocked, “But… you get paid so much!”

This is going nowhere. Why does he put up with this?

“I hope you can find someone else to do your project.”

He walks out.

Our protagonist is doing his best to keep Jack calm. Acklas seems to be gone. Probably got called to a meeting.

10:15 <nicnus> Just set up a fake datastream to send them. You said you can block their attacks now with something you found in their malware code?

10:17 <jjdavis> yesyes, but that’s not going to help me long-term! That solves the datacentre security issue, but I’ve already posted this malware online! I’ve documented the attack!

10:18 <nicnus> Well. Maybe it’s not the US government. Maybe it’s just someone using them to mask his trail.

10:20 <jjdavis> Sure. Yes. That doesn’t help me. If the government finds out I found a security hole in their stuff, they’ll come after me just as hard as if it’s something they did on purpose that I’m stopping.

Our protagonist is a bit worried now. Jack has a point. Governments in general have a history of arresting good guys for reporting bugs.

10:22 <nicnus> Maybe you should come back.

10:23 <jjdavis> I can’t. I’m just about to get things back together down here.

10:23 <nicnus> What, with your girlfriend? THIS IS YOUR LIFE WE’RE TALKING ABOUT.

10:25 <jjdavis> Well… maybe it’ll be ok. I have exit plans, still. Just in case.

Nicnus is shaking his head. Jack’s going to stay. For a girl.

Dystoparx — Part 13

Posted on

Acklas is at home. He should be at work, but he’s called in sick. Is he sick? He’s sick of work.

It’s not like they’ll notice that he’s gone. The amount he gets done in any given day is governed more by a lot of bureaucratic hoop-jumping than by anything he actually does. The meetings he would have sat in will still run. He just will not have sat in them. They don’t really need him sitting there in order to happen. He’ll get a summary by email later anyway. And it will contain different conclusions than will actually be reached in the meeting.

His parts of the Internet are buzzing with the waves of arrests that have been sweeping across the country. Kiddie porn related, all of it. The major news outlets are raving about the brilliant police work that has apparently been happening for quite some time to lead to this. If there has been so much brilliant police work happening, why hasn’t he heard about it? Just suddenly they find all of these people? The pundits and bloggers are opining about how scary it is that there are so many “freaks” out there. If this is how many they found… how many didn’t they find?

The coverage is all positive, which seems odd. Maybe the government is getting it right. Acklas leans back in his chair and yawns. The subsequent stretch is cut short by a very odd and unexpected sound: his ringing phone.

He slides the phone from its holster and looks at the screen. Incoming call from… and some numbers. Numbers? Does that mean the call is from someone he doesn’t know?

Whatever. He answers it.

“Oh thank goodness! I thought no one was going to answer.”

Huh. Acklas still has no idea who it is. Apparently they’re happy he’s around.

“They’ve got me down at the police station. They’re saying something about my computer, but I don’t know what’s going on.”

Drawing a blank. Woman voice. Older or younger? Gah. “I’m sorry… who is this?”

Oh. It’s the old woman from up the street. What? At the police station? Her son is not picking up. No one she knows is picking up. They’re all out of town or something. Acklas is unconvinced she even knows. Well, he’s not doing a lot else. He’ll head down and see what’s up.

05:01 <jjdavis> You’re where?

05:02 <nicnus> waitwait, is this the woman you talk to on your “runs” ?

05:05 <acklas> yesyes. She lives up the street from me.

05:05 <nicnus> And they’re accusing her of kiddie porn involvement?

05:07 <acklas> i htink they started out with that. this point I think they’re just trying to get information about who may have used her computer

05:08 <jjdavis> More like her Internet connection at all, they’re probably just tracing IPs.

05:08 <jjdavis> Does she lock her wifi?

05:09 <nicnus> Hmm, I hope they’re not bringing people in based on just IP traces. That’s terrible.

05:10 <acklas> WEP secured WiFi so basically open. not sure what it’s based on

05:11 <nicnus> I wonder if they’ll still count her in those numbers of how many “weirdos” they’ve brought in

05:12 <jjdavis> Oh, probably

05:12 <acklas> theyre coming out

Acklas is trying to talk to the officers. What’s up? On what basis was she brought in?

“I’m sorry, sir,” says one, “but we can’t discuss matters that have to do with this case. We’ll make formal statements to the media when we know more.”

Ridiculous! The media will be hearing about this!

“Now, now,” the old woman seems much less concerned than she had on the phone. “They just needed to ask a few questions about my Internet. Can’t be too careful you know.” She lowers her voice to a mock whisper, “There’s dirtbags out there as would do all kinds of things!”

Acklas is still shaking his head as they get on the bus. Of course. There’s nothing negative to report on. Just asking a few questions, that’s all. Need to know if your grandma is associated with any child pornographers, that’s all. He glances back at his phone once they’re moving.

05:13 <jjdavis> They?

05:13 <nicnus> The old woman?

05:14 <jjdavis> Oh.

05:14 <jjdavis> and the officers with her

05:14 <nicnus> Ask them what they’re going to do with the answers they got from her.

05:15 <jjdavis> if they’re smart, they won’t talk. Ask her what they wanted to know.

05:17 <acklas> She doesn’t seem that sure. She didn’t really understand their questions.

05:17 <acklas> and yeah, they weren’t big on talking about it

05:18 <nicus> I wonder if this is an isolated case

05:20 <jjdavis> There are no isolated cases. Ever.

Nicnus’ brother is sitting with his girlfriend. She is his girlfriend now, and quite solidly. They’re watching the police take a man from across the street. Middle-aged man. Single, as far as they know. He seems to be going fairly quietly.

“I always thought he was a creep,” his girlfriend is saying next to him.

“Really? I never really talked to him.”

She huffs some air derisively, “You don’t need to talk to someone to know they’re a creep.”

“Well…”

“He didn’t go out much. When he did he was watching everything, like he wasn’t sure what to do with it. And I’ve never seen kids at his place. No nieces or nephews, nothing.” She’s looking at him.

“You just described my brother perfectly.”

She pauses abruptly mid-thought and looks at him. She starts to speak, then stops. Looks away. “Your brother…”

“My brother is kind of a creep. Is that what you’re trying to say?”

She takes a deep breath. How can she word this delicately? His brother is… different. Certainly not normal. “I certainly don’t think your brother is a pervert.”

“Well,” he sounds sarcastic, “thanks for that vote of confidence.”

“You have to admit,” she’s still not looking at him, “he’s different.”

“And, what, that’s reason enough to get rid of someone? For the crime of keeping to himself?”

She scratches her neck and looks over at him. “Of course not. Forget it. Anyway, this guy obviously did something.”

“Did he?”

Now she’s a little annoyed. Not very annoyed. Just a little. “Well, they’re taking him away in a squad car, aren’t they?”

He snorts, “You don’t even know if he’s being accused of anything. Maybe he’s an important witness and they’re taking him into protective custody. You just see a man being led away and assume that he’s a creep that deserved it because he seems different.”

They’re both silent for awhile. Finally she speaks, “Look, I’m sorry, alright? I didn’t mean anything by it.” She’s eyeing him. He is related to his brother. Maybe he’s got that same compulsive debater streak. He seems to be done, though. The conversation is over for now. She sighs in relief, takes his hand, and closes her eyes.

Jack is up to his neck in work. On-site work. The worst kind. As the sysadmin in charge of security for this datacentre, he has to be on site during all major attacks. The current one has not let up for a full day now.

The policy doesn’t strictly make sense. He could do most of what he’s doing from home still. There are things he has to be here to do, however, and those do crop up more often during a major attack.

He stares, bleary-eyed, at his laptop screen. The attackers have access to a lot of different computers to route their attacks through. They don’t stay in any one long enough for him to get much information about them. Well, he can tell they have a lot of machines. So either they’re renting time from the mob, or they’ve got their own virus that’s out there on a lot of computers. With this much power at their command, he would have expected them to try just flooding the datacentre with requests in order to take it down. That doesn’t seem to be their goal, however. They seem much more interested in actually getting access to the machines. Not any of the machines in particular, mind you.

Jack feels like crap. His eyes won’t focus, his back aches, and he really just wants a nap. Bleh. He walks to the vending machines, grabs a bottle of water, and dumps the whole thing on his face. He lets it drip off of him for a moment before wiping his eyes and then going back to hunch over his laptop. There has to be some sort of pattern to the attacks. He has already determined that the attackers aren’t trying to get in through a particular kind of security hole. They seem to be trying every attack that could possibly work.

Maybe they’re trying to get access to particular type of service? He quickly writes a script to graph traffic to machines in the datacentre against what services are running on those machines. Instantly he sees a trend. Mailservers. They seem particularly interested in mail servers. Also chat server, but much less focused there.

He sets up some firewall rules to slow down any traffic going to machines running email servers. It won’t slow them down enough for any legitimate traffic to notice, but it should slow the attacks down a little bit. Then he sends the owners of all those boxes a notice about a “security maintenance window” for later that afternoon. He’ll turn off all traffic to those boxes at that point and then run some intrusion-detection software on all of them to make sure they’re all still secure. Reset any that have been compromised and turn the network back on at the end of the window. Wost-case scenario: some people’s email is a little bit late. If he’s lucky, the attackers will just give up while everything is down. He doesn’t feel hopeful about that, though.

Jack stretches out on some cushions he’s set up on the floor. Time to get some sleep. As sleep robs him of his carefully constructed defences, however, restricted thoughts come streaming in. Thoughts of her.

“Frick.”

He thinks about the best way to reach out to her. In this scenario, he needs to reach her using what she prefers. That has always seemed to be the telephone. Fine. He slides his phone from his belt and stares at it. Ah, the green button. Now it is ringing. No one is picking up. Of course, she can see it’s him. She’s ignoring him. Voice mail.

“Uh… well, crap. I never know what to say to these things. I miss you. Serious.” He lets out a ragged breath. “We’re not a good fit, you and I. I know. I always appreciated that you put up with that. I guess… I guess you did most of the putting up. It always feels like I’m the one doing the putting up.” He thinks about that. Defending himself is not a good course of action. Too late, he’s being recorded. Crap. This is not a good way to compose a message. “Not— not with you specifically. Just in general, you know? Anyway. Call me.”

Phew. Blah. Uhh… What now? Sleep. Blah. Hmm. Yes. Yawn. Sigh. What’s that sound? Oh, an AC unit just came on. Ok. Phew. Hmm. Herm. Haw. OneTwoThree. Fzz. Fop. Flop. Hop. Stop. Hnmmnnm.

Asleep.

Our protagonist is also asleep. On his monitor his news reader is open to a list of headlines.

Local Police Round up 12 in Crack Down on Child Molestation

Sixteen Perverts Nabbed by RCMP

Cleaning up on Child Pornographers

Forty Arrested, Dozens Questioned, Large Law-Enforcement Op

Creeps and Freaks: Getting Tough on Weirdos

Where is Your Excuse Now? Why we need Tougher Cyberlaw

Cybercriminals Help Distribute Child Pornography

He’ll skim them tomorrow. Or not. He knows enough already. The cops are cracking down on anyone with suspicious Internet usage. They’re correlating that into other data they’ve got and turning it into arrests. Who knows how many of the arrests are legitimate. Maybe most of them. Probably.

Problem is, both false positives and false negatives are good for this new law. Either way the media can say the cops need more data. Who can blame them? Law enforcement should have more data about criminals. The question is: how do you keep them from snooping on normal people? Or accusing innocents on the basis of whatever they think they see in the information?

Blah.