mercoledì 30 marzo 2011

La sicurezza è paranoia (?)

Premetto che non sono un esperto di sicurezza informatica, pur tentando di tenermi aggiornato sull'argomento. Qualche giorno fa ho partecipato ad un interessante corso sulla sicurezza informatica dove, fra le altre cose, si e' parlato di buffer overflow. Il buffer overflow e' una tecnica vecchia ma ancora molto in voga di compromissione: in breve si tratta di iniettare nello stack di una applicazione una quantita' di dati opportuna in modo da sovrascrivere l'indirizzo di ritorno dello stack per farlo puntare a del codice malevolo. E qui le opinioni si dividono: di chi e' colpa per questo atteggiamento? Sicuramente del programmatore che ha lasciato una potenziale falla nello stack (mancanza di controllo sul limite dei dati) ma, secondo me, anche e soprattuto del sistema operativo.
Con questo post intendo spiegare le mie ragioni dietro a tale affermazione e vedere a grandi linee come ci si potrebbe difendere.

LA COLPA E' DEL SISTEMA OPERATIVO
Si e' detto che affinche' il buffer overflow di tipo stack funzioni e' necessario "iniettare" codice malevolo nello stack (o comunque nell'area dati - qui si pensi solo allo stack) e far saltare il controllo a tale codice (ossia modificare il registro IP). Cio' significa che il processore salta ed esegue codice in un'area di memoria scrivibile. Si presti attenzione: il processore manda in esecuzione dati da una zona di memoria scrivibile, che quindi potrebbe essere modificata in ogni momento. Sarebbe come dire che un demone di sistema abbia i permessi wx sulla sua immagine su disco stessa, e quindi che possa essere sostituito da qualunque programma si voglia. Apriti cielo! Il ritorno dei programmi automodificanti banditi fin dagli anni 50!
Come ci si potrebbe difendere? Beh, il canary e' una buona tecnica, anzi la migliore probabilmente: si inserisce un valore random nello stack che deve essere controllato al ritorno. Se il processore non trova tale valore corretto allora l'esecuzione e' abortita. Ma chi introduce il canarino? Anche qui ulteriore diatriba al corso: non e' il sistema operativo, e' il compilatore. O meglio, il compilatore inserisce nel prologo e nell'epilogo del metodo istruzioni per il controllo del canarino. Ora, se vogliamo dare ragione al docente del corso, il canarino viene controllato dal sistema operativo che esegue il programma...ma comunque senza la modifica al codice prodotto in fase di compilazione (Propolice) cio' non sarebbe possibile.

W^X
W^X e' un sistema concettualmente molto semplice, quasi disarmante nella sua semplicita', ad opera del team di OpenBSD incluso nella release 3.3 (si, la 3.3). L'idea e' quella di avere le pagine di memoria scrivibili private in toto del flag di esecuzione e viceversa: non e' quindi possibile eseguire lo stack poiche' lo stack e' scrivibile. Se l'architettura hardware supporta il flag NX (Not eXecutable) allora il trucco funziona direttamente: lo stack viene marcato come non eseguibile e quindi il buffer overlow e' evitato. Purtroppo non tutte le architetture supportano in hardware tale tecnica. Ma anche sulle architetture che supportano nativamente il flag la cosa si complica: lo stack utente ha tipicamente in cima un trampolino, denominato sigtramp, che serve come punto di lancio per l'intercettazione dei segnali unix. Tale zona puo' essere in sola lettura (il trampolino non cambia una volta che lo stack di chiamata si attiva) e quindi occorre muovere tale trampolino in una posizione non scrivibile, in modo da pulire lo stack. Inoltre c'e' il problema delle librerie condivise, che ad esempio nel loro spazio dati contengono i cosiddetti ctors e dtors, ossia i costruttori e distruttori c++. Quindi anche le librerie condivise hanno uno spazio dati che oltre ad essere scrivibile e' anche eseguibile. Perfino il GOT (Global Offset Table) e il PLT (Procedure Linkage Table) risultano scrivibili, permettendo quindi la modifica degli indirizzi di ritorno. W^X rende il GOT solo leggibile e il PLT (che deve essere eseguibile) non scrivibile, mettendo un po' di ordine nel caos delle librerie condivise. Analogamente i ctors e dtors vengono resi non scrivibili, garantendo anche in questo caso che salti di codice anomalo non siano possibili.
Nelle architetture che supportano il flag NX a livello di pagina il riordinamento di cui sopra e' sufficiente a garantire la protezione richiesta, nelle altre architetture occorre operare un ulteriore trucco. In sostanza si divide la memoria in due regioni (una scrivibile e una eseguibile) inserendo una linea di separazione virtuale. Compilatore e linker devono lavorare per spezzare i vari blocchi del programma e ordinarli in memoria al fine di inserire ogni pezzo nella giusta area di memoria.

RANDOMIZZAZIONE DEGLI INDIRIZZI
La randomizzazione degli indirizzi e' un'altra tecnica, meno efficace di W^X (secondo me), di protezione contro i buffer overflow. L'idea e' quella di inserire in ogni stack un gap random, cosi' da modificare l'effettivo inizio dei dati sullo stack. In questo modo diventa molto piu' complesso individuare dove il codice malevole e' stato piazzato, poiche' ad ogni esecuzione la sua locazione varia e quindi l'attacco ha meno possibilita' di riuscita. Secondo Theo de Raadt questa randomizzazione richiede 3 linee di codice di modifica nel kernel, e quindi non si vede come mai ancora molti vendor commerciali non l'abbiano inclusa.
La randomizzazione puo' essere anche rivolta alla allocazione della memoria: mmap e malloc solitamente funzionano con allocazioni contigue e quindi prevedibili. E' possibile randomizzare lo spazio di indirizzamento in modo che le aree di memoria siano addirittura intervallate fra loro e quindi che non sia possibile saltare da un'area all'altra.


Per maggiori informazioni consiglio di dare un'occhiata qui.

MSVCR71.dll not found

Capita con alcuni programmi nel mondo M$ che vengano riportati malfuzionamenti relativi alla dll msvcr71.dll. Non so di preciso cosa faccia questa DLL, ma ho notato che diversi programmi si installano tale DLL nella propria directory delle librerie, e così è stato anche per i programmi che causavano problemi a me: è stato sufficiente copiare la DLL da una qualunque posizione del disco fisso (es. system32) nella directory del mio applicativo per risolvere il problema.
Chissà a cosa pensava Microsoft quando ha aggiunto le librerie condivise al proprio sistema, e chissà con quali flag compilano le applicazioni gli sviluppatori....

OpenIndiana e password di root dopo l'installazione

Nelle nuove installazioni di OpenIndiana, la derivata di OpenSolaris, l'utente root e' disabilitato per default. La situazione e' documentata e la modifica e' stata necessaria a causa di alcuni problemi di sicurezza. Tuttavia questo fa si che l'utente che esegue il sistema non sia in grado nemmeno di eseguire il programma per l'installazione di software e aggiornamento. La soluzione al problema e' semplice:

sudo -s
inserire la password utente
passwd root

e cosi' facendo l'utente root viene abilitato nuovamente e il sistema diviene nuovamente usabile nella sua interezza.

Document Freedom Day

Oggi, 30 Marzo 2011, e' il Document Freedom Day (DFD), una giornata promossa dalla Free Software Foundation e altri che festeggia i formati di documenti liberi (Open), come ad esempio ODF (Open Document Format). L'idea e' quella di spingere l'utente ad usare sempre di piu' i formati documentali Open poiche' sono gli unici che possono garantire una vera interoperabilita' fra sistemi e piattaforme, nonche' sono gli unici che possono garantire un accesso nel tempo. Spesso capita infatti che documenti prodotti con formati proprietari siano resi inaccessibili nel tempo, perche' ad esempio il fornitore commerciale, dismesso un certo formato, non fornisce piu' supporto. Nel caso di formati Open e' invece possibile costruirsi la propria implementazione per accedere ai documenti, anche nel caso di assenza di implementazioni di applicazioni.
Per maggiori informazioni si veda http://documentfreedom/2011.

martedì 29 marzo 2011

Ping statistics forzato in Solaris?

Generalmente sono una persona pratica e pragmatica, ed e' per questo motivo che sono rimasto sconvolto da una modifica al comando ping(1) di Solaris. Brevemente: il comando ping di Solaris invia un singolo pacchetto all'host di destinazione, a differenza del ping di una distribuzione Linux che entra automaticamente in statistic mode inviando pacchetti all'infinito. Ebbene, qualcuno, stanco di dover sempre digitare lo switch -s su Solaris per abilitare un ping continuo ha pensato bene di fare una modifica al programma per abilitare di default questa funzionalita'. La modifica prevede che se nell'ambiente di sistema esiste una determinata variabile (impostata a qualunque valore non nullo) ping eseguira' in modalita' non statistica. La cosa e' sorprendetemente stupida! Anzitutto si costringono gli utenti a inserire una variabile di sistema (consumo di memoria) quando un alias del comando sarebbe sufficiente. In secondo luogo cosi' facendo si rischia di modificare il comportamento del comando anche negli script che si ritrovano tale variabile esportata. Ora, e' vero che chi usi ping negli script senza un count (conteggio del numero di pacchetti) e' un'idiota, ma programmi molto vecchi potrebbero risentire negativamente di questa funzionalita'. Insomma, perfino il DOS ha un ping migliore di quello proposto da Solaris!

Oracle non supporta Solaris nel suo open forum?


Il 14 Aprile Oracle terra' una sessione Web aperta in cui spieghera' alcune cose riguardanti Solaris, le strategie di mercato e l'evoluzione dei sistemi operativi, come usare IPS e la virtualizzazione e, ovviamente, tutte le novita' di Solaris 11. L'evento e' gratuito, ma occorre registrarsi per avere la possibilita' di partecipare anche da una chat dal vivo. Ebbene, essendo la sessione dedicata a Solaris mi sarei aspettato di vedere Solaris fra le piattaforme richieste per la partecipazione, mentre il sistema di testing per partecipare alla sessione live richiede la presenza di qualunque altro sistema operativo eccetto Solaris! Significa forse che perfino Oracle non pensa che Solaris possa essere installato come sistema desktop? E' una semplice dimenticanza? E' una svista colossale? In realta' si tratta del sistema che fara' da hosting per l'evento che non elenca Solaris fra i sistemi supportati, mentre e' certo che una installazione base del sistema (o dei suoi derivati) funzionera' a patto di avere Firefox, Flash, cookies abilitati.

Java Comparable: usare indici con peso

Java dispone dell'interfaccia Comparable per permette la comparazione e l'ordinamento di oggetti in memoria. L'idea e' semplice: se un oggetto e' Comparable viene invocato un metodo particolare che deve restituire un valore positivo, negativo o nullo rispettivamente per sapere se tale oggetto e' "maggiore", "minore" o uguale a quello che si sta correntemente esaminando. La specifica pero' non pone nessun vincolo su quanto positivo o negativo debba essere un valore affinche' la comparazione sia valutata, e questo lascia ampio spazio di manovra ai programmatori per implementare in maniera semplice ed efficace i controlli di comparazione.
Si supponga ad esempio di avere un oggetto Document che debba essere ordinato per anno e mese. Il test formale prevede di controllare anzitutto gli anni di due documenti, e se questi coincidono, i rispettivi mesi. Quindi qualcosa di simile a:

public int compareTo(Document toCompare) {
    // controllo argomenti
    if( toCompare == null )
        return 1;

    if( getYear() == toCompare.getYear() ){
        // controllo mesi
        if( getMonth() > toCompare.getMonth() )
            return 1;
        else if( getMonth() < toCompare.getMonth() )
            return -1;
            else
            return 0;
    }
        else if( getYear() > toCompare.getYear() )
             return 1;
        else
         return 0;

}


In effetti il test effettuato con if/else e' abbastanza articolato e ricontrolla in vari punti condizioni simili. E' possibile ovviare a tutto quel codice considerando semplicemente che le due condizioni da testare (anno e mese) hanno pesi diversi: l'anno pesa di piu' (ossia una differenza fra gli anni e' discriminante indipendentemente dalla differenza fra i mesi), e quindi e' possibile calcolare un valore complessivo dato dalla differenza pesata fra i valori. Considerando che la differenza fra i mesi e' compresa fra -12 e +12 e' sufficiente che la differenza fra gli anni sia sempre maggiore a tale intervallo, e quindi:

public int compareTo(Document toCompare) {
    // controllo argomenti
    if( toCompare == null )
        return 1;

    int equality = 0;        // per default i due documenti sono uguali
    equality += ( getYear() - toCompare.getYear() ) * 100;
    equality += ( getMonth() - toCompare.getMonth() );
    return equality;

}



In questo modo una differenza fra gli anni sara' sempre superiore ad una differenza fra i mesi, che quindi sara' non considerata a meno che i due anni non risultino uguali.
In conclusione, considerando i range di differenza dei valori meno filtranti e' possibile costruire un semplice meccanismo di comparazione basato sulla sola differenza pesata dei valori stessi.

Gmail beta (per nostalgici)

GMail, la posta di Google, e' stata in fase beta per molto tempo: gia' dalla pagina di login era possibile visualizzare la scritta "beta" sotto al logo principale dell'applicazione. Ebbene qualcuno ha ritenuto che l'eliminazione di questa dicitura "beta" potesse creare confusione negli utenti, percio' e' possibile ripristinare il logo "beta" dalla configurazione del proprio account.

The_Cube: che schifo di film!

La settimana scorsa mi sono imbattuto in quello che penso sia il peggior film che io abbia mai visto: The Cube. Premetto che non sono un esperto cinematografico, che non intendo nemmeno diventarlo e che solitamente non guardo questi film ad "alta tensione", ma ormai la tv era accesa...
La storia del film sostanzialmente si articola con un gruppo ristretto di individui, fra loro sconosciuti, che si ritrovano rinchiusi in una stanza cubica dalle pareti luminose. L'ingegno umano, si sa, e' sempre in agguato, e ben presto i protagonisti realizzano che ciascuno di loro e' stato inserito nel cubo per uno scopo. In realta' durante tutto il film le persone usate sono solo due: una ragazza con la predilizione per la matematica capace di scovare le trappole che vengono identificate da una serie di numeri, e un ragazzo autistico capace di effettuare calcoli complessi a mente. Il film si svolge lento, senza grossi colpi di scenza; ogni tanto qualche protagonista inciampa in una trappola e viene eliminato (fisicamente) dal gruppo. I protagonisti si muovono da una stanza cubica all'altra scoprendo pian piano di essere dentro ad un labirinto. Ed e' fra discussioni sulla utilita' dell'inutilita' e congetture governative che i protagonisti si rendono conto che ogni stanza si muove in realta' su una griglia. Certo, come si muova non e' dato saperlo, visto che non vi sono binari o altri meccanismi...ma ci vuole un po' di fantasia. E mentre c'e' l'idemoniato di turno che pensa anche a fare sesso in una delle stanze, i protagonisti si avvicinano all'uscita del labirinto. E quando finalmente la trovano cosa fanno? Escono? Corrano fuori urlando? No, stanno qualche istante fermi a pensare a che sforzo sia stato trovare quell'uscita, giusto il tempo perche' il buono-trasformato-in-cattivo uccida i rimanenti (si vede che temeva di non riuscire a passare dalla porta se non singolarmente) anche se alla fine non riesce nemmeno lui ad uscire. Risultato: si mette in salvo solo l'autistico.
Della struttura del labirinto non sono forniti dettagli, dell'ubicazione nemmeno, dei meccanismi niente di niente, insomma, tutto basato sulla fantasia dello spettatore.
Sicuramente piu' costruttivo sarebbe stato fare un filmato sul funzionamento del cubo di Rubik.

Smettetela di proteggere le slide con le password!

Sembra divenuta ormai una moda quella di inserire delle password nelle presentazioni dei docenti universitari, e l'Universita' di Modena e Reggio Emilia non e' da meno. Per l'ennesima volta vengo rimbalzato ad un link dell'universita' che promette di mostrarmi le slide di un determinato argomento, per poi sbeffeggiarmi con una richiesta di password che ovviamente non conosco. E io inizio nuovamente a pormi l'interrogativo sull'utilita' di questo approccio, o meglio sulla sua inutilita'. Molti docenti, lo so per certo, adottano questa tecnica per tenere lontani i curiosi, diciamo studenti di altre facolta' e atenei, mettendo quindi i propri studenti in una posizione privilegiata. Cosa tutto sommato ragionevole, se non fosse che le stesse slide presentate dal docente si basano spesso su argomenti generali, abbastanza generali da essere trovati su Internet su un qualche altro sito, e spesso sono basate su altre presentazioni/lucidi/wiki/documenti liberamente disponibili. Non si vede quindi la ragione di prendere tali slide e farne una versione privata; se si teme che l'utilizzo delle slide non sia coerente con le volonta' del docente si studi un qualche metodo di licensing (es. Creative Commons). Inoltre e' indispensabile una nota riflessiva: possibile che tutti questi docenti si sentano cosi' superiori ai propri colleghi che rilasciano documentazione liberamente? Ad esempio, per un corso di database perche' le slide devono essere "blindate" quando magari si basano su documentazione liberamente disponibile su PostgreSQL (e magari su slide rese pubbliche da ITPug)? E ancora, perche' questi docenti che spiegano ed evangelizzano il free software non evangelizzano anche la free documentation? Il Free Document Day si sta avvicando, urge una riflessione....

L'integrazioe di Gnome

Aaron Seigo ha pubblicato un ottimo post riguardante l'atteggiamento piuttosto Gnome-centric e isolato della community Gnome, che tende ad andare avanti per la propria strada sempre e comunque senza volersi integrare con altri stack software. Questo e' uno dei motivi politici che mi ha sempre spinto a considerare KDE un progetto nettamente superiore, non solo per la tecnologia, ma anche per la mentalita' Free che ha sempre avuto.

mercoledì 9 marzo 2011

Gestione dei riferimenti in Perl

La gestione dei riferimenti in Perl è spesso oggetto di errori e discussioni, perciò ho ritenuto interessante elencare come possono essere gestiti i riferimenti dal punto di vista sintattico.
In Perl un riferimento è un valore scalare, concettualmente assimilabile al puntatore del linguaggio C. I riferimenti possono "puntare" ad un array o un hash, e possono essere a loro volta organizzati in array o hash e quindi permettono la creazione di strutture dati complesse (array di array, hash di array, hash di hash, array di hash, ...).
Il riferimento ad una struttura dati (hash o array) non anonima si ottiene mediante l'operatore backslash (\), concettualmente simile all'operatore & del linguaggio C. Essendo un riferimento un valore scalare, il suo valore viene estratto sempre usando il dollaro ($), ossia il riferimento è sempre usato come una normale variabile scalare. Il valore di un riferimento corrisponde al valore del puntatore, ossia alla dereferenziazione del riferimento stesso. Occorre prestare un po' di attenzione ad alcune regole sintattiche quando si lavora con i riferimenti, siano essi ad array o hash. Come regola generale, sempre valida, si può assumere che la dereferenziazione di un riferimento ha sempre la sintassi ${ $nome_riferimento } ossia è come se si avesse l'estrazione del valore del riferimento ($nome_riferimento) a sua volta estratto ancora. Si può pensare che ${ } corrisponda, in Perl, all'operatore * del C (inteso come operatore di "contenuto del puntatore").
In generale quindi vale la regola che ovunque si scriverebbe il nome dell'array o dell'hash referenziato si debba inserire { $nome_riferimento }. Un esempio chiarira' meglio questo aspetto: si supponga di avere un array @array e il suo riferimento $refToArray e si voglia accedere alla sua cella i-esima. La sintassi diventa:

  • accesso diretto $array[ $i ]
  • accesso tramite riferimento ${ $refToarray }[ $i ]

Come si può notare, da un punto di vista sintattico "array" è stato sostituito completamente da "{refToArray }". Questa regola è sempre valida, e quindi la sua applicazione non produce mai errori. E' comunque possibile semplificare ulteriormente la notazione tenendo conto che:
  • se $refToArray è un valore scalare puro allora le parentesi graffe possono essere rimosse, e quindi ${ $refToArray }[ $i ] diventa $$refToArray[ $i ];
  • se la dereferenziazione punta ad un valore scalare, allora ${ REF }[ $i ] puo' essere convertito nella notazione "frecciata" $REF->[$i]. Questa notazione verra' denominata nel seguito "riferimento smart".
Si consideri ora un esempio di codice che riassume le sintassi e le confronta nel caso di array:

# creazione di un array normale
@array = ( 1, 2, 3, 4, 5);

# creo un riferimento (scalare) all'array
$refToArray = \@array;

# estraggo i dati dell'array
print "\nEstrazione dati da array";
for( $i = 0; $i <= $#array; $i++ ){
    print "\n [ $i ] tramite valore            = " . $array[ $i ];
    print "\n [ $i ] tramite riferimento       = " . ${ $refToArray }[ $i ];
    print "\n [ $i ] tramite riferimento       = " . $$refToArray[ $i ];
    print "\n [ $i ] tramite riferimento smart = " . $refToArray->[ $i ];
}
considerazioni fatte per l'array valgono anche nel caso di un hash. Come detto prima, ogni volta che si inserisce il nome dell'hash si può inserire { $refToHash }:



# creo un hash
%hash = ( "key1" => "value1",
      "key2" => "value2",
      "key3" => "value3",
);

# creo un riferimento ad un hash
$refToHash = \%hash;

# estraggo i dati dall'hash
print "\nEstrazione dati hash";
foreach $key ( keys( %hash ) ){
    print "\n [ $key ] tramite valore            = " . $hash{ $key };
    print "\n [ $key ] tramite riferimento       = " . ${ $refToHash }{ $key };
    print "\n [ $key ] tramite riferimento smart = " . $refToHash->{ $key };
}

E' possibile usare i riferimenti anche per la creazione di hash e array anonimi, ossia senza un nome di variabile ma che vengono acceduti solo tramite un riferimento. In questo caso non si usa l'operatore backslash (\) ma rispettivamente:
  • [] per definire un riferimento ad una lista/array;
  • {} per definire un riferimento ad un hash.

Il seguente pezzo di codice mostra come creare riferimenti ad hash e array anonimi, con il relativo accesso ai dati. Si noti ancora una volta come, ovunque sarebbe comparso il nome ipotetico dell'hash, si sia provveduto a sostituire tale nome con il valore scalare del riferimento.

# creazione di un array tramite riferimento
$refToArray = [ "a", "b", "c", "d" ];

for( $i = 0; $i <= $#$refToArray; $i++ ){
    print "\n [ $i ] tramite riferimento       = " . ${ $refToArray }[ $i ];
    print "\n [ $i ] tramite riferimento smart = " . $refToArray->[ $i ];

}

# creazione di un hash tramite riferimento
$refToHash = {
    "key1" => "value1",
    "key2" => "value2",
    "key3" => "value3",
};


foreach $key ( keys( %${refToHash} ) ){
    print "\n [ $key ] tramite valore            = " . $hash{ $key };
    print "\n [ $key ] tramite riferimento       = " . ${ $refToHash }{ $key };
    print "\n [ $key ] tramite riferimento smart = " . $refToHash->{ $key };
}

Spring, Oracle e Invalid Column Index

Ammetto di essere di parte quando parlo di database, penso che sia ben chiaro quanto stimo PostgreSQL e la sua filosofia di sviluppo. Diciamo semplicemente che trovo naturale sviluppare con PostgreSQL perche' gli strumenti, i comandi, le librerie, e tutto il resto si comporta come io mi comporterei. Cio' non significa che gli altri database (emergenti e non) siano peggiori, ma a volte ci si scontra con delle cose veramente strane e errori indecifrabili che portano via molto tempo che poteva essere impiegato a fare altro.
Scenario: applicazione Java che effettua delle query SQL tramite i template Spring su database Oracle.
La query da eseguire era molto semplice, ma per renderla ancora piu' semplice la si pensi come:

SELECT surname,name,cdfisc FROM person WHERE cdfisc='?';

Risultato della query? SQLException con "Invalid column index" e il row mapper che non entra nemmeno in funzione. Quindi si tratta di un errore sintattico. Diligentemente apro un tool SQL e digito a mano la stessa query, sostituendo al parametro un valore concreto, e la query diligentemente mi restituisce il risultato cercato. Escluso quindi il caso di query palesemente errata, provo a far eseguire alla applicazione Java una query non parametrica:

SELECT surname,name,cdfisc FROM person ;

ma ancora errore, questa volta per un "invalid character". Rimuovo lo spazio alla fine della query e tutto funziona. Sara' un problema di Spring? Sara' un problema di Oracle? Qualcuno nella catena ha pensato che uno spazio sia un carattere significativo se inserito in fondo alla query!
Comunque un passo avanti e' stato fatto, ora si tratta di riprendere in mano la query parametrica che ancora non funziona, eppure di spazi casuali non ce ne sono. Inutile dire che cdfisc e' un campo stringa, da qui il quoting fra apici semplice. Quasi per caso scopro che proprio quello potrebbe essere il problema, quindi rimuovo il quoting scrivendo la query come:


SELECT surname,name,cdfisc FROM person WHERE cdfisc=?;

e magicamente i dati iniziano a venire fuori dal database!
Inutile dire che la query iniziale eseguita con la stessa configurazione su un server PostgreSQL ha eseguito senza alcun problema.

Gnome Shell: la storia si ripete?

Ormai si avvicina il giorno di rilascio ufficiale di Gnome 3 (6 Aprile 2010)  e c'e' molto interesse per la nuova versione di questo ambiente desktop. Io ho provato una versione di test sulla mia macchina e devo ammettere che nonostante lo scetticismo iniziale la community ha svolto veramente un lavoro egregio. Ma non tutti sono contenti del lavoro fatto, e molte critiche sono state espresse circa alcune decisioni "estreme", come la decisione di rimuovere i pulsanti per la riduzione ad icona o la massimizzazione di una finestra.
Queste critiche mi ricordano cosa avvenne al rilascio del KDE 4.0: i coraggiosi come me che installarano la prima versione stabile rimasero delusi: le funzionalita' non erano al massimo ma soprattutto il cambio di "logica" dietro al desktop richiedeva un certo impegno mentale per lasciarsi alle spalle le vecchie abitudini e iniziare ad essere produttivi con la nuova interfaccia.
Penso che la stessa cosa succdera' a Gnome con la sua major release. Il suggerimento che posso dare a tutti gli utenti che migreranno e' quello di tenere duro: l'esperienza mi insegna che solitamente le abitudini radicate in un utente non possono competere con le motivazioni dietro ai cambiamenti di un'intera community. E solitamente si scopre che si stava facendo la cosa giusta nel modo sbagliato (o semplicemente in un modo poco efficiente).

JSF e IllegalMonitorStateException in forwarding

Ci sono casi nei quali il puro uso di JSF non è sufficiente: ad esempio quando si vuole inviare un file o uno stream in download attraverso il browser si deve interagire con la richiesta/risposta della classica HttpServlet. In questo caso potrebbe capitare di ottenere il corretto funzionamento del front-end (ossia del browser) ma di trovare una eccezione IllegalMonitorStateException riferita un doForward(..) sul servlet engine. In sostanza quello che avviene è che la servlet invia un risultato ma poi il sistema JSF (e la relativa servlet), non essendo a conoscenza di questa risposta "on-demand" tenta di inviarne una propria. Il servlet engine si accorge di aver già  mandato una intestazione e dei dati (quelli forniti manualmente) e quindi si scatena l'eccezione di cui sopra. La soluzione è abbastanza semplice: si deve invocare il metodo responseComplete() sul FacesContext corrente una volta che si sia finito di inviare la risposta manualmente.

Linux si avvicina a DTrace (?)

Il kernel di Linux include ora una funzionalita' per molti versi paragonabile a DTrace di (Open)Solaris (e derivati): la tracing API. L'idea della tracing API e' quella di inserire dei marcaposto nel codice del kernel per agganciare puntatori a funzione che verranno invocati al raggiungimento delle probes (sonde) nel kernel stesso. Sostanzialmente si tratta di un meccanismo ad eventi per il kernel. L'API viene divisa sostanzialmente in due parti:
  • trace points: ovvero dichiarazione delle sonde. Mediante una serie di macro si possono definire funzioni generiche (con relativi parametri) e invocare tali funzioni in punti dle codice del kernel. Le funzioni non faranno altro che andare a richiamare i listener agganciati alle sonde.
  • trace events: sono un API di livello piu' alto costruita sui tracepoints. Sostanzialmente un evento e' un trace point con in piu' dei dati (contenuti in una struttura) che puo' essere esaminata lato utente. L'idea e' che quando scatta l'evento la struttura dati venga copiata con dei dati forniti da del codice (es. un modulo caricato).

In userspace occorre abilitare il tracing editando i file del sysfs sotto alla directory kernel/debug/tracing inserendo il classico 1 negli eventi (o nei sottosistemi) per abilitare il tracing. A questo punto si avra' una printk() gratuita per l'evento abilitato, o se si e' scritto un proprio evento si avra' l'esecuzione del codice di tracing specificato.
Si e' ancora abbastanza lontani dalla potenza di DTrace, anche se strumenti quali perf promettono molto bene, ad ogni modo penso che questa sia una bella mossa da parte del kernel Linux che potrebbe portarlo ancora piu' pesantemente a sostituire quei sistemi enterprise che stanno difendendo con i denti la loro posizione. Per maggiori informazioni si veda questo ottimo articolo.