ISO/IEC TS 17961:2013
Information Technology — Programming languages, their environments and system software interfaces — C Secure Coding Rules
http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1624.pdf
この文書は、ISO/IEC JTC1 SC22 WG14の作業文書(Working Draft)です。
公式のISO/IEC TS 17961:2013原本ではありません。
技術内容を検討し、ISO/IEC JTC1 SC22 WG14にフィードバックするために用いるものです。
ISO/IEC TS 17961:2013 C Secure Coding Rules(1)一覧
一つの規則で複数回のコンパイルが必要な場合、別記事にしています。
作業予定
規則の例(断片等)をコンパイル、実行する予定です。
1: コンパイルエラーが出ないようにする。
一覧のaccfree.cがこの段階です。
2: 実行時エラーが出ないようにする。
一覧のptrcomp.cがこの段階です。
3: 意味のある出力が出るようにする。
検討中。
現状では、変な代入、奇異な操作が頻出します。
コンパイルエラーが出ないようにするなるべく短い記述で済まそうという趣旨で、他意はありません。
よりよい記述に変更する予定です。
コンパイラ
Apple LLVM version 9.1.0 (clang-902.0.39.1)
Target: x86_64-apple-darwin17.4.0
または
clang version 6.0.0 (tags/RELEASE_600/final)
Target: x86_64-apple-darwin17.4.0
2)
gcc-7 (Homebrew GCC 7.3.0_1) 7.3.0
Copyright (C) 2017 Free Software Foundation, Inc.
環境(Environment)
hosted Environment macOS 10.13.3 or 10.12.9
コンパイル用shell script
C版(clangとgcc)とC++版(clang++とg++)
https://qiita.com/kaizen_nagoya/items/74220c0577a512c2d7da
5.5. Calling functions in the C Standard Library other than abort, _Exit, and signal from within a signal handler [asyncsig]
EXAMPLE 1 In this noncompliant example, a diagnostic is required because the C Standard Library function fprintf is called from the signal handler handler via the function log_message.
// ISO/IEC JTC 1/SC 22/WG 14 N 1624 Date: 2012-06-26 ISO/IEC TS 17961, p.11
// EXAMPLE 1 In this noncompliant example, a diagnostic is required because the C Standard Library function fprintf is called from the signal handler handler via the function log_message.
/// Compiled on
/// Clang(LLVM) clang version 6.0.0 (tags/RELEASE_600/final)
/// GCC(GNU) gcc-7 (Homebrew GCC 7.3.0_1) 7.3.0
// hosted Environment macOS 10.13.3 or 10.12.9
//
#include <stdio.h> /// for printf
#include <stdlib.h> /// for EXIT_SUCCESS
#include "unistd.h"
#define MAXLINE 1024
char info[MAXLINE];
void log_message(void) {
fprintf(stderr, "%s\n", info); // diagnostic required
}
void handler(int signum) {
log_message();
}
int main(void) {
if (signal(SIGINT, handler) == SIG_ERR) {
/* Handle error */
}
/* An interactive attention signal might invoke handler() from here on. */
while (1) {
/* Main loop program code */
log_message();
sleep(1);
/* More program code */
}
return EXIT_SUCCESS;
}
$ ./gcc7ts.sh asyncsig
$ clang asyncsig.c
//kill from other terminal
./gcc7ts.sh: line 4: 90664 Terminated: 15 ./$1l $2
$ gcc-7 asyncsig.c
//kill from other terminal
./gcc7ts.sh: line 8: 90752 Terminated: 15 ./$1g $2
EXAMPLE 2 In this noncompliant example, a diagnostic is required because the C Standard Library function raise is called from the signal handler int_handler.
//EXAMPLE 2 In this noncompliant example, a diagnostic is required because the C Standard Library function raise is called from the signal handler int_handler.
#include <stdio.h> //added by O.K. fro printf()
#include <stdlib.h> //added by O.K. for EXIT_SUCCESS
#include <signal.h> // added by O.K. for raise()
void term_handler(int signum) {
/* SIGTERM handling specific */
printf("signum:%d \n", signum);// added for output
}
void int_handler(int signum) {
/* SIGINT handling specific */
if (raise(SIGTERM) != 0) { // diagnostic required
/* Handle error */
printf("Handle error:%d \n", signum);// added for output
}
}
int main(void) {
if (signal(SIGTERM, term_handler) == SIG_ERR) {
/* Handle error */
printf("Handle error:signal(SIGTERM, term_handler) \n");// added for output
}
if (signal(SIGINT, int_handler) == SIG_ERR) {
/* Handle error */
printf("Handle error:signal(SIGINT, int_handler) \n");// added for output
}
/* Program code */
if (raise(SIGINT) != 0) {
/* Handle error */
printf("Handle error:raise(SIGINT)\n");// added for output
}
/* More code */
return EXIT_SUCCESS;
}
$ ./gcc7ts.sh asyncsig2
$ clang asyncsig2.c
signum:15
$ gcc-7 asyncsig2.c
signum:15
EXAMPLE 3 In this noncompliant example, a diagnostic is required because the C Standard Library function longjmp is called from the signal handler handler.
//EXAMPLE 3 In this noncompliant example, a diagnostic is required because the C Standard Library function longjmp is called from the signal handler handler.
#include <stdio.h> //added by O.K. fro printf()
#include <stdlib.h> //added by O.K. for EXIT_SUCCESS
#include <setjmp.h>// added by O.K. for raise()
#include "unistd.h"
#define MAXLINE 1024
static jmp_buf env;
void handler(int signum) {
longjmp(env, 1); // diagnostic required
}
void log_message(char *info1, char *info2) {
static char *buf = NULL;
static size_t bufsize;
char buf0[MAXLINE];
if (buf == NULL) {
buf = buf0;
bufsize = sizeof(buf0);
}
/*
* Try to fit a message into buf, else re-allocate
* it on the heap and then log the message.
*/
/*** VULNERABILITY IF SIGINT RAISED HERE ***/
if (buf == buf0) {
buf = NULL;
}
}
int main(void) {
if (signal(SIGINT, handler) == SIG_ERR) {
/* Handle error */
}
char *info1="setjump\n";
char *info2="info2\n";
/* info1 and info2 are set by user input here */
if (setjmp(env) == 0) {
while (1) {
/* Main loop program code */
log_message(info1, info2);
sleep(1);
/* More program code */
}
}
else {
log_message(info1, info2);
}
return EXIT_SUCCESS;
}
./gcc7ts.sh asyncsig3
$ clang asyncsig3.c
^C
$ gcc-7 asyncsig3.c
^C
参考文献
コンパイル用shell script C版(clangとgcc)とC++版(clang++とg++)
https://qiita.com/kaizen_nagoya/items/74220c0577a512c2d7da
C言語(C++)に対する誤解、曲解、無理解、爽快。
https://qiita.com/kaizen_nagoya/items/3f3992c9722c1cee2e3a
MISRA C まとめ #include
https://qiita.com/kaizen_nagoya/items/f1a79a7cbd281607c7c9
どうやって MISRA C Example Suiteをコンパイルするか
https://qiita.com/kaizen_nagoya/items/fbdbff5ff696e2ca7f00
[C][C++]の国際規格案の例題をコンパイルするときの課題7つ。
https://qiita.com/kaizen_nagoya/items/5f4b155030259497c4de
文書履歴
ver 0.10 初稿 20180403
ver 0.11 gcc-7、Example節項目追記 20180407