Wandering Thoughts archives

2014-02-26

PCI slot based device names are not necessarily stable

One of the ways that Linux tries to get stable device names these days is to base them on information about the PCI bus and slot that a particular device is located at. This naming is behind, for example, hardware-based Ethernet names (see also) and /dev/disk/by-path/ for SATA and SAS drives. The theory is that since the name describes the PCI(E) location, as long as you don't physically relocate the card the name will stay the same. This is especially useful for things on the motherboard (because you can't move them at all).

The only problem is that this is not necessarily the case. There exists PC hardware where adding, changing, or removing other hardware will change the PCI bus and slot information for your hardware without you touching it at all; this even includes hardware located on the motherboard. Really. And the shifts aren't necessarily small, either. In the case I ran into today, changing from a dual port to a single port PCIE Gigabit card and moving it one card slot to the left changed two SAS disk controllers from PCI 07:00.0 and 08:00.0 to 04:00.0 and 05:00.0. Of course this totally changed how their disks came up in /dev/disk/by-path.

(For more fun, the new single-port Ethernet became 07:00.0 when the old two ports had been 05:00.0 and 06:00.0.)

The resulting reality is that your PCI based names are only stable if you change no hardware in the system. The moment you change any hardware all bets are off for all hardware. You may get lucky and have some devices keep their current PCI names but you may well not. And I don't think you're necessarily protected against perverse things like two equivalent devices swapping names (or at least one of them winding up with what was the other's old name).

If I'm reading lspci output correctly, what is really going on is that an increasing number of things are behind PCI bridges. These things create additional PCI buses (the first two digits in the PCI device numbering), and some combination of Linux, the system BIOS, and the PCI specification doesn't have a stable assignment for these additional busses. In fact since PCI(E) cards can themselves include additional bridges, a fully stable assignment would be very hard. This is part of what happened in my case; the old dual-port PCIE gigabit card contained not just two Ethernet controllers but two bridges as well (one for each controller) and these forcibly perturbed the numbering of other PCI 'busses' (which were really individual cards behind their own bridges).

PS: This has probably been the case for some time and this is just the first occasion I've run into it. We normally configure machines identically; it just so happened this time around that the first hardware unit we got in was used in part to test the dual-port card while the final unit configuration only needs a single-port card.

linux/PCINamesNotStable written at 23:15:27; Add Comment

Saying goodbye to the PHP pokers the easy way

If you have a public web site or a web app, you almost certainly have people trying drive-by PHP exploits against you whether or not your site shows any sign of using PHP. The people (or software) behind these don't care; they seem to operate by taking one of your URLs and slapping the page name (and sometimes query parameters) of a vulnerable bit of PHP, then seeing if it works. I see requests like:

GET /~cks/space/blog/linux/images/stories/food.php?rf
POST /~cks/space/blog/linux/index.php?option=com_jce&task=plugin&plugin=imgmanager&file=imgmanager&version=1576&cid=20
POST /~cks/space/blog/linux//components/com_jnews/includes/openflashchart/php-ofc-library/ofc_upload_image.php?name=guys.php
GET /~cks/space/blog/linux//components/com_jnews/includes/openflashchart/tmp-upload-images/guys.php?rf

If you have anything other than a static site, these requests are at least annoying (in that they're forcing your code to run just to give the attacker a 'no such URL' answer). If you log potential security issues (such as odd POST content-types or the like) they can also make your logs nag at you. Recently I got irritated at these people and decided to make them go away the easy way.

The easy way here is to have your web server handle refusing the requests instead of letting them go all the way to your actual app code. Front end web servers generally have highly developed and very CPU-efficient ways of doing this (exactly how varies with the web server), plus this means your app code won't be logging any errors because it's never going to see the requests in the first place. In my case this host runs Apache and so the simplest way is a RewriteRule:

RewriteRule ^.*\.php$ - [F,L]

No fuss, no muss, no CPU consumption from my Rube Goldberg stack, and no more log messages.

(Arguably this generates the wrong HTTP error code, if you think that matters, since it generates a 403 instead of the theoretically more correct 404.)

Of course you can only do this trick if you can guarantee that you'll never use a URL ending in .php. This isn't necessarily something you can assert for a general use web program (cf), but it often is something you can say about your particular site. It's certainly something I can say about here; even though I theoretically could create a perfectly valid URL ending in .php (although it wouldn't be a PHP page), I'm never going to.

(And if I do, I can change or remove my RewriteRule.)

web/PHPPokersGoodbye written at 00:03:26; Add Comment


Page tools: See As Normal.
Search:
Login: Password:
Atom Syndication: Recent Pages, Recent Comments.

This dinky wiki is brought to you by the Insane Hackers Guild, Python sub-branch.