Linux 6.7-rc7
[linux-modified.git] / Documentation / translations / sp_SP / process / deprecated.rst
1 .. include:: ../disclaimer-sp.rst
2
3 :Original: :ref:`Documentation/process/deprecated.rst <deprecated>`
4 :Translator: Sergio Gonzalez <sergio.collado@gmail.com>
5
6 .. _sp_deprecated:
7
8 ============================================================================
9 Interfaces obsoletos, Características del lenguaje, Atributos y Convenciones
10 ============================================================================
11
12 En un mundo perfecto, sería posible convertir todas las instancias de
13 alguna API obsoleta en una nueva API y quitar la API anterior en un
14 único ciclo de desarrollo. Desafortunadamente, debido al tamaño del kernel,
15 la jerarquía de mantenimiento, y el tiempo, no siempre es posible hacer
16 estos cambios de una única vez. Esto significa que las nuevas instancias
17 han de ir creándose en el kernel, mientras que las antiguas se quitan,
18 haciendo que la cantidad de trabajo para limpiar las APIs crezca. Para
19 informar a los desarrolladores sobre qué ha sido declarado obsoleto y por
20 qué, ha sido creada esta lista como un lugar donde indicar cuando los usos
21 obsoletos son propuestos para incluir en el kernel.
22
23 __deprecated
24 ------------
25 Mientras que este atributo señala visualmente que un interface ha sido
26 declarado obsoleto, este `no produce más avisos durante las compilaciones
27 <https://git.kernel.org/linus/771c035372a036f83353eef46dbb829780330234>`_
28 porque uno de los objetivos del kernel es que compile sin avisos, y
29 nadie ha hecho nada para quitar estos interfaces obsoletos. Mientras
30 que usar `__deprecated` es sencillo para anotar una API obsoleta en
31 un archivo de cabecera, no es la solución completa. Dichos interfaces
32 deben o bien ser quitados por completo, o añadidos a este archivo para
33 desanimar a otros a usarla en el futuro.
34
35 BUG() y BUG_ON()
36 ----------------
37 Use WARN() y WARN_ON() en su lugar, y gestione las condiciones de error
38 "imposibles" tan elegantemente como se pueda. Mientras que la familia de
39 funciones BUG() fueron originalmente diseñadas para actuar como una
40 "situación imposible", confirmar y disponer de un hilo del kernel de forma
41 "segura", estas funciones han resultado ser demasiado arriesgadas. (e.g.
42 "¿en qué orden se necesitan liberar los locks? ¿Se han restaurado sus
43 estados?). La popular función BUG() desestabilizará el sistema o lo romperá
44 totalmente, lo cual hace imposible depurarlo o incluso generar reportes de
45 crash. Linus tiene una `opinión muy fuerte
46 <https://lore.kernel.org/lkml/CA+55aFy6jNLsywVYdGp83AMrXBo_P-pkjkphPGrO=82SPKCpLQ@mail.gmail.com/>`_
47 y sentimientos `sobre esto
48 <https://lore.kernel.org/lkml/CAHk-=whDHsbK3HTOpTF=ue_o04onRwTEaK_ZoJp_fjbqq4+=Jw@mail.gmail.com/>`_.
49
50 Nótese que la familia de funciones WARN() únicamente debería ser usada
51 en situaciones que se "esperan no sean alcanzables". Si se quiere
52 avisar sobre situaciones "alcanzables pero no deseadas", úsese la familia
53 de funciones pr_warn(). Los responsables del sistema pueden haber definido
54 *panic_on_warn* sysctl para asegurarse que sus sistemas no continúan
55 ejecutándose en presencia del condiciones "no alcanzables". (Por ejemplo,
56 véase commits como `este
57 <https://git.kernel.org/linus/d4689846881d160a4d12a514e991a740bcb5d65a>`_.)
58
59 Operaciones aritméticas en los argumentos de reserva de memoria
60 ---------------------------------------------------------------
61 Los cálculos dinámicos de tamaño (especialmente multiplicaciones) no
62 deberían realizarse en los argumentos de reserva de memoria (o similares)
63 debido al riesgo de desbordamiento. Esto puede llevar a valores rotando y
64 que se realicen reservas de memoria menores que las que se esperaban. El
65 uso de esas reservas puede llevar a desbordamientos en el 'heap' de memoria
66 y otros funcionamientos incorrectos. (Una excepción a esto son los valores
67 literales donde el compilador si puede avisar si estos puede desbordarse.
68 De todos modos, el método recomendado en estos caso es reescribir el código
69 como se sugiere a continuación para evitar las operaciones aritméticas en
70 la reserva de memoria.)
71
72 Por ejemplo, no utilice `count * size`` como argumento, como en::
73
74     foo = kmalloc(count * size, GFP_KERNEL);
75
76 En vez de eso, utilice la reserva con dos argumentos::
77
78         foo = kmalloc_array(count, size, GFP_KERNEL);
79
80 Específicamente, kmalloc() puede ser sustituido con kmalloc_array(),
81 kzalloc() puede ser sustituido con kcalloc().
82
83 Si no existen funciones con dos argumentos, utilice las funciones que se
84 saturan, en caso de desbordamiento::
85
86         bar = vmalloc(array_size(count, size));
87
88 Otro caso común a evitar es calcular el tamaño de una estructura com
89 la suma de otras estructuras, como en::
90
91     header = kzalloc(sizeof(*header) + count * sizeof(*header->item),
92                   GFP_KERNEL);
93
94 En vez de eso emplee::
95
96     header = kzalloc(struct_size(header, item, count), GFP_KERNEL);
97
98 .. note:: Si se usa struct_size() en una estructura que contiene un elemento
99         de longitud cero o un array de un único elemento como un array miembro,
100         por favor reescribir ese uso y cambiar a un `miembro array flexible
101         <#zero-length-and-one-element-arrays>`_
102
103
104 Para otros cálculos, por favor use las funciones de ayuda: size_mul(),
105 size_add(), and size_sub(). Por ejemplo, en el caso de::
106
107     foo = krealloc(current_size + chunk_size * (count - 3), GFP_KERNEL);
108
109 Re-escríbase, como::
110
111     foo = krealloc(size_add(current_size,
112                          size_mul(chunk_size,
113                                   size_sub(count, 3))), GFP_KERNEL);
114
115 Para más detalles, mire también array3_size() y flex_array_size(),
116 como también la familia de funciones relacionadas check_mul_overflow(),
117 check_add_overflow(), check_sub_overflow(), y check_shl_overflow().
118
119
120 simple_strtol(), simple_strtoll(), simple_strtoul(), simple_strtoull()
121 ----------------------------------------------------------------------
122 Las funciones: simple_strtol(), simple_strtoll(), simple_strtoul(), y
123 simple_strtoull() explícitamente ignoran los desbordamientos, lo que puede
124 llevar a resultados inesperados por las funciones que las llaman. Las
125 funciones respectivas kstrtol(), kstrtoll(), kstrtoul(), y kstrtoull()
126 tienden a ser reemplazos correctos, aunque nótese que necesitarán que la
127 cadena de caracteres termine en NUL o en el carácter de línea nueva.
128
129
130 strcpy()
131 --------
132 strcpy() no realiza verificaciones de los límites del buffer de destino.
133 Esto puede resultar en desbordamientos lineals más allá del fin del buffer,
134 causando todo tipo de errores. Mientras `CONFIG_FORTIFY_SOURCE=y` otras
135 varias opciones de compilación reducen el riesgo de usar esta función, no
136 hay ninguna buena razón para añadir nuevos usos de esta. El remplazo seguro
137 es la función strscpy(), aunque se ha de tener cuidado con cualquier caso
138 en el el valor retornado por strcpy() sea usado, ya que strscpy() no
139 devuelve un puntero a el destino, sino el número de caracteres no nulos
140 compilados (o el valor negativo de errno cuando se trunca la cadena de
141 caracteres).
142
143 strncpy() en cadenas de caracteres terminadas en NUL
144 ----------------------------------------------------
145 El uso de strncpy() no garantiza que el buffer de destino esté terminado en
146 NUL. Esto puede causar varios errores de desbordamiento en lectura y otros
147 tipos de funcionamiento erróneo debido a que falta la terminación en NUL.
148 Esta función también termina la cadena de caracteres en NUL en el buffer de
149 destino si la cadena de origen es más corta que el buffer de destino, lo
150 cual puede ser una penalización innecesaria para funciones usen esta
151 función con cadenas de caracteres que sí están terminadas en NUL.
152
153 Cuando se necesita que la cadena de destino sea terminada en NUL,
154 el mejor reemplazo es usar la función strscpy(), aunque se ha de tener
155 cuidado en los casos en los que el valor de strncpy() fuera usado, ya que
156 strscpy() no devuelve un puntero al destino, sino el número de
157 caracteres no nulos copiados (o el valor negativo de errno cuando se trunca
158 la cadena de caracteres). Cualquier caso restante que necesitase todavía
159 ser terminado en el caracter nulo, debería usar strscpy_pad().
160
161 Si una función usa cadenas de caracteres que no necesitan terminar en NUL,
162 debería usarse strtomem(), y el destino debería señalarse con el atributo
163 `__nonstring
164 <https://gcc.gnu.org/onlinedocs/gcc/Common-Variable-Attributes.html>`_
165 para evitar avisos futuros en el compilador. Para casos que todavía
166 necesitan cadenas de caracteres que se rellenen al final con el
167 caracter NUL, usar strtomem_pad().
168
169 strlcpy()
170 ---------
171 strlcpy() primero lee por completo el buffer de origen (ya que el valor
172 devuelto intenta ser el mismo que el de strlen()). Esta lectura puede
173 sobrepasar el límite de tamaño del destino. Esto ineficiente y puede causar
174 desbordamientos de lectura si la cadena de origen no está terminada en el
175 carácter NUL. El reemplazo seguro de esta función es strscpy(), pero se ha
176 de tener cuidado que en los casos en lso que se usase el valor devuelto de
177 strlcpy(), ya que strscpy() devolverá valores negativos de erno cuando se
178 produzcan truncados.
179
180 Especificación de formato %p
181 ----------------------------
182 Tradicionalmente,el uso de "%p" en el formato de cadenas de caracteres
183 resultaría en exponer esas direcciones en dmesg, proc, sysfs, etc. En vez
184 de dejar que sean una vulnerabilidad, todos los "%p" que se usan en el
185 kernel se imprimen como un hash, haciéndolos efectivamente inutilizables
186 para usarlos como direcciones de memoria. Nuevos usos de "%p" no deberían
187 ser añadidos al kernel. Para textos de direcciones, usar "%pS" es
188 mejor, ya que resulta en el nombre del símbolo. Para prácticamente el
189 resto de casos, mejor no usar "%p" en absoluto.
190
191 Parafraseando las actuales `direcciones de Linus <https://lore.kernel.org/lkml/CA+55aFwQEd_d40g4mUCSsVRZzrFPUJt74vc6PPpb675hYNXcKw@mail.gmail.com/>`_:
192
193 - Si el valor "hasheado" "%p" no tienen ninguna finalidad, preguntarse si el
194   puntero es realmente importante. ¿Quizás se podría quitar totalmente?
195 - Si realmente se piensa que el valor del puntero es importante, ¿porqué
196   algún estado del sistema o nivel de privilegio de usuario es considerado
197   "especial"? Si piensa que puede justificarse (en comentarios y mensajes
198   del commit), de forma suficiente como para pasar el escrutinio de Linux,
199   quizás pueda usar el "%p", a la vez que se asegura que tiene los permisos
200   correspondientes.
201
202 Si está depurando algo donde el "%p" hasheado está causando problemas,
203 se puede arrancar temporalmente con la opción de depuración "`no_hash_pointers
204 <https://git.kernel.org/linus/5ead723a20e0447bc7db33dc3070b420e5f80aa6>`_".
205
206
207 Arrays de longitud variable (VLAs)
208 ----------------------------------
209 Usando VLA en la pila (stack) produce un código mucho peor que los arrays
210 de tamaño estático. Mientras que estos errores no triviales de `rendimiento
211 <https://git.kernel.org/linus/02361bc77888>`_  son razón suficiente
212 para no usar VLAs, esto además son un riesgo de seguridad. El crecimiento
213 dinámico del array en la pila, puede exceder la memoria restante en
214 el segmento de la pila. Esto podría llevara a un fallo, posible sobre-escritura
215 de contenido al final de la pila (cuando se construye sin
216 `CONFIG_THREAD_INFO_IN_TASK=y`), o sobre-escritura de la memoria adyacente
217 a la pila (cuando se construye sin `CONFIG_VMAP_STACK=y`).
218
219
220 Switch case fall-through implícito
221 ----------------------------------
222 El lenguaje C permite a las sentencias 'switch' saltar de un caso al
223 siguiente caso cuando la sentencia de ruptura "break" no aparece al final
224 del caso. Esto, introduce ambigüedad en el código, ya que no siempre está
225 claro si el 'break' que falta es intencionado o un olvido. Por ejemplo, no
226 es obvio solamente mirando al código si `STATE_ONE` está escrito para
227 intencionadamente saltar en `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 Ya que ha habido una larga lista de defectos `debidos a declaraciones de "break"
240 que faltan <https://cwe.mitre.org/data/definitions/484.html>`_, no se
241 permiten 'fall-through' implícitos. Para identificar 'fall-through'
242 intencionados, se ha adoptado la pseudo-palabra-clave macro "falltrhrough",
243 que expande las extensiones de gcc `__attribute__((__fallthrough__))
244 <https://gcc.gnu.org/onlinedocs/gcc/Statement-Attributes.html>`_.
245 (Cuando la sintaxis de C17/c18 `[[fallthrough]]` sea más comúnmente
246 soportadas por los compiladores de C, analizadores estáticos, e IDEs,
247 se puede cambiar a usar esa sintaxis para esa pseudo-palabra-clave.
248
249 Todos los bloques switch/case deben acabar en uno de:
250
251 * break;
252 * fallthrough;
253 * continue;
254 * goto <label>;
255 * return [expression];
256
257
258 Arrays de longitud cero y un elemento
259 -------------------------------------
260 Hay una necesidad habitual en el kernel de proveer una forma para declarar
261 un grupo de elementos consecutivos de tamaño dinámico en una estructura.
262 El código del kernel debería usar siempre `"miembros array flexible" <https://en.wikipedia.org/wiki/Flexible_array_member>`_
263 en estos casos. El estilo anterior de arrays de un elemento o de longitud
264 cero, no deben usarse más.
265
266 En el código C más antiguo, los elementos finales de tamaño dinámico se
267 obtenían especificando un array de un elemento al final de una estructura::
268
269         struct something {
270                 size_t count;
271                 struct foo items[1];
272         };
273
274 En código C más antiguo, elementos seguidos de tamaño dinámico eran creados
275 especificando una array de un único elemento al final de una estructura::
276
277         struct something {
278                 size_t count;
279                 struct foo items[1];
280         };
281
282 Esto llevó a resultados incorrectos en los cálculos de tamaño mediante
283 sizeof() (el cual hubiera necesitado eliminar el tamaño del último elemento
284 para tener un tamaño correcto de la "cabecera"). Una `extensión de GNU C
285 <https://gcc.gnu.org/onlinedocs/gcc/Zero-Length.html>`_ se empezó a usar
286 para permitir los arrays de longitud cero, para evitar estos tipos de
287 problemas de tamaño::
288
289         struct something {
290                 size_t count;
291                 struct foo items[0];
292         };
293
294 Pero esto llevó a otros problemas, y no solucionó algunos otros problemas
295 compartidos por ambos estilos, como no ser capaz de detectar cuando ese array
296 accidentalmente _no_ es usado al final de la estructura (lo que podía pasar
297 directamente, o cuando dicha estructura era usada en uniones, estructuras
298 de estructuras, etc).
299
300 C99 introdujo "los arrays miembros flexibles", los cuales carecen de un
301 tamaño numérico en su declaración del array::
302
303         struct something {
304                 size_t count;
305                 struct foo items[];
306         };
307
308 Esta es la forma en la que el kernel espera que se declaren los elementos
309 de tamaño dinámico concatenados. Esto permite al compilador generar
310 errores, cuando el array flexible no es declarado en el último lugar de la
311 estructura, lo que ayuda a prevenir errores en él código del tipo
312 `comportamiento indefinido <https://git.kernel.org/linus/76497732932f15e7323dc805e8ea8dc11bb587cf>`_.
313 Esto también permite al compilador analizar correctamente los tamaños de
314 los arrays (via sizeof(), `CONFIG_FORTIFY_SOURCE`, y `CONFIG_UBSAN_BOUNDS`).
315 Por ejemplo, si no hay un mecanismo que avise que el siguiente uso de
316 sizeof() en un array de longitud cero, siempre resulta en cero::
317
318         struct something {
319                 size_t count;
320                 struct foo items[0];
321         };
322
323         struct something *instance;
324
325         instance = kmalloc(struct_size(instance, items, count), GFP_KERNEL);
326         instance->count = count;
327
328         size = sizeof(instance->items) * instance->count;
329         memcpy(instance->items, source, size);
330
331 En la última línea del código anterior, ``zero`` vale ``cero``, cuando uno
332 podría esperar que representa el tamaño total en bytes de la memoria dinámica
333 reservada para el array consecutivo ``items``. Aquí hay un par de ejemplos
334 más sobre este tema:  `link 1
335 <https://git.kernel.org/linus/f2cd32a443da694ac4e28fbf4ac6f9d5cc63a539>`_,
336 `link 2
337 <https://git.kernel.org/linus/ab91c2a89f86be2898cee208d492816ec238b2cf>`_.
338 Sin embargo, los array de miembros flexibles tienen un type incompleto, y
339 no se ha de aplicar el operador sizeof()<https://gcc.gnu.org/onlinedocs/gcc/Zero-Length.html>`_,
340 así cualquier mal uso de dichos operadores será detectado inmediatamente en
341 el momento de compilación.
342
343 Con respecto a los arrays de un único elemento, se ha de ser consciente de
344 que dichos arrays ocupan al menos tanto espacio como un único objeto del
345 tipo https://gcc.gnu.org/onlinedocs/gcc/Zero-Length.html>`_, de ahí que
346 estos contribuyan al tamaño de la estructura que los contiene. Esto es
347 proclive a errores cada vez que se quiere calcular el tamaño total de la
348 memoria dinámica para reservar una estructura que contenga un array de este
349 tipo como su miembro::
350
351         struct something {
352                 size_t count;
353                 struct foo items[1];
354         };
355
356         struct something *instance;
357
358         instance = kmalloc(struct_size(instance, items, count - 1), GFP_KERNEL);
359         instance->count = count;
360
361         size = sizeof(instance->items) * instance->count;
362         memcpy(instance->items, source, size);
363
364 En el ejemplo anterior, hemos de recordar calcular ``count - 1``, cuando se
365 usa la función de ayuda struct_size(), de otro modo estaríamos
366 --desintencionadamente--reservando memoria para un  ``items`` de más. La
367 forma más clara y menos proclive a errores es implementar esto mediante el
368 uso de `array miembro flexible`, junto con las funciones de ayuda:
369 struct_size() y flex_array_size()::
370
371         struct something {
372                 size_t count;
373                 struct foo items[];
374         };
375
376         struct something *instance;
377
378         instance = kmalloc(struct_size(instance, items, count), GFP_KERNEL);
379         instance->count = count;
380
381         memcpy(instance->items, source, flex_array_size(instance, items, instance->count));