flak rss random

warning: implicit backdoor

One way to slip malicious code into a project is to hack into their build server and just drop it in. Messy. Another way is to hack a trusted developer’s machine and alter the code there so that they commit it, but it might get spotted during code review. A third way is to become a developer, then yourself commit a seemingly innocuous patch containing an obfuscated backdoor. This is sneaky. Even better is to have somebody else intentionally commit the backdoor for you.

code

Consider this code to allocate some buffers.

void *
allocatebufs(int num)
{
    size_t limit = 256;

    if (num > limit)
        return NULL;
    return malloc(num * 64);
}

This isn’t top quality code, but it’s totally safe and secure. It does however trigger a warning about signed vs unsigned comparisons. Many developers don’t like to see those. Some will even try to fix it.

void *
allocatebufs(int num)
{
    size_t limit = 256;

    if (num > (int)limit)
        return NULL;
    return malloc(num * 64);
}

Now the warning is gone. And they’ve introduced a serious security hole.

If you’re a sneaky bastard, you might write the first code and submit it, knowing that a trusted developer somewhere down the line will alter it. And you’ve got perfectly plausible deniability. Your code was secure. They introduced the bug.

thoughts

This is just a thought experiment, and you can dissect it with the razor of your choosing, but what I think is interesting is the paradox of plausibility. What happened? The most likely explanation is the mundane one, that it’s just an accident. People introduce bugs like this with alarming regularity. No reason to suspect foul play. But it’s the dependable regularity of such errors that make the attack possible. If people didn’t introduce bugs fixing harmless warnings, the attack would never succeed.

(There was a concrete incident, somewhat similar, although this is not meant to be a comment on any particular patch or fix.)

Posted 04 Sep 2019 15:18 by tedu Updated: 04 Sep 2019 15:18
Tagged: programming thoughts

some gerc notes

gerc (good enough revision control) is a partial reimplementation of mercurial. Between got and bitbucket, it seems source control is back in the news. Here are some scattered notes about gerc and its development. It’s not complete or recommended for use, so don’t expect much.

more...

Posted 21 Aug 2019 15:50 by tedu Updated: 21 Aug 2019 15:50
Tagged: go programming project

changing defaults and removing options

Times change and programs must change with them. Altering or removing functionality however risks breaking backwards compatibility. A few examples.

more...

Posted 08 Aug 2019 18:14 by tedu Updated: 08 Aug 2019 18:53
Tagged: openbsd programming

fixing telnet fixes

There’s a FreeBSD commit to telnet. fix a couple of snprintf() buffer overflows. It’s received a bit of attention for various reasons, telnet in 2019?, etc. I thought I’d take a look. Here’s a few random observations.

Here are three new lines, after the patch.

                unsigned int buflen = strlen(hbuf) + strlen(cp2) + 1;
		cp = (char *)malloc(sizeof(char)*buflen);
		snprintf((char *)cp, buflen, "%s%s", hbuf, cp2);

1. The first line is indented with spaces while the others use tabs.

2. The correct type for string length is size_t not unsigned int.

3. sizeof(char) is always one. There’s no need to multiply by it.

4. If you do need to multiply by a size, this is an unsafe pattern. Use calloc or something similar. (OpenBSD provides reallocarray to avoid zeroing cost of calloc.)

5. Return value of malloc doesn’t need to be cast. In fact, should not be, lest you disguise a warning.

6. Return value of malloc is not checked for NULL.

7. No reason to cast cp to char * when passing to snprintf. It already is that type. And if it weren’t, what are you doing?

8. The whole operation could be simplified by using asprintf.

9. Although unlikely (probably impossible here, but more generally), adding the two source lengths together can overflow, resulting in truncation with an unchecked snprintf call. asprintf avoids this failure case.

Posted 11 Jul 2019 04:13 by tedu Updated: 11 Jul 2019 04:13
Tagged: c programming

removing array duplicates

I had an array with some duplicates. I wanted to remove them. I know how to do this, but I searched for solutions anyway to make sure I wasn’t missing some trick. The results were disappointing, very language specific, and rarely discussed run time. And if we’re working with an unsorted array, the provided answers are even worse. Just sort the array first. Well, duh; any problem with unsorted data can be transformed into a problem with sorted data by sorting first. That’s not very interesting, though, and maybe there’s a reason the data is unsorted. Here’s a few solutions I worked through, but no stunning algorithmic breakthroughs.

more...

Posted 11 Apr 2019 19:30 by tedu Updated: 11 Apr 2019 19:53
Tagged: programming

patience diffing algorithm

I needed a (text) diff algorithm, and if you search for one you mostly come up with the Myers algorithm. But then I stumbled across something called patience diffing, and it turns out to be just what I wanted. It’s already described elsewhere, but it seems more people could stand to know about it, so here we are. It’s easy to understand, and more importantly, usually makes pretty diffs (often prettier than Myers).

more...

Posted 13 Feb 2019 21:34 by tedu Updated: 20 Feb 2019 10:06
Tagged: programming

griping about go

I mostly like go, but after working with it a bit more I realize there are a few jibs of which the cut I do not like.

more...

Posted 07 Feb 2019 15:11 by tedu Updated: 07 Feb 2019 15:11
Tagged: go programming

toying with gomacro

I had some go code I wanted to quickly iterate on. Go compiles pretty quickly, but not instantly. Like 2 seconds. In some places, I can use gopher-lua, which gets me pretty close to 0 second iteration delay, but there’s a big up front development cost. It’s useful for scripting an existing program and adding custom behavior, but less useful for experimenting to see what happens when I do X. What I need is an actual interpreter for go, not an interpreter in go.

more...

Posted 19 Jan 2019 02:38 by tedu Updated: 19 Jan 2019 04:10
Tagged: go programming

xterm full reverse

Depending on whether it is day or night, I prefer a light screen or a dark screen. I would like switching between these two modes of operation to be quick and easy. Easy in this case means I am willing to run a command, but not ctrl-click on 21 different xterms.

more...

Posted 13 Dec 2018 21:14 by tedu Updated: 13 Dec 2018 21:31
Tagged: c programming x11

strict structs

Contrary to popular belief, C does have types. It even has type qualifiers. Unfortunately, the selection is somewhat limited and there are several implicit conversions that may lead to less than robust code. The good news is that with a little effort we can define our own types and enforce our own rules. I’ve forgotten where I first saw this, and don’t really have a good name for it.

more...

Posted 14 Nov 2018 15:45 by tedu Updated: 14 Nov 2018 15:45
Tagged: c programming