2
* Copyright (C) 2009 Sourcefire, Inc.
4
* Authors: Tomasz Kojm <tkojm@clamav.net>
6
* This program is free software; you can redistribute it and/or modify
7
* it under the terms of the GNU General Public License version 2 as
8
* published by the Free Software Foundation.
10
* This program is distributed in the hope that it will be useful,
11
* but WITHOUT ANY WARRANTY; without even the implied warranty of
12
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
* GNU General Public License for more details.
15
* You should have received a copy of the GNU General Public License
16
* along with this program; if not, write to the Free Software
17
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
22
#include "clamav-config.h"
31
#include <sys/types.h>
69
struct cpio_hdr_newc {
86
#define EC16(v, conv) (conv ? cbswap16(v) : v)
88
static void sanitname(char *name)
91
if(!isascii(*name) || strchr("%\\\t\n\r", *name))
97
int cli_scancpio_old(int fd, cli_ctx *ctx)
99
struct cpio_hdr_old hdr_old;
101
unsigned int file = 0, trailer = 0;
102
uint32_t filesize, namesize, hdr_namesize;
107
while(read(fd, &hdr_old, sizeof(hdr_old)) == sizeof(hdr_old)) {
108
if(!hdr_old.magic && trailer)
111
if(hdr_old.magic == 070707) {
113
} else if(hdr_old.magic == 0143561) {
116
cli_dbgmsg("cli_scancpio_old: Invalid magic number\n");
120
cli_dbgmsg("CPIO: -- File %u --\n", ++file);
122
if(hdr_old.namesize) {
123
hdr_namesize = EC16(hdr_old.namesize, conv);
124
namesize = MIN(sizeof(name), hdr_namesize);
125
if(read(fd, name, namesize) != namesize) {
126
cli_dbgmsg("cli_scancpio_old: Can't read file name\n");
129
name[namesize - 1] = 0;
131
cli_dbgmsg("CPIO: Name: %s\n", name);
132
if(!strcmp(name, "TRAILER!!!"))
135
if(namesize < hdr_namesize) {
138
lseek(fd, hdr_namesize - namesize, SEEK_CUR);
139
} else if(hdr_namesize % 2)
140
lseek(fd, 1, SEEK_CUR);
142
filesize = (uint32_t) (EC16(hdr_old.filesize[0], conv) << 16 | EC16(hdr_old.filesize[1], conv));
143
cli_dbgmsg("CPIO: Filesize: %u\n", filesize);
147
if(cli_matchmeta(ctx, name, filesize, filesize, 0, file, 0, NULL) == CL_VIRUS)
150
pos = lseek(fd, 0, SEEK_CUR);
152
if((EC16(hdr_old.mode, conv) & 0170000) != 0100000) {
153
cli_dbgmsg("CPIO: Not a regular file, skipping\n");
155
ret = cli_checklimits("cli_scancpio_old", ctx, filesize, 0, 0);
156
if(ret == CL_EMAXFILES) {
158
} else if(ret == CL_SUCCESS) {
159
ret = cli_dumpscan(fd, 0, filesize, ctx);
167
lseek(fd, pos + filesize, SEEK_SET);
173
int cli_scancpio_odc(int fd, cli_ctx *ctx)
175
struct cpio_hdr_odc hdr_odc;
176
char name[513], buff[12];
177
unsigned int file = 0, trailer = 0;
178
uint32_t filesize, namesize, hdr_namesize;
183
while(read(fd, &hdr_odc, sizeof(hdr_odc)) == sizeof(hdr_odc)) {
185
if(!hdr_odc.magic[0] && trailer)
188
if(strncmp(hdr_odc.magic, "070707", 6)) {
189
cli_dbgmsg("cli_scancpio_odc: Invalid magic string\n");
193
cli_dbgmsg("CPIO: -- File %u --\n", ++file);
195
strncpy(buff, hdr_odc.namesize, 6);
197
if(sscanf(buff, "%o", &hdr_namesize) != 1) {
198
cli_dbgmsg("cli_scancpio_odc: Can't convert name size\n");
202
namesize = MIN(sizeof(name), hdr_namesize);
203
if(read(fd, name, namesize) != namesize) {
204
cli_dbgmsg("cli_scancpio_odc: Can't read file name\n");
207
name[namesize - 1] = 0;
209
cli_dbgmsg("CPIO: Name: %s\n", name);
210
if(!strcmp(name, "TRAILER!!!"))
213
if(namesize < hdr_namesize)
214
lseek(fd, hdr_namesize - namesize, SEEK_CUR);
217
strncpy(buff, hdr_odc.filesize, 11);
219
if(sscanf(buff, "%o", &filesize) != 1) {
220
cli_dbgmsg("cli_scancpio_odc: Can't convert file size\n");
223
cli_dbgmsg("CPIO: Filesize: %u\n", filesize);
227
if(cli_matchmeta(ctx, name, filesize, filesize, 0, file, 0, NULL) == CL_VIRUS)
230
pos = lseek(fd, 0, SEEK_CUR);
232
ret = cli_checklimits("cli_scancpio_odc", ctx, filesize, 0, 0);
233
if(ret == CL_EMAXFILES) {
235
} else if(ret == CL_SUCCESS) {
236
ret = cli_dumpscan(fd, 0, filesize, ctx);
241
lseek(fd, pos + filesize, SEEK_SET);
247
int cli_scancpio_newc(int fd, cli_ctx *ctx, int crc)
249
struct cpio_hdr_newc hdr_newc;
250
char name[513], buff[9];
251
unsigned int file = 0, trailer = 0;
252
uint32_t filesize, namesize, hdr_namesize, pad;
257
while(read(fd, &hdr_newc, sizeof(hdr_newc)) == sizeof(hdr_newc)) {
259
if(!hdr_newc.magic[0] && trailer)
262
if((!crc && strncmp(hdr_newc.magic, "070701", 6)) || (crc && strncmp(hdr_newc.magic, "070702", 6))) {
263
cli_dbgmsg("cli_scancpio_newc: Invalid magic string\n");
267
cli_dbgmsg("CPIO: -- File %u --\n", ++file);
269
strncpy(buff, hdr_newc.namesize, 8);
271
if(sscanf(buff, "%x", &hdr_namesize) != 1) {
272
cli_dbgmsg("cli_scancpio_newc: Can't convert name size\n");
276
namesize = MIN(sizeof(name), hdr_namesize);
277
if(read(fd, name, namesize) != namesize) {
278
cli_dbgmsg("cli_scancpio_newc: Can't read file name\n");
281
name[namesize - 1] = 0;
283
cli_dbgmsg("CPIO: Name: %s\n", name);
284
if(!strcmp(name, "TRAILER!!!"))
287
pad = (4 - (sizeof(hdr_newc) + hdr_namesize) % 4) % 4;
288
if(namesize < hdr_namesize) {
291
lseek(fd, hdr_namesize - namesize, SEEK_CUR);
293
lseek(fd, pad, SEEK_CUR);
296
strncpy(buff, hdr_newc.filesize, 8);
298
if(sscanf(buff, "%x", &filesize) != 1) {
299
cli_dbgmsg("cli_scancpio_newc: Can't convert file size\n");
302
cli_dbgmsg("CPIO: Filesize: %u\n", filesize);
306
if(cli_matchmeta(ctx, name, filesize, filesize, 0, file, 0, NULL) == CL_VIRUS)
309
pos = lseek(fd, 0, SEEK_CUR);
311
ret = cli_checklimits("cli_scancpio_newc", ctx, filesize, 0, 0);
312
if(ret == CL_EMAXFILES) {
314
} else if(ret == CL_SUCCESS) {
315
ret = cli_dumpscan(fd, 0, filesize, ctx);
320
if((pad = filesize % 4))
321
filesize += (4 - pad);
323
lseek(fd, pos + filesize, SEEK_SET);