Neil Williams: Maintaining packages in an unfamiliar language
First of all, congratulations Steve!Debian Project Leader Election 2008 Results
The winner of the election is Steve McIntyre.
Security and languages
Meanwhile, Steve Kemp confirms my preference (prejudice?) that Debian maintainers and sponsors must have an understanding of the language used for their packages. (I do not maintain or sponsor KDE, Python or Mono packages for this reason - my C++ knowledge is too patchy to do more than a few queries of the apt C++ interface and I wouldn't understand a single line of python or mono source code.)
Andrew Pollock thinks that all C bugs are upstream bugs.
"Any bug in the software packaged is inherently an upstream bug, and the problem of the upstream author" - noting that he also has a good relationship with upstream and feels competent to apply and refit patches. I must say, I feel that this not something I could consider doing myself or recommending to anyone as sponsor.
Steve Kemp is naturally taking the security point of view and I fully agree that understanding the infamous Smashing The Stack For Fun And Profit (the code itself may need a few updates to work but it still explains the issues) is part of the job of any maintainer or sponsor handling a package that contains a setuid or setgid binary.
I'm upstream for some of my Debian packages and one, in particular, has known issues with static buffers which I inherited from the old upstream. Most of those have been removed but some are embedded a little too deeply into the codebase and it will take time to remove them all. (The ones I know about are tagged in the doxygen output of the source code.) My other programs use GLib dynamic string allocation / parsing instead of calling
strcpy and friends directly.I don't think it is fair or reasonable to maintain a package in a state that would require a new upstream release to fix a critical security bug. Equally, not being able to fix such a bug by creating the patch yourself (e.g. when upstream is not contactable) is also, IMHO, sub-optimal. (The security team are busy enough as it is without being required to write the patches as well.) As I've found with one of my own upstream packages, removing or protecting static buffers is not necessarily trivial and just extending the buffer is usually insufficient. Poor code design or code that is simply very old and stale can be hard to update. (Removing one static buffer required a patch/RCS commit changing some 300 lines in 6 source files during the development of one of my packages.) Changing the buffer behaviour can also cause mysterious bugs elsewhere - in the case of the package referred to above, inability to read or write its own data files and likely corruption of existing files. Thankfully, that application is never going to be one that needs setuid or setgid and is already in a much better state than it was in the Etch release so I'm working on fixing the other buffer issues but without the urgency that would otherwise be necessary.
I'm still learning about improving the security implications of my own code - I would certainly not be happy maintaining a package that uses a root process or a daemon that was written in a language that I simply don't understand, no matter how good my relationship with upstream. IMHO, the problem with security bugs is that the person writing the patch often has to understand the language and the package at a fairly deep level if the fix is not to cause bugs elsewhere in the application. Fixing a static buffer by breaking the application isn't good but then neither is leaving a Debian security bug open whilst waiting for upstream to create a suitable patch for your own Debian package. The problem gets worse if the security bug is architecture-specific or the fix causes bugs that only appear on certain architectures. There are some things that matter in Debian that simply do not matter as much upstream - if a security bug lands in that gap, the Debian maintainer must be able to solve the problem in Debian - at least, that is how I see it.



It's been a long time since I've written on my blog; longer than I'd like. I really want to get back in the swing of it, if only to keep this entire site from bitrotting interminably. My
So here's the hard part, if you start writing about people and relationships you have to continue, otherwise people who do follow will make assumptions, or not be aware of any potential gaffes they are about to make.
I've written in the past about some stuff which I now wish I hadn't because this post is suprisngly hard to compose.
The lenny l10n NMU campaign is now running for about two months now.
The objectives of this campaign are tackling
As
One of the loveliest things about Unix is the select() function (or
its replacement, poll()), and the way it lets a single thread handle a
host of concurrent tasks efficiently by just using file descriptors as
work queues.
Unfortunately, it can be a nuisance to use – you end up having to
structure your program as a state machine around the select() invocation,
rather than the actual procedure you want to have happen. You can avoid that
by not using select() and instead just having a separate thread/process for
every task you want to do – but that creates a bunch of tedious overhead
for the OS (and admin) to worry about.
But magically making state machines is what Python’s generators are
all about; so for my little pet project that involves forking a bunch
of subprocesses to do the interesting computational work my python program
wants done, I thought I’d see if I could use that to make my code more
obvious.
What I want to achieve is to have a bunch of subprocesses accepting
some setup data, then a bunch of two byte ids, terminated by two bytes
of 0xFF, and for each of the two byte inputs to output a line of text
giving the calculation result. For the time being at least, I want the
IO to be asynchronous: so I’ll give it as many inputs as I can, rather
than waiting for the result before sending the next input.
So basically, I want to write something like:
I do very little law-firm-life blogging here, although that life is where I spend the overwhelming majority of my time. Consider
I'm currently looking for a printer. I want a Laser printer,
black & white should be enough, but color may be ok too if not
too expensive (especially toner). I guess I prefer a network one,
even if I don't really understand the way everything should
work.
As I understand it, a network printer just listens on a defined
port (9100/jetdirect or ipp/63), and prints jobs sent by a spooler.
There is no integrated spooler, so there are two solutions: