-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy path0005-glibc-add-clang-style-FORTIFY.patch
2617 lines (2469 loc) · 102 KB
/
0005-glibc-add-clang-style-FORTIFY.patch
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
From 1e582b31eca589ef4fc5b85b2e4ad1251e65e178 Mon Sep 17 00:00:00 2001
From: George Burgess IV <gbiv@google.com>
Date: Wed, 10 Aug 2016 17:34:09 -0700
Subject: [PATCH 5/9] glibc: add clang-style FORTIFY.
This patch adds support for a clang-style FORTIFY to ChromeOS's glibc.
Without this, when we swap to clang as the default compiler for
ChromeOS, our FORTIFY story will get *way* worse. When given a gcc-style
FORTIFY, clang is unable to emit just about any compile-time
diagnostics, and the dynamic checks that clang emits is a (small) subset
of gcc's.
This patch makes clang's diagnostic story nearly on-par with gcc's, and
should allow clang to dynamically catch just about any bug that gcc can
(either statically or dynamically). Due to differences in how the
compilers work (e.g. how they optimize code, etc.), there may be cases
where clang detects errors at run-time where gcc can't and vice-versa.
This patch is from
https://sourceware.org/ml/libc-alpha/2017-09/msg00434.html
[Adrian: forward-ported to glibc 2.35]
---
io/bits/fcntl2.h | 125 ++++++++--
io/bits/poll2.h | 46 ++--
io/fcntl.h | 2 +-
libio/bits/stdio2.h | 313 +++++++++++++----------
misc/bits/syslog.h | 30 ++-
misc/sys/cdefs.h | 164 +++++++++++-
posix/bits/unistd.h | 302 +++++++++++-----------
rt/bits/mqueue2.h | 44 +++-
rt/mqueue.h | 2 +-
socket/bits/socket2.h | 54 ++--
stdlib/bits/stdlib.h | 107 ++++----
string/bits/string_fortified.h | 143 +++++++----
string/bits/strings_fortified.h | 38 ++-
wcsmbs/bits/wchar2.h | 426 +++++++++++++++++---------------
14 files changed, 1131 insertions(+), 665 deletions(-)
diff --git a/io/bits/fcntl2.h b/io/bits/fcntl2.h
index bdb48fa815..b30815dd97 100644
--- a/io/bits/fcntl2.h
+++ b/io/bits/fcntl2.h
@@ -32,10 +32,28 @@ extern int __REDIRECT (__open_2, (const char *__path, int __oflag),
extern int __REDIRECT (__open_alias, (const char *__path, int __oflag, ...),
open64) __nonnull ((1));
#endif
-__errordecl (__open_too_many_args,
- "open can be called either with 2 or 3 arguments, not more");
-__errordecl (__open_missing_mode,
- "open with O_CREAT or O_TMPFILE in second argument needs 3 arguments");
+
+#define __warn_open_too_many_args \
+ "open can be called either with 2 or 3 arguments, not more"
+#define __warn_open_missing_mode \
+ "open with O_CREAT in second argument needs 3 arguments"
+#ifdef __use_clang_fortify
+__fortify_overload __clang_prefer_this_overload int
+open (const char *const __clang_pass_object_size __path, int __oflag)
+ __clang_error_if (__OPEN_NEEDS_MODE (__oflag), __warn_open_missing_mode)
+{
+ return __open_2 (__path, __oflag);
+}
+
+__fortify_overload int
+open (const char *const __clang_pass_object_size __path, int __oflag,
+ mode_t __mode)
+{
+ return __open_alias (__path, __oflag, __mode);
+}
+#else
+__errordecl (__open_too_many_args, __warn_open_too_many_args);
+__errordecl (__open_missing_mode, __warn_open_missing_mode);
__fortify_function int
open (const char *__path, int __oflag, ...)
@@ -58,16 +76,37 @@ open (const char *__path, int __oflag, ...)
return __open_alias (__path, __oflag, __va_arg_pack ());
}
+#endif
+#undef __warn_open_too_many_args
+#undef __warn_open_missing_mode
#ifdef __USE_LARGEFILE64
extern int __open64_2 (const char *__path, int __oflag) __nonnull ((1));
extern int __REDIRECT (__open64_alias, (const char *__path, int __oflag,
...), open64) __nonnull ((1));
-__errordecl (__open64_too_many_args,
- "open64 can be called either with 2 or 3 arguments, not more");
-__errordecl (__open64_missing_mode,
- "open64 with O_CREAT or O_TMPFILE in second argument needs 3 arguments");
+
+# define __warn_open64_too_many_args \
+ "open64 can be called either with 2 or 3 arguments, not more"
+# define __warn_open64_missing_mode \
+ "open64 with O_CREAT in second argument needs 3 arguments"
+# ifdef __use_clang_fortify
+__fortify_overload __clang_prefer_this_overload int
+open64 (const char *const __clang_pass_object_size __path, int __oflag)
+ __clang_error_if (__OPEN_NEEDS_MODE (__oflag), __warn_open64_missing_mode)
+{
+ return __open64_2 (__path, __oflag);
+}
+
+__fortify_overload __clang_prefer_this_overload int
+open64 (const char *const __clang_pass_object_size __path, int __oflag,
+ int __mode)
+{
+ return __open64_alias (__path, __oflag, __mode);
+}
+# else
+__errordecl (__open64_too_many_args, __warn_open64_too_many_args);
+__errordecl (__open64_missing_mode, __warn_open64_missing_mode);
__fortify_function int
open64 (const char *__path, int __oflag, ...)
@@ -90,6 +129,9 @@ open64 (const char *__path, int __oflag, ...)
return __open64_alias (__path, __oflag, __va_arg_pack ());
}
+# endif
+# undef __warn_open64_too_many_args
+# undef __warn_open64_missing_mode
#endif
@@ -108,10 +150,32 @@ extern int __REDIRECT (__openat_alias, (int __fd, const char *__path,
int __oflag, ...), openat64)
__nonnull ((2));
# endif
-__errordecl (__openat_too_many_args,
- "openat can be called either with 3 or 4 arguments, not more");
-__errordecl (__openat_missing_mode,
- "openat with O_CREAT or O_TMPFILE in third argument needs 4 arguments");
+
+# define __warn_openat_too_many_args "openat can be called either with 3 or " \
+ "4 arguments, not more"
+# define __warn_openat_missing_mode "openat with O_CREAT in third argument " \
+ "needs 4 arguments"
+# ifdef __use_clang_fortify
+__fortify_error_function __clang_error (__warn_openat_too_many_args) int
+openat (int __fd, const char *__path, int __oflag, int __mode, ...);
+
+__fortify_overload __clang_prefer_this_overload int
+openat (int __fd, const char *const __clang_pass_object_size __path,
+ int __oflag)
+ __clang_error_if (__OPEN_NEEDS_MODE (__oflag), __warn_openat_missing_mode)
+{
+ return __openat_2 (__fd, __path, __oflag);
+}
+
+__fortify_overload __clang_prefer_this_overload int
+openat (int __fd, const char *const __clang_pass_object_size __path,
+ int __oflag, int __mode)
+{
+ return __openat_alias (__fd, __path, __oflag, __mode);
+}
+# else
+__errordecl (__openat_too_many_args, __warn_openat_too_many_args);
+__errordecl (__openat_missing_mode, __warn_openat_missing_mode);
__fortify_function int
openat (int __fd, const char *__path, int __oflag, ...)
@@ -134,6 +198,9 @@ openat (int __fd, const char *__path, int __oflag, ...)
return __openat_alias (__fd, __path, __oflag, __va_arg_pack ());
}
+# endif
+# undef __warn_openat_too_many_args
+# undef __warn_openat_missing_mode
# ifdef __USE_LARGEFILE64
@@ -142,11 +209,34 @@ extern int __openat64_2 (int __fd, const char *__path, int __oflag)
extern int __REDIRECT (__openat64_alias, (int __fd, const char *__path,
int __oflag, ...), openat64)
__nonnull ((2));
-__errordecl (__openat64_too_many_args,
- "openat64 can be called either with 3 or 4 arguments, not more");
-__errordecl (__openat64_missing_mode,
- "openat64 with O_CREAT or O_TMPFILE in third argument needs 4 arguments");
+# define __warn_openat64_too_many_args "openat64 can be called either with " \
+ "3 or 4 arguments, not more"
+# define __warn_openat64_missing_mode "openat64 with O_CREAT in third " \
+ "argument needs 4 arguments"
+
+# ifdef __use_clang_fortify
+__fortify_error_function __clang_error (__warn_openat64_too_many_args) int
+openat64 (int __fd, const char *__path, int __oflag, int __mode, ...);
+
+__fortify_overload __clang_prefer_this_overload int
+openat64 (int __fd, const char *const __clang_pass_object_size __path,
+ int __oflag)
+ __clang_error_if (__OPEN_NEEDS_MODE (__oflag),
+ __warn_openat64_missing_mode)
+{
+ return __openat64_2 (__fd, __path, __oflag);
+}
+
+__fortify_overload __clang_prefer_this_overload int
+openat64 (int __fd, const char *const __clang_pass_object_size __path,
+ int __oflag, int __mode)
+{
+ return __openat64_alias (__fd, __path, __oflag, __mode);
+}
+# else
+__errordecl (__openat64_too_many_args, __warn_openat64_too_many_args);
+__errordecl (__openat64_missing_mode, __warn_openat64_missing_mode);
__fortify_function int
openat64 (int __fd, const char *__path, int __oflag, ...)
{
@@ -168,5 +258,8 @@ openat64 (int __fd, const char *__path, int __oflag, ...)
return __openat64_alias (__fd, __path, __oflag, __va_arg_pack ());
}
+# endif
+# undef __warn_openat64_too_many_args
+# undef __warn_openat64_missing_mode
# endif
#endif
diff --git a/io/bits/poll2.h b/io/bits/poll2.h
index d85d3ff48d..dcab4e68e3 100644
--- a/io/bits/poll2.h
+++ b/io/bits/poll2.h
@@ -28,19 +28,20 @@ extern int __REDIRECT (__poll_alias, (struct pollfd *__fds, nfds_t __nfds,
extern int __poll_chk (struct pollfd *__fds, nfds_t __nfds, int __timeout,
__SIZE_TYPE__ __fdslen)
__attr_access ((__write_only__, 1, 2));
-extern int __REDIRECT (__poll_chk_warn, (struct pollfd *__fds, nfds_t __nfds,
- int __timeout, __SIZE_TYPE__ __fdslen),
- __poll_chk)
- __warnattr ("poll called with fds buffer too small file nfds entries");
-__fortify_function __fortified_attr_access (__write_only__, 1, 2) int
-poll (struct pollfd *__fds, nfds_t __nfds, int __timeout)
+__fortify_potential_overload int
+poll (struct pollfd *const __clang_pass_object_size __fds, nfds_t __nfds,
+ int __timeout)
+__FORTIFY_PRECONDITIONS
+ __FORTIFY_WARNING_ONLY_IF_BOS_LT2 (__poll_warn, __nfds, __fds,
+ sizeof (*__fds),
+ "poll called with fds buffer too small")
{
- return __glibc_fortify (poll, __nfds, sizeof (*__fds),
- __glibc_objsize (__fds),
- __fds, __nfds, __timeout);
+ if (__FORTIFY_CALL_CHK && __glibc_objsize (__fds) != (__SIZE_TYPE__) -1)
+ return __poll_chk (__fds, __nfds, __timeout, __glibc_objsize (__fds));
+ return __poll_alias (__fds, __nfds, __timeout);
}
-
+__FORTIFY_FUNCTION_END
#ifdef __USE_GNU
# ifdef __USE_TIME_BITS64
@@ -74,21 +75,22 @@ extern int __ppoll_chk (struct pollfd *__fds, nfds_t __nfds,
const struct timespec *__timeout,
const __sigset_t *__ss, __SIZE_TYPE__ __fdslen)
__attr_access ((__write_only__, 1, 2));
-extern int __REDIRECT (__ppoll_chk_warn, (struct pollfd *__fds, nfds_t __nfds,
- const struct timespec *__timeout,
- const __sigset_t *__ss,
- __SIZE_TYPE__ __fdslen),
- __ppoll_chk)
- __warnattr ("ppoll called with fds buffer too small file nfds entries");
-__fortify_function __fortified_attr_access (__write_only__, 1, 2) int
-ppoll (struct pollfd *__fds, nfds_t __nfds, const struct timespec *__timeout,
- const __sigset_t *__ss)
+__fortify_potential_overload int
+ppoll (struct pollfd *const __clang_pass_object_size __fds, nfds_t __nfds,
+ const struct timespec *__timeout, const __sigset_t *__ss)
+__FORTIFY_PRECONDITIONS
+ __FORTIFY_WARNING_ONLY_IF_BOS_LT2 (__ppoll_warn, __nfds, __fds,
+ sizeof (*__fds),
+ "ppoll called with fds buffer too "
+ "small file nfds entries")
{
- return __glibc_fortify (ppoll, __nfds, sizeof (*__fds),
- __glibc_objsize (__fds),
- __fds, __nfds, __timeout, __ss);
+ if (__FORTIFY_CALL_CHK && __glibc_objsize (__fds) != (__SIZE_TYPE__) -1)
+ return __ppoll_chk (__fds, __nfds, __timeout, __ss,
+ __glibc_objsize (__fds));
+ return __ppoll_alias (__fds, __nfds, __timeout, __ss);
}
+__FORTIFY_FUNCTION_END
# endif
#endif
diff --git a/io/fcntl.h b/io/fcntl.h
index dd620c086f..e973c61f9d 100644
--- a/io/fcntl.h
+++ b/io/fcntl.h
@@ -338,7 +338,7 @@ extern int posix_fallocate64 (int __fd, off64_t __offset, off64_t __len);
/* Define some inlines helping to catch common problems. */
#if __USE_FORTIFY_LEVEL > 0 && defined __fortify_function \
- && defined __va_arg_pack_len
+ && (defined __va_arg_pack_len || defined __use_clang_fortify)
# include <bits/fcntl2.h>
#endif
diff --git a/libio/bits/stdio2.h b/libio/bits/stdio2.h
index ad85f7df8b..126c4f98b3 100644
--- a/libio/bits/stdio2.h
+++ b/libio/bits/stdio2.h
@@ -23,13 +23,23 @@
# error "Never include <bits/stdio2.h> directly; use <stdio.h> instead."
#endif
-#ifdef __va_arg_pack
-__fortify_function int
-__NTH (sprintf (char *__restrict __s, const char *__restrict __fmt, ...))
+#define __mul_may_overflow(size, n) \
+ ((size | n) >= (((size_t)1) << (8 * sizeof (size_t) / 2)))
+
+#ifdef __FORTIFY_ARG_PACK_OK
+/* clang doesn't have __va_arg_pack, so we need to defer to the va_arg versions
+ of these functions. */
+__fortify_potential_overload __attribute__ ((__format__ (__printf__, 2, 3))) int
+__NTH (sprintf (char *__restrict const __clang_pass_object_size __s,
+ const char *__restrict __fmt, ...))
{
- return __builtin___sprintf_chk (__s, __USE_FORTIFY_LEVEL - 1,
- __glibc_objsize (__s), __fmt,
- __va_arg_pack ());
+ __FORTIFY_INIT_ARG_PACK(__fmt);
+ int __result = __FORTIFY_CALL_VA_BUILTIN (sprintf, __s,
+ __USE_FORTIFY_LEVEL - 1,
+ __glibc_objsize (__s), __fmt,
+ __FORTIFY_ARG_PACK);
+ __FORTIFY_FREE_ARG_PACK();
+ return __result;
}
#elif !defined __cplusplus
# define sprintf(str, ...) \
@@ -37,23 +47,30 @@ __NTH (sprintf (char *__restrict __s, const char *__restrict __fmt, ...))
__glibc_objsize (str), __VA_ARGS__)
#endif
-__fortify_function int
-__NTH (vsprintf (char *__restrict __s, const char *__restrict __fmt,
- __gnuc_va_list __ap))
+__fortify_potential_overload int
+__NTH (vsprintf (char *__restrict const __clang_pass_object_size __s,
+ const char *__restrict __fmt, __gnuc_va_list __ap))
{
return __builtin___vsprintf_chk (__s, __USE_FORTIFY_LEVEL - 1,
__glibc_objsize (__s), __fmt, __ap);
}
#if defined __USE_ISOC99 || defined __USE_UNIX98
-# ifdef __va_arg_pack
-__fortify_function int
-__NTH (snprintf (char *__restrict __s, size_t __n,
- const char *__restrict __fmt, ...))
+# ifdef __FORTIFY_ARG_PACK_OK
+__fortify_potential_overload __attribute__ ((__format__ (__printf__, 3, 4))) int
+__NTH (snprintf (char *__restrict const __clang_pass_object_size __s,
+ size_t __n, const char *__restrict __fmt, ...))
+ /* GCC's builtin will catch this, so we just need to cover clang here. */
+ __clang_warning_if (__bos_static_lt (__n, __s),
+ "call to snprintf may overflow the destination buffer")
{
- return __builtin___snprintf_chk (__s, __n, __USE_FORTIFY_LEVEL - 1,
- __glibc_objsize (__s), __fmt,
- __va_arg_pack ());
+ __FORTIFY_INIT_ARG_PACK(__fmt);
+ int __result = __FORTIFY_CALL_VA_BUILTIN (snprintf, __s, __n,
+ __USE_FORTIFY_LEVEL - 1,
+ __glibc_objsize (__s), __fmt,
+ __FORTIFY_ARG_PACK);
+ __FORTIFY_FREE_ARG_PACK();
+ return __result;
}
# elif !defined __cplusplus
# define snprintf(str, len, ...) \
@@ -61,9 +78,12 @@ __NTH (snprintf (char *__restrict __s, size_t __n,
__glibc_objsize (str), __VA_ARGS__)
# endif
-__fortify_function int
-__NTH (vsnprintf (char *__restrict __s, size_t __n,
- const char *__restrict __fmt, __gnuc_va_list __ap))
+__fortify_potential_overload __attribute__ ((__format__ (__printf__, 3, 0))) int
+__NTH (vsnprintf (char *__restrict const __clang_pass_object_size __s,
+ size_t __n, const char *__restrict __fmt, __gnuc_va_list __ap))
+ __clang_warning_if (__bos_static_lt (__n, __s),
+ "call to vsnprintf may overflow the destination "
+ "buffer")
{
return __builtin___vsnprintf_chk (__s, __n, __USE_FORTIFY_LEVEL - 1,
__glibc_objsize (__s), __fmt, __ap);
@@ -72,18 +92,27 @@ __NTH (vsnprintf (char *__restrict __s, size_t __n,
#endif
#if __USE_FORTIFY_LEVEL > 1
-# ifdef __va_arg_pack
-__fortify_function int
-fprintf (FILE *__restrict __stream, const char *__restrict __fmt, ...)
+# ifdef __FORTIFY_ARG_PACK_OK
+__fortify_potential_overload __attribute__ ((__format__ (__printf__, 2, 3))) int
+fprintf (FILE *__restrict const __clang_pass_object_size __stream,
+ const char *__restrict __fmt, ...)
{
- return __fprintf_chk (__stream, __USE_FORTIFY_LEVEL - 1, __fmt,
- __va_arg_pack ());
+ __FORTIFY_INIT_ARG_PACK(__fmt);
+ int __result = __FORTIFY_CALL_VA_CHK (fprintf, __stream,
+ __USE_FORTIFY_LEVEL - 1, __fmt,
+ __FORTIFY_ARG_PACK);
+ __FORTIFY_FREE_ARG_PACK();
+ return __result;
}
-__fortify_function int
-printf (const char *__restrict __fmt, ...)
+__fortify_potential_overload __attribute__ ((__format__ (__printf__, 1, 2))) int
+printf (const char *__restrict const __clang_pass_object_size __fmt, ...)
{
- return __printf_chk (__USE_FORTIFY_LEVEL - 1, __fmt, __va_arg_pack ());
+ __FORTIFY_INIT_ARG_PACK(__fmt);
+ int __result = __FORTIFY_CALL_VA_CHK (printf, __USE_FORTIFY_LEVEL - 1, __fmt,
+ __FORTIFY_ARG_PACK);
+ __FORTIFY_FREE_ARG_PACK();
+ return __result;
}
# elif !defined __cplusplus
# define printf(...) \
@@ -92,66 +121,94 @@ printf (const char *__restrict __fmt, ...)
__fprintf_chk (stream, __USE_FORTIFY_LEVEL - 1, __VA_ARGS__)
# endif
-__fortify_function int
-vprintf (const char *__restrict __fmt, __gnuc_va_list __ap)
+__fortify_potential_overload __attribute__ ((__format__ (__printf__, 1, 0))) int
+vprintf (const char *__restrict const __clang_pass_object_size __fmt,
+ __gnuc_va_list __ap)
{
-#ifdef __USE_EXTERN_INLINES
+# ifdef __USE_EXTERN_INLINES
return __vfprintf_chk (stdout, __USE_FORTIFY_LEVEL - 1, __fmt, __ap);
-#else
+# else
return __vprintf_chk (__USE_FORTIFY_LEVEL - 1, __fmt, __ap);
-#endif
+# endif
}
-__fortify_function int
-vfprintf (FILE *__restrict __stream,
+__fortify_potential_overload __attribute__ ((__format__ (__printf__, 2, 0))) int
+vfprintf (FILE *__restrict const __clang_pass_object_size __stream,
const char *__restrict __fmt, __gnuc_va_list __ap)
{
return __vfprintf_chk (__stream, __USE_FORTIFY_LEVEL - 1, __fmt, __ap);
}
# ifdef __USE_XOPEN2K8
-# ifdef __va_arg_pack
-__fortify_function int
-dprintf (int __fd, const char *__restrict __fmt, ...)
+# ifdef __FORTIFY_ARG_PACK_OK
+__fortify_potential_overload __attribute__ ((__format__ (__printf__, 2, 3))) int
+dprintf (int __fd, const char *__restrict const __clang_pass_object_size __fmt,
+ ...)
{
- return __dprintf_chk (__fd, __USE_FORTIFY_LEVEL - 1, __fmt,
- __va_arg_pack ());
+ __FORTIFY_INIT_ARG_PACK(__fmt);
+ int __result = __FORTIFY_CALL_VA_CHK (dprintf, __fd, __USE_FORTIFY_LEVEL - 1,
+ __fmt, __FORTIFY_ARG_PACK);
+ __FORTIFY_FREE_ARG_PACK();
+ return __result;
}
# elif !defined __cplusplus
# define dprintf(fd, ...) \
__dprintf_chk (fd, __USE_FORTIFY_LEVEL - 1, __VA_ARGS__)
# endif
-__fortify_function int
-vdprintf (int __fd, const char *__restrict __fmt, __gnuc_va_list __ap)
+__fortify_potential_overload __attribute__ ((__format__ (__printf__, 2, 0))) int
+vdprintf (int __fd,
+ const char *__restrict const __clang_pass_object_size __fmt,
+ __gnuc_va_list __ap)
{
return __vdprintf_chk (__fd, __USE_FORTIFY_LEVEL - 1, __fmt, __ap);
}
# endif
# ifdef __USE_GNU
-# ifdef __va_arg_pack
-__fortify_function int
-__NTH (asprintf (char **__restrict __ptr, const char *__restrict __fmt, ...))
+# ifdef __FORTIFY_ARG_PACK_OK
+__fortify_potential_overload __attribute__ ((__format__ (__printf__, 2, 3)))
+__wur int
+__NTH (asprintf (char **__restrict const __clang_pass_object_size __ptr,
+ const char *__restrict __fmt, ...))
{
- return __asprintf_chk (__ptr, __USE_FORTIFY_LEVEL - 1, __fmt,
- __va_arg_pack ());
+ __FORTIFY_INIT_ARG_PACK(__fmt);
+ int __result = __FORTIFY_CALL_VA_CHK (asprintf, __ptr,
+ __USE_FORTIFY_LEVEL - 1, __fmt,
+ __FORTIFY_ARG_PACK);
+ __FORTIFY_FREE_ARG_PACK();
+ return __result;
}
-__fortify_function int
-__NTH (__asprintf (char **__restrict __ptr, const char *__restrict __fmt,
- ...))
+__fortify_potential_overload __attribute__ ((__format__ (__printf__, 2, 3)))
+__wur int
+__NTH (__asprintf (char **__restrict const __clang_pass_object_size __ptr,
+ const char *__restrict __fmt, ...))
{
- return __asprintf_chk (__ptr, __USE_FORTIFY_LEVEL - 1, __fmt,
- __va_arg_pack ());
+ __FORTIFY_INIT_ARG_PACK(__fmt);
+ int __result = __FORTIFY_CALL_VA_CHK (asprintf, __ptr,
+ __USE_FORTIFY_LEVEL - 1, __fmt,
+ __FORTIFY_ARG_PACK);
+ __FORTIFY_FREE_ARG_PACK();
+ return __result;
}
-__fortify_function int
-__NTH (obstack_printf (struct obstack *__restrict __obstack,
+__fortify_potential_overload __attribute__ ((__format__ (__printf__, 2, 3))) int
+__NTH (obstack_printf (struct obstack *
+ __restrict const __clang_pass_object_size __obstack,
const char *__restrict __fmt, ...))
{
- return __obstack_printf_chk (__obstack, __USE_FORTIFY_LEVEL - 1, __fmt,
- __va_arg_pack ());
+ __FORTIFY_INIT_ARG_PACK(__fmt);
+ int __result =
+# ifdef __use_clang_fortify
+ __obstack_vprintf_chk
+# else
+ __obstack_printf_chk
+# endif
+ (__obstack, __USE_FORTIFY_LEVEL - 1, __fmt,
+ __FORTIFY_ARG_PACK);
+ __FORTIFY_FREE_ARG_PACK();
+ return __result;
}
# elif !defined __cplusplus
# define asprintf(ptr, ...) \
@@ -162,15 +219,17 @@ __NTH (obstack_printf (struct obstack *__restrict __obstack,
__obstack_printf_chk (obstack, __USE_FORTIFY_LEVEL - 1, __VA_ARGS__)
# endif
-__fortify_function int
-__NTH (vasprintf (char **__restrict __ptr, const char *__restrict __fmt,
- __gnuc_va_list __ap))
+__fortify_potential_overload __attribute__ ((__format__ (__printf__, 2, 0)))
+__wur int
+__NTH (vasprintf (char **__restrict const __clang_pass_object_size __ptr,
+ const char *__restrict __fmt, __gnuc_va_list __ap))
{
return __vasprintf_chk (__ptr, __USE_FORTIFY_LEVEL - 1, __fmt, __ap);
}
-__fortify_function int
-__NTH (obstack_vprintf (struct obstack *__restrict __obstack,
+__fortify_potential_overload __attribute__ ((__format__ (__printf__, 2, 0))) int
+__NTH (obstack_vprintf (struct obstack *
+ __restrict const __clang_pass_object_size __obstack,
const char *__restrict __fmt, __gnuc_va_list __ap))
{
return __obstack_vprintf_chk (__obstack, __USE_FORTIFY_LEVEL - 1, __fmt,
@@ -182,85 +241,81 @@ __NTH (obstack_vprintf (struct obstack *__restrict __obstack,
#endif
#if __GLIBC_USE (DEPRECATED_GETS)
-extern char *__REDIRECT (__gets_warn, (char *__str), gets)
- __wur __warnattr ("please use fgets or getline instead, gets can't "
- "specify buffer size");
-
-__fortify_function __wur char *
-gets (char *__str)
+extern char *__REDIRECT_NTH (__gets_alias, (char *__buf), gets) __wur;
+
+__fortify_potential_overload __wur char *
+gets (char *const __clang_pass_object_size __str)
+__FORTIFY_PRECONDITIONS
+ __FORTIFY_WARNING_IF (__gets_warn, __glibc_objsize (__str) == (size_t) -1,
+ "please use fgets or getline instead, gets can't "
+ "specify buffer size")
{
if (__glibc_objsize (__str) != (size_t) -1)
return __gets_chk (__str, __glibc_objsize (__str));
- return __gets_warn (__str);
+ return __gets_alias (__str);
}
+__FORTIFY_FUNCTION_END
#endif
extern char *__REDIRECT (__fgets_alias,
(char *__restrict __s, int __n,
FILE *__restrict __stream), fgets)
__wur __attr_access ((__write_only__, 1, 2));
-extern char *__REDIRECT (__fgets_chk_warn,
- (char *__restrict __s, size_t __size, int __n,
- FILE *__restrict __stream), __fgets_chk)
- __wur __warnattr ("fgets called with bigger size than length "
- "of destination buffer");
-
-__fortify_function __wur __fortified_attr_access (__write_only__, 1, 2) char *
-fgets (char *__restrict __s, int __n, FILE *__restrict __stream)
+
+__fortify_potential_overload __wur __attr_access ((__write_only__, 1, 2)) char *
+fgets (char *__restrict const __clang_pass_object_size __s, int __n,
+ FILE *__restrict __stream)
+__FORTIFY_PRECONDITIONS
+ __FORTIFY_WARNING_IF (__fgets_warn, __bos_static_lt (__n, __s) && __n > 0,
+ "fgets called with bigger size than length of "
+ "destination buffer")
{
- size_t sz = __glibc_objsize (__s);
- if (__glibc_safe_or_unknown_len (__n, sizeof (char), sz))
- return __fgets_alias (__s, __n, __stream);
- if (__glibc_unsafe_len (__n, sizeof (char), sz))
- return __fgets_chk_warn (__s, sz, __n, __stream);
- return __fgets_chk (__s, sz, __n, __stream);
+ if (__glibc_objsize (__s) != (size_t) -1)
+ return __fgets_chk (__s, __glibc_objsize (__s), __n, __stream);
+ return __fgets_alias (__s, __n, __stream);
}
+__FORTIFY_FUNCTION_END
extern size_t __REDIRECT (__fread_alias,
(void *__restrict __ptr, size_t __size,
size_t __n, FILE *__restrict __stream),
fread) __wur;
-extern size_t __REDIRECT (__fread_chk_warn,
- (void *__restrict __ptr, size_t __ptrlen,
- size_t __size, size_t __n,
- FILE *__restrict __stream),
- __fread_chk)
- __wur __warnattr ("fread called with bigger size * nmemb than length "
- "of destination buffer");
-
-__fortify_function __wur size_t
-fread (void *__restrict __ptr, size_t __size, size_t __n,
- FILE *__restrict __stream)
+
+__fortify_potential_overload __wur size_t
+fread (void *__restrict const __clang_pass_object_size0 __ptr, size_t __size,
+ size_t __n, FILE *__restrict __stream)
+__FORTIFY_PRECONDITIONS
+ __FORTIFY_WARNING_IF (__fread_warn, __bos0_static_lt (__size * __n, __ptr)
+ && !__mul_may_overflow (__size, __n),
+ "fread called with bigger size * nmemb than length "
+ "of destination buffer")
{
- size_t sz = __glibc_objsize0 (__ptr);
- if (__glibc_safe_or_unknown_len (__n, __size, sz))
- return __fread_alias (__ptr, __size, __n, __stream);
- if (__glibc_unsafe_len (__n, __size, sz))
- return __fread_chk_warn (__ptr, sz, __size, __n, __stream);
- return __fread_chk (__ptr, sz, __size, __n, __stream);
+ if (__glibc_objsize0 (__ptr) != (size_t) -1)
+ return __fread_chk (__ptr, __glibc_objsize0 (__ptr), __size, __n, __stream);
+ return __fread_alias (__ptr, __size, __n, __stream);
}
+__FORTIFY_FUNCTION_END
#ifdef __USE_GNU
extern char *__REDIRECT (__fgets_unlocked_alias,
(char *__restrict __s, int __n,
FILE *__restrict __stream), fgets_unlocked)
__wur __attr_access ((__write_only__, 1, 2));
-extern char *__REDIRECT (__fgets_unlocked_chk_warn,
- (char *__restrict __s, size_t __size, int __n,
- FILE *__restrict __stream), __fgets_unlocked_chk)
- __wur __warnattr ("fgets_unlocked called with bigger size than length "
- "of destination buffer");
-
-__fortify_function __wur __fortified_attr_access (__write_only__, 1, 2) char *
-fgets_unlocked (char *__restrict __s, int __n, FILE *__restrict __stream)
+
+__fortify_potential_overload __wur __attr_access ((__write_only__, 1, 2)) char *
+fgets_unlocked (char *__restrict const __clang_pass_object_size __s, int __n,
+ FILE *__restrict __stream)
+__FORTIFY_PRECONDITIONS
+ __FORTIFY_WARNING_IF (__fgets_unlocked_warn,
+ __bos_static_lt (__n, __s) && __n > 0,
+ "fgets_unlocked called with bigger size than length "
+ "of destination buffer")
{
- size_t sz = __glibc_objsize (__s);
- if (__glibc_safe_or_unknown_len (__n, sizeof (char), sz))
- return __fgets_unlocked_alias (__s, __n, __stream);
- if (__glibc_unsafe_len (__n, sizeof (char), sz))
- return __fgets_unlocked_chk_warn (__s, sz, __n, __stream);
- return __fgets_unlocked_chk (__s, sz, __n, __stream);
+ if (__glibc_objsize (__s) != (size_t) -1)
+ return __fgets_unlocked_chk (__s, __glibc_objsize (__s), __n, __stream);
+ return __fgets_unlocked_alias (__s, __n, __stream);
}
+__FORTIFY_FUNCTION_END
#endif
#ifdef __USE_MISC
@@ -269,21 +324,20 @@ extern size_t __REDIRECT (__fread_unlocked_alias,
(void *__restrict __ptr, size_t __size,
size_t __n, FILE *__restrict __stream),
fread_unlocked) __wur;
-extern size_t __REDIRECT (__fread_unlocked_chk_warn,
- (void *__restrict __ptr, size_t __ptrlen,
- size_t __size, size_t __n,
- FILE *__restrict __stream),
- __fread_unlocked_chk)
- __wur __warnattr ("fread_unlocked called with bigger size * nmemb than "
- "length of destination buffer");
-
-__fortify_function __wur size_t
-fread_unlocked (void *__restrict __ptr, size_t __size, size_t __n,
- FILE *__restrict __stream)
+
+__fortify_potential_overload __wur size_t
+fread_unlocked (void *__restrict const __clang_pass_object_size0 __ptr,
+ size_t __size, size_t __n, FILE *__restrict __stream)
+__FORTIFY_PRECONDITIONS
+ __FORTIFY_WARNING_IF (__fread_unlocked_warn,
+ __bos0_static_lt (__size * __n, __ptr)
+ && !__mul_may_overflow(__size, __n),
+ "fread_unlocked called with bigger size * n than "
+ "length of destination buffer")
{
- size_t sz = __glibc_objsize0 (__ptr);
- if (__glibc_safe_or_unknown_len (__n, __size, sz))
- {
+ if (__glibc_objsize0 (__ptr) != (size_t) -1)
+ return __fread_unlocked_chk (__ptr, __glibc_objsize0 (__ptr), __size, __n, __stream);
+
# ifdef __USE_EXTERN_INLINES
if (__builtin_constant_p (__size)
&& __builtin_constant_p (__n)
@@ -306,12 +360,9 @@ fread_unlocked (void *__restrict __ptr, size_t __size, size_t __n,
}
# endif
return __fread_unlocked_alias (__ptr, __size, __n, __stream);
- }
- if (__glibc_unsafe_len (__n, __size, sz))
- return __fread_unlocked_chk_warn (__ptr, sz, __size, __n, __stream);
- return __fread_unlocked_chk (__ptr, sz, __size, __n, __stream);
-
}
+__FORTIFY_FUNCTION_END
#endif
+#undef __mul_may_overflow
#endif /* bits/stdio2.h. */
diff --git a/misc/bits/syslog.h b/misc/bits/syslog.h
index 305cac4ba0..9602513a22 100644
--- a/misc/bits/syslog.h
+++ b/misc/bits/syslog.h
@@ -20,7 +20,6 @@
# error "Never include <bits/syslog.h> directly; use <sys/syslog.h> instead."
#endif
-
extern void __syslog_chk (int __pri, int __flag, const char *__fmt, ...)
__attribute__ ((__format__ (__printf__, 3, 4)));
@@ -28,6 +27,13 @@ extern void __syslog_chk (int __pri, int __flag, const char *__fmt, ...)
extern void __vsyslog_chk (int __pri, int __flag, const char *__fmt,
__gnuc_va_list __ap)
__attribute__ ((__format__ (__printf__, 3, 0)));
+
+__fortify_potential_overload __attribute__ ((__format__ (__printf__, 2, 0))) void
+vsyslog (int __pri, const char *const __clang_pass_object_size __fmt,
+ __gnuc_va_list __ap)
+{
+ __vsyslog_chk (__pri, __USE_FORTIFY_LEVEL - 1, __fmt, __ap);
+}
#endif
#include <bits/floatn.h>
@@ -38,7 +44,18 @@ extern void __vsyslog_chk (int __pri, int __flag, const char *__fmt,
/* The following functions must be used only after applying all asm
redirections, e.g. long double asm redirections. */
-#ifdef __va_arg_pack
+#if defined __use_clang_fortify && __USE_MISC
+/* clang doesn't support __va_arg_pack, so this is only possible if we have
+ vsyslog. */
+__fortify_overload __attribute__ ((__format__ (__printf__, 2, 3))) void
+syslog (int __pri, const char *const __clang_pass_object_size __fmt, ...)
+{
+ __gnuc_va_list __ap;
+ __builtin_va_start (__ap, __fmt);
+ __vsyslog_chk (__pri, __USE_FORTIFY_LEVEL - 1, __fmt, __ap);
+ __builtin_va_end (__ap);
+}
+#elif defined __va_arg_pack
__fortify_function void
syslog (int __pri, const char *__fmt, ...)
{
@@ -48,12 +65,3 @@ syslog (int __pri, const char *__fmt, ...)
# define syslog(pri, ...) \
__syslog_chk (pri, __USE_FORTIFY_LEVEL - 1, __VA_ARGS__)
#endif
-
-
-#ifdef __USE_MISC
-__fortify_function void
-vsyslog (int __pri, const char *__fmt, __gnuc_va_list __ap)
-{
- __vsyslog_chk (__pri, __USE_FORTIFY_LEVEL - 1, __fmt, __ap);
-}
-#endif
diff --git a/misc/sys/cdefs.h b/misc/sys/cdefs.h
index c37a3ff637..9b74a76b59 100644
--- a/misc/sys/cdefs.h
+++ b/misc/sys/cdefs.h
@@ -137,9 +137,49 @@
# define __END_DECLS
#endif
+#if defined __clang__ && defined __has_extension
+# define __clang_has_extension(x) __has_extension (x)
+#else
+# define __clang_has_extension(x) 0
+#endif
/* Fortify support. */
-#define __bos(ptr) __builtin_object_size (ptr, __USE_FORTIFY_LEVEL > 1)
+#define __fortify_function __extern_always_inline __attribute_artificial__
+#if defined __clang__ && __USE_FORTIFY_LEVEL > 0 \
+ && !defined _CLANG_FORTIFY_DISABLE \
+ && __clang_has_extension(overloadable_unmarked)
+# define __use_clang_fortify 1
+/* Clang-style FORTIFY creates a different symbol for each FORTIFY'ed function,
+ whereas GCC-style doesn't. Thus, GCC can assume that the FORTIFY'ed
+ function is always available externally, but clang can't. */
+# define __attribute_overloadable__ __attribute__ ((__overloadable__))
+# define __attribute_transparent_overload__ \
+ __attribute__ ((__overloadable__("transparent")))
+# define __fortify_overload static __always_inline __attribute_overloadable__
+/* For FORTIFY functions that exist only as decls. */
+# define __fortify_error_function static __attribute_overloadable__
+# define __clang_pass_object_size_n(n) __attribute__ ((pass_object_size (n)))
+# define __clang_warning(what) __attribute__ ((deprecated(what)))
+# define __clang_prefer_this_overload __attribute__ ((enable_if (1, "")))
+# define __clang_warning_if(c, m) \
+ __attribute__ ((__diagnose_if__ ((c), (m), "warning")))
+# define __clang_error(what) __attribute__ ((unavailable(what)))
+# define __clang_error_if(c, m) \
+ __attribute__ ((__diagnose_if__ ((c), (m), "error")))
+# define __fortify_potential_overload __fortify_overload
+#else
+# define __fortify_potential_overload __fortify_function
+/* Some functions/decls can be shared between clang and non-clang FORTIFY.
+ Turning these into nops makes that possible. */
+# define __clang_pass_object_size_n(n)
+# define __attribute_overloadable__
+# define __bos_n(ptr, n) __builtin_object_size (ptr, n)
+# define __clang_warning_if(c, m)
+# define __clang_error_if(c, m)
+#endif
+
+#define __bos_level (__USE_FORTIFY_LEVEL > 1)
+#define __bos(ptr) __builtin_object_size (ptr, __bos_level)
#define __bos0(ptr) __builtin_object_size (ptr, 0)
/* Use __builtin_dynamic_object_size at _FORTIFY_SOURCE=3 when available. */
@@ -201,6 +241,105 @@
: __ ## f ## _chk (__VA_ARGS__, (__osz) / (__s))))
#endif
+#define __clang_pass_object_size0 __clang_pass_object_size_n (0)
+#define __clang_pass_object_size __clang_pass_object_size_n (__bos_level)
+
+/* Some of these macros are awkwardly written, and more repetitive than they'd
+ ideally need to be. This is because both clang and gcc will emit 'note's
+ about where these warnings originate from. For every macro that's expanded,
+ the user sees a note that ultimately doesn't matter to them... */
+#ifdef __use_clang_fortify
+# define __FORTIFY_PRECONDITIONS
+# define __FORTIFY_FUNCTION_END
+# define __FORTIFY_WARNING_IF(_, c, msg) __clang_warning_if(c, msg)
+/* __builtin_constant_p isn't needed: this is only used in constructs that
+ must be fully evaluated at compile-time. */
+# define __bos_static_lt_impl(bos_val, n, s) \
+ ((bos_val) != -1ULL && (n) > (bos_val) / (s))
+# define __FORTIFY_CALL_CHK 1
+
+# define __FORTIFY_BOSN_ARGS(bos_fn, n, buf, div, complaint) \
+ (__bos_static_lt_impl (bos_fn (buf), n, div)), (complaint), "warning"
+
+#define __FORTIFY_WARNING_ONLY_IF_BOS0_LT2(fn_name, n, buf, div, complaint) \
+ __attribute__ ((__diagnose_if__ \
+ (__FORTIFY_BOSN_ARGS (__bos0, n, buf, div, complaint))))
+#define __FORTIFY_WARNING_ONLY_IF_BOS0_LT(fn_name, n, buf, complaint) \
+ __attribute__ ((__diagnose_if__ \
+ (__FORTIFY_BOSN_ARGS (__bos0, n, buf, 1, complaint))))
+#define __FORTIFY_WARNING_ONLY_IF_BOS_LT2(fn_name, n, buf, div, complaint) \
+ __attribute__ ((__diagnose_if__ \
+ (__FORTIFY_BOSN_ARGS (__bos, n, buf, div, complaint))))
+#define __FORTIFY_WARNING_ONLY_IF_BOS_LT(fn_name, n, buf, complaint) \
+ __attribute__ ((__diagnose_if__ \
+ (__FORTIFY_BOSN_ARGS (__bos, n, buf, 1, complaint))))
+#else
+# define __FORTIFY_PRECONDITIONS {
+# define __FORTIFY_FUNCTION_END }
+/* __chk_fail was chosen arbitrarily. The function should never be called
+ anyway; it just exists to be reachable after optimizations. */
+# define __FORTIFY_DECLARE_WARNING_FUNCTION(name, msg) \
+ __attribute ((__warning__(msg))) \
+ extern void __REDIRECT_NTH (name, (void), __chk_fail)
+
+# define __FORTIFY_WARNING_IF_BEGIN(fn_name, cond, complaint, if_cond_true) \
+ { \
+ if (cond) { \
+ if_cond_true; \
+ __FORTIFY_DECLARE_WARNING_FUNCTION (fn_name, complaint); \
+ volatile char __t = 0; \
+ if (__glibc_unlikely (__t)) \
+ {
+
+# define __FORTIFY_WARNING_IF_END \
+ } \
+ } \
+ }
+
+# define __FORTIFY_WARNING_IF(err_fn, cond, complaint) \
+ __FORTIFY_WARNING_IF_BEGIN (err_fn, cond, complaint, (void)0) \
+ err_fn (); \
+ __FORTIFY_WARNING_IF_END
+
+# define __bos_static_lt_impl(bos_val, n, s) \
+ (__builtin_constant_p (n) && (bos_val) != -1ULL && (n) > (bos_val) / (s))
+
+#define __FORTIFY_BOS_WARNING_BEGIN(fn_name, bos_fn, n, buf, div, complaint) \
+ char __need_dynamic_check = !__builtin_constant_p (n); \
+ __FORTIFY_WARNING_IF_BEGIN (fn_name, \
+ __bos_static_lt_impl (bos_fn (buf), n, div), \
+ complaint, (__need_dynamic_check = 1))
+
+/* Duplicate this so that the fn_name call happens with the smallest possible
+ macro "call stack". This minimizes diagnostics about expanding macros. */
+#define __FORTIFY_WARNING_ONLY_IF_BOS0_LT2(err_fn, n, buf, div, complaint) \
+ __FORTIFY_BOS_WARNING_BEGIN (err_fn, __bos0, n, buf, div, complaint) \
+ err_fn (); \
+ __FORTIFY_WARNING_IF_END
+
+#define __FORTIFY_WARNING_ONLY_IF_BOS0_LT(err_fn, n, buf, complaint) \
+ __FORTIFY_BOS_WARNING_BEGIN (err_fn, __bos0, n, buf, 1, complaint) \
+ err_fn (); \
+ __FORTIFY_WARNING_IF_END
+
+#define __FORTIFY_WARNING_ONLY_IF_BOS_LT2(err_fn, n, buf, div, complaint) \
+ __FORTIFY_BOS_WARNING_BEGIN (err_fn, __bos, n, buf, div, complaint) \
+ err_fn (); \
+ __FORTIFY_WARNING_IF_END
+
+#define __FORTIFY_WARNING_ONLY_IF_BOS_LT(err_fn, n, buf, complaint) \
+ __FORTIFY_BOS_WARNING_BEGIN (err_fn, __bos, n, buf, 1, complaint) \
+ err_fn (); \
+ __FORTIFY_WARNING_IF_END
+
+# define __FORTIFY_CALL_CHK (__need_dynamic_check)
+#endif
+
+#define __bos_static_lt2(n, e, s) __bos_static_lt_impl (__bos (e), n, s)
+#define __bos_static_lt(n, e) __bos_static_lt2 (n, e, 1)
+#define __bos0_static_lt2(n, e, s) __bos_static_lt_impl (__bos0 (e), n, s)
+#define __bos0_static_lt(n, e) __bos0_static_lt2 (n, e, 1)
+
#if __GNUC_PREREQ (4,3)
# define __warnattr(msg) __attribute__((__warning__ (msg)))
# define __errordecl(name, msg) \
@@ -470,6 +609,29 @@
# define __va_arg_pack_len() __builtin_va_arg_pack_len ()
#endif
+#if defined(__use_clang_fortify)
+/* clang doesn't support __va_arg_pack, so we need to call the v* version of
+ FORTIFY'ed functions. */
+#define __FORTIFY_ARG_PACK __fortify_ap
+#define __FORTIFY_INIT_ARG_PACK(va_arg) \
+ __gnuc_va_list __FORTIFY_ARG_PACK; \
+ __builtin_va_start (__FORTIFY_ARG_PACK, va_arg)
+#define __FORTIFY_CALL_VA_ALIAS(fn, ...) __v##fn##_alias (__VA_ARGS__)
+#define __FORTIFY_CALL_VA_CHK(fn, ...) __v##fn##_chk (__VA_ARGS__)
+#define __FORTIFY_CALL_VA_BUILTIN(fn, ...) \
+ __builtin___v##fn##_chk (__VA_ARGS__)
+#define __FORTIFY_FREE_ARG_PACK() __builtin_va_end (__FORTIFY_ARG_PACK)