On Wed, Sep 18, 2013 at 6:14 AM, Tetsuo Handa <penguin-ker...@i-love.sakura.ne.jp> wrote: > Kees Cook wrote: >> > Consider, e.g. introducing __vsnprint(), with vsnprintf(s, n, fmt, ...) >> > expanding to __vsnprintf(1, s, n, fmt, ...) if fmt is a string literal >> > and __vsnprintf(0, s, n, fmt, ...) otherwise. Now, >> > int __sprintf(int safe, char *buf, const char *fmt, ...) >> > { >> > va_list args; >> > int i; >> > >> > va_start(args, fmt); >> > i = __vsnprintf(safe, buf, INT_MAX, fmt, args); >> > va_end(args); >> > >> > return i; >> > } >> >> Unless I've misunderstood, I think we'd already get very close to this >> with the gcc options instead. This patch set is what I've been using >> to generate the format string fixes over the last few months, with 7 >> sent this last round: > > Can we utilize __builtin_constant_p() ?
This seems promising. > > ---------- source start ---------- > #include <stdio.h> > > #define func(fmt) \ > if (__builtin_constant_p(fmt)) \ > printf("const : %s\n", fmt); \ > else \ > printf("not const : %s\n", fmt); \ > > > int main(int argc, char *argv[]) > { > const char *fmt1 = "const char *"; > const char fmt2[] = "const char []"; > const char * const fmt3 = "const char * const"; > func("literal"); > func(fmt1); > func(fmt2); > func(fmt3); > return 0; > } > ---------- source end ---------- > > ---------- output start ---------- > const : literal > not const : const char * > not const : const char [] > const : const char * const What version of gcc did you use? I don't get the last as const, for some reason. And as Dan mentions, shouldn't const char[] be detected as const too? -Kees > ---------- output end ---------- > > __builtin_constant_p() seems to enforce use of either "literal" or "* const". > > An example change > > ---------- patch start ---------- > --- a/include/linux/printk.h > +++ b/include/linux/printk.h > @@ -120,8 +120,9 @@ asmlinkage int printk_emit(int facility, int level, > const char *dict, size_t dictlen, > const char *fmt, ...); > > -asmlinkage __printf(1, 2) __cold > -int printk(const char *fmt, ...); > +//asmlinkage __printf(1, 2) __cold > +//int printk(const char *fmt, ...); > +#define printk(fmt, ...) compiletime_assert(__builtin_constant_p(fmt), > "Non-c onstant format string") > > /* > * Special printk facility for scheduler use only, _DO_NOT_USE_ ! > ---------- patch end ---------- > > caught errors like below. > > CC [M] drivers/scsi/esas2r/esas2r_log.o > drivers/scsi/esas2r/esas2r_log.c: In function 'esas2r_log_master': > drivers/scsi/esas2r/esas2r_log.c:174: error: call to > '__compiletime_assert_174' declared with attribute error: Non-constant format > string -- Kees Cook Chrome OS Security -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/