[successivo] [precedente] [inizio] [fine] [indice generale] [indice ridotto] [indice analitico] [home] [volume] [parte]


Capitolo 199.   Controllo dello spazio rimasto libero

Se da un lato ci può essere l'esigenza di ripescare i dati cancellati all'interno di un'unità di memorizzazione, dall'altro c'è sicuramente quella di poter eliminare definitivamente ciò che si intende cancellare. Il modo più semplice e intuitivo per premunirsi contro la ricerca di dati all'intero dello spazio inutilizzato di un'unità di memorizzazione, consiste nel creare una serie di file temporanei, il cui contenuto sia innocuo, cancellandoli successivamente.

Questo problema può essere considerato con maggiore o minore serietà, a seconda del contesto: se si tratta solo di un piccolo scrupolo, una sovrascrittura singola dei dati può essere sufficiente; se invece il problema della riservatezza è grave, sono necessarie più sovrascritture con dati diversi e casuali.

L'efficacia del procedimento di sovrascrittura dei dati cancellati dipende anche dalle caratteristiche del file system e dal modo in cui si comunica effettivamente con l'unità di memorizzazione. Per avere un risultato accettabile occorre che l'unità di memorizzazione sia collegata localmente, perché un file system di rete potrebbe essere gestito tramite una memoria tampone significativa, dove molti file creati e poi cancellati non vengono nemmeno memorizzati effettivamente, o comunque dove non tutte le sovrascritture ripetute vengono eseguite realmente. Inoltre, il file system non deve conservare lo storico (ovvero il diario) delle modifiche ai file, altrimenti il procedimento di sovrascrittura diventa perfettamente inutile e dannoso per altri versi.

Eventualmente va considerato anche il problema della cancellazione della memoria di scambio (quella che estende la memoria virtuale in un'unità di memorizzazione di massa), ma in questo capitolo la questione non viene trattata.

199.1   Secure-delete

Secure-delete(1) è un piccolo insieme di programmi destinati alla cancellazione definitiva dei dati. In particolare è importante il programma sfill, con il quale si va a sovrascrivere più volte lo spazio inutilizzato all'interno di un file system:

sfill [opzioni] directory

La sintassi del programma richiede almeno l'indicazione di una directory, all'interno della quale creare i file temporanei per la sovrascrittura. Per esempio, supponendo che nella directory /home/ sia innestato il file system all'interno del quale si vuole fare un po' di pulizia, sarebbe sufficiente il comando seguente:

sfill /home[Invio]

In generale, il programma va usato dall'amministratore, ma non viene escluso dagli utenti comuni. Tuttavia, se un utente comune utilizza sfill, è molto probabile che non possa sovrascrivere tutto lo spazio libero, in base alla politica del sistema.

Tabella 199.1. Alcune opzioni per l'uso di sfill.

Opzione Descrizione
-f
Richiede una modalità di funzionamento rapida (fast), ma logicamente poco efficace sul piano della sicurezza della cancellazione.
-l
Richiede solo due sovrascritture (less), una delle quali con dati casuali.
-z
Richiede che l'ultimo passaggio di sovrascrittura avvenga utilizzando il valore zero.

Va letta la documentazione, costituita dalla pagina di manuale sfill(1), se il problema della cancellazione dei dati è delicato nel proprio contesto. Si vedano eventualmente anche gli altri programmi del pacchetto Secure-delete.

199.2   Esempio di programma per la sovrascrittura dello spazio libero

Viene proposto un programma molto semplice, scritto in C, con il quale si creano una serie di file nella directory corrente, contenenti la ripetizione di una stringa fornita attraverso la riga di comando. La scrittura avviene una sola volta e i file temporanei vanno cancellati manualmente, dopo l'uso del programma.

empty-space-filler [blocco [stringa]]

Ammesso che il programma venga chiamato come si vede nel modello sintattico, il primo argomento opzionale è costituito dalla dimensione del blocco, ovvero la dimensione di ogni file temporaneo creato; il secondo argomento, se fornito, deve essere la stringa da usare ripetutamente per riempire lo spazio dei file temporanei. Per esempio, il programma potrebbe essere usato così:

cd /tmp[Invio]

empty-space-filler 131072 "Ciao a tutti! :-) :-) :-)"[Invio]

Naturalmente, se non si forniscono opzioni vengono usati i valori predefiniti nel programma. Segue il listato del programma che dovrebbe essere disponibile presso <allegati/a2/c/empty-space-filler.c>).

#include <limits.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

const unsigned int  p_default_block_size = 65536;
const unsigned int  p_max_block_size     = 1048576;
const         char  p_default_message[]  = "ciao";
              char *p_program_name;

void
command_line_error (void)
{
    printf ("%s: syntax error!\n", p_program_name);
    printf ("\n");
    printf ("syntax:\n");
    printf ("%s [[BLOCK_SIZE MESSAGE]\n", p_program_name);
    printf ("\n");
    printf ("max BLOCK_SIZE is %u.\n", p_max_block_size);
    printf ("\n");
    printf ("example:\n");
    printf ("%s %u \"empty block\"\n",
            p_program_name,
            p_default_block_size);
}

char *
fill_the_block (char *block,
                unsigned int block_size,
                const char *message)
{
    unsigned int i;
    unsigned int j;
    unsigned int message_size = strlen (message);
    
    for (i = 0; i < block_size; i++)
      {
        for (j = 0; i < block_size && j <= message_size; j++, i++)
          {
            block[i] = message[j];
          }
        i--;
      }

    return block;
}

int
make_temp_file (char *block,
                unsigned int block_size,
                const unsigned n)
{
      char  temp_file_name[64];
       int  byte_composed;
    size_t  byte_written;
      FILE *temp_stream;
    
    byte_composed = sprintf (temp_file_name,
                             "empty-space-filler-%u.tmp",
                             n);
    
    if (byte_composed <= 0)
      {
        printf ("%s: unknown error 1!\n", p_program_name);
        return -1;
      }

    temp_stream = fopen (temp_file_name, "wb");
    
    if (temp_stream == NULL)
      {
        printf ("%s: cannot create more files!\n", p_program_name);
        return -1;
      }

    byte_written = fwrite (block, 1, block_size, temp_stream);
        
    if (byte_written != block_size)
      {
        fclose (temp_stream);
        return -1;
      }

    fclose (temp_stream);
    return 0;
}

int
main (int argc, char *argv[])
{
         unsigned int  block_size = p_default_block_size;
                  int  scan_status;
                  int  temp_status;
    unsigned long int  n_temp;
                 char *message = (char *) p_default_message;
    unsigned long int  total_size;

    // Save the program name.

    p_program_name = argv[0];

    // Check argument and fix it.

    if (argc > 3)
      {
        command_line_error ();
        exit (-1);
      }

    if (argc == 1)
      {
        block_size = p_default_block_size;
        message = (char *) p_default_message;
      }

    if (argc >= 2)
      {
        scan_status = sscanf (argv[1], "%u", &block_size);
        
        if (scan_status != 1)
          {
            command_line_error ();
            exit (-1);
          }
        else if (block_size == 0)
          {
            block_size = p_default_block_size;
          }
        else if (block_size > p_max_block_size)
          {
            command_line_error ();
            exit (-1);
          }
      }

    if (argc == 3)
      {
        message = argv[2];
                
        if (strlen (message) < 1)
          {
            message = (char *) p_default_message;
          }

      }

    // Define the block to be written and fill it.
    
    char block[block_size];
    
    fill_the_block (block, block_size, message);

    // Make files.

    for (n_temp = 0, temp_status = 0;
         n_temp <= UINT_MAX && temp_status >= 0;
         n_temp++)
      {
        temp_status = make_temp_file (block, block_size, n_temp);

        if (temp_status != 0)
          {
            break;
          }

        total_size = n_temp * block_size;
        
        printf ("%s: written %lu x %u = %lu bytes\r",
                p_program_name,
                n_temp,
                block_size,
                total_size);

      }

    printf ("%s: written %lu x %u = %lu bytes\n",
            p_program_name,
            n_temp,
            block_size,
            total_size);
    return 0;
}

Per compilare il programma, ammesso che il file originale sia empty-space-filler.c, si può procedere nel modo seguente:

cc -o empty-space-filler empty-space-filler.c[Invio]


1) Secure-delete   GNU GPL


Appunti di informatica libera 2008 --- Copyright © 2000-2008 Daniele Giacomini -- <appunti2 (ad) gmail·com>


Dovrebbe essere possibile fare riferimento a questa pagina anche con il nome controllo_dello_spazio_rimasto_libero.htm

[successivo] [precedente] [inizio] [fine] [indice generale] [indice ridotto] [indice analitico] [home]

Valid ISO-HTML!

CSS validator!

Gjlg Metamotore e Web Directory