Alt om ingenting og litt i mellom En blogg av Knut-Olav

Gjenopprett filer med TestDisk

15. oktober 2009 · Én kommentar

En kollega på jobben hadde filmet noen korte videoklipp og disse var lagret på et Compact Flash-kort. Dessverre fikk hun bare “read error”-meldinger da hun prøvde å hente ut videoklippene, både på sin laptop og direkte fra kameraet.

Illustrasjonsfoto: Canon Compact Flash Card av Simon Clayson, Creative Commons

Jeg ga Linux-maskinen min et forsøk. Ved første øyekast så det mørkt ut og jeg fikk mange stygge feilmeldinger i dmesg-loggen. “fdisk -l” viste meg ingen partisjoner på minnekortet.

Jeg prøvde å ta ut og sette inn kortet igjen, bare for å sjekke en gang til. Denne gangen gikk det mye bedre.

Først tok jeg en kopi av minnekortet til en fil med verktøyet dd. Dette er viktig å gjøre hvis man har med ustabilt medium å gjøre for å ikke slite unødvendig på minnekortet eller risikere å slette noe.


$ sudo dd if=/dev/sdb of=/tmp/sdb.dd

Deretter lastet jeg ned programmet TestDisk fra CGSecurity. Dette er et gjenopprettingsverktøy som jeg ikke har brukt tidligere. Det dukket opp i flere søkeresultater på Google, så jeg ga det en sjanse. Og jeg kommer garantert til å bruke det ved liknende anledninger senere.

Jeg startet testdisk med “/list”-opsjonen mot kopien jeg lagde av minnekortet, for å se om verktøyet fant noe nyttig om disken.


$ sudo testdisk /list sdb.dd
TestDisk 6.10, Data Recovery Utility, July 2008
Christophe GRENIER 

http://www.cgsecurity.org

Please wait...
Disk sdb.dd - 256 MB / 245 MiB - CHS 32 255 63, sector size=512

Disk sdb.dd - 256 MB / 245 MiB - CHS 32 255 63
    Partition                  Start        End    Size in sectors

Partition sector doesn't have the endmark 0xAA55

Dette lovet ikke bra. Jeg forsøkte så å starte opp testdisk uten list-opsjonen og ble så presentert med en meny for å velge disk søke etter partisjoner, samt noen valg.

Jeg forsøkte flere av valgene, blant annet at disken var opprettet på et i386-system, men da fant den ingen partisjoner. Siden dette minnekortet har stått i et kompaktkamera var det sikkert ikke opprettet noen partisjoner på kortet, så jeg forsøkte det valget i stedet.

Det viste seg at det ikke var noen partisjoner på kortet. Filsystemet, som var vfat, var skrevet rett på minnekortet. Programmet viste meg en filbrowser og jeg kunne navigere rundt og kopiere ut filer.

Det ga meg også mulighet til å kopiere ut filer som tidligere hadde vært slettet. Jeg forsøkte å hente ut to bilder, for å teste dette. Det ene bildet var korrupt, trolig skrevet over etter at det var slettet, mens det andre bildet kunne vises uten problemer.

Må si at dette verktøyet var en stor suksess!

MySQL på nye fremmednøkkeleventyr

13. oktober 2009 · Comments Off

Ikke så lenge siden skrev jeg om MySQL sine problemer med datatyper og NULL-konstraints. Og problemene stopper ikke der.

Jeg kom i dag over en merkelig og helt uforståelig bug i MySQL. Eller, det heter vel kanskje feature når det gjelder MySQL.

Ta følgende scenario: En kolonne “disabled_reason_ref” i tabellen “countries” refererer til feltet “uuid” i tabellen “texts”. Kolonnen “disabled_reason_ref” er definert med mindre størrelse enn feltet den refererer til. Dette visste jeg ikke om. Begge tabellene bruker InnoDB og det er satt opp fremmednøkler. Hvordan dette gir noe som helst mening i MySQL-verden vet jeg ikke.

Ihvertfall. Det hele startet med denne SQL INSERT-spørringen.


mysql> INSERT INTO countries (uuid, country_code, disabled, disabled_reason_ref, page_ref) VALUES ("a63d5a26-9719-47dd-9617-c07bd8126061", "NO", 1, "e80c8d7c-dd84-4a4f-8df4-778efe9b311a", NULL);
ERROR 1452 (23000): Cannot add or update a child row: a foreign key constraint fails (`utenlandsbolig/countries`, CONSTRAINT `countries_ibfk_2` FOREIGN KEY (`disabled_reason_ref`) REFERENCES `texts` (`uuid`))

Det er ingenting i feilmeldingen fra denne spørringen som sier noe om det.

Jeg lurte litt på om kolonnenavnet var for langt, så jeg lagde en ny kolonne som heter “reason_ref”.


mysql> alter table countries add column  reason_ref VARCHAR(32)  REFERENCES texts(uuid);
Query OK, 1 row affected (0.52 sec)
Records: 1  Duplicates: 0  Warnings: 0

MySQL satte riktignok ikke opp noen fremmednøkkel her, noe jeg sjekket med “SHOW CREATE TABLE countries”.
Lurer da fælt på hva den i så fall referer til…
Vel, MySQL er MySQL.

Jeg tenkte så at jeg ikke trengte “disabled_reason_ref” lenger.


mysql> alter table countries drop column disabled_reason_ref;
ERROR 1025 (HY000): Error on rename of './utenlandsbolig/#sql-4fa3_6' to './utenlandsbolig/countries' (errno: 150)

Hva i alle dager betyr dette?
Jeg kom meg ikke rundt feilen, så jeg lot kolonnen bare ligge.

Jeg hadde på dette tidspunktet ikke oppdaget at “reason_ref” var for liten. Kolonnen den refererer til er nemlig av type VARCHAR(36).

Et nytt forsøk på INSERT, nå ved å bruke den nye kolonnen.


mysql> INSERT INTO countries (uuid, country_code, disabled, reason_ref, page_ref) VALUES ("a63d5a26-9719-47dd-9617-c07bd8126061", "NO", 1, "e80c8d7c-dd84-4a4f-8df4-778efe9b311a", NULL);
Query OK, 1 row affected, 1 warning (0.19 sec)

mysql> show warnings;
+---------+------+-------------------------------------------------+
| Level   | Code | Message                                         |
+---------+------+-------------------------------------------------+
| Warning | 1265 | Data truncated for column 'reason_ref' at row 1 |
+---------+------+-------------------------------------------------+
1 row in set (0.00 sec)

Og det viste seg at kolonnen var for liten. Dermed fant den ingen rad i “texts”-tabellen som hadde den refererte verdien på 32 tegn, da verdien egentlig skulle vært på 36 tegn.


mysql> alter table countries modify column disabled_reason_ref varchar(36);
Query OK, 2 rows affected (0.40 sec)
Records: 2  Duplicates: 0  Warnings: 0

Greit at det var jeg som gjorde feilen med å deklarere kolonnen for liten.
Men hallooo, litt hjelp kan man vel få fra en database? Spesielt fra en relasjonsdatabase!

Dumme MySQL!

MySQL – mangel på integritet

3. oktober 2009 · Én kommentar

MySQL gjør mye rart. Her har vi en ganske normal tabell, med kolonner som krever en verdi og med kolonner av forskjellige datatyper. Fire av kolonnene i tabellen kan ta default verdier, resten kan det ikke.


mysql> DESC user_status;
+-------------------+--------------+------+-----+---------+-------+
| Field             | Type         | Null | Key | Default | Extra |
+-------------------+--------------+------+-----+---------+-------+
| uid               | int(10)      | NO   | PRI | NULL    |       |
| verified          | tinyint(1)   | NO   |     | 0       |       |
| registered_nick   | tinyint(1)   | NO   |     | 0       |       |
| first_time        | tinyint(1)   | NO   |     | 1       |       |
| registration_date | datetime     | NO   |     | NULL    |       |
| verification_code | int(10)      | NO   |     | NULL    |       |
| nick              | varchar(32)  | NO   |     | NULL    |       |
| active            | tinyint(1)   | NO   |     | 1       |       |
| ban_reason        | varchar(255) | NO   |     | NULL    |       |
| logincount        | int(11)      | NO   |     | NULL    |       |
| lastlogin         | datetime     | NO   |     | NULL    |       |
+-------------------+--------------+------+-----+---------+-------+

Så legger vi inn en rad i tabellen. Legg merke til at vi bare legger inn data i noen av kolonnene.


INSERT INTO user_status(
  uid, verified, registration_date,
  verification_code, nick)
VALUES(1, 1, NOW(), "asd", "ut");

Så får jeg en suksessmelding tilbake fra MySQL, jippi. Eller vent, det står noe om at det er generert tre advarsler. Ok tenker jeg, så jeg får vel finne ut hva disse advarslene er.


mysql> SHOW WARNINGS;
+---------+------+------------------------------------------------------------------------+
| Level   | Code | Message                                                                |
+---------+------+------------------------------------------------------------------------+
| Warning | 1364 | Field 'ban_reason' doesn't have a default value                        |
| Warning | 1364 | Field 'logincount' doesn't have a default value                        |
| Warning | 1364 | Field 'lastlogin' doesn't have a default value                         |
| Warning | 1366 | Incorrect integer value: 'asd' for column 'verification_code' at row 1 |
+---------+------+------------------------------------------------------------------------+

Det at MySQL gir blaffen i påkrevde kolonner visste jeg egentlig, og jeg blir sinna hver gang jeg tenker på det. Så egentlig var de første advarslene godt kjente for meg.

Det som virkelig overrasket meg var,

Hva?! Tillater MySQL meg å opprette en rad i en tabell med noe data i en kollonne med en annen datatype?

MySQL tillater meg faktisk å sende inn tekststrengen “asd” inn kolonnen “verification_code” som er deklarert som et heltall. Hva i alle dager? Hvilken verdi har MySQL satt inn i tabellen min da? Dette må undersøkes.


mysql> SELECT * FROM user_status;
+-----+----------+-----------------+------------+---------------------+-------------------+------+--------+------------+------------+---------------------+
| uid | verified | registered_nick | first_time | registration_date   | verification_code | nick | active | ban_reason | logincount | lastlogin           |
+-----+----------+-----------------+------------+---------------------+-------------------+------+--------+------------+------------+---------------------+
|   1 |        1 |               0 |          1 | 2009-09-29 17:08:57 |                 0 | ut   |      1 |            |          0 | 0000-00-00 00:00:00 |
+-----+----------+-----------------+------------+---------------------+-------------------+------+--------+------------+------------+---------------------+

Den satte inn tallet “0″ i verification_code-kolonnen. Hvordan MySQL fant ut at det var en smart idé vet jeg ikke. Kolonnen er av type heltall, den krever en verdi og er deklarert uten noen default verdi. Jeg sender inn tekststrengen “asd”.

I et scriptspråk som PHP eller Perl evalueres denne strengen til en bolsk sann verdi. Så kanskje kunne heltallsrepresentasjonen av strengen vært “1″. Derimot er det ikke sikkert at kolonnen representerer en bolsk verdi, for da ville jeg vel brukt en datatype som bit eller bool, ikke sant? Det eneste fornuftige å gjøre er faktisk å ikke tillate verdien og forhindre meg i å opprette raden.

Det jeg stusser litt på, og blir lei meg over, er den manglende forståelsen av integritet i MySQL. Hvis jeg forsøker å opprette en rad i en tabell uten å sende inn alle påkrevde felt, så burde jeg ikke få lov til å opprette raden. Så enkelt kan det gjøres.

MySQL må ikke tro at den er smartere enn meg.

Could not dupe: Bad file descriptor

8. september 2009 · 2 Kommentarer

Ok, so I have been debugging a Perl application that I wrote about six months ago. Basically it creates some meta data and copies files to other user accounts using SSH.

For file transfer it uses File::RsyncP and for remote control it uses Net::SSH::Perl. Some times I get the error message Could not dupe: Bad file descriptor. Not a very informative error message, but I had an idea that it might have something to do with the file transfer. After I restart the application, running as a FastCGI web application, everything works, for a short while, then it breaks again.

I found out that it stops working right after I end my SSH connection, after debugging and restarting the application. After some research I found out it had something to do with the loss of STDIN. My best guess is that SSH needs STDIN to be able to read the password entered by the user, but I use keys for authentication, so I won’t need STDIN at all for interacting with SSH.

I tried different tactics to keep STDIN open. Running it using nohup did not help. Then I tried starting up the web application using screen, and now it still runs several hours after logging out from the server.

I don’t like this workaround very much. So if anyone has a better solution to this problem, I would love to hear about it.

A possible solution might be to redirect STDIN to a temporary file. Anyone had success doing this with Net::SSH::Perl or File::RsyncP?

How to not tell about a security breach?

7. september 2009 · Én kommentar

WordPress is breached, again. I guess I run an unsecure version of WordPress, but I’m not sure. All I am told is that i don’t runt he latest version of WordPress and that I should upgrade, because upgrading is easy.

No, it’s not easy. I keep history of my webpage in Subversion, so every time I need to upgrade WordPress I need to add the new version into Subversion in the vendor branch, merge in the changes in a WordPress current branch and then merge the changes into trunk of my web page. Why I do this, you say? No software is perfect, WordPress is far from it, so I need to alter some core code from time to time. That’s why.

Ok, back to the topic. Matt Mullenweg does not tell me in his blog post (link above) anything about what versions of WordPress that are potential targets for this Internet worm that exploits this security breach, nor what part of the code that makes it possible, not even how to patch it up. The entire blog post is just explaining that security holes do happen and some theory about how to protect yourself from it. Nothing concrete. Not very useful.

Føler meg nummenummen i munnen

27. august 2009 · Comments Off

Jeg føler meg nummenummen i munnen. Var hos tannlegen i dag, og han røska ut to visdomstenner. Måtte ha en ekstra sprøyte på den ene siden. Artig.

Det viste seg faktisk at jeg hadde fem av dem… faktisk. Jeg har to visdomstenner tett-i-tett i overkjeven. Nå har jeg to færre da, ble tre igjen. De to nede er borte vekk.

Så nå føler jeg meg litt dummere her jeg sitter med to visdomstenner mindre – med blodig kjeft, tørre lepper, numme kinn, numm tunge og biter på litt bomul.

Funky med ømme kinn. Merkelig å ta på dem. Gleder meg om en time eller to, når bedøvelsen avtar…

Noen minner fra Notodden Bluesfestival

10. august 2009 · Comments Off

Jeg var på Notodden Bluesfestival lørdag 1. august i år. Vi var på bygga og hørte på Beth Hart. Dessverre gikk jeg glipp av Buddy Guy, og jeg angrer ennå på at jeg gikk for å spise akkurat da. Men gjort er gjort og spist er spist, ironisk nok.

Jeg tok ikke så mange bilder, men et par ble bra. Det første bildet er av Beth Hart, en noe merkelig dame, men flink som bare det. Det andre bildet er av et ungdomsband fra musikkskolen som stod i hovedgata og spilte. Det var flere ungdomsband der, men disse stoppet jeg og hørte litt på. God musikk spilte de.

Enda en tur til steinbruddet

6. august 2009 · Comments Off

Helt utrolig, men jeg tok med bikkja på nok en tur opp til steinbruddet i dag også. Endelig har feriefølelsen kommet til meg.

Tok noen bilder i dag og, et par av en åpning i skogen, og så klart noen av bikkja mi Rex. De to siste bildene er tatt etter vi kom tilbake til hytta. Jeg tror Rex ble enda mer sliten enn meg.

På tur til steinbruddet

6. august 2009 · Comments Off

I dag, onsdag, skinte endelig sola. Det er ferie, og jeg tok på meg shorts, joggesko, tok bikkja i bånd og la på vei. Vi gikk en liten tur, opp i skogen og opp til toppen av steinbruddet som ligger ved Bekkestranda i Sande.

Jeg tok noen bilder da jeg var på toppen. Her er det god utsikt over Sandebukta. Ganske flott natur, selv etter at næringsvirksomheten har gjort sitt med med naturen, med å grave ut fjellet. Det er kanskje derfor det er så pent der oppe. Tok også et bilde av Rex, bikkja mi, etter vi var kommet tilbake til hytta.