[Pkg-clamav-commits] [SCM] Debian repository for ClamAV branch, debian/unstable, updated. debian/0.95+dfsg-1-6156-g094ec9b

Tomasz Kojm (none) zolw at Quad.
Sun Apr 4 00:55:21 UTC 2010


The following commit has been merged in the debian/unstable branch:
commit e6417b01b8fff721738c10c92cc85d91f878e871
Author: Tomasz Kojm <zolw at Quad.(none)>
Date:   Thu Jul 2 17:10:14 2009 +0200

    libclamav: add support for cpio archives (bb#1649)

diff --git a/libclamav/cpio.c b/libclamav/cpio.c
new file mode 100644
index 0000000..524601a
--- /dev/null
+++ b/libclamav/cpio.c
@@ -0,0 +1,378 @@
+/*
+ *  Copyright (C) 2009 Sourcefire, Inc.
+ *
+ *  Authors: Tomasz Kojm <tkojm at clamav.net>
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License version 2 as
+ *  published by the Free Software Foundation.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ *  MA 02110-1301, USA.
+ */
+
+#if HAVE_CONFIG_H
+#include "clamav-config.h"
+#endif
+
+#include <stdio.h>
+#include <string.h>
+#include <ctype.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+
+#include "cltypes.h"
+#include "others.h"
+#include "cpio.h"
+#include "scanners.h"
+
+struct cpio_hdr_old {
+    uint16_t magic;
+    uint16_t dev;
+    uint16_t ino;
+    uint16_t mode;
+    uint16_t uid;
+    uint16_t gid;
+    uint16_t nlink;
+    uint16_t rdev;
+    uint16_t mtime[2];
+    uint16_t namesize;
+    uint16_t filesize[2];
+};
+
+struct cpio_hdr_odc {
+    char magic[6];
+    char dev[6];
+    char ino[6];
+    char mode[6];
+    char uid[6];
+    char gid[6];
+    char nlink[6];
+    char rdev[6];
+    char mtime[11];
+    char namesize[6];
+    char filesize[11];
+};
+
+struct cpio_hdr_newc {
+    char magic[6];
+    char ino[8];
+    char mode[8];
+    char uid[8];
+    char gid[8];
+    char nlink[8];
+    char mtime[8];
+    char filesize[8];
+    char devmajor[8];
+    char devminor[8];
+    char rdevmajor[8];
+    char rdevminor[8];
+    char namesize[8];
+    char check[8];
+};
+
+#ifndef O_BINARY
+#define O_BINARY    0
+#endif
+
+static int cpio_scanfile(int fd, uint32_t size, cli_ctx *ctx)
+{
+	int newfd, bread, sum = 0, ret;
+	char buff[FILEBUFF];
+	char *name;
+
+
+    if(!(name = cli_gentemp(ctx->engine->tmpdir)))
+	return CL_EMEM;
+
+    if((newfd = open(name, O_RDWR|O_CREAT|O_TRUNC|O_BINARY, S_IRWXU)) < 0) {
+	cli_errmsg("cpio_scanfile: Can't create file %s\n", name);
+	free(name);
+	return CL_ECREAT;
+    }
+
+    while((bread = cli_readn(fd, buff, FILEBUFF)) > 0) {
+	if((uint32_t) (sum + bread) >= size) {
+	    if(write(newfd, buff, size - sum) == -1) {
+		cli_errmsg("cpio_scanfile: Can't write to %s\n", name);
+		cli_unlink(name);
+		free(name);
+		close(newfd);
+		return CL_EWRITE;
+	    }
+	    break;
+	} else {
+	    if(write(newfd, buff, bread) == -1) {
+		cli_errmsg("cpio_scanfile: Can't write to %s\n", name);
+		cli_unlink(name);
+		free(name);
+		close(newfd);
+		return CL_EWRITE;
+	    }
+	}
+	sum += bread;
+    }
+    cli_dbgmsg("CPIO: Extracted to %s\n", name);
+    lseek(newfd, 0, SEEK_SET);
+    if((ret = cli_magic_scandesc(newfd, ctx)) == CL_VIRUS)
+	cli_dbgmsg("cpio_scanfile: Infected with %s\n", *ctx->virname);
+
+    close(newfd);
+    if(!ctx->engine->keeptmp) {
+	if(cli_unlink(name)) {
+	    free(name);
+	    return CL_EUNLINK;
+	}
+    }
+    free(name);
+    return ret;
+}
+
+static inline uint16_t EC16(uint16_t v, int c)
+{
+    if(!c)
+	return v;
+    else
+	return ((v >> 8) + (v << 8));
+}
+
+static void sanitname(char *name)
+{
+    while(*name) {
+	if(!isascii(*name) || strchr("%\\\t\n\r", *name))
+	    *name = '_';
+	name++;
+    }
+}
+
+int cli_scancpio_old(int fd, cli_ctx *ctx)
+{
+	struct cpio_hdr_old hdr_old;
+	char name[513];
+	unsigned int file = 0, trailer = 0;
+	uint32_t filesize, namesize, hdr_namesize;
+	int ret, conv;
+	off_t pos;
+
+
+    while(read(fd, &hdr_old, sizeof(hdr_old)) == sizeof(hdr_old)) {
+	if(!hdr_old.magic && trailer)
+	    return CL_SUCCESS;
+
+	if(hdr_old.magic == 070707) {
+	    conv = 0;
+	} else if(hdr_old.magic == 0143561) {
+	    conv = 1;
+	} else {
+	    cli_dbgmsg("cli_scancpio_old: Invalid magic number\n");
+	    return CL_EFORMAT;
+	}
+
+	cli_dbgmsg("CPIO: -- File %u --\n", ++file);
+
+	if(hdr_old.namesize) {
+	    hdr_namesize = EC16(hdr_old.namesize, conv);
+	    namesize = MIN(sizeof(name), hdr_namesize);
+	    if(read(fd, name, namesize) != namesize) {
+		cli_dbgmsg("cli_scancpio_old: Can't read file name\n");
+		return CL_EFORMAT;
+	    }
+	    name[namesize - 1] = 0;
+	    sanitname(name);
+	    cli_dbgmsg("CPIO: Name: %s\n", name);
+	    if(!strcmp(name, "TRAILER!!!"))
+		trailer = 1;
+
+	    if(namesize < hdr_namesize) {
+		if(hdr_namesize % 2)
+		    hdr_namesize++;
+		lseek(fd, hdr_namesize - namesize, SEEK_CUR);
+	    } else if(hdr_namesize % 2)
+		lseek(fd, 1, SEEK_CUR);
+	}
+	filesize = (uint32_t) (EC16(hdr_old.filesize[0], conv) << 16 | EC16(hdr_old.filesize[1], conv));
+	cli_dbgmsg("CPIO: Filesize: %u\n", filesize);
+	if(!filesize)
+	    continue;
+
+	pos = lseek(fd, 0, SEEK_CUR);
+
+	if((EC16(hdr_old.mode, conv) & 0170000) != 0100000) {
+	    cli_dbgmsg("CPIO: Not a regular file, skipping\n");
+	} else {
+	    ret = cli_checklimits("cli_scancpio_old", ctx, filesize, 0, 0);
+	    if(ret == CL_EMAXFILES) {
+		return ret;
+	    } else if(ret == CL_SUCCESS) {
+		ret = cpio_scanfile(fd, filesize, ctx);
+		if(ret == CL_VIRUS)
+		    return ret;
+	    }
+	}
+	if(filesize % 2)
+	    filesize++;
+
+	lseek(fd, pos + filesize, SEEK_SET);
+    }
+
+    return CL_CLEAN;
+}
+
+int cli_scancpio_odc(int fd, cli_ctx *ctx)
+{
+	struct cpio_hdr_odc hdr_odc;
+	char name[513], buff[12];
+	unsigned int file = 0, trailer = 0;
+	uint32_t filesize, namesize, hdr_namesize;
+	int ret;
+	off_t pos;
+
+
+    while(read(fd, &hdr_odc, sizeof(hdr_odc)) == sizeof(hdr_odc)) {
+
+	if(!hdr_odc.magic[0] && trailer)
+	    return CL_SUCCESS;
+
+	if(strncmp(hdr_odc.magic, "070707", 6)) {
+	    cli_dbgmsg("cli_scancpio_odc: Invalid magic string\n");
+	    return CL_EFORMAT;
+	}
+
+	cli_dbgmsg("CPIO: -- File %u --\n", ++file);
+
+	strncpy(buff, hdr_odc.namesize, 6);
+	buff[6] = 0;
+	if(sscanf(buff, "%o", &hdr_namesize) != 1) {
+	    cli_dbgmsg("cli_scancpio_odc: Can't convert name size\n");
+	    return CL_EFORMAT;
+	}
+	if(hdr_namesize) {
+	    namesize = MIN(sizeof(name), hdr_namesize);
+	    if(read(fd, name, namesize) != namesize) {
+		cli_dbgmsg("cli_scancpio_odc: Can't read file name\n");
+		return CL_EFORMAT;
+	    }
+	    name[namesize - 1] = 0;
+	    sanitname(name);
+	    cli_dbgmsg("CPIO: Name: %s\n", name);
+	    if(!strcmp(name, "TRAILER!!!"))
+		trailer = 1;
+
+	    if(namesize < hdr_namesize)
+		lseek(fd, hdr_namesize - namesize, SEEK_CUR);
+	}
+
+	strncpy(buff, hdr_odc.filesize, 11);
+	buff[11] = 0;
+	if(sscanf(buff, "%o", &filesize) != 1) {
+	    cli_dbgmsg("cli_scancpio_odc: Can't convert file size\n");
+	    return CL_EFORMAT;
+	}
+	cli_dbgmsg("CPIO: Filesize: %u\n", filesize);
+	if(!filesize)
+	    continue;
+
+	pos = lseek(fd, 0, SEEK_CUR);
+
+	ret = cli_checklimits("cli_scancpio_odc", ctx, filesize, 0, 0);
+	if(ret == CL_EMAXFILES) {
+	    return ret;
+	} else if(ret == CL_SUCCESS) {
+	    ret = cpio_scanfile(fd, filesize, ctx);
+	    if(ret == CL_VIRUS)
+		return ret;
+	}
+
+	lseek(fd, pos + filesize, SEEK_SET);
+    }
+
+    return CL_CLEAN;
+}
+
+int cli_scancpio_newc(int fd, cli_ctx *ctx, int crc)
+{
+	struct cpio_hdr_newc hdr_newc;
+	char name[513], buff[9];
+	unsigned int file = 0, trailer = 0;
+	uint32_t filesize, namesize, hdr_namesize, pad;
+	int ret;
+	off_t pos;
+
+
+    while(read(fd, &hdr_newc, sizeof(hdr_newc)) == sizeof(hdr_newc)) {
+
+	if(!hdr_newc.magic[0] && trailer)
+	    return CL_SUCCESS;
+
+	if((!crc && strncmp(hdr_newc.magic, "070701", 6)) || (crc && strncmp(hdr_newc.magic, "070702", 6))) {
+	    cli_dbgmsg("cli_scancpio_newc: Invalid magic string\n");
+	    return CL_EFORMAT;
+	}
+
+	cli_dbgmsg("CPIO: -- File %u --\n", ++file);
+
+	strncpy(buff, hdr_newc.namesize, 8);
+	buff[8] = 0;
+	if(sscanf(buff, "%x", &hdr_namesize) != 1) {
+	    cli_dbgmsg("cli_scancpio_newc: Can't convert name size\n");
+	    return CL_EFORMAT;
+	}
+	if(hdr_namesize) {
+	    namesize = MIN(sizeof(name), hdr_namesize);
+	    if(read(fd, name, namesize) != namesize) {
+		cli_dbgmsg("cli_scancpio_newc: Can't read file name\n");
+		return CL_EFORMAT;
+	    }
+	    name[namesize - 1] = 0;
+	    sanitname(name);
+	    cli_dbgmsg("CPIO: Name: %s\n", name);
+	    if(!strcmp(name, "TRAILER!!!"))
+		trailer = 1;
+
+	    pad = (4 - (sizeof(hdr_newc) + hdr_namesize) % 4) % 4;
+	    if(namesize < hdr_namesize) {
+		if(pad)
+		    hdr_namesize += pad;
+		lseek(fd, hdr_namesize - namesize, SEEK_CUR);
+	    } else if(pad)
+		lseek(fd, pad, SEEK_CUR);
+	}
+
+	strncpy(buff, hdr_newc.filesize, 8);
+	buff[8] = 0;
+	if(sscanf(buff, "%x", &filesize) != 1) {
+	    cli_dbgmsg("cli_scancpio_newc: Can't convert file size\n");
+	    return CL_EFORMAT;
+	}
+	cli_dbgmsg("CPIO: Filesize: %u\n", filesize);
+	if(!filesize)
+	    continue;
+
+	pos = lseek(fd, 0, SEEK_CUR);
+
+	ret = cli_checklimits("cli_scancpio_newc", ctx, filesize, 0, 0);
+	if(ret == CL_EMAXFILES) {
+	    return ret;
+	} else if(ret == CL_SUCCESS) {
+	    ret = cpio_scanfile(fd, filesize, ctx);
+	    if(ret == CL_VIRUS)
+		return ret;
+	}
+
+	if((pad = filesize % 4))
+	    filesize += (4 - pad);
+
+	lseek(fd, pos + filesize, SEEK_SET);
+    }
+
+    return CL_CLEAN;
+}
diff --git a/shared/actions.h b/libclamav/cpio.h
similarity index 75%
copy from shared/actions.h
copy to libclamav/cpio.h
index ada3b0f..abfc66b 100644
--- a/shared/actions.h
+++ b/libclamav/cpio.h
@@ -1,7 +1,7 @@
 /*
  *  Copyright (C) 2009 Sourcefire, Inc.
  *
- *  Authors: aCaB
+ *  Authors: Tomasz Kojm <tkojm at clamav.net>
  *
  *  This program is free software; you can redistribute it and/or modify
  *  it under the terms of the GNU General Public License version 2 as
@@ -18,13 +18,13 @@
  *  MA 02110-1301, USA.
  */
 
-#ifndef ACTIONS_H
-#define ACTIONS_H
+#ifndef __CPIO_H
+#define __CPIO_H
 
-#include "shared/optparser.h"
+#include "others.h"
 
-extern void (*action)(const char *);
-int actsetup(const struct optstruct *opts);
-extern unsigned int notremoved, notmoved;
+int cli_scancpio_old(int fd, cli_ctx *ctx);
+int cli_scancpio_odc(int fd, cli_ctx *ctx);
+int cli_scancpio_newc(int fd, cli_ctx *ctx, int crc);
 
 #endif

-- 
Debian repository for ClamAV



More information about the Pkg-clamav-commits mailing list