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
n1624は、ISO/IEC JTC1 SC22 WG14の作業文書(Working Draft)です。
公式のISO/IEC TS 17961:2013原本ではありません。
ISO/IEC JTC1 SC22 WG14では、可能な限り作業文書を公開し、幅広い意見を求めています。技術内容を検討し、ISO/IEC JTC1 SC22 WG14にフィードバックするために用います。
<この項は書きかけです。順次追記します。>
作業予定
下記規則の例をコンパイルする予定です。
1: コンパイルエラーが出ないようにする。
accfree.cがこの段階です。
2: 実行時エラーが出ないようにする。
ptrcomp.cがこの段階です。
3: 意味のある出力が出るようにする。
検討中。
複数のコンパイルが必要な例のある規則は、別項目としリンクを記載する。
主な作業内容
1: Header fileをincludeする。
元資料にも記載があると良い。
コンパイラによっては、知らんぷりしてエラーだけ出す場合と、ヘッダファイル名を推奨する場合と、がある。
2: main関数を追記する。
main関数がある場合もある。main関数に関数呼び出しを追記する場合もある。
int main(int argc; char ** arg)
int main(void)
など複数の宣言方法をとることがある
3: 変数、定数を宣言する。
ライブラリヘッダファイル に見当たらない変数、定数を宣言する。
完全に調べ切れているわけではない。無駄な宣言があれば、ご指摘ください。
4: 処理がわかる出力を記述する。
if文のどちらを通ったかなど、既存の出力ではわからない場合に追記する。
計算結果を出力していない場合も記載することがある。
5:コンパイル・リンク・実行結果を記録する。
コンパイルエラー、警告、リンクエラー等を記録する。
コンパイルができた場合には実行結果を記録する。
処理系の都合、システム設定の都合でうまく出ない場合には、
別のコンパイラ、処理系で順次試す。
現在利用中のコンパイラ
Apple LLVM version 9.1.0 (clang-902.0.39.1)
Target: x86_64-apple-darwin17.4.0 on macOS 10.13.3
または
Apple LLVM version 9.0.0 (clang-900.0.39.2)
Target: x86_64-apple-darwin16.7.0
on macOS 10.12.6
gcc-7 (Homebrew GCC 7.3.0_1) 7.3.0
Copyright (C) 2017 Free Software Foundation, Inc.
gccは順次追記中です。その後、Visual Studioを予定しています。
環境(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
目的(purpose)
この資料の目的は、国際規格・日本工業規格の内容の理解ではなく、処理系の振る舞いを理解し、結果としてプログラマの意図通りに、作ったプログラムが安全に動作するかどうかの確からしさを向上させることにある。
成果(outcome)
複数のプログラムを複数の処理系で処理することにより、
プログラマの意図が、特定の処理系の範囲内での実現を目指しているか、
複数の処理系で動作する可搬性を目指しているかの区分を明確にできること。
特定の処理系の範囲内での実現を目指したプログラムを、
誤って別の処理系で翻訳して、プログラマの意図しない動作をさせないこと。
任意のデータ(意図しないデータを含む)に対する処理が、プログラマの意図した範囲に収めることができるかどうかを確かめ、Security の基本機能を実現する。
マクロ
p.ixに2つのマクロの記載あり。
get.hとして利用。
5.16,5.23 でstring
5.25, 5.29, 5.36, 5.39, 5.45でinteger
を利用
/// ISO/IEC JTC 1/SC 22/WG 14 N 1624 Date: 2012-06-26 ISO/IEC TS 17961, p.ix
// http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1624.pdf
//Tainted source macros
//The function-like macros GET_TAINTED_STRING and //GET_TAINTED_INTEGER defined in this section are used in the examples in this Technical Specification to represent one possible method to obtain a tainted string and tainted integer.
#define GET_TAINTED_STRING(buf, buf_size) \
do { \
const char *taint = getenv("TAINT"); \
if (taint == 0) { \
exit(1); \
} \
\
size_t taint_size = strlen(taint) + 1; \
if (taint_size > buf_size) { \
exit(1); \
} \
\
strncpy(buf, taint, taint_size); \
} while (0)
#define GET_TAINTED_INTEGER(type, val) \
do { \
const char *taint = getenv("TAINT"); \
if (taint == 0) { \
exit(1); \
} \
\
errno = 0; \
long tmp = strtol(taint, 0, 10); \
if ((tmp == LONG_MIN || tmp == LONG_MAX) && \
errno == ERANGE) \
; /* retain LONG_MIN or LONG_MAX */ \
val = tmp & ~(type)0; \
} while (0)
4.5 mutilated value(コード断片のある用語定義)
/// ISO/IEC JTC 1/SC 22/WG 14 N 1624 Date: 2012-06-26 ISO/IEC TS 17961, p.4
//http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1624.pdf
//4.5 mutilated value:result of an operation performed on an untainted value that yields either an undefined result (such as the result of signed integer overflow), the result of right-shifting a negative number, implicit conversion to an integral type where the value cannot be represented in the destination type, or unsigned integer wrapping
#include <stdio.h>///
#include <stdlib.h>///
#include <limit.h>///
int j = INT_MAX + 1; // j is mutilated
char c = 1234; // c is mutilated if char is eight bits
unsigned int u = 0U - 1; // u is mutilated
int main(void){///
printf("j=%d:%x c=%x u=%d:%x \n",j,j,c,u,u);///
return EXIT_SUCCESS;///
}///
$ cc mutilated.c
mutilated.c:7:17: warning: overflow in expression; result is -2147483648 with type 'int' [-Winteger-overflow]
int j = INT_MAX + 1; // j is mutilated
^
mutilated.c:8:10: warning: implicit conversion from 'int' to 'char' changes value from 1234 to -46 [-Wconstant-conversion]
char c = 1234; // c is mutilated if char is eight bits
~ ^~~~
2 warnings generated.
$ ./a.out
j=-2147483648:80000000 c=ffffffd2 u=-1:ffffffff
5. Rules
5.1. Accessing an object through a pointer to an incompatible type [ptrcomp]
/// // ISO/IEC JTC 1/SC 22/WG 14 N 1624 Date: 2012-06-26 ISO/IEC TS 17961, p.7
//http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1624.pdf
void f(void) {
if (sizeof(int) == sizeof(float)) {
float f = 0.0f;
int *ip = (int *)&f;
printf("float is %f\n", f);
(*ip)++; // diagnostic required
printf("float is %f\n", f);
}
}
上記を含む実行可能なコードに追記し、コンパイル、実行。
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char** argv){
f();
return EXIT_SUCCESS;
}
$ ./gcc7ts.sh ptrcomp
$ clang ptrcomp.c
float is 0.000000
float is 0.000000
$ gcc-7 ptrcomp.c
float is 0.000000
float is 0.000000
以下では、例と作り込んだ部分と資料の断片とを一つのファイルとしている。
作り込んだところは///を記載するように変更中である。
5.2. Accessing freed memory
C Secure Coding Rules(2) 5.2. Accessing freed memory - kaizen_nagoya @ Qiita
https://qiita.com/kaizen_nagoya/items/c8198a6ca3d43b274ef5
5.3. Accessing shared objects in signal handlers [accsig]
#include <stdio.h> ///
#include <stdlib.h> ///初めから書いて置いて欲しい。
#include <string.h> ///初めから書いて置いて欲しい。
#define MAX_MSG_SIZE 24
char *err_msg;
void handler(int signum) {
if ((strcpy(err_msg, "SIGINT detected.")) == err_msg){
// diagnostic required
/* ... */
}
}
int main(void) {
signal(SIGINT, handler);
err_msg = (char *)malloc(MAX_MSG_SIZE);
if (err_msg == NULL) {
/* Handle error condition */
printf("NULL \n");///
}
if ((strcpy(err_msg, "No errors yet.")) == err_msg) {
/* ... */
printf("%s\n",err_msg);///
}
/* Main code loop */
printf("EXIT \n");///
return EXIT_SUCCESS;
}
$ cc accsig.c
$ ./a.out
No errors yet.
EXIT
5.4. No assignment in conditional expressions [boolasgn]
#include <stdio.h> ///
#include <stdlib.h>///
int foo(){
return true;
}
int main(int argc, char* argv[]}{ ///
int x = TRUE;///
int y = FALSE;///
int p; ///
int q; ///
int v; ///
int w; ///
//EXAMPLE 1 In this noncompliant example, a diagnostic is required because the expression x = y is used as the controlling expression of the while statement.
while ( x = y ) { /* ... */ } // diagnostic required
//EXAMPLE 2 In this noncompliant example, a diagnostic is required because the expression x = y is used as the controlling expression of the while statement.
do { /* ... */ } while ( foo(), x = y ) ; // diagnostic required
//EXAMPLE 3 In this compliant example, no diagnostic is required because the expression x = y is not used as the controlling expression of the while statement.
do { /* ... */ } while ( x = y, p == q ) ; // no diagnostic required
//Exceptions
// EX1: Assignment is permitted where the result of the assignment is itself a parameter to a comparison expression (e.g., x == y or x != y) or relational expression and need not be diagnosed.
//EXAMPLE This example shows an acceptable use of this exception.
if ( ( x = y ) != 0 ) { /* ... */ }
// EX2: Assignment is permitted where the expression consists of a single primary expression.
//EXAMPLE 1 This example shows an acceptable use of this exception.
if ( ( x = y ) ) { /* ... */ }
//EXAMPLE 2 In this noncompliant example, a diagnostic is required because && is not a comparison or relational operator and the entire expression is not primary.
if ( ( v = w ) && flag ) { /* ... */ } // diagnostic required
// EX3: Assignment is permitted in the above contexts where it occurs in a function argument or array index.
//EXAMPLE This example shows an acceptable use of this exception.
if ( foo( x = y ) ) { /* ... */ }
return EXIT_SUCCESS;///
}
fooの定義が不完全です。修正予定。
$ cc boolasgn.c
boolasgn.c:19:13: warning: using the result of an assignment as a condition without parentheses [-Wparentheses]
while ( x = y ) { /* ... */ } // diagnostic required
~~^~~
boolasgn.c:19:13: note: place parentheses around the assignment to silence this warning
while ( x = y ) { /* ... */ } // diagnostic required
^
( )
boolasgn.c:19:13: note: use '==' to turn this assignment into an equality comparison
while ( x = y ) { /* ... */ } // diagnostic required
^
==
boolasgn.c:45:19: warning: too many arguments in call to 'foo'
if ( foo( x = y ) ) { /* ... */ }
~~~ ^
2 warnings generated.
$ ./a.out
// 無限ループかも。
5.5. Calling functions in the C Standard Library other than abort, _Exit, and signal from within a signal handler [asyncsig]
C Secure Coding Rules(3) 5.5 Calling functions in the C Standard Library other than abort, _Exit, and signal from within a signal handler - kaizen_nagoya @ Qiita
https://qiita.com/kaizen_nagoya/items/caba4fddb9088ee07a1e
5.6. Calling functions with incorrect arguments [argcomp]
C Secure Coding Rules(4) 5.6. Calling functions with incorrect arguments [argcomp] - kaizen_nagoya @ Qiita
https://qiita.com/kaizen_nagoya/items/3d33047a8cc59e0d2965
5.7. Calling signal from interruptible signal handlers [sigcall]
#include <stdio.h> ///
#include <stdlib.h>///
void handler(int signum) {
if (signal(signum, handler) == SIG_ERR) { // diagnostic required
/* ... */
printf("SIG_ERR: signumd\n");
}
/* ... */
}
void f(void) {
if (signal(SIGUSR1, handler) == SIG_ERR) {
/* ... */
printf("SIG_ERR:SIGUSR1d\n");
}
/* ... */
}
int main(int argc, char* argv[]){
printf("main\n");
return EXIT_SUCCESS;///
}
$ cc sigcall.c
$ ./a.out
main
5.8. Calling system [syscall]
#include <stdio.h> ///
#include <stdlib.h>///
//EXAMPLE 1 In this noncompliant example, a diagnostic is required because a string consisting of any_cmd and the tainted value stored in input is copied into cmdbuf and then passed as an argument to the system function to execute.
void f(char *input) {
char cmdbuf[512];
int len_wanted = snprintf(
cmdbuf, sizeof(cmdbuf), "any_cmd '%s'", input);
if (len_wanted >= sizeof(cmdbuf)) {
perror("Input too long");
} else if (len_wanted < 0) {
perror("Encoding error");
} else if (system(cmdbuf) == -1) { // diagnostic required
perror("Error executing input");
}
}
//EXAMPLE 2 In this noncompliant example, a diagnostic is required because system is used to remove the .config file in the user’s home directory.
void g(void) {
system("rm ~/.config"); // diagnostic required
}
int main(int argc, char* argv[]){///
f("Hello World!");///
g();///
return EXIT_SUCCESS;///
}///
$ cc syscall.c
$ ./a.out
sh: any_cmd: command not found
rm: /Users/administrator/.config: is a directory
5.9. Comparison of padding data [padcomp]
#include <stdio.h> ///for printf
#include <stdlib.h>///for EXIT_SUCCESS
#include <string.h>/// for memcmp
struct my_buf {
char buff_type;
size_t size;
char buffer[50];
};
unsigned int buf_compare(
const struct my_buf *s1,
const struct my_buf *s2)
{
if (!memcmp(s1, s2, sizeof(struct my_buf))) { // diagnostic required
/* ... */
printf("a: %s, $s \n",s1->buffer, s2->buffer);
}
printf("b: %s, $s \n",s2->buffer, s1->buffer);
return 0;
}
int main(int argc, char* argv[]){///
const struct my_buf b1 = {'a',13,"Hello World!n\n",14};///
const struct my_buf b2 = {'b', 10,"hello world\n",11};///
buf_compare(&b1,&b2);//
return EXIT_SUCCESS;///
}///
$ cc padcomp.c
$ ./a.out
b: hello world, Hello World!
5.10. Converting a pointer to integer or integer to pointer [intptrconv]
#include <stdio.h> ///for printf
#include <stdlib.h>///for EXIT_SUCCESS
#include <assert.h> /// for assert
//EXAMPLE 1 In this noncompliant example, a diagnostic is required on an implementation where pointers are 64-bits and unsigned integers are 32 bits because the pointer ptr is converted to an integer.
void f(void) {
char *ptr;
/* ... */
unsigned int number = (unsigned int)ptr; // diagnostic required
/* ... */
printf("f:%s ",ptr);
}
//EXAMPLE 2 In this noncompliant example, a diagnostic is required because the integer literal 0xdeadbeef is converted to a pointer.
unsigned int *g(void) {
unsigned int *ptr = (unsigned int *)0xdeadbeef; // diagnostic required
/* ... */
printf("g:%d ",*ptr);
return ptr;
}
//Exceptions
// EX1: A null pointer can be converted to an integer; it takes on the value 0. Likewise, a 0 integer can be converted to a pointer; it becomes the null pointer.
// EX2: Any valid pointer to void can be converted to intptr_t or uintptr_t and back with no change in value. (This includes the underlying types if intptr_t and uintptr_t are typedefs and any typedefs that denote the same types as intptr_t and uintptr_t.)
// EXAMPLE
void h(void) {
intptr_t i = (intptr_t)(void *)&i;
uintptr_t j = (uintptr_t)(void *)&j;
void *ip = (void *)i;
void *jp = (void *)j;
assert(ip == &i);
assert(jp == &j);
printf("h: %ld %ld",i,j);
}
int main(int argc, char* argv[]){///
f();///
printf("%d ",*g());///
h();///
return EXIT_SUCCESS;///
}///
$ cc intptrconv.c
$ ./a.out
Segmentation fault: 11
5.11. Converting pointer values to more strictly aligned pointer types [alignconv]
C Secure Coding Rules(5) 5.11 Converting pointer values to more strictly aligned pointer types - kaizen_nagoya @ Qiita
https://qiita.com/kaizen_nagoya/items/7bcfbdde26d50a3438be
5.12. Copying a FILE object [filecpy]
#include <stdio.h> ///for printf
#include <stdlib.h>///for EXIT_SUCCESS
int main(void) {
FILE my_stdout = *(stdout); // diagnostic required
if (fputs("Hello, World!\n", &my_stdout) == EOF) {
/* ... */
}
return EXIT_SUCCESS;
}
$ cc filecpy.c
$ ./a.out
Hello, World!
5.13. Declaring the same function or object in incompatible ways [funcdecl]
C Secure Coding Rules(6) 5.13. Declaring the same function or object in incompatible ways [funcdecl] - kaizen_nagoya @ Qiita
https://qiita.com/kaizen_nagoya/items/756d3bac5e763f42c643
5.14. Dereferencing an out-of-domain pointer [nullref]
//Example(s)
//EXAMPLE In this noncompliant example, a diagnostic is required because if malloc returns NULL, then the call to memcpy will dereference the null pointer c_str.
#include <stdio.h> /// for printf
#include <stdlib.h> /// for EXIT_SUCCESS
void f(const char *input_str) {
size_t size = strlen(input_str) + 1;
char *c_str = (char *)malloc(size);
if ((memcpy(c_str, input_str, size)) == c_str) { // diagnostic required
/* ... */
printf("%s \n",c_srt);
}
/* ... */
free(c_str);
c_str = NULL;
}
int main(int argc, char** argv){ ///
const char *input_str=argv[0];///
f(input_str); ///
return EXIT_SUCCESS;///
}//
```/
```shell_session:shell
cc addrescape.c
$ ./a.out
./a.out
5.15. Escaping of the address of an automatic object [addrescape]
C Secure Coding Rules(7) 5.15. Escaping of the address of an automatic object [addrescape] - kaizen_nagoya @ Qiita
https://qiita.com/kaizen_nagoya/items/cb337c06f75291074f48
5.16. Conversion of signed characters to wider integer types before a check for EOF [signconv]
//Example(s)
//EXAMPLE In this noncompliant example, a diagnostic is required because the character of type char pointed to by c_str is converted to int without being cast to unsigned char first.
#include <stdio.h> /// for printf
#include <stdlib.h> /// for EXIT_SUCCESS
#include <string.h> /// for strlen
#include "get.h" /// for GET_TAINTED_STRING
int yy_string_get(char *c_str) {
int c = EOF;
if (c_str && *c_str) {
c = *c_str++; // if char is signed, a 0xFF char can be confused with EOF
printf("yy\n");
}
printf("str\n");
return c;
}
/* ... */
char string[BUFSIZ];
int main(int argc, char** argv){ ///
GET_TAINTED_STRING(string, BUFSIZ);
if (yy_string_get( string) == EOF) // diagnostic required
{
printf("EOF\n");///
}
printf("return\n");///
return EXIT_SUCCESS;///
}///
実行結果調整中
5.17. Use of an implied default in a switch statement [swtchdflt]
//Example(s)
//EXAMPLE In this noncompliant example, a diagnostic is required because not all possible values of widget_type are checked for in the switch statement.
#include <stdio.h> /// for printf
#include <stdlib.h> /// for EXIT_SUCCESS
enum WidgetEnum { WE_W, WE_X, WE_Y, WE_Z };
void f(enum WidgetEnum widget_type) {
switch (widget_type) { // diagnostic required
case WE_X:
/* ... */
printf("WE_X:%d\n",widget_type);
break;
case WE_Y:
/* ... */
printf("WE_Y:%d\n",widget_type);
break;
case WE_Z:
/* ... */
printf("WE_Z:%d\n",widget_type);
break;
}
}
int main(int argc, char** argv){ ///
f(WE_W);///
printf("WE_W:%d\n",WE_W);///
return EXIT_SUCCESS;///
}///
$ cc swtchdflt.c
swtchdflt.c:9:11: warning: enumeration value 'WE_W' not handled in switch [-Wswitch]
switch (widget_type) { // diagnostic required
^
swtchdflt.c:9:11: note: add missing switch cases
switch (widget_type) { // diagnostic required
^
1 warning generated.
$ ./a.out
WE_W:0
5.18. Failing to close files or free dynamic memory when they are no longer needed [fileclose]
C Secure Coding Rules(8) 5.18. Failing to close files or free dynamic memory when they are no longer needed [fileclose] - kaizen_nagoya @ Qiita
https://qiita.com/kaizen_nagoya/items/a45f1ef86281710b8eb0
5.19. Failing to detect and handle standard library errors [liberr]
#include <stdio.h> /// for printf
#include <stdlib.h> /// for EXIT_SUCCESS
//Example(s)
//EXAMPLE In this noncompliant example, a diagnostic is required because the return value of fseek is not checked for an error condition.
void test_unchecked_return(FILE *file, long offset) {
fseek(file, offset, SEEK_SET); // diagnostic required
}
//NOTE Return values from the following functions (Table 3) do not need to be checked because their historical use has overwhelmingly omitted error checking, and the consequences are not relevant to security.
//Exceptions
//EX1: The use of a void cast to signify programmer intent to ignore a return value from a function need not be diagnosed.
//EXAMPLE This example shows an acceptable use of this exception.
void foo(FILE *file) {
(void)fputs("foo", file);
/* ... */
}
//EX2: Ignoring the return value of a function that cannot fail or whose return value cannot signify an error condition need not be diagnosed. For example, strcpy is one such function.
int main(void){ ///
long offset;
FILE * fp=NULL;
FILE my_stdout = *(stdout); // diagnostic required
fp = &my_stdout;
if (NULL != fp) {///
test_unchecked_return(fp,offset);///
printf("seek:%d\n",fseek(fp, offset, SEEK_SET) );///
foo(fp);///
} else {///
return EXIT_FAILURE;///
}///
return EXIT_SUCCESS;///
}///
$ cc libber.c
$ ./a.out
seek:0
foo関数の出力するように変更予定
5.20. Forming invalid pointers by library function [libptr]
5.20.1. Library functions that take a pointer and an integer
5.20.2. Library functions that take two pointers and an integer
5.20.3. Library functions that take a pointer and two integers
5.20.4. Standard memory allocation functions
#include <stdio.h> /// for printf
#include <stdlib.h> /// for EXIT_SUCCESS
#include <string.h> /// for memset, memcpy
#include <wchar.h> /// for wcslen
//Example(s)
//EXAMPLE 1 In this noncompliant example, a diagnostic is required because the size argument used in the memset() call is one longer than the size allocated for p.
void f1(size_t nchars) {
char *p = (char *)malloc(nchars);
const size_t n = nchars + 1;
if (p) {
memset(p, 0, n); // diagnostic required
/* ... */
}
}
//EXAMPLE 2 In this noncompliant example, a diagnostic is required because the size argument used in the memset() call is possibly miscalculated. There is no requirement that the size of an int is the same as the size of a float.
void f2(void) {
float a[4];
const size_t n = sizeof(int) * 4;
void *p = a;
memset(p, 0, n); // diagnostic required
/* ... */
}
//EXAMPLE 3 In this noncompliant example, a diagnostic is required because the size argument used in the memcpy() call is possibly miscalculated. The size of an int does not need to be smaller than that of a double.
void f3(int *a) {
double b = 3.14;
const size_t n = sizeof(*a);
void *p = a;
void *q = &b;
if ((memcpy(p, q, n)) == p) { // diagnostic required
/* ... */
}
/* ... */
}
//EXAMPLE In this noncompliant example, a diagnostic is required because the value of n is not computed correctly, allowing a possible write past the end of the object referenced by p.
void f4(char p[], const char *q) {
const size_t n = sizeof(p);
if ((memcpy(p, q, n)) == p) { // diagnostic required
/* ... */
}
/* ... */
}
//EXAMPLE 5 In this noncompliant example, a diagnostic is required because the value of n that is used in the malloc() call has been possibly miscalculated.
wchar_t *f5(void) {
const wchar_t *p = L"Hello, World!";
const size_t n = sizeof(p) * (wcslen(p) + 1);
wchar_t *q = (wchar_t *)malloc(n); // diagnostic required
/* ... */
return q;
}
int main(int argc, char** argv){ ///
size_t nchars=4;///
char* p ="end of";///
char* q ="object";///
int b = 3;///
int * a= &b;///
f1(nchars);///
f2();///
f3(a);///
f4(p,q);///
printf("f5:%ls\n",f5());///
return EXIT_SUCCESS;///
}//]/
$ cc libptr.c
libptr.c:41:26: warning: sizeof on array function parameter will return size of 'char *' instead of
'char []' [-Wsizeof-array-argument]
const size_t n = sizeof(p);
^
libptr.c:40:14: note: declared here
void f4(char p[], const char *q) {
^
1 warning generated.
$ ./a.out
Bus error: 10
Bus errorの原因調査予定。
5.21. Forming or using out-of-bounds pointers or array subscripts [invptr]
5.22. Freeing memory multiple times [dblfree]
//EXAMPLE 1 In this noncompliant example, a diagnostic is required because x could be freed twice depending on the value of error_condition.
#include <stdio.h> /// for printf
#include <stdlib.h> /// for EXIT_SUCCESS, NULL
//#include <string.h> /// for memset, memcpy
//#include <wchar.h> /// for wcslen
void f(size_t num_elem) {
int error_condition = 0;
int *x = (int *)malloc(num_elem * sizeof(int));
if (x == NULL) {
/* ... */
printf("x == NULL\n")
}
/* ... */
if (error_condition == 1) {
/* ... */
printf("error_condition == 1\n")
free(x);
}
/* ... */
free(x); // diagnostic required
printf("free(x)\n")
x = NULL;
}
//EXAMPLE 2 In this noncompliant example, a diagnostic is required because realloc may free c_str1 when it returns NULL, resulting in c_str1 being freed twice.
void g(char *c_str1, size_t size) {
char *c_str2 = (char *)realloc(c_str1, size);
if (c_str2 == NULL) {
free(c_str1); // diagnostic required
return;
}
printf("str:%s\n",c_str2);///
}
int main(void){ ///
size_t t = sizeof(int);
char * s = "dblfree";
f(t);///
g(s,t);///
return EXIT_SUCCESS;///
}///
$ cc dblfree.c
$ ./a.out
free(x)
a.out(71277,0x7fffa098d340) malloc: *** error for object 0x10743afa2: pointer being realloc'd was not allocated
*** set a breakpoint in malloc_error_break to debug
Abort trap: 6
5.23. Including tainted or out-of-domain input in a format string [usrfmt]
5.24. Incorrectly setting and using errno [inverrno]
5.24.1. Library functions that set errno and return an in-band error indicator
5.24.2. Library functions that set errno and return an out-of-band error indicator
5.24.3. Library functions that occasionally set errno and return an out-of-band error indicator
5.24.4. Library functions that may or may not set errno
5.24.5. Library functions that do not explicitly set errno
Example 1
//EXAMPLE 1 In this noncompliant example, a diagnostic is required because errno is used for error checking and errno is not set to zero before the C Standard Library function strtoul is called.
#include <stdio.h> /// for printf
#include <stdlib.h> /// for EXIT_SUCCESS, NULL
#include <errno.h> /// for errno
#include <limits.h> /// for 'ULONG_MAX'
#include <locale.h> /// for LC_ALL
void f(const char *c_str) {
char *endptr = NULL;
unsigned long number = strtoul(c_str, &endptr, 0);
if (endptr == c_str || (number == ULONG_MAX && errno == ERANGE)) { // diagnostic required
/* ... */
printf("endptr == c_str\n");///
} else {
/* ... */
printf("endptr != c_str\n");///
}
/* ... */
}
//EXAMPLE 2 In this noncompliant example, a diagnostic is required because errno is used for error checking and the return value of the call to the C Standard Library function signal is not checked before checking errno.
void g(void) {
errno = 0;
signal(SIGINT, SIG_DFL);
if (errno != 0) { // diagnostic required
/* ... */
printf("errno != 0\n");///
}
}
//EXAMPLE 3 In this noncompliant example, a diagnostic is required because errno is used for error checking and errno is checked after the call to the C Standard Library function setlocale because setlocale does not explicitly set errno.
void h(void) {
errno = 0;
setlocale(LC_ALL, "");
if (errno != 0) { // diagnostic required
/* ... */
printf("LC_ALL:errno != 0\n");///
}
}
int main(void){ ///
char* s="inverrno";
f(s);///
g();///
h();///
return EXIT_SUCCESS;///
}///
$ cc inverrno.c
$ ./a.out
endptr == c_str
5.25. Integer division errors [diverr]
5.26. Interleaving stream inputs and outputs without a flush or positioning call [ioileave]
//EXAMPLE In this noncompliant example, a diagnostic is required because fread and fwrite are called on the same file without an intervening call to fflush, fseek, fsetpos, or rewind on the file.
#include <stdio.h> /// for printf
#include <stdlib.h> /// for EXIT_SUCCESS, NULL
#include <errno.h> /// for errno
#include <limits.h> /// for 'ULONG_MAX'
#include <locale.h> /// for LC_ALL
void f(const char *filename, char append_data[BUFSIZ]) {
char data[BUFSIZ];
FILE *file;
file = fopen(filename, "a+");
if (file == NULL) {
/* ... */
printf("NULL == file\n");///
return;///
}
if (fwrite(append_data, sizeof(char), BUFSIZ, file) != BUFSIZ) {
/* ... */
printf("NULL == file\n");///
return;///
}
if (fread(data, sizeof(char), BUFSIZ, file) != 0) { // diagnostic required
/* ... */
printf("data:%s\n",data);
}
fclose(file);
}
int main(void){ ///
char* s="ioileave.c";///
char data[BUFSIZ];///
f(s, data)///
return EXIT_SUCCESS;///
}///
$ cc ioileave.c
$ ./a.out
5.27. Modifying string literals [strmod]
//EXAMPLE 1 In this noncompliant example, a diagnostic is required because the string literal "string literal" is modified through the pointer p.
#include <stdio.h> /// for printf
#include <stdlib.h> /// for EXIT_SUCCESS, NULL
#include <string.h> /// for strrchr
void f1(void) {
char *p = "string literal";
p[0] = 'S'; // diagnostic required
/* ... */
}
//EXAMPLE 2 In this noncompliant example, a diagnostic is required because the string literal "/tmp/edXXXXXX" is modified by the C Standard Library function tmpnam.
void f2(void) {
if (tmpnam("/tmp/edXXXXXX")) { // diagnostic required
/* ... */
}
}
//EXAMPLE 3 In this noncompliant example, a diagnostic is required because the string literal "/tmp/filename" is modified through the pointer returned from the C Standard Library function strrchr.
void f3(void) {
char *last_slash = strrchr("/tmp/filename", '/');
*last_slash = '\0'; // diagnostic required
/* ... */
}
//EXAMPLE 4 In this noncompliant example, a diagnostic is required because the string literal "/tmp/filename" is modified through the pointer returned from the C Standard Library function strrchr.
void f4(void) {
*strrchr("/tmp/filename", '/') = '\0'; // diagnostic required
/* ... */
}
//EXAMPLE 5 In this noncompliant example, a diagnostic is required because the string literal "/tmp/filename" is modified.
void f5(void) {
"/tmp/filename"[4] = '\0'; // diagnostic required
/* ... */
}
//Exception
//No diagnostic need be issued if the analyzer can determine that the value of the pointer to non-const is never used to attempt to modify the characters of the string literal.
int main(void) {
char *p = "abc";
printf("%s\n", p);
f1();///
f2();///
f3();///
f4();///
f5();///
return EXIT_SUCCESS;
}
$ cc strmod.c
strmod.c:15:7: warning: 'tmpnam' is deprecated: This function is provided for compatibility reasons only. Due to
security concerns inherent in the design of tmpnam(3), it is highly recommended that you use mkstemp(3)
instead. [-Wdeprecated-declarations]
if (tmpnam("/tmp/edXXXXXX")) { // diagnostic required
^
/usr/include/stdio.h:186:1: note: 'tmpnam' has been explicitly marked deprecated here
__deprecated_msg("This function is provided for compatibility reasons only. Due to security concerns in...
^
/usr/include/sys/cdefs.h:180:48: note: expanded from macro '__deprecated_msg'
#define __deprecated_msg(_msg) __attribute__((deprecated(_msg)))
^
1 warning generated.
$ ./a.out
abc
Bus error: 10
5.28. Modifying the string returned by getenv, localeconv, setlocale, and strerror [libmod]
//Rule
//Modifying the objects or strings returned by the library functions listed in getenv, localeconv, setlocale, and strerror shall be diagnosed.
//Rationale
//C identifies the following three instances of undefined behavior, which arise as a result of modifying the data structures or strings returned from getenv, localeconv, setlocale, and strerror:
//UB120
//The program modifies the string pointed to by the value returned by the setlocale function (7.11.1.1).
//UB121
//The program modifies the structure pointed to by the value returned by the localeconv function (7.11.2.1).
//UB184
//The string set up by the getenv or strerror function is modified by the program (7.22.4.6, 7.24.6.2).
```c:libmod.c
//EXAMPLE 1 In this noncompliant example, a diagnostic is required because the string returned from the C Standard Library function setlocale is modified.
#include <stdio.h> /// for printf
#include <stdlib.h> /// for EXIT_SUCCESS, NULL
#include <string.h> /// for strstr
#include <errno.h> /// for errno
#include <locale.h> /// for set locale
#define BUFFER_SIZE BUFSIZ
void f1(void) {
char *locale = setlocale(LC_ALL, 0);
if (locale != NULL) {
char *cats[8];
char *sep = locale;
cats[0] = locale;
int i;
if (sep) {
for (i = 0; (sep = strstr(sep, ";:")) && i < 8; ++i) {
*sep = '\0'; // diagnostic required
cats[i] = ++sep;
}
}
}
/* ... */
printf("f1:setlocale\n");///
}
//EXAMPLE 2 In this noncompliant example, a diagnostic is required because the object returned from the C Standard Library function localeconv is modified.
void f2(void) {
struct lconv *conv = localeconv();
if ('\0' == conv->decimal_point[0]) {
conv->decimal_point = "."; // diagnostic required
printf("f2:decimal_point\n");///
}
if ('\0' == conv->thousands_sep[0]) {
conv->thousands_sep = ","; // diagnostic required
printf("f2:thousands_sep\n");///
}
/* ... */
printf("f2:localconv\n");///
}
//EXAMPLE 3 In this noncompliant example, a diagnostic is required because the string returned from the C Standard Library function getenv is modified.
void f3(void) {
char *shell_dir = getenv("SHELL");
if (shell_dir != NULL) {
char *slash = strrchr(shell_dir, '/');
if (slash) {
*slash = '\0'; // diagnostic required
printf("f3:slash:%s\n", shell_dir);///
return;///
}
/* use shell_dir */
printf("f3:%s\n", shell_dir);///
return;//
}
}
//EXAMPLE 4 In this noncompliant example, a diagnostic is required because the string returned from the C Standard Library function strerror is modified.
const char *f4(int error) {
char buf[BUFFER_SIZE];
sprintf(buf, "(errno = %d)", error);
char *error_str = strerror(error);
strcat(error_str, buf); // diagnostic required
return error_str;
}
int main(void) {
int i = 1;
f1();///
f2();///
f3();///
printf("%s \n",f4(i));///
return EXIT_SUCCESS;
}
$ cc libmod.c
$ ./a.out
f1:setlocale
f2:thousands_sep
f2:localconv
f3:slash:/bin
Bus error: 10
5.29. Overflowing signed integers [intoflow]
5.30. Passing a non-null-terminated string to a library function [nonnullstr]
//EXAMPLE 1 In this noncompliant example, a diagnostic is required because the string str will not be null-terminated when passed as an argument to printf.
#include <stdio.h> /// for printf
#include <stdlib.h> /// for EXIT_SUCCESS
#include <string.h> /// for strlen
#include <stddef.h> /// for size_t
#include <limits.h> /// for 'ULONG_MAX'
void f(){///
char str[3] = "abc";
printf("%s\n", str); // diagnostic required
}///
//EXAMPLE 2 In this noncompliant example, a diagnostic is required because the wide string cur_msg will not be null-terminated when passed to wcslen. This will occur if lessen_memory_usage is invoked while cur_msg_size still has its initial value of 1024.
wchar_t *cur_msg = NULL;
size_t cur_msg_size = 1024;
size_t cur_msg_len = 0;
void lessen_memory_usage(void) {
wchar_t *temp;
size_t temp_size;
/* ... */
if (cur_msg != NULL) {
temp_size = cur_msg_size / 2 + 1;
temp = realloc(cur_msg, temp_size * sizeof(wchar_t));
// temp & cur_msg might not be null-terminated
if (temp == NULL) {
/* ... */
}
cur_msg = temp;
cur_msg_size = temp_size;
cur_msg_len = wcslen(cur_msg); // diagnostic required
}
}
//EXAMPLE 3 In this compliant example, a diagnostic is not required because cur_msg will always be null-terminated when passed to wcslen.
//wchar_t *cur_msg = NULL;
//size_t cur_msg_size = 1024;
//size_t cur_msg_len = 0;
void lessen_memory_usage2(void) {
wchar_t *temp;
size_t temp_size;
/* ... */
if (cur_msg != NULL) {
temp_size = cur_msg_size / 2 + 1;
temp = realloc(cur_msg, temp_size * sizeof(wchar_t));
// temp & cur_msg might not be null-terminated
if (temp == NULL) {
/* ... */
}
cur_msg = temp;
cur_msg[ temp_size - 1] = L'\0'; // cur_msg now properly null-terminated
cur_msg_size = temp_size;
cur_msg_len = wcslen(cur_msg); // diagnostic not required
}
}
int main(void) {
f();///
lessen_memory_usage();///
lessen_memory_usage2();///
printf("nonnullstr \n");///
return EXIT_SUCCESS;///
}///
cc nonnullstr.c
OgawaKiyoshi-no-MacBook-Pro:ts17961 ogawakiyoshi$ ./a.out
abc`?_??
nonnullstr
5.31. Passing arguments to character-handling functions that are not representable as unsigned char [chrsgnext]
//EXAMPLE In this noncompliant example, a diagnostic is required because the parameter to isspace, *t may not be representable as an unsigned char.
#include <stdio.h> /// for printf
#include <stdlib.h> /// for EXIT_SUCCESS
#include <ctype.h> /// for isspace
#include <string.h> /// for strlen
size_t count_preceding_whitespace(const char *s) {
const char *t = s;
size_t length = strlen(s) + 1;
while (isspace(*t) && (t - s < length)) { // diagnostic required
++t;
}
return t - s;
}
int main(void) {
char * s = "";
printf("nonnullstr \n", count_preceding_whitespace());///
return EXIT_SUCCESS;///
}///
$ cc chrsgnext.c
$ ./a.out
0
5.32. Passing pointers into the same object as arguments to different restrict-qualified parameters [restrict]
//EXAMPLE 1 In this noncompliant example, a diagnostic is required because the restrict-qualified pointer parameters to memcpy, ptr1, and ptr2 reference overlapping objects.
#include <stdio.h> /// for printf
#include <stdlib.h> /// for EXIT_SUCCESS
#include <string.h> /// for strlen
#include <stddef.h> /// for size_t
void abcabc(void) {
char c_str[]= "abc123edf";
char *ptr1 = c_str;
char *ptr2 = c_str + strlen("abc");
memcpy(ptr2, ptr1, 6); // diagnostic required
puts(c_str);
}
//EXAMPLE 2 In this noncompliant example, the src operand is used twice to refer to unmodified memory, which is allowed by the C Standard; the aliasing restrictions apply only when the object is modified. A diagnostic is required nontheless because the pointer src is twice a restrict-qualified pointer parameter to dual_memcpy, referencing overlapping objects.
void *dual_memcpy(void *restrict s1, const void *restrict s2, size_t n1, void *restrict s3, const void *restrict s4, size_t n2) {
memcpy(s1, s2, n1);
memcpy(s3, s4, n2);
printf("%d %d %d %d \n",(int)s1,(int)s2,(int)s3,(int)s4);///
return s1;
}
void f(void) {
char dest1[10];
char dest2[10];
char src[] = "hello";
dual_memcpy(dest1, src, sizeof(src),
dest2, src, sizeof(src)); // diagnostic required
puts(dest1);
puts(dest2);
}
int main(void) {
void abcabc(void);
void *restrict s1;
const void *restrict s2;
size_t n1;
void *restrict s3;
const void *restrict s4;
size_t n2;
dual_memcpy(s1, s2, n1, s3, s4, n2)
f();
return EXIT_SUCCESS;///
}///
$ cc restrict.c
$ ./a.out
-475007112 0 0 0
-475007234 -475007250 -475007244 -475007250
hello
hello
5.33. Reallocating or freeing memory that was not dynamically allocated [xfree]
//EXAMPLE 1 In this noncompliant example, a diagnostic is required because the pointer parameter to realloc, buf does not refer to dynamically allocated memory.
#include <stdio.h> /// for printf
#include <stdlib.h> /// for EXIT_SUCCESS
#include <string.h> /// for strlen
#include <stddef.h> /// for size_t
#define BUFSIZE 256
void f(void) {
char buf[BUFSIZE];
char *p;
/* ... */
p = (char *)realloc(buf, 2 * BUFSIZE); // diagnostic required
/* ... */
printf("%s \n",p);
}
//EXAMPLE 2 In this noncompliant example, a diagnostic is required because the pointer parameter to free, c_str may not refer to dynamically allocated memory.
#define MAX_ALLOCATION 1000
int main(int argc, char *argv[]) {
char *c_str = NULL;
size_t len;
f();///
if (argc == 2) {
len = strlen(argv[1]) + 1;
if (len > MAX_ALLOCATION) {
/* Handle error */
}
c_str = (char *)malloc(len);
if (c_str == NULL) {
/* Handle allocation error */
}
strcpy(c_str, argv[1]);
}
else {
c_str = "usage: $>a.exe[string]";
printf("%s\n", c_str);
}
/* ... */
free(c_str); // diagnostic required
return EXIT_SUCCESS;
}
$ cc xfree.c
$ ./a.out
a.out(76770,0x7fffa098d340) malloc: *** error for object 0x7ffee9598610: pointer being realloc'd was not allocated
*** set a breakpoint in malloc_error_break to debug
Abort trap: 6
## 5.34. Referencing uninitialized memory [uninitref]
```c:uninitref.c
//EXAMPLE 1 In this noncompliant example, a diagnostic is required because the variable sign may be uninitialized when it is accessed in the return statement of the function is_negative.
#include <stdio.h> /// for printf
#include <stdlib.h> /// for EXIT_SUCCESS
#include <errno.h> /// for errno
#include <limits.h> /// for 'ULONG_MAX'
void g(double *a, size_t n) ;///
void f(size_t n);///
void get_sign(int number, int *sign) {
if (sign == NULL) {
/* ... */
}
if (number > 0) {
*sign = 1;
} else if (number < 0) {
*sign = -1;
} // If number == 0, sign is not changed.
}
int is_negative(int number) {
int sign;
get_sign(number, &sign);
return (sign < 0); // diagnostic required
}
//EXAMPLE 2 In this noncompliant example, a diagnostic is required because the variable error_log is uninitialized when it is passed to sprintf.
int do_auth(void) {
int result = -1;
/* ... */
return result;
}
void report_error(const char *msg) {
const char *error_log;
char buffer[24];
sprintf(buffer, "Error: %s", error_log); // diagnostic required
printf("%s\n", buffer);
}
int main(void) {
double b = 2;
double *a = &b;
size_t n =sizeof(int);
g(double *a, size_t n) ;///
f(size_t n);///
if (do_auth() == -1) {
report_error("Unable to login");
}
return EXIT_SUCCESS;
}
//EXAMPLE 3 In this noncompliant example, a diagnostic is required because the elements of the array a are uninitialized when they are accessed in the for loop.
void f(size_t n) {
int *a = (int *)malloc(n * sizeof(int));
if (a != NULL) {
for (size_t i = 0; i != n; ++i) {
a[i] = a[i] ^ a[i]; // diagnostic required
}
/* ... */
free(a);
}
}
//EXAMPLE 4 In this noncompliant example, a diagnostic is required because the array elements a[n..2n] are uninitialized when they are accessed in the for loop.
void g(double *a, size_t n) {
a = (double *)realloc(a, (n * 2 + 1) * sizeof(double));
if (a != NULL) {
for (size_t i = 0; i != n * 2 + 1; ++i) {
if (a[i] < 0) {
a[i] = -a[i]; // diagnostic required
}
}
/* ... */
free(a);
}
}
$ cc uninitref.c
$ ./a.out
a.out(76835,0x7fffa098d340) malloc: *** error for object 0x7ffeea041750: pointer being realloc'd was not allocated
*** set a breakpoint in malloc_error_break to debug
Abort trap: 6
5.35. Subtracting or comparing two pointers that do not refer to the same array [ptrobj]
//EXAMPLE In this noncompliant example, a diagnostic is required because the pointers c_str and (char **)next_num_ptr are subtracted and do not refer to the same array.
#include <stdio.h> /// for printf
#include <stdlib.h> /// for EXIT_SUCCESS
#define SIZE 256
void f(void) {
int nums[SIZE];
char *c_str[SIZE];
int *next_num_ptr = nums;
int free_bytes;
/* ... */
/* increment next_num_ptr as array fills */
free_bytes = c_str - (char **)next_num_ptr; // diagnostic required
printf("%d, %d, %s \n",*next_num_ptr,free_bytes, *c_str);
/* ... */
}
int main(void) {
f();
return EXIT_SUCCESS;///
}///
$ cc probj.c
$ ./a.out
0, -256, (null)
5.36. Tainted strings are passed to a string copying function [taintstrcpy]
//EXAMPLE In this noncompliant example, a diagnostic is required because the size of the string referenced by argv[0] might be greater than the size of the destination array pgm.
#include <stdio.h> /// for printf
#include <stdlib.h> /// for EXIT_SUCCESS
#include <string.h> /// for strcpy
void main(int argc, char *argv[]) {
char pgm[BUFSIZ];
if (argc > 1) {
strcpy(pgm, argv[0]); // diagnostic required
printf("%s\n",pgm);
}
return EXIT_SUCCESS;///
}
$ cc taintstrcpy.c
$ ./a.out taintstrcpy
./a.out
5.37. Taking the size of a pointer to determine the size of the pointed-to type [sizeofptr]
//EXAMPLE In this noncompliant example, a diagnostic is required because the sizeof operator is applied to the pointer parameter array.
#include <stdio.h> /// for printf
#include <stdlib.h> /// for EXIT_SUCCESS
void clear(int array[]) {
for (size_t i = 0; i < sizeof(array) / sizeof(array[0]); // diagnostic required
++i) {
printf("array[%d] =%d\n",(int)i,array[i]);
array[i] = 0;
}
}
int main(int argc, char *argv[]) {///
int array[]={1,2,3,4};///
clear(array);///
return EXIT_SUCCESS;///
}///
$ cc sizeofptr.c
sizeofptr.c:7:32: warning: sizeof on array function parameter will return size of 'int *' instead of 'int []' [-Wsizeof-array-argument]
for (size_t i = 0; i < sizeof(array) / sizeof(array[0]); // diagnostic required
^
sizeofptr.c:6:16: note: declared here
void clear(int array[]) {
^
1 warning generated.
$ ./a.out
array[0] =1
array[1] =2
5.38. Using a tainted value as an argument to an unprototyped function pointer [taintnoproto]
//EXAMPLE 1 In this noncompliant example, a diagnostic is required because the tainted argument tainted is passed as an argument to a call through an unprototyped pointer to function pf. The initialization of pf and the definition of restricted_sink are informational and not necessary for this diagnosis.
#include <stdio.h> /// for printf
#include <stdlib.h> /// for EXIT_SUCCESS
#include <errno.h> /// for errno
#include <limits.h> /// for 'lONG_MAX'
#include "get.h" ///
void restricted_sink(int i) {
int array[2];
array[i] = 0;
printf("%d %d\n",i,array[i]);
}
void (*pf)() = restricted_sink;
void f(void) {
int tainted;
GET_TAINTED_INTEGER(int, tainted);
printf("%d\n",tainted);
(*pf)(tainted); // diagnostic required
}
//EXAMPLE 2 In this compliant example, a diagnostic is not required because the tainted argument tainted2 is passed as an argument to a call through a properly prototyped pointer to function pf2.
void (*pf2)(int);
void g(void) {
int tainted2;
GET_TAINTED_INTEGER(int, tainted2);
printf("2:%d \n", tainted2);
(*pf2)(tainted2);
}
int main(int argc, char *argv[]) {///
f();///
g();///
return EXIT_SUCCESS;///
}///
$ cc taintnoproto.c
$ ./a.out
5.39. Using a tainted value to write to an object using a formatted input or output function [taintformatio]
//EXAMPLE 1 In this noncompliant example, a diagnostic is required because the call to fscanf can result in a write outside the character array buf.
#include <stdio.h> /// for printf
#include <stdlib.h> /// for EXIT_SUCCESS
#include <string.h> /// for strlen
#include <errno.h> /// for errno
#include <limits.h> /// for 'lONG_MAX'
#include "get.h" /// for GET_TAINTED_INTEGER
#define BUF_LENGTH BUFSIZ
int main(void){ ///
char buf[BUF_LENGTH];
fscanf(stdin, "%s\n", buf); // diagnostic required
printf("buf:%s\n", buf);///
//EXAMPLE 2 In this noncompliant example, a diagnostic is required because the sprintf function will write outside the bounds of the character array buf.
int rc = 0;
int x;
GET_TAINTED_INTEGER(int, x);
char buf2[sizeof("999")];
rc = sprintf("buf2, "%d\n", x); // diagnostic required
printf("buf2:%s", buf2);///
if (rc == -1 || rc >= sizeof(buf2)) {
/* handle error */
printf("handle error\n");
}
return EXIT_SUCCESS;///
}
cc taintformatio.c
$ ./a.out
^C
5.40. Using a value for fsetpos other than a value returned from fgetpos [xfilepos]
//EXAMPLE In this noncompliant example, a diagnostic is required because an offset value other than one returned from fgetpos is used in a call to fsetpos.
#include <stdio.h> /// for printf
#include <stdlib.h> /// for EXIT_SUCCESS
#include <string.h> /// for strlen
#include <errno.h> /// for errno
#include <limits.h> /// for 'lONG_MAX'
FILE *opener(const char *filename) {
fpos_t offset;
if (filename == NULL) {
/* ... */
printf("filename == NULL");
}
FILE *file = fopen(filename, "r");
if (file == NULL) {
/* ... */
printf("file == NULL");
return (FILE *)NULL;
}
memset(&offset, 0, sizeof(offset));
if (fsetpos(file, &offset) != 0) { // diagnostic required
/* ... */
printf("%x",offset);
}
return file;
}
int main(int argc, char *argv[]) {///
char * fn = "xfilepos.c"
printf("%d",(int)opener(fn));///
return EXIT_SUCCESS;///
}///
$cc xfilepos.c
$ ./a.out
-1600712656O
$ cc taintformatio.c
taintformatio.c:20:30: warning: incompatible integer to pointer conversion passing 'int' to parameter of type 'const char *' [-Wint-conversion]
rc = sprintf("buf2, %d\n", x); // diagnostic required
^
/usr/include/secure/_stdio.h:47:56: note: expanded from macro 'sprintf'
__builtin___sprintf_chk (str, 0, __darwin_obsz(str), __VA_ARGS__)
^~~~~~~~~~~
taintformatio.c:20:30: warning: format string is not a string literal (potentially insecure) [-Wformat-security]
rc = sprintf("buf2, %d\n", x); // diagnostic required
^
/usr/include/secure/_stdio.h:47:56: note: expanded from macro 'sprintf'
__builtin___sprintf_chk (str, 0, __darwin_obsz(str), __VA_ARGS__)
^~~~~~~~~~~
taintformatio.c:20:30: note: treat the string as an argument to avoid this
rc = sprintf("buf2, %d\n", x); // diagnostic required
^
"%s",
/usr/include/secure/_stdio.h:47:56: note: expanded from macro 'sprintf'
__builtin___sprintf_chk (str, 0, __darwin_obsz(str), __VA_ARGS__)
^
2 warnings generated.
5.41. Using an object overwritten by getenv, localeconv, setlocale, and strerror [libuse]
//EXAMPLE 1 In this noncompliant example, a diagnostic is required because the string returned by the first call to the C Standard Library function getenv is accessed, after the second call to getenv, in the call to the C Standard Library function strcmp.
#include <stdio.h> /// for printf
#include <stdlib.h> /// for EXIT_SUCCESS
#include <string.h> /// for strlen
#include <errno.h> /// for errno
#include <limits.h> /// for 'lONG_MAX'
#include <locale.h> /// for LC_ALL
int f(void) {
char *tmpvar = getenv("TMP");
char *tempvar = getenv("TEMP");
if (!tmpvar || !tempvar) {
/* ... */
}
return strcmp(tmpvar, tempvar) == 0; // diagnostic required
}
//EXAMPLE 2 In this noncompliant example, a diagnostic is required because the string returned by the first call to the C Standard Library function setlocale is accessed, after the second call to setlocale, in the third call to setlocale.
void g(const char *name) {
const char *save = setlocale(LC_ALL, 0);
if (setlocale(LC_ALL, name)) {
/* ... */
}
setlocale(LC_ALL, save); // diagnostic required
}
//EXAMPLE 3 In this noncompliant example, a diagnostic is required because the pointer returned from the first call to the C Standard Library function strerror is accessed, in the call to fprintf, after the second call to strerror.
void h(const char *a, const char *b) {
errno = 0;
unsigned long x = strtoul(a, NULL, 0);
int e1 = ULONG_MAX == x ? errno : 0;
errno = 0;
unsigned long y = strtoul(b, NULL, 0);
int e2 = ULONG_MAX == y ? errno : 0;
char* err1 = strerror(e1);
char* err2 = strerror(e2);
fprintf(stderr, "parsing results: %s, %s", err1, err2); // diagnostic required
}
int main(int argc, char *argv[]) {///
char* st1 = "libuse";///
char* st2 = "strerr";///
f();///
g(st1);///
h(st1,st2);///
return EXIT_SUCCESS;///
}///
$ cc libuse.c
$ ./a.out
Segmentation fault: 11
5.42. Using character values that are indistinguishable from EOF [chreof]
//EXAMPLE 1 In this noncompliant example, a diagnostic is required because the result of the call to the C Standard Library function getchar is stored into a variable of type char, c, and c is compared to EOF.
#include <stdio.h> /// for printf
#include <stdlib.h> /// for EXIT_SUCCESS
#include <string.h> /// for strlen
#include <errno.h> /// for errno
#include <limits.h> /// for 'lONG_MAX'
#include <locale.h> /// for LC_ALL
#include <wchar.h> /// for wcslen
void f(void) {
char buf[BUFSIZ];
char c;
size_t i = 0;
while ((c = getchar()) != '\n' && c != EOF) { // diagnostic required
if (i < BUFSIZ - 1) {
buf[i++] = c;
}
}
buf[i] = '\0';
printf("%s\n", buf);
}
//EXAMPLE 2 In this noncompliant example, a diagnostic is required because the result of the call to the C Standard Library function getwc is stored into a variable of type wchar_t, wc, and wc is compared to WEOF.
void g(void) {
wchar_t buf[BUFSIZ];
wchar_t wc;
size_t i = 0;
while ((wc = getwc(stdin)) != '\n' && wc != WEOF) { // diagnostic required
if (i < BUFSIZ - 1) {
buf[i++] = wc;
}
}
buf[i] = '\0';
wprintf("%s\n", buf);
}
int main(int argc, char *argv[]) {///
f();///
g();///
return EXIT_SUCCESS;///
}///
cc chreof.c
chreof.c:35:11: warning: incompatible pointer types passing 'char [4]' to parameter of type 'const wchar_t *' (aka 'const int *')
[-Wincompatible-pointer-types]
wprintf("%s\n", buf);
^~~~~~
/usr/include/wchar.h:155:39: note: passing argument to parameter here
int wprintf(const wchar_t * __restrict, ...);
^
1 warning generated.
$ ./a.out
^C
5.43. Using identifiers
that are reserved for the implementation [resident]
https://qiita.com/kaizen_nagoya/items/b160f07b261b0a5fcf88
5.44. Using invalid format strings [invfmtstr]
//EXAMPLE In this noncompliant example, a diagnostic is required because the arguments to printf do not match the conversion specifiers in the supplied format string.
#include <stdio.h> /// for printf
#include <stdlib.h> /// for EXIT_SUCCESS
void f(void) {
const char *error_msg = "Resource not available to user.";
int error_type = 3;
/* ... */
printf("Error (type %s): %d\n", error_type, error_msg); // diagnostic required
}
int main(int argc, char *argv[]) {///
f();///
return EXIT_SUCCESS;///
}///
$ cc invfmtstr.c
invfmtstr.c:10:35: warning: format specifies type 'char *' but the argument has type 'int' [-Wformat]
printf("Error (type %s): %d\n", error_type, error_msg); // diagnostic required
~~ ^~~~~~~~~~
%d
invfmtstr.c:10:47: warning: format specifies type 'int' but the argument has type 'const char *' [-Wformat]
printf("Error (type %s): %d\n", error_type, error_msg); // diagnostic required
~~ ^~~~~~~~~
%s
2 warnings generated.
$ ./a.out
Segmentation fault: 11
5.45. Tainted, potentially mutilated,
or out-of-domain integer values are used in a restricted sink [taintsink]
#include <stdio.h> /// for printf
#include <stdlib.h> /// for EXIT_SUCCESS
#include <string.h> /// for strlen
#include <errno.h> /// for errno
#include <limits.h> /// for 'lONG_MAX'
#include "get.h" /// for GET_TAINTED_INTEGER
//EXAMPLE 1 In this noncompliant example, a diagnostic is required because the tainted integer size is used to declare the size of the variable length array vla.
void f(const char *c_str) {
size_t size;
GET_TAINTED_INTEGER(size_t, size);
char vla[size]; // diagnostic required
strncpy(vla, c_str, size);
vla[size - 1] = '\0';
/* ... */
}
//EXAMPLE 2 In this noncompliant example, a diagnostic is required because the tainted integer color_index is used in pointer arithmetic to index into the array table.
const char *table[] = { "black", "white", "blue", "green" };
const char *set_background_color(void) {
int color_index;
GET_TAINTED_INTEGER(int, color_index);
printf("%d\n",color_index);
const char *color = table[color_index]; // diagnostic required
/* ... */
return color;
}
int main(int argc, char *argv[]) {///
char * s = "taintsink.c";///
f(s);///
printf("back:%s\n", set_background_color());///
return EXIT_SUCCESS;///
}///
$ cc taintsink.c
$ ./a.out
Annex A (informative)
Intra- to Interprocedural Transformations
A.1 Function arguments and return values
FILE *fp = fopen(name, mode);
if (fp != NULL) /* checking for success */
/* ... */
void check_it(FILE *fp) {
if (fp != NULL) /* checking for success */
/* ... */
}
/* ... */
check_it(fopen(name, mode));
/* a wrapper around fopen */
FILE *xfopen(const char *name, const char *mode) {
return fopen(name, mode); /* return for checking elsewhere */
}
...
FILE *fp = xfopen(name, mode);
if (fp != NULL) /* checking for success */
/* ... */
/* trivial example */
FILE *identity(FILE *fp) {
return fp;
}
FILE *fp = identity(fopen(name, mode));
if (fp != NULL) /* checking for success */
/* ... */
A.2 Indirection
void check_indirect(FILE **pfp) {
if (*pfp != NULL) /* checking for success */
/* ... */
}
/* ... */
FILE *fp = fopen(name, mode);
check_indirect(&fp);
void return_result_thru_param(const char *name, const char *mode,
FILE **result) {
*result = fopen(name, mode);
}
/* ... */
FILE *fp;
return_result_thru_param(name, mode, &fp);
if (fp != NULL) /* checking for success */
/* ... */
int array[2];
int index = 2; /* part of violation */
array[index] = 0; /* violation */
Applying some of the interprocedural transformations yields
void indexer(int *array, int index) {
array[index] = 0; /* part of violation */
}
/* ... */
int array[2];
int index = 2; /* part of violation */
indexer(array, index); /* violation */
or
static int array[2];
int *get_array() {
return array; /* part of violation */
}
/* ... */
get_array()[2] = 0; /* violation */
or
struct array_params {
int *array;
int index;
};
void indexer(struct array_params *ap) {
ap->array[ap->index] = 0; /* part of violation */
}
/* ... */
int array[2];
struct array_params params;
params.array = array; /* part of violation */
params.index = 2; /* part of violation */
indexer(¶ms); /* violation */
These violations involve three steps: the array, the index, and the address arithmetic, where each could occur in a different function:
int *add(int *base, int offset) {
return base + offset; /* part of violation */
}
/* ... */
int array[2];
int index = 2; /* part of violation */
*add(array, index) = 0; /* violation */
Indirection may also be applied to a pointer being returned from a function:
const int *ptr_to_index() {
static int rv;
rv = 2; /* part of violation */
return &rv; /* part of violation */
}
/* ... */
int array[2];
array[*ptr_to_index()] = 0; /* violation */
A.3 Transformation involving standard library functions
const char* basename(const char *pathname) {
char *slash;
slash = strchr(pathname, '/');
if (slash) {
*slash++ = '\0'; /* violates EXP40-C. Do not modify constant values */
return slash;
}
return pathname;
}
A.4 Data flow through globals
int global_index;
void set_it() {
global_index = 2; /* part of violation */
}
/* ... */
int array[2];
set_it(); /* part of violation */
array[global_index] = 0; /* violation */
A.5 Data flow through the heap
struct some_record {
int index;
/* ... */
};
/* returns the heap-allocated record (created elsewhere)
* matching 'key'
*/
struct some_record *find_record(const char *key);
void set_it() {
struct some_record *record = find_record("xyz");
record->index = 2;
}
/* ... */
int array[2];
set_it(); /* part of violation */
struct some_record *record = find_record("xyz"); /* part of violation */
array[record->index] = 0; /* violation */
/* note that find_record() could even be called before set_it() */
A.6 Combined example
struct trouble {
int *array;
int index;
int *effective_address;
};
void set_array(struct trouble *t, int *array) {
t->array = array; /* part of violation *.
}
void set_index(struct trouble *t, int *index) {
t->index = *index; /* part of violation */
}
void compute_effective_address(struct trouble *t) {
t->effective_address = t->array + t->index; /* part of violation */
}
void store(struct trouble *t, int value) {
*t->effective_address = value; /* part of violation */
}
...
int array[2];
int index = 2; /* part of violation */
struct trouble t;
set_array(t, array); /* part of violation */
set_index(t, &index); /* part of violation */
compute_effective_address(&t); /* violation */
store(&t, 0); /* violation */
参考文献
ISO/IEC TS 17961:2013 C Secure Coding Rules(1) All list(to be confirmed)
https://qiita.com/kaizen_nagoya/items/54e056195c4f11b850a1
コンパイル用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
ISO/IEC TS 17961:2013 C Secure Coding Rules(1) All list(to be confirmed)
https://qiita.com/kaizen_nagoya/items/54e056195c4f11b850a1
Ethernet 記事一覧 Ethernet(0)
https://qiita.com/kaizen_nagoya/items/88d35e99f74aefc98794
Wireshark 一覧 wireshark(0)、Ethernet(48)
https://qiita.com/kaizen_nagoya/items/fbed841f61875c4731d0
線網(Wi-Fi)空中線(antenna)(0) 記事一覧(118/300目標)
https://qiita.com/kaizen_nagoya/items/5e5464ac2b24bd4cd001
OSEK OS設計の基礎 OSEK(100)
https://qiita.com/kaizen_nagoya/items/7528a22a14242d2d58a3
Error一覧(C/C++, python, bash...) Error(0)
https://qiita.com/kaizen_nagoya/items/48b6cbc8d68eae2c42b8
なぜdockerで機械学習するか 書籍・ソース一覧作成中 (目標100)
https://qiita.com/kaizen_nagoya/items/ddd12477544bf5ba85e2
言語処理100本ノックをdockerで。python覚えるのに最適。:10+12
https://qiita.com/kaizen_nagoya/items/7e7eb7c543e0c18438c4
プログラムちょい替え(0)一覧:4件
https://qiita.com/kaizen_nagoya/items/296d87ef4bfd516bc394
TOPPERSまとめ #名古屋のIoTは名古屋のOSで
https://qiita.com/kaizen_nagoya/items/9026c049cb0309b9d451
docker(0) 資料集
https://qiita.com/kaizen_nagoya/items/45699eefd62677f69c1d
Qiita-dockerお宝鑑定団
https://qiita.com/kaizen_nagoya/items/509e125263559b5aed5b
The C++ Standard Library: clang++とg++でコンパイルしてみた(まとめ):14件
https://qiita.com/kaizen_nagoya/items/9bdfaa392443d13e5759
C++17 - The Complete Guide clang++とg++でコンパイルしてみた(まとめ):4件
https://qiita.com/kaizen_nagoya/items/c000f307e642990781e1
C++N3242, 2011, ISO/IEC 14882, C++ standard(1) Example code compile list
https://qiita.com/kaizen_nagoya/items/685b5c1a2c17c1bf1318
C++N4606 Working Draft 2016, ISO/IEC 14882, C++ standard(1) Example code compile list
https://qiita.com/kaizen_nagoya/items/df5d62c35bd6ed1c3d43/
C++N4741, 2018 Standard Working Draft on ISO/IEC 14882 sample code compile list
https://qiita.com/kaizen_nagoya/items/3294c014044550896010
C++N4910:2022 Standard Working Draft on ISO/IEC 14882(0) sample code compile list
https://qiita.com/kaizen_nagoya/items/fc957ddddd402004bb91
Autosar Guidelines C++14 example code compile list(1-169)
https://qiita.com/kaizen_nagoya/items/8ccbf6675c3494d57a76
ISO/IEC TS 17961:2013 C Secure Coding Rules(1) All list(to be confirmed)
https://qiita.com/kaizen_nagoya/items/54e056195c4f11b850a1
プログラマによる、プログラマのための、統計と確率のプログラミングとその後 統計と確率一覧(0)
https://qiita.com/kaizen_nagoya/items/6e9897eb641268766909
<この項は書きかけです。順次追記します。>
This article is not completed. I will add some words and/or centences in order.
Este artículo no está completo. Agregaré algunas palabras en orden.
Qiita Calendar 2024
祝休日・謹賀新年 2025年の目標
https://qiita.com/kaizen_nagoya/items/dfa34827932f99c59bbc
Qiita 1年間をまとめた「振り返りページ」@2024
https://qiita.com/kaizen_nagoya/items/ed6be239119c99b15828
2024 参加・主催Calendarと投稿記事一覧 Qiita(248)
https://qiita.com/kaizen_nagoya/items/d80b8fbac2496df7827f
主催Calendar2024分析 Qiita(254)
https://qiita.com/kaizen_nagoya/items/15807336d583076f70bc
Calendar 統計
https://qiita.com/kaizen_nagoya/items/e315558dcea8ee3fe43e
LLM 関連 Calendar 2024
https://qiita.com/kaizen_nagoya/items/c36033cf66862d5496fa
Large Language Model Related Calendar
https://qiita.com/kaizen_nagoya/items/3beb0bc3fb71e3ae6d66
博士論文 Calendar 2024 を開催します。
https://qiita.com/kaizen_nagoya/items/51601357efbcaf1057d0
博士論文(0)関連記事一覧
https://qiita.com/kaizen_nagoya/items/8f223a760e607b705e78
関連資料
' @kazuo_reve 私が効果を確認した「小川メソッド」
https://qiita.com/kazuo_reve/items/a3ea1d9171deeccc04da
' @kazuo_reve 新人の方によく展開している有益な情報
https://qiita.com/kazuo_reve/items/d1a3f0ee48e24bba38f1
' @kazuo_reve Vモデルについて勘違いしていたと思ったこと
https://qiita.com/kazuo_reve/items/46fddb094563bd9b2e1e
自己記事一覧
Qiitaで逆リンクを表示しなくなったような気がする。時々、スマフォで表示するとあらわっることがあり、完全に削除したのではなさそう。
4月以降、せっせとリンクリストを作り、統計を取って確率を説明しようとしている。
2025年2月末を目標にしている。
一覧の一覧( The directory of directories of mine.) Qiita(100)
https://qiita.com/kaizen_nagoya/items/7eb0e006543886138f39
仮説(0)一覧(目標100現在40)
https://qiita.com/kaizen_nagoya/items/f000506fe1837b3590df
Qiita(0)Qiita関連記事一覧(自分)
https://qiita.com/kaizen_nagoya/items/58db5fbf036b28e9dfa6
Error一覧 error(0)
https://qiita.com/kaizen_nagoya/items/48b6cbc8d68eae2c42b8
C++ Support(0)
https://qiita.com/kaizen_nagoya/items/8720d26f762369a80514
Coding(0) Rules, C, Secure, MISRA and so on
https://qiita.com/kaizen_nagoya/items/400725644a8a0e90fbb0
Ethernet 記事一覧 Ethernet(0)
https://qiita.com/kaizen_nagoya/items/88d35e99f74aefc98794
Wireshark 一覧 wireshark(0)、Ethernet(48)
https://qiita.com/kaizen_nagoya/items/fbed841f61875c4731d0
線網(Wi-Fi)空中線(antenna)(0) 記事一覧(118/300目標)
https://qiita.com/kaizen_nagoya/items/5e5464ac2b24bd4cd001
なぜdockerで機械学習するか 書籍・ソース一覧作成中 (目標100)
https://qiita.com/kaizen_nagoya/items/ddd12477544bf5ba85e2
プログラムちょい替え(0)一覧:4件
https://qiita.com/kaizen_nagoya/items/296d87ef4bfd516bc394
言語処理100本ノックをdockerで。python覚えるのに最適。:10+12
https://qiita.com/kaizen_nagoya/items/7e7eb7c543e0c18438c4
Python(0)記事をまとめたい。
https://qiita.com/kaizen_nagoya/items/088c57d70ab6904ebb53
安全(0)安全工学シンポジウムに向けて: 21
https://qiita.com/kaizen_nagoya/items/c5d78f3def8195cb2409
プログラマによる、プログラマのための、統計(0)と確率のプログラミングとその後
https://qiita.com/kaizen_nagoya/items/6e9897eb641268766909
転職(0)一覧
https://qiita.com/kaizen_nagoya/items/f77520d378d33451d6fe
技術士(0)一覧
https://qiita.com/kaizen_nagoya/items/ce4ccf4eb9c5600b89ea
Reserchmap(0) 一覧
https://qiita.com/kaizen_nagoya/items/506c79e562f406c4257e
物理記事 上位100
https://qiita.com/kaizen_nagoya/items/66e90fe31fbe3facc6ff
量子(0) 計算機, 量子力学
https://qiita.com/kaizen_nagoya/items/1cd954cb0eed92879fd4
数学関連記事100
https://qiita.com/kaizen_nagoya/items/d8dadb49a6397e854c6d
coq(0) 一覧
https://qiita.com/kaizen_nagoya/items/d22f9995cf2173bc3b13
統計(0)一覧
https://qiita.com/kaizen_nagoya/items/80d3b221807e53e88aba
図(0) state, sequence and timing. UML and お絵描き
https://qiita.com/kaizen_nagoya/items/60440a882146aeee9e8f
色(0) 記事100書く切り口
https://qiita.com/kaizen_nagoya/items/22331c0335ed34326b9b
品質一覧
https://qiita.com/kaizen_nagoya/items/2b99b8e9db6d94b2e971
言語・文学記事 100
https://qiita.com/kaizen_nagoya/items/42d58d5ef7fb53c407d6
医工連携関連記事一覧
https://qiita.com/kaizen_nagoya/items/6ab51c12ba51bc260a82
水の資料集(0) 方針と成果
https://qiita.com/kaizen_nagoya/items/f5dbb30087ea732b52aa
自動車 記事 100
https://qiita.com/kaizen_nagoya/items/f7f0b9ab36569ad409c5
通信記事100
https://qiita.com/kaizen_nagoya/items/1d67de5e1cd207b05ef7
日本語(0)一欄
https://qiita.com/kaizen_nagoya/items/7498dcfa3a9ba7fd1e68
英語(0) 一覧
https://qiita.com/kaizen_nagoya/items/680e3f5cbf9430486c7d
音楽 一覧(0)
https://qiita.com/kaizen_nagoya/items/b6e5f42bbfe3bbe40f5d
「@kazuo_reve 新人の方によく展開している有益な情報」確認一覧
https://qiita.com/kaizen_nagoya/items/b9380888d1e5a042646b
鉄道(0)鉄道のシステム考察はてっちゃんがてつだってくれる
https://qiita.com/kaizen_nagoya/items/faa4ea03d91d901a618a
OSEK OS設計の基礎 OSEK(100)
https://qiita.com/kaizen_nagoya/items/7528a22a14242d2d58a3
coding (101) 一覧を作成し始めた。omake:最近のQiitaで表示しない5つの事象
https://qiita.com/kaizen_nagoya/items/20667f09f19598aedb68
官公庁・学校・公的団体(NPOを含む)システムの課題、官(0)
https://qiita.com/kaizen_nagoya/items/04ee6eaf7ec13d3af4c3
「はじめての」シリーズ ベクタージャパン
https://qiita.com/kaizen_nagoya/items/2e41634f6e21a3cf74eb
AUTOSAR(0)Qiita記事一覧, OSEK(75)
https://qiita.com/kaizen_nagoya/items/89c07961b59a8754c869
プログラマが知っていると良い「公序良俗」
https://qiita.com/kaizen_nagoya/items/9fe7c0dfac2fbd77a945
LaTeX(0) 一覧
https://qiita.com/kaizen_nagoya/items/e3f7dafacab58c499792
自動制御、制御工学一覧(0)
https://qiita.com/kaizen_nagoya/items/7767a4e19a6ae1479e6b
Rust(0) 一覧
https://qiita.com/kaizen_nagoya/items/5e8bb080ba6ca0281927
programの本質は計画だ。programは設計だ。
https://qiita.com/kaizen_nagoya/items/c8545a769c246a458c27
登壇直後版 色使い(JIS安全色) Qiita Engineer Festa 2023〜私しか得しないニッチな技術でLT〜 スライド編 0.15
https://qiita.com/kaizen_nagoya/items/f0d3070d839f4f735b2b
プログラマが知っていると良い「公序良俗」
https://qiita.com/kaizen_nagoya/items/9fe7c0dfac2fbd77a945
逆も真:社会人が最初に確かめるとよいこと。OSEK(69)、Ethernet(59)
https://qiita.com/kaizen_nagoya/items/39afe4a728a31b903ddc
統計の嘘。仮説(127)
https://qiita.com/kaizen_nagoya/items/63b48ecf258a3471c51b
自分の言葉だけで論理展開できるのが天才なら、文章の引用だけで論理展開できるのが秀才だ。仮説(136)
https://qiita.com/kaizen_nagoya/items/97cf07b9e24f860624dd
参考文献駆動執筆(references driven writing)・デンソークリエイト編
https://qiita.com/kaizen_nagoya/items/b27b3f58b8bf265a5cd1
「何を」よりも「誰を」。10年後のために今見習いたい人たち
https://qiita.com/kaizen_nagoya/items/8045978b16eb49d572b2
Qiitaの記事に3段階または5段階で到達するための方法
https://qiita.com/kaizen_nagoya/items/6e9298296852325adc5e
出力(output)と呼ばないで。これは状態(state)です。
https://qiita.com/kaizen_nagoya/items/80b8b5913b2748867840
coding (101) 一覧を作成し始めた。omake:最近のQiitaで表示しない5つの事象
https://qiita.com/kaizen_nagoya/items/20667f09f19598aedb68
あなたは「勘違いまとめ」から、勘違いだと言っていることが勘違いだといくつ見つけられますか。人間の間違い(human error(125))の種類と対策
https://qiita.com/kaizen_nagoya/items/ae391b77fffb098b8fb4
プログラマの「プログラムが書ける」思い込みは強みだ。3つの理由。仮説(168)統計と確率(17) , OSEK(79)
https://qiita.com/kaizen_nagoya/items/bc5dd86e414de402ec29
出力(output)と呼ばないで。これは状態(state)です。
https://qiita.com/kaizen_nagoya/items/80b8b5913b2748867840
これからの情報伝達手段の在り方について考えてみよう。炎上と便乗。
https://qiita.com/kaizen_nagoya/items/71a09077ac195214f0db
ISO/IEC JTC1 SC7 Software and System Engineering
https://qiita.com/kaizen_nagoya/items/48b43f0f6976a078d907
アクセシビリティの知見を発信しよう!(再び)
https://qiita.com/kaizen_nagoya/items/03457eb9ee74105ee618
統計論及確率論輪講(再び)
https://qiita.com/kaizen_nagoya/items/590874ccfca988e85ea3
読者の心をグッと惹き寄せる7つの魔法
https://qiita.com/kaizen_nagoya/items/b1b5e89bd5c0a211d862
「@kazuo_reve 新人の方によく展開している有益な情報」確認一覧
https://qiita.com/kaizen_nagoya/items/b9380888d1e5a042646b
ソースコードで議論しよう。日本語で議論するの止めましょう(あるプログラミング技術の議論報告)
https://qiita.com/kaizen_nagoya/items/8b9811c80f3338c6c0b0
脳内コンパイラの3つの危険
https://qiita.com/kaizen_nagoya/items/7025cf2d7bd9f276e382
心理学の本を読むよりはコンパイラ書いた方がよくね。仮説(34)
https://qiita.com/kaizen_nagoya/items/fa715732cc148e48880e
NASAを超えるつもりがあれば読んでください。
https://qiita.com/kaizen_nagoya/items/e81669f9cb53109157f6
データサイエンティストの気づき!「勉強して仕事に役立てない人。大嫌い!!」『それ自分かも?』ってなった!!!
https://qiita.com/kaizen_nagoya/items/d85830d58d8dd7f71d07
「ぼくの好きな先生」「人がやらないことをやれ」プログラマになるまで。仮説(37)
https://qiita.com/kaizen_nagoya/items/53e4bded9fe5f724b3c4
なぜ経済学徒を辞め、計算機屋になったか(経済学部入学前・入学後・卒業後対応) 転職(1)
https://qiita.com/kaizen_nagoya/items/06335a1d24c099733f64
プログラミング言語教育のXYZ。 仮説(52)
https://qiita.com/kaizen_nagoya/items/1950c5810fb5c0b07be4
【24卒向け】9ヶ月後に年収1000万円を目指す。二つの関門と三つの道。
https://qiita.com/kaizen_nagoya/items/fb5bff147193f726ad25
「【25卒向け】Qiita Career Meetup for STUDENT」予習の勧め
https://qiita.com/kaizen_nagoya/items/00eadb8a6e738cb6336f
大学入試不合格でも筆記試験のない大学に入って卒業できる。卒業しなくても博士になれる。
https://qiita.com/kaizen_nagoya/items/74adec99f396d64b5fd5
全世界の不登校の子供たち「博士論文」を書こう。世界子供博士論文遠隔実践中心 安全(99)
https://qiita.com/kaizen_nagoya/items/912d69032c012bcc84f2
小川メソッド 覚え(書きかけ)
https://qiita.com/kaizen_nagoya/items/3593d72eca551742df68
DoCAP(ドゥーキャップ)って何ですか?
https://qiita.com/kaizen_nagoya/items/47e0e6509ab792c43327
views 20,000越え自己記事一覧
https://qiita.com/kaizen_nagoya/items/58e8bd6450957cdecd81
Views1万越え、もうすぐ1万記事一覧 最近いいねをいただいた213記事
https://qiita.com/kaizen_nagoya/items/d2b805717a92459ce853
amazon 殿堂入りNo1レビュアになるまで。仮説(102)
https://qiita.com/kaizen_nagoya/items/83259d18921ce75a91f4
100以上いいねをいただいた記事16選
https://qiita.com/kaizen_nagoya/items/f8d958d9084ffbd15d2a
小川清最終講義、最終講義(再)計画, Ethernet(100) 英語(100) 安全(100)
https://qiita.com/kaizen_nagoya/items/e2df642e3951e35e6a53
<この記事は個人の過去の経験に基づく個人の感想です。現在所属する組織、業務とは関係がありません。>
This article is an individual impression based on my individual experience. It has nothing to do with the organization or business to which I currently belong.
Este artículo es una impresión personal basada en mi experiencia personal. No tiene nada que ver con la organización o empresa a la que pertenezco actualmente.
文書履歴(document history)
ver. 0.10 初稿 5.10まで 2018/04/03
ver. 0.11 4.5 mutilated value 及び 5.17まで追記 未完 2つ。2018/04/04
ver. 0.12 5.28まで追記 半分超え 2018/04/05
ver. 0.13 主な作業内容を追記 2018/04/05
ver. 0.14 5.45まで追記。実行結果不十分。2018/04/06
ver. 0.15 Annex A追記。コンパイルまだ 2018/06/16
ver. 0.16 加筆 20220103
最後までおよみいただきありがとうございました。
いいね 💚、フォローをお願いします。
Thank you very much for reading to the last sentence.
Please press the like icon 💚 and follow me for your happy life.
Muchas gracias por leer hasta la última oración.
Por favor, haz clic en el ícono Me gusta 💚 y sígueme para tener una vida feliz.