Merge branch 'next' into for-linus
[linux-2.6-microblaze.git] / Documentation / translations / it_IT / process / deprecated.rst
1 .. SPDX-License-Identifier: GPL-2.0
2
3 .. include:: ../disclaimer-ita.rst
4
5 :Original: :ref:`Documentation/process/deprecated.rst <deprecated>`
6 :Translator: Federico Vaga <federico.vaga@vaga.pv.it>
7
8 .. _it_deprecated:
9
10 ==============================================================================
11 Interfacce deprecate, caratteristiche del linguaggio, attributi, e convenzioni
12 ==============================================================================
13
14 In un mondo perfetto, sarebbe possibile prendere tutti gli usi di
15 un'interfaccia deprecata e convertirli in quella nuova, e così sarebbe
16 possibile rimuovere la vecchia interfaccia in un singolo ciclo di sviluppo.
17 Tuttavia, per via delle dimensioni del kernel, la gerarchia dei manutentori e
18 le tempistiche, non è sempre possibile fare questo tipo di conversione tutta
19 in una volta. Questo significa che nuove istanze di una vecchia interfaccia
20 potrebbero aggiungersi al kernel proprio quando si sta cercando di rimuoverle,
21 aumentando così il carico di lavoro. Al fine di istruire gli sviluppatori su
22 cosa è considerato deprecato (e perché), è stata create la seguente lista a cui
23 fare riferimento quando qualcuno propone modifiche che usano cose deprecate.
24
25 __deprecated
26 ------------
27 Nonostante questo attributo marchi visibilmente un interfaccia come deprecata,
28 `non produce più alcun avviso durante la compilazione
29 <https://git.kernel.org/linus/771c035372a036f83353eef46dbb829780330234>`_
30 perché uno degli obiettivi del kernel è quello di compilare senza avvisi;
31 inoltre, nessuno stava agendo per rimuovere queste interfacce. Nonostante l'uso
32 di `__deprecated` in un file d'intestazione sia opportuno per segnare una
33 interfaccia come 'vecchia', questa non è una soluzione completa. L'interfaccia
34 deve essere rimossa dal kernel, o aggiunta a questo documento per scoraggiarne
35 l'uso.
36
37 BUG() e BUG_ON()
38 ----------------
39 Al loro posto usate WARN() e WARN_ON() per gestire le
40 condizioni "impossibili" e gestitele come se fosse possibile farlo.
41 Nonostante le funzioni della famiglia BUG() siano state progettate
42 per asserire "situazioni impossibili" e interrompere in sicurezza un
43 thread del kernel, queste si sono rivelate essere troppo rischiose
44 (per esempio, in quale ordine rilasciare i *lock*? Ci sono stati che
45 sono stati ripristinati?). Molto spesso l'uso di BUG()
46 destabilizza il sistema o lo corrompe del tutto, il che rende
47 impossibile un'attività di debug o anche solo leggere un rapporto
48 circa l'errore.  Linus ha un'opinione molto critica al riguardo:
49 `email 1
50 <https://lore.kernel.org/lkml/CA+55aFy6jNLsywVYdGp83AMrXBo_P-pkjkphPGrO=82SPKCpLQ@mail.gmail.com/>`_,
51 `email 2
52 <https://lore.kernel.org/lkml/CAHk-=whDHsbK3HTOpTF=ue_o04onRwTEaK_ZoJp_fjbqq4+=Jw@mail.gmail.com/>`_
53
54 Tenete presente che la famiglia di funzioni WARN() dovrebbe essere
55 usato solo per situazioni che si suppone siano "impossibili".  Se
56 volete avvisare gli utenti riguardo a qualcosa di possibile anche se
57 indesiderato, usare le funzioni della famiglia pr_warn().  Chi
58 amministra il sistema potrebbe aver attivato l'opzione sysctl
59 *panic_on_warn* per essere sicuri che il sistema smetta di funzionare
60 in caso si verifichino delle condizioni "inaspettate". (per esempio,
61 date un'occhiata al questo `commit
62 <https://git.kernel.org/linus/d4689846881d160a4d12a514e991a740bcb5d65a>`_)
63
64 Calcoli codificati negli argomenti di un allocatore
65 ----------------------------------------------------
66 Il calcolo dinamico delle dimensioni (specialmente le moltiplicazioni) non
67 dovrebbero essere fatto negli argomenti di funzioni di allocazione di memoria
68 (o simili) per via del rischio di overflow. Questo può portare a valori più
69 piccoli di quelli che il chiamante si aspettava. L'uso di questo modo di
70 allocare può portare ad un overflow della memoria di heap e altri
71 malfunzionamenti. (Si fa eccezione per valori numerici per i quali il
72 compilatore può generare avvisi circa un potenziale overflow. Tuttavia usare
73 i valori numerici come suggerito di seguito è innocuo).
74
75 Per esempio, non usate ``count * size`` come argomento::
76
77         foo = kmalloc(count * size, GFP_KERNEL);
78
79 Al suo posto, si dovrebbe usare l'allocatore a due argomenti::
80
81         foo = kmalloc_array(count, size, GFP_KERNEL);
82
83 Se questo tipo di allocatore non è disponibile, allora dovrebbero essere usate
84 le funzioni del tipo *saturate-on-overflow*::
85
86         bar = vmalloc(array_size(count, size));
87
88 Un altro tipico caso da evitare è quello di calcolare la dimensione di una
89 struttura seguita da un vettore di altre strutture, come nel seguente caso::
90
91         header = kzalloc(sizeof(*header) + count * sizeof(*header->item),
92                          GFP_KERNEL);
93
94 Invece, usate la seguente funzione::
95
96         header = kzalloc(struct_size(header, item, count), GFP_KERNEL);
97
98 Per maggiori dettagli fate riferimento a array_size(),
99 array3_size(), e struct_size(), così come la famiglia di
100 funzioni check_add_overflow() e check_mul_overflow().
101
102 simple_strtol(), simple_strtoll(), simple_strtoul(), simple_strtoull()
103 ----------------------------------------------------------------------
104 Le funzioni simple_strtol(), simple_strtoll(),
105 simple_strtoul(), e simple_strtoull() ignorano volutamente
106 i possibili overflow, e questo può portare il chiamante a generare risultati
107 inaspettati. Le rispettive funzioni kstrtol(), kstrtoll(),
108 kstrtoul(), e kstrtoull() sono da considerarsi le corrette
109 sostitute; tuttavia va notato che queste richiedono che la stringa sia
110 terminata con il carattere NUL o quello di nuova riga.
111
112 strcpy()
113 --------
114 La funzione strcpy() non fa controlli agli estremi del buffer
115 di destinazione. Questo può portare ad un overflow oltre i limiti del
116 buffer e generare svariati tipi di malfunzionamenti. Nonostante l'opzione
117 `CONFIG_FORTIFY_SOURCE=y` e svariate opzioni del compilatore aiutano
118 a ridurne il rischio, non c'è alcuna buona ragione per continuare ad usare
119 questa funzione. La versione sicura da usare è strscpy().
120
121 strncpy() su stringe terminate con NUL
122 --------------------------------------
123 L'utilizzo di strncpy() non fornisce alcuna garanzia sul fatto che
124 il buffer di destinazione verrà terminato con il carattere NUL. Questo
125 potrebbe portare a diversi overflow di lettura o altri malfunzionamenti
126 causati, appunto, dalla mancanza del terminatore. Questa estende la
127 terminazione nel buffer di destinazione quando la stringa d'origine è più
128 corta; questo potrebbe portare ad una penalizzazione delle prestazioni per
129 chi usa solo stringe terminate. La versione sicura da usare è
130 strscpy(). (chi usa strscpy() e necessita di estendere la
131 terminazione con NUL deve aggiungere una chiamata a memset())
132
133 Se il chiamate no usa stringhe terminate con NUL, allore strncpy()
134 può continuare ad essere usata, ma i buffer di destinazione devono essere
135 marchiati con l'attributo `__nonstring <https://gcc.gnu.org/onlinedocs/gcc/Common-Variable-Attributes.html>`_
136 per evitare avvisi durante la compilazione.
137
138 strlcpy()
139 ---------
140 La funzione strlcpy(), per prima cosa, legge interamente il buffer di
141 origine, magari leggendo più di quanto verrà effettivamente copiato. Questo
142 è inefficiente e può portare a overflow di lettura quando la stringa non è
143 terminata con NUL. La versione sicura da usare è strscpy().
144
145 Segnaposto %p nella stringa di formato
146 --------------------------------------
147
148 Tradizionalmente, l'uso del segnaposto "%p" nella stringa di formato
149 esponne un indirizzo di memoria in dmesg, proc, sysfs, eccetera.  Per
150 evitare che questi indirizzi vengano sfruttati da malintenzionati,
151 tutto gli usi di "%p" nel kernel rappresentano l'hash dell'indirizzo,
152 rendendolo di fatto inutilizzabile.  Nuovi usi di "%p" non dovrebbero
153 essere aggiunti al kernel.  Per una rappresentazione testuale di un
154 indirizzo usate "%pS", l'output è migliore perché mostrerà il nome del
155 simbolo.  Per tutto il resto, semplicemente non usate "%p".
156
157 Parafrasando la `guida
158 <https://lore.kernel.org/lkml/CA+55aFwQEd_d40g4mUCSsVRZzrFPUJt74vc6PPpb675hYNXcKw@mail.gmail.com/>`_
159 di Linus:
160
161 - Se il valore hash di "%p" è inutile, chiediti se il puntatore stesso
162   è importante. Forse dovrebbe essere rimosso del tutto?
163 - Se credi davvero che il vero valore del puntatore sia importante,
164   perché alcuni stati del sistema o i livelli di privilegi di un
165   utente sono considerati "special"? Se pensi di poterlo giustificare
166   (in un commento e nel messaggio del commit) abbastanza bene da
167   affrontare il giudizio di Linus, allora forse potrai usare "%px",
168   assicurandosi anche di averne il permesso.
169
170 Infine, sappi che un cambio in favore di "%p" con hash `non verrà
171 accettato
172 <https://lore.kernel.org/lkml/CA+55aFwieC1-nAs+NFq9RTwaR8ef9hWa4MjNBWL41F-8wM49eA@mail.gmail.com/>`_.
173
174 Vettori a dimensione variabile (VLA)
175 ------------------------------------
176
177 Usare VLA sullo stack produce codice molto peggiore rispetto a quando si usano
178 vettori a dimensione fissa. Questi `problemi di prestazioni <https://git.kernel.org/linus/02361bc77888>`_,
179 tutt'altro che banali, sono già un motivo valido per eliminare i VLA; in
180 aggiunta sono anche un problema per la sicurezza. La crescita dinamica di un
181 vettore nello stack potrebbe eccedere la memoria rimanente in tale segmento.
182 Questo può portare a dei malfunzionamenti, potrebbe sovrascrivere
183 dati importanti alla fine dello stack (quando il kernel è compilato senza
184 `CONFIG_THREAD_INFO_IN_TASK=y`), o sovrascrivere un pezzo di memoria adiacente
185 allo stack (quando il kernel è compilato senza `CONFIG_VMAP_STACK=y`).
186
187 Salto implicito nell'istruzione switch-case
188 -------------------------------------------
189
190 Il linguaggio C permette ai casi di un'istruzione `switch` di saltare al
191 prossimo caso quando l'istruzione "break" viene omessa alla fine del caso
192 corrente. Tuttavia questo rende il codice ambiguo perché non è sempre ovvio se
193 l'istruzione "break" viene omessa intenzionalmente o è un baco. Per esempio,
194 osservando il seguente pezzo di codice non è chiaro se lo stato
195 `STATE_ONE` è stato progettato apposta per eseguire anche `STATE_TWO`::
196
197   switch (value) {
198   case STATE_ONE:
199           do_something();
200   case STATE_TWO:
201           do_other();
202           break;
203   default:
204           WARN("unknown state");
205   }
206
207 Dato che c'è stata una lunga lista di problemi `dovuti alla mancanza dell'istruzione
208 "break" <https://cwe.mitre.org/data/definitions/484.html>`_, oggigiorno non
209 permettiamo più che vi sia un "salto implicito" (*fall-through*). Per
210 identificare un salto implicito intenzionale abbiamo adottato la pseudo
211 parola chiave 'fallthrough' che viene espansa nell'estensione di gcc
212 `__attribute__((fallthrough))` `Statement Attributes
213 <https://gcc.gnu.org/onlinedocs/gcc/Statement-Attributes.html>`_.
214 (Quando la sintassi C17/C18 `[[fallthrough]]` sarà più comunemente
215 supportata dai compilatori C, analizzatori statici, e dagli IDE,
216 allora potremo usare quella sintassi per la pseudo parola chiave)
217
218 Quando la sintassi [[fallthrough]] sarà più comunemente supportata dai
219 compilatori, analizzatori statici, e ambienti di sviluppo IDE,
220 allora potremo usarla anche noi.
221
222 Ne consegue che tutti i blocchi switch/case devono finire in uno dei seguenti
223 modi:
224
225 * ``break;``
226 * `fallthrough;``
227 * ``continue;``
228 * ``goto <label>;``
229 * ``return [expression];``