Merge tag 'docs-6.0' of git://git.lwn.net/linux
[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, anche in
73 questi casi è preferibile riscrivere il codice come suggerito di seguito).
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 Nello specifico, kmalloc() può essere sostituta da kmalloc_array(), e kzalloc()
84 da kcalloc().
85
86 Se questo tipo di allocatore non è disponibile, allora dovrebbero essere usate
87 le funzioni del tipo *saturate-on-overflow*::
88
89         bar = vmalloc(array_size(count, size));
90
91 Un altro tipico caso da evitare è quello di calcolare la dimensione di una
92 struttura seguita da un vettore di altre strutture, come nel seguente caso::
93
94         header = kzalloc(sizeof(*header) + count * sizeof(*header->item),
95                          GFP_KERNEL);
96
97 Invece, usate la seguente funzione::
98
99         header = kzalloc(struct_size(header, item, count), GFP_KERNEL);
100
101 .. note:: Se per caso state usando struct_size() su una struttura dati che
102           in coda contiene un array di lunghezza zero o uno, allora siete
103           invitati a riorganizzare il vostro codice usando il
104           `flexible array member <#zero-length-and-one-element-arrays>`_.
105
106 Per altri calcoli, usate le funzioni size_mul(), size_add(), e size_sub(). Per
107 esempio, al posto di::
108
109        foo = krealloc(current_size + chunk_size * (count - 3), GFP_KERNEL);
110
111 dovreste scrivere:
112
113        foo = krealloc(size_add(current_size,
114                                size_mul(chunk_size,
115                                         size_sub(count, 3))), GFP_KERNEL);
116
117 Per maggiori dettagli fate riferimento a array3_size() e flex_array_size(), ma
118 anche le funzioni della famiglia check_mul_overflow(), check_add_overflow(),
119 check_sub_overflow(), e check_shl_overflow().
120
121 simple_strtol(), simple_strtoll(), simple_strtoul(), simple_strtoull()
122 ----------------------------------------------------------------------
123 Le funzioni simple_strtol(), simple_strtoll(),
124 simple_strtoul(), e simple_strtoull() ignorano volutamente
125 i possibili overflow, e questo può portare il chiamante a generare risultati
126 inaspettati. Le rispettive funzioni kstrtol(), kstrtoll(),
127 kstrtoul(), e kstrtoull() sono da considerarsi le corrette
128 sostitute; tuttavia va notato che queste richiedono che la stringa sia
129 terminata con il carattere NUL o quello di nuova riga.
130
131 strcpy()
132 --------
133 La funzione strcpy() non fa controlli agli estremi del buffer
134 di destinazione. Questo può portare ad un overflow oltre i limiti del
135 buffer e generare svariati tipi di malfunzionamenti. Nonostante l'opzione
136 `CONFIG_FORTIFY_SOURCE=y` e svariate opzioni del compilatore aiutano
137 a ridurne il rischio, non c'è alcuna buona ragione per continuare ad usare
138 questa funzione. La versione sicura da usare è strscpy(), tuttavia va
139 prestata attenzione a tutti quei casi dove viene usato il valore di
140 ritorno di strcpy().  La funzione strscpy() non ritorna un puntatore
141 alla destinazione, ma un contatore dei byte non NUL copiati (oppure
142 un errno negativo se la stringa è stata troncata).
143
144 strncpy() su stringe terminate con NUL
145 --------------------------------------
146 L'utilizzo di strncpy() non fornisce alcuna garanzia sul fatto che
147 il buffer di destinazione verrà terminato con il carattere NUL. Questo
148 potrebbe portare a diversi overflow di lettura o altri malfunzionamenti
149 causati, appunto, dalla mancanza del terminatore. Questa estende la
150 terminazione nel buffer di destinazione quando la stringa d'origine è più
151 corta; questo potrebbe portare ad una penalizzazione delle prestazioni per
152 chi usa solo stringe terminate. La versione sicura da usare è
153 strscpy(), tuttavia va prestata attenzione a tutti quei casi dove
154 viene usato il valore di ritorno di strncpy().  La funzione strscpy()
155 non ritorna un puntatore alla destinazione, ma un contatore dei byte
156 non NUL copiati (oppure un errno negativo se la stringa è stata
157 troncata). Tutti i casi che necessitano di estendere la
158 terminazione con NUL dovrebbero usare strscpy_pad().
159
160 Se il chiamate no usa stringhe terminate con NUL, allore strncpy()
161 può continuare ad essere usata, ma i buffer di destinazione devono essere
162 marchiati con l'attributo `__nonstring <https://gcc.gnu.org/onlinedocs/gcc/Common-Variable-Attributes.html>`_
163 per evitare avvisi durante la compilazione.
164
165 strlcpy()
166 ---------
167 La funzione strlcpy(), per prima cosa, legge interamente il buffer di
168 origine, magari leggendo più di quanto verrà effettivamente copiato. Questo
169 è inefficiente e può portare a overflow di lettura quando la stringa non è
170 terminata con NUL. La versione sicura da usare è strscpy(), tuttavia
171 va prestata attenzione a tutti quei casi dove viene usato il valore di
172 ritorno di strlcpy(), dato che strscpy() ritorna un valore di errno
173 negativo quanto la stringa viene troncata.
174
175 Segnaposto %p nella stringa di formato
176 --------------------------------------
177
178 Tradizionalmente, l'uso del segnaposto "%p" nella stringa di formato
179 esponne un indirizzo di memoria in dmesg, proc, sysfs, eccetera.  Per
180 evitare che questi indirizzi vengano sfruttati da malintenzionati,
181 tutto gli usi di "%p" nel kernel rappresentano l'hash dell'indirizzo,
182 rendendolo di fatto inutilizzabile.  Nuovi usi di "%p" non dovrebbero
183 essere aggiunti al kernel.  Per una rappresentazione testuale di un
184 indirizzo usate "%pS", l'output è migliore perché mostrerà il nome del
185 simbolo.  Per tutto il resto, semplicemente non usate "%p".
186
187 Parafrasando la `guida
188 <https://lore.kernel.org/lkml/CA+55aFwQEd_d40g4mUCSsVRZzrFPUJt74vc6PPpb675hYNXcKw@mail.gmail.com/>`_
189 di Linus:
190
191 - Se il valore hash di "%p" è inutile, chiediti se il puntatore stesso
192   è importante. Forse dovrebbe essere rimosso del tutto?
193 - Se credi davvero che il vero valore del puntatore sia importante,
194   perché alcuni stati del sistema o i livelli di privilegi di un
195   utente sono considerati "special"? Se pensi di poterlo giustificare
196   (in un commento e nel messaggio del commit) abbastanza bene da
197   affrontare il giudizio di Linus, allora forse potrai usare "%px",
198   assicurandosi anche di averne il permesso.
199
200 Potete disabilitare temporaneamente l'hashing di "%p" nel caso in cui questa
201 funzionalità vi sia d'ostacolo durante una sessione di debug. Per farlo
202 aggiungete l'opzione di debug "`no_hash_pointers
203 <https://git.kernel.org/linus/5ead723a20e0447bc7db33dc3070b420e5f80aa6>`_" alla
204 riga di comando del kernel.
205
206 Vettori a dimensione variabile (VLA)
207 ------------------------------------
208
209 Usare VLA sullo stack produce codice molto peggiore rispetto a quando si usano
210 vettori a dimensione fissa. Questi `problemi di prestazioni <https://git.kernel.org/linus/02361bc77888>`_,
211 tutt'altro che banali, sono già un motivo valido per eliminare i VLA; in
212 aggiunta sono anche un problema per la sicurezza. La crescita dinamica di un
213 vettore nello stack potrebbe eccedere la memoria rimanente in tale segmento.
214 Questo può portare a dei malfunzionamenti, potrebbe sovrascrivere
215 dati importanti alla fine dello stack (quando il kernel è compilato senza
216 `CONFIG_THREAD_INFO_IN_TASK=y`), o sovrascrivere un pezzo di memoria adiacente
217 allo stack (quando il kernel è compilato senza `CONFIG_VMAP_STACK=y`).
218
219 Salto implicito nell'istruzione switch-case
220 -------------------------------------------
221
222 Il linguaggio C permette ai casi di un'istruzione `switch` di saltare al
223 prossimo caso quando l'istruzione "break" viene omessa alla fine del caso
224 corrente. Tuttavia questo rende il codice ambiguo perché non è sempre ovvio se
225 l'istruzione "break" viene omessa intenzionalmente o è un baco. Per esempio,
226 osservando il seguente pezzo di codice non è chiaro se lo stato
227 `STATE_ONE` è stato progettato apposta per eseguire anche `STATE_TWO`::
228
229   switch (value) {
230   case STATE_ONE:
231           do_something();
232   case STATE_TWO:
233           do_other();
234           break;
235   default:
236           WARN("unknown state");
237   }
238
239 Dato che c'è stata una lunga lista di problemi `dovuti alla mancanza dell'istruzione
240 "break" <https://cwe.mitre.org/data/definitions/484.html>`_, oggigiorno non
241 permettiamo più che vi sia un "salto implicito" (*fall-through*). Per
242 identificare un salto implicito intenzionale abbiamo adottato la pseudo
243 parola chiave 'fallthrough' che viene espansa nell'estensione di gcc
244 `__attribute__((fallthrough))` `Statement Attributes
245 <https://gcc.gnu.org/onlinedocs/gcc/Statement-Attributes.html>`_.
246 (Quando la sintassi C17/C18 `[[fallthrough]]` sarà più comunemente
247 supportata dai compilatori C, analizzatori statici, e dagli IDE,
248 allora potremo usare quella sintassi per la pseudo parola chiave)
249
250 Quando la sintassi [[fallthrough]] sarà più comunemente supportata dai
251 compilatori, analizzatori statici, e ambienti di sviluppo IDE,
252 allora potremo usarla anche noi.
253
254 Ne consegue che tutti i blocchi switch/case devono finire in uno dei seguenti
255 modi:
256
257 * ``break;``
258 * `fallthrough;``
259 * ``continue;``
260 * ``goto <label>;``
261 * ``return [expression];``
262
263 Array di lunghezza zero o con un solo elemento
264 ----------------------------------------------
265 All'interno del kernel ricorre spesso la necessita di avere membri
266 di dimensione variabile all'interno di una struttura dati. In questi
267 casi il codice del kernel dovrebbe usare sempre i `"flexible array
268 member" <https://en.wikipedia.org/wiki/Flexible_array_member>`_. La
269 tecnica degli array a lunghezza nulla o di un solo elemento non
270 dovrebbe essere più usata.
271
272 Nel codice C più vecchio, la dichiarazione di un membro di dimensione
273 variabile in coda ad una struttura dati veniva fatto dichiarando un
274 array di un solo elemento posizionato alla fine della struttura dati::
275
276         struct something {
277                 size_t count;
278                 struct foo items[1];
279         };
280
281 Questo ha portato ad un calcolo di sizeof() traballante (dovrebbe
282 rimuovere la dimensione del singolo elemento in coda per calcolare la
283 dimensione esatta dell' "intestazione"). Per evitare questi problemi è
284 stata introdotta un' `estensione a GNU C
285 <https://gcc.gnu.org/onlinedocs/gcc/Zero-Length.html>`_ che
286 permettesse la dichiarazione di array a lungezza zero::
287
288         struct something {
289                 size_t count;
290                 struct foo items[0];
291         };
292
293 Ma questo ha portato nuovi problemi, e non ha risolto alcuni dei
294 problemi che affliggono entrambe le tecniche: per esempio
295 l'impossibilità di riconoscere se un array di quel tipo viene usato
296 nel mezzo di una struttura dati e _non_ alla fine (potrebbe accadere
297 sia direttamente, sia indirettamente quando si usano le unioni o le
298 strutture di strutture).
299
300 Lo standard C99 introduce i "flexible array members". Questi array non
301 hanno una dimensione nella loro dichiarazione::
302
303         struct something {
304                 size_t count;
305                 struct foo items[];
306         };
307
308 Questo è il modo con cui ci si aspetta che vengano dichiarati gli
309 elementi di lunghezza variabile in coda alle strutture dati.  Permette
310 al compilatore di produrre errori quando gli array flessibili non si
311 trovano alla fine della struttura dati, il che permette di prevenire
312 alcuni tipi di bachi dovuti a `comportamenti inaspettati
313 <https://git.kernel.org/linus/76497732932f15e7323dc805e8ea8dc11bb587cf>`_.
314 Inoltre, permette al compilatore di analizzare correttamente le
315 dimensioni degli array (attraverso sizeof(), `CONFIG_FORTIFY_SOURCE`,
316 e `CONFIG_UBSAN_BOUNDS`). Per esempio, non esiste alcun meccanismo in
317 grado di avvisarci che il seguente uso di sizeof() dia sempre come
318 zero come risultato::
319
320         struct something {
321                 size_t count;
322                 struct foo items[0];
323         };
324
325         struct something *instance;
326
327         instance = kmalloc(struct_size(instance, items, count), GFP_KERNEL);
328         instance->count = count;
329
330         size = sizeof(instance->items) * instance->count;
331         memcpy(instance->items, source, size);
332
333 Il valore di ``size`` nell'ultima riga sarà ``zero``, quando uno
334 invece si aspetterebbe che il suo valore sia la dimensione totale in
335 byte dell'allocazione dynamica che abbiamo appena fatto per l'array
336 ``items``. Qui un paio di esempi reali del problema: `collegamento 1
337 <https://git.kernel.org/linus/f2cd32a443da694ac4e28fbf4ac6f9d5cc63a539>`_,
338 `collegamento 2
339 <https://git.kernel.org/linus/ab91c2a89f86be2898cee208d492816ec238b2cf>`_.
340 Invece, `i flexible array members hanno un tipo incompleto, e quindi
341 sizeof() non può essere applicato
342 <https://gcc.gnu.org/onlinedocs/gcc/Zero-Length.html>`_; dunque ogni
343 uso scorretto di questo operatore verrà identificato immediatamente
344 durante la compilazione.
345
346 Per quanto riguarda gli array di un solo elemento, bisogna essere
347 consapevoli che `questi array occupano almeno quanto lo spazio di un
348 singolo oggetti dello stesso tipo
349 <https://gcc.gnu.org/onlinedocs/gcc/Zero-Length.html>`_, e quindi
350 contribuiscono al calcolo della dimensione della struttura che li
351 contiene. In questo caso è facile commettere errori quando si vuole
352 calcolare la dimensione totale della memoria totale da allocare per
353 una struttura dati::
354
355         struct something {
356                 size_t count;
357                 struct foo items[1];
358         };
359
360         struct something *instance;
361
362         instance = kmalloc(struct_size(instance, items, count - 1), GFP_KERNEL);
363         instance->count = count;
364
365         size = sizeof(instance->items) * instance->count;
366         memcpy(instance->items, source, size);
367
368 In questo esempio ci siamo dovuti ricordare di usare ``count - 1`` in
369 struct_size(), altrimenti avremmo --inavvertitamente-- allocato
370 memoria per un oggetti ``items`` in più. Il modo più pulito e meno
371 propenso agli errori è quello di usare i `flexible array member`, in
372 combinazione con struct_size() e flex_array_size()::
373
374         struct something {
375                 size_t count;
376                 struct foo items[];
377         };
378
379         struct something *instance;
380
381         instance = kmalloc(struct_size(instance, items, count), GFP_KERNEL);
382         instance->count = count;
383
384         memcpy(instance->items, source, flex_array_size(instance, items, instance->count));