~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/Documentation/dev-tools/checkuapi.rst

Version: ~ [ linux-6.12-rc7 ] ~ [ linux-6.11.7 ] ~ [ linux-6.10.14 ] ~ [ linux-6.9.12 ] ~ [ linux-6.8.12 ] ~ [ linux-6.7.12 ] ~ [ linux-6.6.60 ] ~ [ linux-6.5.13 ] ~ [ linux-6.4.16 ] ~ [ linux-6.3.13 ] ~ [ linux-6.2.16 ] ~ [ linux-6.1.116 ] ~ [ linux-6.0.19 ] ~ [ linux-5.19.17 ] ~ [ linux-5.18.19 ] ~ [ linux-5.17.15 ] ~ [ linux-5.16.20 ] ~ [ linux-5.15.171 ] ~ [ linux-5.14.21 ] ~ [ linux-5.13.19 ] ~ [ linux-5.12.19 ] ~ [ linux-5.11.22 ] ~ [ linux-5.10.229 ] ~ [ linux-5.9.16 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.285 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.323 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.336 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.337 ] ~ [ linux-4.4.302 ] ~ [ linux-3.10.108 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.12 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

Diff markup

Differences between /Documentation/dev-tools/checkuapi.rst (Version linux-6.12-rc7) and /Documentation/dev-tools/checkuapi.rst (Version unix-v6-master)


  1 .. SPDX-License-Identifier: GPL-2.0-only          
  2                                                   
  3 ============                                      
  4 UAPI Checker                                      
  5 ============                                      
  6                                                   
  7 The UAPI checker (``scripts/check-uapi.sh``) i    
  8 checks UAPI header files for userspace backwar    
  9 the git tree.                                     
 10                                                   
 11 Options                                           
 12 =======                                           
 13                                                   
 14 This section will describe the options with wh    
 15 can be run.                                       
 16                                                   
 17 Usage::                                           
 18                                                   
 19     check-uapi.sh [-b BASE_REF] [-p PAST_REF]     
 20                                                   
 21 Available options::                               
 22                                                   
 23     -b BASE_REF    Base git reference to use f    
 24                    will use any dirty changes     
 25                    dirty changes, HEAD will be    
 26     -p PAST_REF    Compare BASE_REF to PAST_RE    
 27                    will use BASE_REF^1. Must b    
 28                    that exist on PAST_REF will    
 29     -j JOBS        Number of checks to run in     
 30     -l ERROR_LOG   Write error log to file (de    
 31     -i             Ignore ambiguous changes th    
 32     -q             Quiet operation.               
 33     -v             Verbose operation (print mo    
 34                                                   
 35 Environmental args::                              
 36                                                   
 37     ABIDIFF  Custom path to abidiff binary        
 38     CC       C compiler (default is "gcc")        
 39     ARCH     Target architecture of C compiler    
 40                                                   
 41 Exit codes::                                      
 42                                                   
 43     0) Success                                    
 44     1) ABI difference detected                    
 45     2) Prerequisite not met                       
 46                                                   
 47 Examples                                          
 48 ========                                          
 49                                                   
 50 Basic Usage                                       
 51 -----------                                       
 52                                                   
 53 First, let's try making a change to a UAPI hea    
 54 won't break userspace::                           
 55                                                   
 56     cat << 'EOF' | patch -l -p1                   
 57     --- a/include/uapi/linux/acct.h               
 58     +++ b/include/uapi/linux/acct.h               
 59     @@ -21,7 +21,9 @@                             
 60      #include <asm/param.h>                       
 61      #include <asm/byteorder.h>                   
 62                                                   
 63     -/*                                           
 64     +#define FOO                                  
 65     +                                             
 66     +/*                                           
 67       *  comp_t is a 16-bit "floating" point n    
 68       *  exponent and a 13-bit fraction.          
 69       *  comp2_t is 24-bit with 5-bit base 2 e    
 70     diff --git a/include/uapi/linux/bpf.h b/in    
 71     EOF                                           
 72                                                   
 73 Now, let's use the script to validate::           
 74                                                   
 75     % ./scripts/check-uapi.sh                     
 76     Installing user-facing UAPI headers from d    
 77     Installing user-facing UAPI headers from H    
 78     Checking changes to UAPI headers between H    
 79     All 912 UAPI headers compatible with x86 a    
 80                                                   
 81 Let's add another change that *might* break us    
 82                                                   
 83     cat << 'EOF' | patch -l -p1                   
 84     --- a/include/uapi/linux/bpf.h                
 85     +++ b/include/uapi/linux/bpf.h                
 86     @@ -74,7 +74,7 @@ struct bpf_insn {           
 87             __u8    dst_reg:4;      /* dest re    
 88             __u8    src_reg:4;      /* source     
 89             __s16   off;            /* signed     
 90     -       __s32   imm;            /* signed     
 91     +       __u32   imm;            /* unsigne    
 92      };                                           
 93                                                   
 94      /* Key of an a BPF_MAP_TYPE_LPM_TRIE entr    
 95     EOF                                           
 96                                                   
 97 The script will catch this::                      
 98                                                   
 99     % ./scripts/check-uapi.sh                     
100     Installing user-facing UAPI headers from d    
101     Installing user-facing UAPI headers from H    
102     Checking changes to UAPI headers between H    
103     ==== ABI differences detected in include/l    
104         [C] 'struct bpf_insn' changed:            
105           type size hasn't changed                
106           1 data member change:                   
107             type of '__s32 imm' changed:          
108               typedef name changed from __s32     
109               underlying type 'int' changed:      
110                 type name changed from 'int' t    
111                 type size hasn't changed          
112     ==========================================    
113                                                   
114     error - 1/912 UAPI headers compatible with    
115                                                   
116 In this case, the script is reporting the type    
117 break a userspace program that passes in a neg    
118 say you know that no userspace program could p    
119 value in ``imm``, so changing to an unsigned t    
120 anything. You can pass the ``-i`` flag to the     
121 in which the userspace backwards compatibility    
122                                                   
123     % ./scripts/check-uapi.sh -i                  
124     Installing user-facing UAPI headers from d    
125     Installing user-facing UAPI headers from H    
126     Checking changes to UAPI headers between H    
127     All 912 UAPI headers compatible with x86 a    
128                                                   
129 Now, let's make a similar change that *will* b    
130                                                   
131     cat << 'EOF' | patch -l -p1                   
132     --- a/include/uapi/linux/bpf.h                
133     +++ b/include/uapi/linux/bpf.h                
134     @@ -71,8 +71,8 @@ enum {                      
135                                                   
136      struct bpf_insn {                            
137             __u8    code;           /* opcode     
138     -       __u8    dst_reg:4;      /* dest re    
139             __u8    src_reg:4;      /* source     
140     +       __u8    dst_reg:4;      /* dest re    
141             __s16   off;            /* signed     
142             __s32   imm;            /* signed     
143      };                                           
144     EOF                                           
145                                                   
146 Since we're re-ordering an existing struct mem    
147 and the script will report the breakage even i    
148                                                   
149     % ./scripts/check-uapi.sh -i                  
150     Installing user-facing UAPI headers from d    
151     Installing user-facing UAPI headers from H    
152     Checking changes to UAPI headers between H    
153     ==== ABI differences detected in include/l    
154         [C] 'struct bpf_insn' changed:            
155           type size hasn't changed                
156           2 data member changes:                  
157             '__u8 dst_reg' offset changed from    
158             '__u8 src_reg' offset changed from    
159     ==========================================    
160                                                   
161     error - 1/912 UAPI headers compatible with    
162                                                   
163 Let's commit the breaking change, then commit     
164                                                   
165     % git commit -m 'Breaking UAPI change' inc    
166     [detached HEAD f758e574663a] Breaking UAPI    
167      1 file changed, 1 insertion(+), 1 deletio    
168     % git commit -m 'Innocuous UAPI change' in    
169     [detached HEAD 2e87df769081] Innocuous UAP    
170      1 file changed, 3 insertions(+), 1 deleti    
171                                                   
172 Now, let's run the script again with no argume    
173                                                   
174     % ./scripts/check-uapi.sh                     
175     Installing user-facing UAPI headers from H    
176     Installing user-facing UAPI headers from H    
177     Checking changes to UAPI headers between H    
178     All 912 UAPI headers compatible with x86 a    
179                                                   
180 It doesn't catch any breaking change because,     
181 compares ``HEAD`` to ``HEAD^1``. The breaking     
182 ``HEAD~2``. If we wanted the search scope to g    
183 use the ``-p`` option to pass a different past    
184 let's pass ``-p HEAD~2`` to the script so it c    
185 ``HEAD~2`` and ``HEAD``::                         
186                                                   
187     % ./scripts/check-uapi.sh -p HEAD~2           
188     Installing user-facing UAPI headers from H    
189     Installing user-facing UAPI headers from H    
190     Checking changes to UAPI headers between H    
191     ==== ABI differences detected in include/l    
192         [C] 'struct bpf_insn' changed:            
193           type size hasn't changed                
194           2 data member changes:                  
195             '__u8 dst_reg' offset changed from    
196             '__u8 src_reg' offset changed from    
197     ==========================================    
198                                                   
199     error - 1/912 UAPI headers compatible with    
200                                                   
201 Alternatively, we could have also run with ``-    
202 base reference to ``HEAD~`` so then the script    
203                                                   
204 Architecture-specific Headers                     
205 -----------------------------                     
206                                                   
207 Consider this change::                            
208                                                   
209     cat << 'EOF' | patch -l -p1                   
210     --- a/arch/arm64/include/uapi/asm/sigconte    
211     +++ b/arch/arm64/include/uapi/asm/sigconte    
212     @@ -70,6 +70,7 @@ struct sigcontext {         
213      struct _aarch64_ctx {                        
214             __u32 magic;                          
215             __u32 size;                           
216     +       __u32 new_var;                        
217      };                                           
218                                                   
219      #define FPSIMD_MAGIC   0x46508001            
220     EOF                                           
221                                                   
222 This is a change to an arm64-specific UAPI hea    
223 running the script from an x86 machine with an    
224 the script only checks x86-compatible UAPI hea    
225                                                   
226     % ./scripts/check-uapi.sh                     
227     Installing user-facing UAPI headers from d    
228     Installing user-facing UAPI headers from H    
229     No changes to UAPI headers were applied be    
230                                                   
231 With an x86 compiler, we can't check header fi    
232 script doesn't even try.                          
233                                                   
234 If we want to check the header file, we'll hav    
235 set ``ARCH`` accordingly::                        
236                                                   
237     % CC=aarch64-linux-gnu-gcc ARCH=arm64 ./sc    
238     Installing user-facing UAPI headers from d    
239     Installing user-facing UAPI headers from H    
240     Checking changes to UAPI headers between H    
241     ==== ABI differences detected in include/a    
242         [C] 'struct _aarch64_ctx' changed:        
243           type size changed from 64 to 96 (in     
244           1 data member insertion:                
245             '__u32 new_var', at offset 64 (in     
246         -- snip --                                
247         [C] 'struct zt_context' changed:          
248           type size changed from 128 to 160 (i    
249           2 data member changes (1 filtered):     
250             '__u16 nregs' offset changed from     
251             '__u16 __reserved[3]' offset chang    
252     ==========================================    
253                                                   
254     error - 1/884 UAPI headers compatible with    
255                                                   
256 We can see with ``ARCH`` and ``CC`` set proper    
257 change is reported properly. Also notice that     
258 header files checked by the script changes. Th    
259 of headers installed for arm64 platforms is di    
260                                                   
261 Cross-Dependency Breakages                        
262 --------------------------                        
263                                                   
264 Consider this change::                            
265                                                   
266     cat << 'EOF' | patch -l -p1                   
267     --- a/include/uapi/linux/types.h              
268     +++ b/include/uapi/linux/types.h              
269     @@ -52,7 +52,7 @@ typedef __u32 __bitwise     
270      #define __aligned_be64 __be64 __attribute    
271      #define __aligned_le64 __le64 __attribute    
272                                                   
273     -typedef unsigned __bitwise __poll_t;         
274     +typedef unsigned short __bitwise __poll_t    
275                                                   
276      #endif /*  __ASSEMBLY__ */                   
277      #endif /* _UAPI_LINUX_TYPES_H */             
278     EOF                                           
279                                                   
280 Here, we're changing a ``typedef`` in ``types.    
281 a UAPI in ``types.h``, but other UAPIs in the     
282 this change::                                     
283                                                   
284     % ./scripts/check-uapi.sh                     
285     Installing user-facing UAPI headers from d    
286     Installing user-facing UAPI headers from H    
287     Checking changes to UAPI headers between H    
288     ==== ABI differences detected in include/l    
289         [C] 'struct epoll_event' changed:         
290           type size changed from 96 to 80 (in     
291           2 data member changes:                  
292             type of '__poll_t events' changed:    
293               underlying type 'unsigned int' c    
294                 type name changed from 'unsign    
295                 type size changed from 32 to 1    
296             '__u64 data' offset changed from 3    
297     ==========================================    
298     include/linux/eventpoll.h did not change b    
299     It's possible a change to one of the heade    
300     #include <linux/fcntl.h>                      
301     #include <linux/types.h>                      
302                                                   
303 Note that the script noticed the failing heade    
304 so it assumes one of its includes must have ca    
305 we can see ``linux/types.h`` is used from ``ev    
306                                                   
307 UAPI Header Removals                              
308 --------------------                              
309                                                   
310 Consider this change::                            
311                                                   
312     cat << 'EOF' | patch -l -p1                   
313     diff --git a/include/uapi/asm-generic/Kbui    
314     index ebb180aac74e..a9c88b0a8b3b 100644       
315     --- a/include/uapi/asm-generic/Kbuild         
316     +++ b/include/uapi/asm-generic/Kbuild         
317     @@ -31,6 +31,6 @@ mandatory-y += stat.h       
318      mandatory-y += statfs.h                      
319      mandatory-y += swab.h                        
320      mandatory-y += termbits.h                    
321     -mandatory-y += termios.h                     
322     +#mandatory-y += termios.h                    
323      mandatory-y += types.h                       
324      mandatory-y += unistd.h                      
325     EOF                                           
326                                                   
327 This script removes a UAPI header file from th    
328 the script::                                      
329                                                   
330     % ./scripts/check-uapi.sh                     
331     Installing user-facing UAPI headers from d    
332     Installing user-facing UAPI headers from H    
333     Checking changes to UAPI headers between H    
334     ==== UAPI header include/asm/termios.h was    
335                                                   
336     error - 1/912 UAPI headers compatible with    
337                                                   
338 Removing a UAPI header is considered a breakin    
339 will flag it as such.                             
340                                                   
341 Checking Historic UAPI Compatibility              
342 ------------------------------------              
343                                                   
344 You can use the ``-b`` and ``-p`` options to e    
345 git tree. For example, to check all changed UA    
346 v6.0 and v6.1, you'd run::                        
347                                                   
348     % ./scripts/check-uapi.sh -b v6.1 -p v6.0     
349     Installing user-facing UAPI headers from v    
350     Installing user-facing UAPI headers from v    
351     Checking changes to UAPI headers between v    
352                                                   
353     --- snip ---                                  
354     error - 37/907 UAPI headers compatible wit    
355                                                   
356 Note: Before v5.3, a header file needed by the    
357 so the script is unable to check changes befor    
358                                                   
359 You'll notice that the script detected many UA    
360 backwards compatible. Knowing that kernel UAPI    
361 forever, this is an alarming result. This brin    
362 caveats.                                          
363                                                   
364 Caveats                                           
365 =======                                           
366                                                   
367 The UAPI checker makes no assumptions about th    
368 types of changes may be flagged even though th    
369                                                   
370 Removals For Refactoring or Deprecation           
371 ---------------------------------------           
372                                                   
373 Sometimes drivers for very old hardware are re    
374                                                   
375     % ./scripts/check-uapi.sh -b ba47652ba655     
376     Installing user-facing UAPI headers from b    
377     Installing user-facing UAPI headers from b    
378     Checking changes to UAPI headers between b    
379     ==== UAPI header include/linux/meye.h was     
380                                                   
381     error - 1/910 UAPI headers compatible with    
382                                                   
383 The script will always flag removals (even if     
384                                                   
385 Struct Expansions                                 
386 -----------------                                 
387                                                   
388 Depending on how a structure is handled in ker    
389 expands a struct could be non-breaking.           
390                                                   
391 If a struct is used as the argument to an ioct    
392 must be able to handle ioctl commands of any s    
393 to be careful when copying data from the user.    
394 ``struct foo`` is changed like this::             
395                                                   
396     struct foo {                                  
397         __u64 a; /* added in version 1 */         
398     +   __u32 b; /* added in version 2 */         
399     +   __u32 c; /* added in version 2 */         
400     }                                             
401                                                   
402 By default, the script will flag this kind of     
403                                                   
404     [C] 'struct foo' changed:                     
405       type size changed from 64 to 128 (in bit    
406       2 data member insertions:                   
407         '__u32 b', at offset 64 (in bits)         
408         '__u32 c', at offset 96 (in bits)         
409                                                   
410 However, it is possible that this change was m    
411                                                   
412 If a userspace program was built with version     
413 ``sizeof(struct foo)`` is 8. That size will be    
414 ioctl value that gets sent to the kernel. If t    
415 with version 2, it will think the ``sizeof(str    
416                                                   
417 The kernel can use the ``_IOC_SIZE`` macro to     
418 in the ioctl code that the user passed in and     
419 ``copy_struct_from_user()`` to safely copy the    
420                                                   
421     int handle_ioctl(unsigned long cmd, unsign    
422     {                                             
423         switch _IOC_NR(cmd) {                     
424         0x01: {                                   
425             struct foo my_cmd;  /* size 16 in     
426                                                   
427             ret = copy_struct_from_user(&my_cm    
428             ...                                   
429                                                   
430 ``copy_struct_from_user`` will zero the struct    
431 only the bytes passed in from the user (leavin    
432 If the user passed in a larger struct, the ext    
433                                                   
434 If you know this situation is accounted for in    
435 pass ``-i`` to the script, and struct expansio    
436                                                   
437 Flex Array Migration                              
438 --------------------                              
439                                                   
440 While the script handles expansion into an exi    
441 still flag initial migration to flex arrays fr    
442 arrays. For example::                             
443                                                   
444     struct foo {                                  
445           __u32 x;                                
446     -     __u32 flex[1]; /* fake flex */          
447     +     __u32 flex[];  /* real flex */          
448     };                                            
449                                                   
450 This change would be flagged by the script::      
451                                                   
452     [C] 'struct foo' changed:                     
453       type size changed from 64 to 32 (in bits    
454       1 data member change:                       
455         type of '__u32 flex[1]' changed:          
456           type name changed from '__u32[1]' to    
457           array type size changed from 32 to '    
458           array type subrange 1 changed length    
459                                                   
460 At this time, there's no way to filter these t    
461 aware of this possible false positive.            
462                                                   
463 Summary                                           
464 -------                                           
465                                                   
466 While many types of false positives are filter    
467 it's possible there are some cases where the s    
468 which does not break UAPI. It's also possible     
469 break userspace would not be flagged by this s    
470 has been run on much of the kernel history, th    
471 cases that are not accounted for.                 
472                                                   
473 The intention is for this script to be used as    
474 maintainers or automated tooling, not as the e    
475 patch compatibility. It's best to remember: us    
476 (and ideally a unit test in userspace) to make    
477 are backwards-compatible!                         
                                                      

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

sflogo.php