Search Results: "cas"

25 November 2008

Ian Wienand: Position Independent Code and x86-64 libraries

If you've ever tried to link non-position independent code into a shared library on x86-64, you should have seen a fairly cryptic error about invalid relocations and missing symbols. Hopefully this will clear it up a little! Let's start with a small program to illustrate.
$ cat function.c
int global = 100;
int function(int i)  
	return i + global;
 
$ gcc -c function.c
Firstly, inspect the disassembley of this function:
0000000000000000 <function>:
   0:	55                   	push   %rbp
   1:	48 89 e5             	mov    %rsp,%rbp
   4:	89 7d fc             	mov    %edi,-0x4(%rbp)
   7:	8b 05 00 00 00 00    	mov    0x0(%rip),%eax        # d <function+0xd>
   d:	03 45 fc             	add    -0x4(%rbp),%eax
  10:	c9                   	leaveq
  11:	c3                   	retq
Lets just go through that for clarity: The IP relative move is really the trick here. We know from the code that it has to move the value of the global variable here. The zero value is simply a place holder - the compiler currently does not determine the address (i.e. how far away from the instruction pointer the memory holding the global variable is. It leaves behind a relocation -- a note that says to the linker "you should determine the correct address of foo, and then patch this address of the code to point to that addresss (i.e. foo)." Relocations with addend The image above gives some idea of how it works. We can examine relocations with the readelf tool.
$ readelf --relocs ./function.o
Relocation section '.rela.text' at offset 0x518 contains 1 entries:
  Offset          Info           Type           Sym. Value    Sym. Name + Addend
000000000009  000800000002 R_X86_64_PC32     0000000000000000 global + fffffffffffffffc
If you try and build a shared object (dynamic library) with this function, you should get something like
$ gcc -shared function.c
/usr/bin/ld: /tmp/ccQ2ttcT.o: relocation R_X86_64_32 against  a local symbol' can not be used when making a shared object; recompile with -fPIC
/tmp/ccQ2ttcT.o: could not read symbols: Bad value
collect2: ld returned 1 exit status
Position Independent Code (PIC, enabled with -fPIC) just means that the output binary does not expect to be loaded at a particular base address, but is happy being put anywhere in memory (compare the output of readelf --segments on a binary such as /bin/ls to that of any shared library). This is obviously critical for implementing shared-libraries, where you may have many, many libraries loaded in essentially any order, and trying to pre-allocate where in memory they would all live just does not work. However, PIC has slightly wider implications than simply movable base addresses. So, back to relocations. The exact rules for different relocation types are described in the ABI for the architecture. The R_X86_64_PC32 relocation is defined as "the base of the section the symbol is within, plus the symbol value, plus the addend". The addend makes it look more tricky than it is; remember that when an instruction is executing the instruction pointer points to the next instruction to be executed. Therefore, to correctly find the data relative to the instruction pointer, we need to subtract the extra. This can be seen more clearly when layed out in a linear fashion (as in the bottom of the above diagram). What's the problem with this in a shared library? In a shared library situation, we can not depend on the local value of global actually being the one we want. Consider the following example, where we override the value of global with a LD_PRELOAD library.
$ cat function.c
int global = 100;
int function(int i)  
	return i + global;
 
$ gcc -fPIC -shared -o libfunction.so function.c
$ cat preload.c
int global = 200;
$ gcc -shared preload.c -o libpreload.so
$ cat program.c
#include <stdio.h>
int function(int i);
int main(void)  
   printf("%d\n", function(10));
 
$ gcc -L. -lfunction program.c -o program
$ LD_LIBRARY_PATH=. ./program
110
$ LD_PRELOAD=libpreload.so LD_LIBRARY_PATH=. ./program
210
If the code in libfunction.so has a fixed offset into its own data section, it will not be able to see the overridden value provided by libpreload.so. This is not the case when building a stand-alone executable, where references are satisfied internally. Of course, any problem in computer science can be solved with a layer of abstraction, and that is what is done when compiling with -fPIC. To examine this case, let's see what happens with PIC turned on.
$ gcc -fPIC -shared -c  function.c
$ objdump --disassemble ./function.o
./function.o:     file format elf64-x86-64
Disassembly of section .text:
0000000000000000 <function>:
   0:	55                   	push   %rbp
   1:	48 89 e5             	mov    %rsp,%rbp
   4:	89 7d fc             	mov    %edi,-0x4(%rbp)
   7:	48 8b 05 00 00 00 00 	mov    0x0(%rip),%rax        # e <function+0xe>
   e:	8b 00                	mov    (%rax),%eax
  10:	03 45 fc             	add    -0x4(%rbp),%eax
  13:	c9                   	leaveq
  14:	c3                   	retq
It's almost the same! We setup the frame pointer with the first two instructions as before. We push the first argument into memory in the pre-allocated "red-zone" as before. Then, however, we do an IP relative load of an address into rax. Next we de-reference this into eax (e.g. eax = *rax in C) before adding the incoming argument to it and returning.
$ readelf --relocs ./function.o
Relocation section '.rela.text' at offset 0x550 contains 1 entries:
  Offset          Info           Type           Sym. Value    Sym. Name + Addend
00000000000a  000800000009 R_X86_64_GOTPCREL 0000000000000000 global + fffffffffffffffc
The magic here is again in the relocations. Notice this time we have a P_X86_64_GOTPCREL relocation. This says "replace the data at offset 0xa with the global offset table (GOT) entry of global. Global Offset Table operation with data variables As shown above, the GOT ensures the abstraction required so symbols can be diverted as expected. Each entry is essentially a pointer to the real data (hence the extra dereference in the code above). Since the GOT is at a fixed offset from the program code, it can use an IP relative address to gain access to the table entries. This extra reference is obviously slower; however for the most part I imagine the overhead would be essentially immeasurable and is required for "generic" operation. If you have figured the cost of indirection through the GOT is the major bottleneck of your program, I imagine you wouldn't be reading this and would already be considering strategies to remove it! The next question is why this works on plain old x86-32. Inspecting the code reveals why:
$ objdump --disassemble ./function.o
00000000 <function>:
   0:	55                   	push   %ebp
   1:	89 e5                	mov    %esp,%ebp
   3:	a1 00 00 00 00       	mov    0x0,%eax
   8:	03 45 08             	add    0x8(%ebp),%eax
   b:	5d                   	pop    %ebp
   c:	c3                   	ret
$ readelf --relocs ./function.o
Relocation section '.rel.text' at offset 0x2ec contains 1 entries:
 Offset     Info    Type            Sym.Value  Sym. Name
00000004  00000701 R_386_32          00000000   global
We start out the same, with the first two instructions setting up the frame pointer. However, next we load a memory value into eax -- as we can see from the relocation information, the address of global. Next we add the incoming argument from the stack (0x8(%ebp)) to the value in this memory location; implicitly dereferencing it. This provides the abstraction we need -- if the relocation makes the patched address at 0x4 the address of the GOT entry, it will be correctly dereferenced. It is the inability of the x86-32 architecture to try and optimise by doing instruction-pointer relative offseting which means it always needs to do slower memory references, which turns out to be just what you want when you're making a shared library! So, the executive summary: the ability of x86-64 to use instruction-pointer relative offsetting to data addresses is a nice optimisation, but in a shared-library situation assumptions about the relative location of data are invalid and can not be used. In this case, access to global data (i.e. anything that might be changed around on you) must go through a layer of abstraction, namely the global offset table.

Russell Coker: SE Linux and Decrypted Data

There is currently a discussion on the Debian-security mailing list about how to protect data which came from an encrypted file. I was going to skip that one until someone summoned me by mentioning SE Linux. The issue which was raised is that data from an encrypted file can be read from /dev/mem (for all memory of the machine) or /proc/<pid>/mem (for the memory of the process). It was suggested that SE Linux can prevent such attacks, however it’s not that simple. In most SE Linux configurations there will be a domain with ultimate privileges, examples are unconfined_t for a default configuration (also known as targeted) and sysadm_t for a “strict” configuration. SE Linux differs from many security models (such as the Unix permissions model that we are familiar with) in that there is no inherent requirement for a domain with ultimate privileges. I have in the past written policy for machines in which no domain could read /dev/mem or modify the running policy. This meant that booting from installation media might be required to modify the configuration of the system - some people desire systems like this and have good reasons for doing so! As the vast majority of SE Linux users will have a “targeted” configuration, and the majority of the rest will have a “strict” configuration with minimal changes (IE sysadm_t will work as expected) there will always be a domain that can access /dev/mem (I’m not certain that sysadm_t can directly access /dev/mem on all variants of the policy - but given that it can put SE Linux in permissive mode it has ultimate access to work around that). This however doesn’t mean that SE Linux provides no benefit. A typical Linux system will have many daemons running as root, while a typical SE Linux system will have few processes running as root while also having a SE Linux context that grants ultimate privileges. The root owned processes that SE Linux constrains are generally the network facing daemons and other processes which provide a risk, while the root owned processes that are not constrained by SE Linux policy are generally processes related to early stages of the system boot and programs run as part of the system administrator’s login session - processes that are inherently trusted. Now regarding the memory of the process (and the ptrace API), in most cases a process that is likely to be accessing such a file will run in a domain that permits such access to itself. If the process in question is run from a login session (ssh login etc) then other processes in the same session will have access to the data. It is quite possible to write policy to create a new domain for the program which accesses the decrypted data and to deny the domain the ability to ptrace itself, but it will require at least 10 minutes of work (it’s not a default configuration). So while SE Linux will generally help you to improve your security no matter what your exact requirements may be, it’s not something that can be used to make such corner cases entirely disappear. In a more general sense the idea that only a single program can access certain data is almost unattainable in a typical system. Among other things to consider is the fact that the Linux kernel is one of the larger programs on a typical Linux system…

Wouter Verhelst: New hackergochi

... again. This must be my third, in about as many years. The picture from which I made it was taken by Andrew, with my camera. I kindof like it; and I think the hackergochi came out well, too. No, I'm not planning on changing my hackergochi every year, even though it's turning out to be the case. Oh well. (Speaking of hackergochi: If people on Planet Grep have a hackergochi or something similar that they'd like to get associated with their posts, please send it to me. Now, preferably :-)

24 November 2008

David Welton: Slicehost vs Linode

Since hosting is the major expense for DedaSys LLC, and obviously a critical part of much of what I do, getting the right one is very important. Naturally, "the right one" for me may not be the right one for everyone. I am a fair sysadmin for small numbers of machines, so I don't mind doing that myself - I don't need, nor want to pay for hand holding. I recently moved everything over to Slicehost on the recommendations of friends, and am so far fairly happy with the experience. It's cheaper, simpler, and more flexible than Layered Tech was. To boot, I also like the fact that Slicehost is run out of St. Louis, Missouri, rather than some really expensive tech center like San Francisco or Boston. Hosting is basically a commodity, and much like you wouldn't want to put a factory in San Francisco, you don't want your hosting their either. However, I discovered something annoying about Slicehost: they use x86_64 servers, which, per se, doesn't really matter to me - I use open source code that can run on any number of architectures. The problem is that this particular architecture uses more memory than plain old x86. Significantly more. My Layered Tech server with 1 gig of memory was hitting the swap space a bit, but the same code on a slice was swapping quite heavily, despite the fact that I'd moved PostgreSQL off to its own slice. Since I pretty much exclusively run Rails, I decided to look into Phusion's "Ruby Enterprise Edition", which is basically just some nice hacking on Ruby's garbage collection mechanism. What they've done is nice, and I may end up using it, but ultimately it's buying me space that I would also gain from simply moving back to x86. With that in mind, I decided to take another look at what appears to be emerging as one of Slicehost's main competitors, Linode, who *do* use x86 servers. Here are my results, which are admittedly not all that scientific, but what the heck - you're getting them for free, and they were pretty quick to whip up. Service, Support, Setup But before we begin with the numbers, I want to add a few words of caution. One of the big things about hosting, to me at least, is how they deal with unexpected random negative events. Connections going down, disk breakage, DoS attacks, and so on. It's really hard to get an idea of just what sort of people you're dealing with until you've "ridden the river together". I don't really know what sort of response times, uptime, and all that either Slicehost or Linode have, so there are potentially some big intangibles there that are not quite as easy to draw pretty charts for. In terms of the console/setup/management tools, I liked Slicehost's simplicity more - Linode gives you more options, but they're a bit fiddly and cluttered feeling at times. For instance, Linode lets you pick how much swap space to give your disk image, but doesn't include a bit of javascript to balance out the swap and regular partitions, so that if you type in a larger swap number, you have to do the math and subtract that from the other number. Annoying, but not a big deal. Linode lets you pick various data centers in the US (no Europe, yet). Slicehost gives you the option to do backups of your disk images, which is nice, and something that Linode lacks. Comparing plans Since I'm interested in comparing hardware and machines I actually have access to, here are the plans I am currently signed up with, and the salient numbers:
Slicehost 1024 Slicehost 512 Linode 720
Memory 1024 512 720
Bandwidth 400 200 400
Disk 40 20 24
Cost 70 38 39.95
Memory / Dollar: Bandwidth / Dollar: Disk / Dollar: Linode mostly comes out ahead, but not by that much, except for bandwidth. However, let's take a crude look at x86_64 vs x86 memory usage. First, ./script/console (a Rails console) for the same code base on two different machines, showing the virtual memory size (VSZ) and resident set size (RSS): And just to look at something else that's a bit smaller, I ran the following script:
puts File.open("/proc/self/status", "r").read
And got the following data: Being charitable with those numbers, we get x86 taking up 77% the memory that x86_64 does. So let's add that to our comparison of how much memory you're getting per dollar on Slicehost and Linode: Wow! That's a fairly significant difference. Performance That's most of what we can glean from published numbers, and running a few simple experiments. However, there's another factor that's important: performance. "Virtual Private Server" systems, or simply VPS's, got a bad name in the past because they were "overbooked" - too many virtual servers competing for the same CPU resources on one machine. Slicehost and Linode both look like they want to avoid that kind of bad reputation, and so far all the systems I have used have felt snappy and responsive. Now here's where we get really unscientific... I decided to try and do something, even if it wasn't much, to get some kind of objective measurement of what kind of CPU I was getting on the machines. This is really unscientific, because the machines do have other duties (I don't have the cash, time or inclination to set up random servers just for testing), and of course, who knows what else is sharing the computer with my systems: if you get a relatively unused computer, you can apparently pick up extra cycles for yourself, over and above your guaranteed minimum. But c'est la vie, and so I decided to do some numbers anyway. I picked a C implementation of mandelbrot from the language shootout more or less "for the hell of it" (I'm going to keep repeating "unscientific" and invite someone to do better tests than I have). I ran this code every 20 minutes for a couple days, and then averaged out the run times: As expected, the higher power Slicehost 1024 machine wins out in terms of raw speed (less time is better), but not by that much over the Linode system. Indeed, when we factor in the relative prices, Linode comes out ahead, again: So it looks like we're not paying a CPU penalty for having more memory, bandwidth, disk, etc... Notes
  • Nothing in these statistics is indicative of future directions that both Linode and Slicehost might take. Slicehost was recently acquired by Rackspace, and that could have effects on the service they provide. Maybe one or both will come under financial pressure and start "overbooking" their servers.
  • The spreadsheet I used is available via Google docs, for the curious. I did most of the work in OpenOffice, and then uploaded it though, because working with the web spreadsheet was kind of painful. Unfortunately, you can't select non-contiguous data ranges in the Google spreadsheet, so the labels are interspersed with the data. Yuck. Also, Google docs doesn't handle 'time' values nicely, which is what the performance data was originally. The spreadsheet is here: http://spreadsheets.google.com/pub?key=pVDeZF6ire2YwATBYb4mBKQ
  • The standard deviation on the processing times is higher for both slices than the linode system. Not quite sure what that means in terms of what's going on under the hood, but I thought it was interesting.

Simon McVittie: Why you shouldn't block on D-Bus calls

I've found myself writing this several times recently in the context of Telepathy, so I thought I'd make a blog post that I can refer people to. D-Bus is defined (by the wire protocol spec) to be an asynchronous message-passing system, and libdbus behaves accordingly; there are no blocking calls at the wire protocol level. However, libdbus provides a "blocking" API (dbus_do_something_and_block), via a mechanism I'll refer to as "pseudo-blocking" for the purposes of this post. Most D-Bus bindings (at least dbus-glib, dbus-python and QtDBus) expose this pseudo-blocking behaviour to library users. These pseudo-blocking calls work like this: The messages received between M and R are delivered when the main loop is next entered. This can cause a number of problems: As a result, telepathy-glib's code generation mechanism does not generate any pseudo-blocking code. There are several alternative modes of operation that we do support: We make a couple of narrowly targeted exceptions to the "no pseudo-blocking" policy in internal code, by allowing telepathy-glib internals to make a small number of pseudo-blocking method calls to the dbus-daemon (which is the one component we can definitely trust to return results promptly). Here are some examples of the same strategies in other libraries:

Wouter Verhelst: Rails? Stay the f* away from my system.

I knew for a long time that rails is somewhat fun to work with. The first time I read something about it, I went to check it out, and kindof liked the idea. Web development really isn't my cup of tea, so I didn't do anything with rails; but really, the idea made somewhat sense to me. It's unfortunate that the implementation is such a piece of crap. Luckily I don't have to deal with it firsthand, but the stories I hear and read everywhere speak for themselves. I won't enumerate them all; but in case you're not familiar with them, the Debian Ruby team has a pretty clear explanation on their website. In addition to complaints by packagers, I also hear that many ruby developers recommend that you install gems inside the project you're running (or that you ship your software in such a way that it includes those libraries as part of your source). Oh, the horror. Now, however, they've really topped it. Via Koen's blog, I found some other page that contains this:
Now, in theory, to update to the latest version of RubyGems, you just need to run

sudo gem update --system

But - depending on what version of RubyGems you have installed, running that command may lie and tell you that you have nothing to update. If you re currently on RubyGems 1.1 or 1.2, you need to run a different set of commands to update RubyGems:

sudo gem install rubygems-update
sudo update_rubygems
Seriously. This is why we have distributions, packagers, and, really, people spending a whole shitload of time making sure everything works together nicely. This is why there is Debian, RedHat, CentOS, Mandrake, SuSE, and whatever. Me touching rails? Not with a 10-foot pole. Not if you pay me a million, in any currency. Stay away from my system!

Josselin Mouette: The great return of the broomsticks

While a few developers have the chance to be paid for their job on Debian, most of us are doing it on our spare time, for fun. Yes, we are making the best operating system out there, for fun. Yet a large number of developers are taking this project way too seriously. To say it in other words, they have a carrot up the ass. I happen to prefer the French expression though, since it conveys better the rigidity of their attitude: they have a broomstick up the ass. Recently, when I launched the idea of the Bug Sprint, someone wrote to me to propose, instead of rewarding people with cookies, to send them money. This is the best example of broomstick behavior: taking the fun out of people by bringing back rampantly the very idea that almost split the project in two the last time it was introduced. The very same person, when faced with a sarcastic email sent to an announcement mailing list, immediately rushed in to send a ban request to list masters (a totally useless one, since I don t have the habit to make the same joke twice). That person happens to be the project leader. So it seems the only thing the DPL has to do, at a time when we d rather need people to fix RC bugs, is to protect the project from seditious members who don t share their love for broomsticks. When someone makes a bad-taste joke, you are not forced to laugh. But you are not forced to impose your rigid and moralist views either. And on top of that, throwing random accusations of sexism without any kind of justification does not improve the mood. This is even very close to defamation, but since I don t have a broomstick in the ass myself, I prefer to just laugh at them with the help of some fellow developers. I will go on shocking these people. And they won t like it more than in the past. Every time one of them climbs on her high horse to take a pathetic and patronizing stance while totally missing the point, it will bring a bit of fun. Bonus #1: as for the promised statistics, we are, at the time of writing, at 493 599 unique IPs who clicked on the trap. Quite a good investment for someone who d want to make money from smelly geeks. Bonus #2: here is a sexist picture.

22 November 2008

Enrico Zini: Show local configuration changes

Show local configuration changes Following a train of thought, I got to the idea that it would be nice to have a way to ask an installed package to show a diff between the configuration that it would autogenerate and the configuration that is on the system. For example:
# /var/lib/dpkg/info/postfix.postinst config-diff
--- a/aliases
    +++ b/aliases
    @@ -2,3 +2,7 @@
     postmaster:    root
     clamav: root
     logcheck: root
    +
    +root: enrico
    --- a/postfix/main.cf
    +++ b/postfix/main.cf
    @@ -25,14 +25,35 @@ smtp_tls_session_cache_database = btree:$ queue_directory /smtp_scache
     alias_database = hash:/etc/aliases
     myorigin = /etc/mailname
     mydestination = enricozini.org, localhost.localdomain, localhost
    +virtual_alias_domains = enricozini.com
    +virtual_alias_maps = hash:/etc/postfix/aliases-virtual
     relayhost = 
     mynetworks = 127.0.0.0/8
     mailbox_command = procmail -a "$EXTENSION"
     mailbox_size_limit = 0
     recipient_delimiter = +
     inet_interfaces = all
    +message_size_limit = 20480000

This would be quite useful (if you're not using a tool such as etckeeper): partly for backups, but more interestingly for inspecting a Debian box, to see what is stock configuration and what has been manually changed. Moreover, this could be used to automately create an installation CD that would install a system with the same configuration, by saving the set of debconf preseeds and the set of /etc/ patches. In theory, it would not be too difficult to generate such a diff: for packages that don't change config files in postinst, it's just a matter to diff with the original files as found in the .deb. For the other packages, the code to generate the configuration can be recycled outputting the results to a temporary directory, then a diff can be made with the corresponding files in /etc. I can see this being easily doable for 90% of the packages, and I am wondering about the rest: is it thinkable to pursue this way, assuming that what wouldn't support it today could be made to support it in the future, or are there some configuration cases that just cannot be made to work in this way, no matter what? Note

21 November 2008

Alexander Reichle-Schmehl: Dear Lazyweb,

I have several Linux systems (mostly workstations) which are in desperate need of a backup solution. However the "official" backup server runs Windows 2003. It's out of a questions to migrate that to a better system. Now I'm wondering about a good backup strategy... and am failing to find a working software. Constraints: I want' to have weekly full backups and daily incremental backups. I would like to have a central service, where I can see if some machines haven't been backed up for some time (ideally I would like to get a mail, if a machine hasn't been backed up for some time). It would be nice if I didn't need to install any special software on the systems to be backed up; but if it can't be done otherwise so be it. I have the resources to set up an additional Linux systems, but due to various circumstances the hard discs I can use in that machine are not very reliable. Therefore backups must end on the Windows system; either directly or via cifs / network share. So far I have looked at BackupPC which seems very nice, but depends on a file system supporting hard links. Which isn't the case here :( Bacula seems a bit overkill, but better to much functionality than missing functionality ;) However, Bacula needs a Database, and I wouldn't know where to set up that. As said, the local Linux system which would run the backup server might have a disc crash, therefore the database should run somewhere else. Bacula may use SQLite as database; where I could store the SQLite files on the Windows server via network share, however the Bacla Documentation doesn't recommend using SQLite on a production environment. I looked at amanda, too; but honestly I didn't understood the documentation very well :( So much for the first ideas... Any good pointers where I should go next? I know, it's a quiet unusual scenario, but there must be some kind of solution, mustn't it?

MJ Ray: Libraries, Cooperatives, OCLC and TTLLP

Thanks to Koha, TTLLP is partly a library services worker cooperative and just now there’s a massive flame-storm about the largest library services consumer cooperative - OCLC, the Online Computer Library Center - because it just updated the terms for sharing its book data collection. OCLC seems to be treating it as a private asset that it can exploit, not the common resource that many librarians thought it was. I’ve been watching this fire with interest - because, at best, I don’t think it’s helping other cooperatives that sell to libraries - and here is my summary. OCLC and the Great Library Scandal is a good introduction and there’s a summary of the Talis Podcast about OCLC WorldCat Record Use Policy with Karen Clahoun and Roy Tennant which reveals some of the OCLC thinking. Just like CC and Open Source? Still No is a great illustration of how some librarians think OCLC is reaching the wrong conclusion, which then leads to asking Is OCLC truly cooperative? and What would it look like if OCLC was broken up? A commenter on Tom Watson: Library data asks: “Why would libraries play this game?” Well, the road to hell is paved with good intentions and this road has taken 40 years. First off, OCLC is essentially a good idea - libraries cooperating to act as a counter-weight to the large library service companies. However, I believe OCLC predates many recent company rule innovations (stronger common asset locks) and data licensing innovations (Share-Alike, Fiduciary Licensing and the general free and open source software movements), so there’s nothing to stop them trying to privatise the assets (library data) that the libraries have given to OCLC and it was only a matter of time before someone tried. I’m having a similar discussion with another organisation that has been given data by its members under vague terms and is now apparently about to exploit that data for the organisation’s benefit, to the detriment of some members. TTLLP is a member but has not contributed much data because I was suspicious of the lack of terms. In time, hopefully, asset locks and more awareness of data licensing will eliminate these problems, but there’s going to be a lot more people getting burnt first. Finally, a quick shout-out to the Open Library Environment as a possible emerging alternative to OCLC for practical services. Raw Thought: Stealing Your Library: The OCLC Powergrab covers some of its motivation (and includes a link to a petition to OCLC, if you want something to sign), but I share Stefano’s (now there’s someone I’d not read in 7 or so years) analysis of some of the challenges:
“any grass-root approach that will get big enough to take on OCLC on the metadata collection and redistribution service that libraries need will have to incorporate under the pressure of its users (if only for legal liability protection) and will have to find an answer to the same set of problems (policy, governance, financial sustainability) that OCLC has.”

20 November 2008

Martin Michlmayr: Case stories of good and bad community interaction

It is often argued that companies have to work with the FOSS community and there are good reasons for doing so. I've tried to collect a number of case stories of good and bad community interaction that may help as a starting point for further exploration of this topic: Can you think of other examples? (Originally published on FOSSBazaar where comments are possible)

John Goerzen: The Demise of PC Magazine

I just read the news that PC Magazine is being canceled. It’s not exactly a shock, given the state of technical magazines right now. I haven’t read one of those in years, since they turned to be more of a consumer than a technical publication. But I hope I am not the only one out there that remembers PC Magazine from the mid to late 1980s. I had two favorite parts in each issue: the programming example, and the “Abort, Retry, Fail” page at the back of the magazine. The programming example was usually some sort of DOS (or, on occasion, OS/2) utility. It was usually written in assembly, and would be accompanied by a BASIC program you could type in to get the resulting binary, as assemblers weren’t readily available. The BASIC program was line after line of decimal numbers that would decode them and write out the resulting binary — sort of a primitive uuencode for paper. Trying to type those in gave me some serious eyestrain on more than one occasion. By now, I forget what most of those utilities did, but I remember one: BatchMan. It was a collection of tools for use in DOS batch files, and could do things like display output in color or even — yes — play monophonic music. It came with an example that displayed some lyrics about batch programming on-screen, set to what I later realized was the Batman theme. Geek nirvana, right? But Batchman was too big to publish the source code, or the BASIC decoder, in print. It might have been one of those things that eventually led me to a CompuServe account. PC Magazine had some deal with CompuServe that you could get their utilities for free, or reduced cost — I forget. CompuServe was probably where I sent my first email, from my account which was 71510,1421 — comma and all. In later years, you could pay a small fee to send email to the Internet, and I had the amazingly attractive email address of 71510.1421@cis.compuserve.com. Take that, gmail. PC Magazine eventually stopped running utilities that taught people about assembly or batch programming and shifted more to the genre of Windows screensavers. They stopped their articles about how hard disks work and what SCSI is all about, and instead have cover stories like “Vista made easy!” I am, sadly, not making this up. Gone are the days of investigating alternative operating systems like OS/2. It appears that “Abort, Retry, Fail” is gone, too. It was a one-page thing at the back of each magazine that featured braindead error messages and funny stories about people that did things like FAX an image of a floppy disk to a remote office — before such stories were cliche. Sort of like DailyWTF these days. The sad truth is that the people that would FAX an image of a floppy are probably the ones that are reading PC Magazine today. I still have a bunch of PC Magazine issues — the good ones — in my parents’ basement. I also still have my floppies with the utilities on them somewhere. One day, when I get some time — I’m estimating this will be about when Jacob goes to college — I’ll go back and take another look at them.

19 November 2008

Y Giridhar Appaji Nag: The Complete Bootleg Woodstock 69 - ID3 (ID3v2) tags

A few weeks ago, I was searching for ID3 (ID3v2) tags for The Complete Bootleg Woodstock 69 collection for a friend of mine. I was able to find them at FreeDB but: So armed with Wikipedia's help, we created better tags on our own. In case you are interested, the tags are available for download here.

Each directory has a tags.txt file (which has also been split into individual TrackXX.tags files for all the tracks). The files are 'scripting' friendly.

PS: It seems the collection converted to mp3 (at a constant 128kbps bit rate) comes to 618MB. Very nice if you want to burn it to a single CD.

18 November 2008

Kees Cook: md5 lookups for 4 chars and common words

Here’s a fun link. This site appears to have seeded their md5 hash list with all lower case character strings of 4 characters or fewer and many english words (probably from some large dictionaries), and they seem to be adding more as they go. This makes me want to put up an interface to the 7 character alpha-numeric-plus-many-special-chars rainbow table I’ve got. But searching the 500G table for a single hash takes… a while. I’d need to batch it up. Go-go-gadget web 2.0!

Uwe Hermann: Migrating bdb svn repositories from one version to another and to fsfs

Today I had to work with a really old svn repository again, which was still in the old bdb format (not in the newer and recommended fsfs one). This caused quite some problems, like, um... you cannot checkout, update, or commit anything. $ svn co file:///path/to/myrepo
svn: Unable to open an ra_local session to URL
svn: Unable to open repository 'file:///path/to/myrepo'
svn: Berkeley DB error for filesystem '/path/to/myrepo/db' while opening environment:
svn: DB_VERSION_MISMATCH: Database environment version mismatch
svn: bdb: Program version 4.6 doesn't match environment version 4.4 A quick search revealed that this is bug #342508, a solution is/was supposedly mentioned in /usr/share/doc/subversion/README.db4.3 (which does no longer exist in the Debian unstable package). Luckily this blogpost has some details. So, the short HOWTO for upgrading an svn repository of one Berkeley DB version to another one is: $ cd /path/to/myrepo/db
$ db4.4_checkpoint -1
$ db4.4_recover
$ db4.4_archive
$ svnlook youngest ..
$ db4.6_archive -d In this case I upgraded from 4.4 to 4.6 (do "apt-get install db4.4-util db4.6-util" if necessary). While I was at it, I also switched the repository to the fsfs format then: $ svnadmin dump /path/to/myrepo > myrepo.dump
$ mv /path/to/myrepo /path/to/myrepo.bak
$ svnadmin create --fs-type fsfs /path/to/myrepo
$ svnadmin load /path/to/myrepo < myrepo.dump Maybe this is helpful for some other people out there.

Matthew Garrett: Aggressive graphics power management

My current desktop PC has an RS790-based Radeon on-board graphics controller. It also has a Radeon X1900 plugged in. Playing with my Watts Up, I found that the system was (at idle!) drawing around 35W more power with the X1900 than with the on-board graphics.

This is clearly less than ideal.

Recent Radeons all support dynamic clock gating, a technology where the clocks to various bits of the chip are turned off when not in use. Unfortunately it seems that this is generally already enabled by the BIOS on most hardware, so playing with that didn't give me any power savings. Next I looked at Powerplay, the AMD technology for reducing clocks and voltages. It turns out that my desktop hardware doesn't provide any Powerplay tables, so no joy there either. What next?

Radeons all carry a ROM containing a bunch of tables and scripts written in a straightforward bytecode language called Atom. The idea is that OS-specific drivers can call the Atom tables to perform tasks that are hardware dependent, even without knowledge of the specific low-level nature of the hardware they're driving. You can use Atom to do several things, from card initialisation through mode setting to (crucially) setting the clock frequencies. Jerome Glisse wrote a small utility called Atomtools that lets you execute Atom scripts and set the core and RAM frequencies. Playing with this showed that it was possible to save the best part of 5W by underclocking the graphics core, and about the same again by reducing the memory clock. A total saving of 9-10W was pretty significant.

The main problem with reducing the memory clock was that doing it while the screen is being scanned out results in memory corruption, showing up as big ugly graphical artifacts on the screen. I'm a fan of doing power management as aggressively as possible, which means reclocking the memory whenever the system is idle. Turning the screen off to reclock the memory would avoid the graphical corruption but introduce irritating flicker, so that wasn't really an option. The next plan was to synchronise the memory reclocking to the vertical refresh interval, the period of time between the bottom of a frame and the top of the next frame being drawn. Unfortunately setting the memory frequency took somewhere between 2 and 20 milliseconds, far too long to finish inside that time period.

So. Just using Atom was clearly not going to be possible. The next step was to try writing the registers directly. Looking at the R500 register documentation showed that the MPLL_FUNC_CNTL register contained the PLL dividers for the memory clock. Simply smacking a new value in here would allow changing the frequency of the memory clock with a single register write. It even worked. Almost. I could change the frequency within small ranges, but going any further resulted in increasingly severe graphical corruption. Unlike the sort I got with the Atom approach to changing the frequency, this corruption manifested itself as a range of effects from shimmering on the screen down to blocks of image gradually disappearing in an impressively trippy (though somewhat disturbing) way.

Next step was to perform a register dump before and after changing the frequencies via Atom, and compare them to the registers I was programming. MC_ARB_RATIO_CLK_SEQ was consistently different, which is where things got interesting. The AMD docs helpfully describe this register as "Magic field, please use the excel programming guide. Sets the hclk/sclk ratio in the arbiter", about as helpful as being told that the register contents are defined by careful examination of a series of butterflies kept somewhere in Taiwan. Now what?

Back to Atomtools. Enabling debugging let me watch a dump of the Atom script as it ran. The relevant part of the dump is here. The most significant point was:
MOVE_REG @ 0xBC09
src: ID[0x0000+B39E].[31:0] -> 0xFF7FFF7F
dst: REG[0xFE16].[31:0] <- 0xFF7FFF7F
, showing that the value in question was being read out of a table in the video BIOS (ID[0x0000+B39E] indicating the base of the ROM plus 0xB39E). Looking further back showed that WS[0x40] contained a number that was used as an index into the table. Grepping the header files gave 0x40 as ATOM_WS_QUOTIENT, containing the quotient of a division operation immediately beforehand. Working back from there showed that the value was derived from a formula involving the divider frequencies of the memory PLL and the source PLL. Reimplementing that was trivial, and now I could program the same register values. Hurrah!

It didn't work, of course. These things never do. It looked like modifying this value didn't actually do anything unless the memory controller was reinitialised. Looking through the Atom dump showed that this was achieved by calling the MemoryDeviceInit script. Reimplementing this from scratch was one option, but it had a bunch of branches and frankly I'm lazy and that's why I work on this Linux stuff rather than getting a proper job. This particular script was fast, so there was no real reason to do it by hand instead of just using the interpreter. Timing showed that doing so could easily be done within the vblank interval. This time, it even worked.

I've done a proof of concept that involved wedging this into the Radeon DRM code with extreme prejudice, but it needs some rework. However, it demonstrates that it's possible to downclock the memory whenever the screen is idle without there being any observable screen flicker. Combine that with GPU downclocking and we can save about 10W without any noticable degradation in performance or output. Victory!

I gave the code to someone with an X1300 and it promptly corrupted their screen and locked their machine up. Oh well. Turns out that they have a different memory controller or some such madness.

So, obviously, there's more work to be done on this. I've put some test code here. It's a small program that should be run as root. It should reprogram an Atom-based discrete graphics card[1] to half its memory clock. Running it again will halve it again. I don't recommend doing that. You'll need to reboot to get the full clock back. This isn't vblank synced, so it may introduce some graphical corruption. If the corruption is static (ie, isn't moving or flickering) then that's fine. If it's moving then I (and/or the docs) suck and there's still work to be done. If your machine hangs then I'm interested in knowing what hardware you have and may have some further debugging code to be run. Unless you have an X1300, in which case it's known to break and what were you thinking running this code you crazy mad fool.

Once this is stable it shouldn't take long to integrate it into the DRM and X layers. I'm also trying to get hold of some mobile AMD hardware to test what impact we can have on laptops.

[1] Shockingly enough, it's somewhat harder to underclock graphics memory on a shared memory system

MJ Ray: How to Check Web Shops for Basic Security

I just had a very nice chat on the phone with a man whose first attempt at online shopping seemed to have resulted in a fraudster using his card to buy mobile phone top-ups. I don’t understand why he called us (it wasn’t one of my web shops), but I hope I did the right thing by directing him back to his credit card company’s fraud department. While I was talking to him, I was checking the shop he had problems with. I wouldn’t have bought from it. Here’s how I checked it:- 1. Check the Page Open the front page of the site in one browser window and then use another window to get to a page that ought to be secure (the payment/checkout page is my usual one). Look at them both. Do either of them show any logos from well-known payment (Barclays, RBS, Protx, …) or security-checking services (thawte - who else?)? That’s not entirely reliable, but it’s usually a good sign because those companies attack people using their marks without permission. Look at the payment/checkout page - does the address in the address bar start “https”? If so, is the padlock in the browser status bar (usually bottom right) closed? That usually means it’s encrypted with a Secure Sockets Layer (SSL) certificate. 2. Check the Certificate Open the certificate details. In Firefox-based browsers, double-click the padlock, then click the “View Certificate” button. Then pick “Subject” in the second list box. Usually, it looks like this:-
screenshot

Basic Certificate Screenshot


in that case, as long as the “CN” (common name) is the webserver you thought you were using and the “O” (organisation) and country code (C) make sense, then there’s nothing wrong. Some shops now use Extended Validation certificates and give a bit more information. Here’s one from a train company:-
screenshot

Extended Validation Screenshot


In addition to the CN and O, it shows Organisational Unit (OU), Location (L), State (ST) and also other address parts and company number that Firefox doesn’t display neatly. This is a bit more reassuring, but also a lot more expensive for the shop owner (around 20 times more, last I checked), so I don’t blame shops for not using them. 3. Check the Registrations By this point, the payment processing and actual transaction are looking pretty good. Finally, I check the recipient. Find the business details on the web shop. Does it include a geographic address? If it contains a company registration number, look it up on the Companies House website. Then I find the business details on the domain names - you can use CoolWhois to look up domain names. If any of the addresses or numbers don’t match (Website, SSL Certificate, Whois), then I call them to ask why their website says they’re based in Bristol but their domain name is registered to Bolton. If they don’t answer messages, or - worse - the domain name says “Non-trading Individual” and the address has been omitted from the public listing, I give up on them and look for another shop. There’s no point securely paying someone that you can never reach if there’s a problem. 4. Buy Stuff and Check the Statements All being well, I then buy stuff and check my credit card statement each month before I pay it. I think any web shop owner (or webmaster - I help some people with this sort of thing) should be taking care of the basics above. Do your shops measure up? Despite the above checks, I can only remember not buying something online once in the last year. A couple of times, I’ve worked through the above steps and it’s changed which shop I bought from - and I’m pretty sure it saved me from losing 400 on one purchase.

Matthew Palmer: Dependency Resolution Failure

So, the yum package manager (and, I assume, RPM underlying that) has a fairly neat (to my naive eyes, anyway) implementation of multiarch support -- on an amd64 system you can install i386 packages, and they go into a separate lib tree, and there's no conflicts or unhappiness. It even installs both the i386 and x86_64 versions of libraries automatically when you ask for them, which is a nice touch. However, the dependency resolver doesn't quite seem to have gotten the hang of some of the corner cases. For instance, if you want to install a noarch package that depends on an architecture-specific package, but for some reason only the i386 version is available (say, your local package repo hasn't quite built the x86_64 version yet) then yum will happily install the i386 version and say "OK, dependency resolved". Nice try, but no cigar. What makes it a bit more irritating is that once you work this out and the x86_64 package is available, you need to remove the i386 version of the package by hand in order for it to pick up the x86_64 package and install it. Just asking yum "hey, can you install this package" results in "nope, it's already installed, go away".

17 November 2008

Lucas Nussbaum: -vote@ discussions on DFSG violations

There have been 470 mails during the last month in the DFSG violations threads on -vote@, but only 10 posters have contributed more than 10 mails so far:
85 Robert Millan
51 Manoj Srivastava
18 Pierre Habouzit
18 Josselin Mouette
16 Thomas Bushnell BSG
14 Stephen Gran
13 Frans Pop
13 Ean Schuessler
13 Adeodato Simo
12 Russ Allbery
Is someone working on a summary of the discussions? I would really hate it if we were asked to vote on this, with a “for details, see the -vote@ archives” footnote. (Robert Millan sounds like a perfect candidate for this task :-) )

16 November 2008

Bdale Garbee: Level 3!

I wrote last month about my failed first attempt to achieve a "level 3" high power rocketry certification. Last week, I learned that one of the commercial altimeters I flew for control of the ejection sequence has a firmware bug, which can cause premature ejection of the main parachute on flights above 10k feet! So it may in fact be the case that everything I did was perfect and I was simply the victim of a bug in software... how ironic! Yesterday, on my second certification attempt, I was successful! The rocket I flew this time was based on a Polecat Aerospace ten inch Goblin kit. I incorporated several modifications in my build, including additional fiberglass and carbon fiber reinforcement, and a payload bay in the nose cone. Once again, my wife Karen graced me with a parachute sewn from the Team Vatsaas design, this time a slightly larger one in burgundy and black rip-stop nylon. She incorporated several design tweaks based on her experiences sewing the first one which we'll try to write up at some point, that allowed her to sew this one in less time. The motor selected was again an Aerotech M1297W reload. The launch went perfectly, and the ascent was impressive. At apogee, the nose cone separated as planned and the drogue parachute deployed. Unfortunately, when the backup charge fired two seconds later, the main parachute also deployed. That wasn't intended... the main was supposed to deploy much lower, at 1300 feet. Luckily, the winds were light enough that the rocket touched down only about a mile downrange from the launch rail, well within the waiver distance, and was easily recovered without damage. There are three things I'll consider changing before flying this rocket again. First, the chute size calculator used to design the main parachute seems way off. The actual descent rate was around 32 feet per second, while our goal was 20. Other than that, the parachute performed admirably! Second, the premature deployment of the main at apogee could be cured by replacing the paper taped over that parachute bay with another piston capping the bay and held in with a pair of shear pins. Finally, the hard touch down snapped some of the nylon wire ties holding the batteries in place in the avionics bay. While no damage was done, and reducing the descent rate might prevent it happening again, improving the battery mounting would be an easy upgrade. For more information, see my project page for this rocket. James Russell took some pictures at the launch, including a great one of the rocket under boost just leaving the launch rail. And Jeff Lane captured video of the ascent and descent. It was a great flight and a great day, and represents a major milestone in our hobby rocket activities!

Next.

Previous.