Valgrindは私にこのエラーをスローします:
==11204== Syscall param write(buf) points to uninitialised byte(s)
==11204== at 0x4109033: write (in /lib/libc-2.13.so)
==11204== by 0x8049654: main (mmboxman.c:289)
==11204== Address 0xbe92f861 is on thread 1's stack
==11204==
どうしたの?初期化されていないバイトが何を叫んでいるかわかりません。ここにコードの犯罪的な行があります(前述の289行は関数lockUpを呼び出す行です):
Request request;
Response response;
fillRequest(&request, MANADDUSER, getpid(), argument1, NULL, NULL, 0, 0);
lockUp(&request, &response, NULL);
ここで関数プロトタイプと構造体宣言:
void fillRequest(Request *request, char code, pid_t pid, char *name1, char *name2, char *object, int id, size_t size)
{
int k;
request->code = code;
request->pid = getpid();
if(name1) for(k=0; k<strlen(name1)+1; k++) request->name1[k] = name1[k];
else request->name1[0] = '\0';
if(name2) for(k=0; k<strlen(name2)+1; k++) request->name2[k] = name2[k];
else request->name2[0] = '\0';
if(object) for(k=0; k<strlen(name2)+1; k++) request->name2[k] = name2[k];
else request->object[0] = '\0';
request->id = id;
request->size = size;
}
void lockUp(Request *request, Response *response, void **buffer)
{
int fifofrom, fifoto, lock; /* file descriptor delle fifo e del lock */
/* locko per l'accesso alle FIFO */
if((lock = open(LOCK, O_RDONLY)) == -1) logMmboxman("error in opening LOCK\n", 1);
else logMmboxman("opened LOCK\n", 0);
if(flock(lock, LOCK_EX) == -1) logMmboxman("error in acquiring LOCK\n", 1);
else logMmboxman("acquired LOCK\n", 0);
/* apro la fifoto e scrivo la mia richiesta */
if((fifoto = open(FIFOTOMMBOXD, O_WRONLY)) == -1) logMmboxman("error in opening FIFOTO\n", 1);
else logMmboxman("opened FIFOTO\n", 0);
if((write(fifoto, request, sizeof(Request))) != sizeof(Request)) logMmboxman("error in writing FIFOTO\n", 1);
else logMmboxman("written on FIFOTO\n", 0);
close(fifoto);
/* rimango in attesa della risposta da mmboxd sulla fifofrom */
if((fifofrom = open(FIFOFROMMMBOXD, O_RDONLY)) == -1) logMmboxman("error in opening FIFOFROM\n", 1);
else logMmboxman("opened FIFOFROM\n", 0);
if((read(fifofrom, response, sizeof(Response))) != sizeof(Response)) logMmboxman("error in reading FIFOFROM\n", 1);
else logMmboxman("read from FIFOFROM\n", 0);
close(fifofrom);
/* se mi deve comunicare un buffer riapro la fifo e lo leggo */
if(response->size)
{
if((fifofrom = open(FIFOFROMMMBOXD, O_RDONLY)) == -1) logMmboxman("error in opening FIFOFROM again for the buffer\n", 1);
else logMmboxman("opened FIFOFROM again for the buffer\n", 0);
*buffer = (void*)malloc(response->size);
if(read(fifofrom, *buffer, response->size) != response->size) logMmboxman("error in reading FIFOFROM again for the buffer\n", 1);
else logMmboxman("read from FIFOFROM again for the buffer\n", 0);
close(fifofrom);
}
/* letta la risposta rilascio il lock */
if(flock(lock, LOCK_UN) == -1) logMmboxman("error in releasing LOCK\n", 1);
else logMmboxman("released LOCK\n", 0);
return;
}
typedef struct
{
char code;
pid_t pid;
char name1[41];
char name2[41];
char object[101];
int id;
size_t size;
} Request;
typedef struct
{
char result;
int num;
int num2;
size_t size;
} Response;
Request
構造体には、ヌルで終了する文字列を含む配列name1
、name2
などがあります。それらを埋めるとき、ヌルターミネーターを超えて書き込むことはありません。後でファイルに構造を書き込むと、これらのバイトが初期化されていないため、valgrindは文句を言います。その他の初期化されていないバイト(たとえば、コンパイラーによって挿入されたパディング)も存在する可能性があります。
これは、小さなセキュリティの問題以外は必ずしも問題ではありません。機密情報を保持している可能性のある以前のメモリの内容がファイルに書き込まれます。
このエラーを回避するために、フィールドに入力する前に構造を0にmemsetできます。