git-svn-id: file:///var/lib/svn/clamav-devel/trunk/clamav-devel@526 77e5149b-7576-45b1-b177-96237e5ba77b
Tomasz Kojm authored on 2004/04/27 21:55:18... | ... |
@@ -1,3 +1,11 @@ |
1 |
+Tue Apr 27 14:53:39 CEST 2004 (tk) |
|
2 |
+---------------------------------- |
|
3 |
+ * clamscan: fix file access problem when using clamscan with external |
|
4 |
+ unpackers in a superuser mode (reported by Robert Allerstorfer |
|
5 |
+ <roal*anet.at> and ZMan Z. <x86zman*go-a-way.dyndns.org>). |
|
6 |
+ Access verification mechanism is POSIX compliant now. |
|
7 |
+ * libclamav: ignore more file types |
|
8 |
+ |
|
1 | 9 |
Tue Apr 27 12:42:14 BST 2004 (trog) |
2 | 10 |
----------------------------------- |
3 | 11 |
* libclamav/vba_extract.[ch]: Word6 macro extraction code (not yet activated) |
... | ... |
@@ -202,7 +202,7 @@ int scanmanager(const struct optstruct *opt) |
202 | 202 |
tmpdir = "/tmp"; |
203 | 203 |
#endif |
204 | 204 |
|
205 |
- if(writeaccess(tmpdir, UNPUSER) != 1) { |
|
205 |
+ if(checkaccess(tmpdir, UNPUSER, W_OK) != 1) { |
|
206 | 206 |
mprintf("@Can't write to the temporary directory.\n"); |
207 | 207 |
exit(64); |
208 | 208 |
} |
... | ... |
@@ -417,13 +417,13 @@ int scanfile(const char *filename, struct cl_node *root, const struct passwd *us |
417 | 417 |
&& (optl(opt, "tgz") || optl(opt, "deb"))) ) { |
418 | 418 |
|
419 | 419 |
/* check permissions */ |
420 |
- switch(readaccess(filename, UNPUSER)) { |
|
420 |
+ switch(checkaccess(filename, UNPUSER, R_OK)) { |
|
421 | 421 |
case -1: |
422 | 422 |
mprintf("@Can't get information about user "UNPUSER".\n"); |
423 |
- exit(60); /* this is critical problem, so we just exit here */ |
|
423 |
+ exit(60); /* this is a critical problem so we just exit here */ |
|
424 | 424 |
case -2: |
425 |
- mprintf("@Can't get information about current user.\n"); |
|
426 |
- exit(59); /* this is critical problem, so we just exit here */ |
|
425 |
+ mprintf("@Can't fork.\n"); |
|
426 |
+ exit(61); |
|
427 | 427 |
case 0: /* read access denied */ |
428 | 428 |
if(getuid()) { |
429 | 429 |
if(!printinfected) |
... | ... |
@@ -446,14 +446,10 @@ int scanfile(const char *filename, struct cl_node *root, const struct passwd *us |
446 | 446 |
} |
447 | 447 |
|
448 | 448 |
if(getuid()) |
449 |
- switch(readaccess(filename, NULL)) { |
|
450 |
- case -2: |
|
451 |
- mprintf("@Can't get information about current user.\n"); |
|
452 |
- exit(59); /* this is critical problem, so we just exit here */ |
|
453 |
- case 0: /* read access denied */ |
|
454 |
- if(!printinfected) |
|
455 |
- mprintf("%s: Access denied.\n", filename); |
|
456 |
- return 0; |
|
449 |
+ if(checkaccess(filename, NULL, R_OK) != 1) { |
|
450 |
+ if(!printinfected) |
|
451 |
+ mprintf("%s: Access denied.\n", filename); |
|
452 |
+ return 0; |
|
457 | 453 |
} |
458 | 454 |
|
459 | 455 |
if((ret = checkfile(filename, root, limits, options)) == CL_VIRUS) { |
... | ... |
@@ -499,7 +495,7 @@ int scancompressed(const char *filename, struct cl_node *root, const struct pass |
499 | 499 |
tmpdir = "/tmp"; |
500 | 500 |
#endif |
501 | 501 |
|
502 |
- if(writeaccess(tmpdir, UNPUSER) != 1) { |
|
502 |
+ if(checkaccess(tmpdir, UNPUSER, W_OK) != 1) { |
|
503 | 503 |
mprintf("@Can't write to the temporary directory.\n"); |
504 | 504 |
exit(64); |
505 | 505 |
} |
... | ... |
@@ -701,7 +697,7 @@ int scandenied(const char *filename, struct cl_node *root, const struct passwd * |
701 | 701 |
#endif |
702 | 702 |
|
703 | 703 |
|
704 |
- if(writeaccess(tmpdir, UNPUSER) != 1) { |
|
704 |
+ if(checkaccess(tmpdir, UNPUSER, W_OK) != 1) { |
|
705 | 705 |
mprintf("@Can't write to the temporary directory %s.\n", tmpdir); |
706 | 706 |
exit(64); |
707 | 707 |
} |
... | ... |
@@ -68,66 +68,41 @@ int fileinfo(const char *filename, short i) |
68 | 68 |
} |
69 | 69 |
} |
70 | 70 |
|
71 |
-int readaccess(const char *path, const char *username) |
|
71 |
+int checkaccess(const char *path, const char *username, int mode) |
|
72 | 72 |
{ |
73 | 73 |
struct passwd *user; |
74 |
- unsigned int su = 0, acc = 0; |
|
74 |
+ int ret = 0, status; |
|
75 | 75 |
|
76 |
+ if(!getuid()) { |
|
76 | 77 |
|
77 |
- if(!getuid()) |
|
78 |
- su = 1; |
|
79 |
- |
|
80 |
- if(su) { |
|
81 | 78 |
if((user = getpwnam(username)) == NULL) { |
82 | 79 |
return -1; |
83 | 80 |
} |
84 | 81 |
|
85 |
- /* WARNING: it's not POSIX compliant */ |
|
86 |
- |
|
87 |
- seteuid(user->pw_uid); |
|
88 |
- setegid(user->pw_gid); |
|
89 |
- } |
|
90 |
- |
|
91 |
- if(!access(path, R_OK)) |
|
92 |
- acc = 1; |
|
93 |
- |
|
94 |
- if(su) { |
|
95 |
- seteuid(0); |
|
96 |
- setegid(0); |
|
97 |
- } |
|
98 |
- |
|
99 |
- return acc; |
|
100 |
-} |
|
101 |
- |
|
102 |
-int writeaccess(const char *path, const char *username) |
|
103 |
-{ |
|
104 |
- struct passwd *user; |
|
105 |
- unsigned int su = 0, acc = 0; |
|
106 |
- |
|
107 |
- |
|
108 |
- if(!getuid()) |
|
109 |
- su = 1; |
|
110 |
- |
|
111 |
- if(su) { |
|
112 |
- if((user = getpwnam(username)) == NULL) { |
|
113 |
- return -1; |
|
82 |
+ switch(fork()) { |
|
83 |
+ case -1: |
|
84 |
+ return -2; |
|
85 |
+ |
|
86 |
+ case 0: |
|
87 |
+ setuid(user->pw_uid); |
|
88 |
+ setgid(user->pw_gid); |
|
89 |
+ if(access(path, mode)) |
|
90 |
+ exit(0); |
|
91 |
+ else |
|
92 |
+ exit(1); |
|
93 |
+ |
|
94 |
+ default: |
|
95 |
+ wait(&status); |
|
96 |
+ if(WIFEXITED(status) && WEXITSTATUS(status) == 1) |
|
97 |
+ ret = 1; |
|
114 | 98 |
} |
115 | 99 |
|
116 |
- /* WARNING: it's not POSIX compliant */ |
|
117 |
- |
|
118 |
- seteuid(user->pw_uid); |
|
119 |
- setegid(user->pw_gid); |
|
120 |
- } |
|
121 |
- |
|
122 |
- if(!access(path, W_OK)) |
|
123 |
- acc = 1; |
|
124 |
- |
|
125 |
- if(su) { |
|
126 |
- seteuid(0); |
|
127 |
- setegid(0); |
|
100 |
+ } else { |
|
101 |
+ if(!access(path, mode)) |
|
102 |
+ ret = 1; |
|
128 | 103 |
} |
129 | 104 |
|
130 |
- return acc; |
|
105 |
+ return ret; |
|
131 | 106 |
} |
132 | 107 |
|
133 | 108 |
int filecopy(const char *src, const char *dest) |
... | ... |
@@ -20,17 +20,8 @@ |
20 | 20 |
#define __OTHERS_H |
21 | 21 |
|
22 | 22 |
int fileinfo(const char *filename, short i); |
23 |
-int readaccess(const char *path, const char *username); |
|
24 |
-int writeaccess(const char *path, const char *username); |
|
23 |
+int checkaccess(const char *path, const char *username, int mode); |
|
25 | 24 |
int filecopy(const char *src, const char *dest); |
26 | 25 |
int isnumb(const char *str); |
27 | 26 |
|
28 |
- |
|
29 |
-/* njh@bandsman.co.uk: for BeOS */ |
|
30 |
-/* TODO: configure should see if sete[ug]id is set on the target */ |
|
31 |
-#if defined(C_BEOS) || defined(C_HPUX) |
|
32 |
-#define seteuid(u) (-1) |
|
33 |
-#define setegid(g) (-1) |
|
34 |
-#endif |
|
35 |
- |
|
36 | 27 |
#endif |
... | ... |
@@ -97,15 +97,19 @@ static const struct cli_magic_s cli_magic[] = { |
97 | 97 |
|
98 | 98 |
{0, "\000\000\001\263", 4, "MPEG video stream", CL_DATAFILE}, |
99 | 99 |
{0, "\000\000\001\272", 4, "MPEG sys stream", CL_DATAFILE}, |
100 |
- {0, "RIFF", 4, "RIFF file", CL_DATAFILE}, |
|
100 |
+ {0, "RIFF", 4, "RIFF", CL_DATAFILE}, |
|
101 | 101 |
{0, "GIF87a", 6, "GIF (87a)", CL_DATAFILE}, |
102 | 102 |
{0, "GIF89a", 6, "GIF (89a)", CL_DATAFILE}, |
103 | 103 |
{0, "\x89PNG\r\n\x1a\n", 8, "PNG", CL_DATAFILE}, |
104 | 104 |
{0, "\377\330\377\340", 4, "JPEG", CL_DATAFILE}, |
105 | 105 |
{0, "\377\330\377\356", 4, "JPG", CL_DATAFILE}, |
106 | 106 |
{0, "OggS", 4, "Ogg Stream", CL_DATAFILE}, |
107 |
+ {0, "ID3", 3, "MP3", CL_DATAFILE}, |
|
108 |
+ {0, "\377\373\220", 3, "MP3", CL_DATAFILE}, |
|
109 |
+ {0, "\%PDF-", 5, "PDF document", CL_DATAFILE}, |
|
110 |
+ {0, "\060\046\262\165\216\146\317", 7, "WMA/WMV/ASF", CL_DATAFILE}, |
|
107 | 111 |
|
108 |
- {-1, NULL, 0, NULL, CL_UNKNOWN_TYPE} |
|
112 |
+ {-1, NULL, 0, NULL, CL_UNKNOWN_TYPE} |
|
109 | 113 |
}; |
110 | 114 |
|
111 | 115 |
cli_file_t cli_filetype(const char *buf, size_t buflen) |
... | ... |
@@ -689,7 +693,7 @@ static int cli_vba_scandir(const char *dirname, const char **virname, long int * |
689 | 689 |
DIR *dd; |
690 | 690 |
struct dirent *dent; |
691 | 691 |
struct stat statbuf; |
692 |
- char *fname, *dir, *fullname; |
|
692 |
+ char *fname, *fullname; |
|
693 | 693 |
unsigned char *data; |
694 | 694 |
|
695 | 695 |
cli_dbgmsg("VBA scan dir: %s\n", dirname); |
... | ... |
@@ -767,10 +771,8 @@ static int cli_vba_scandir(const char *dirname, const char **virname, long int * |
767 | 767 |
static int cli_scanole2(int desc, const char **virname, long int *scanned, const struct cl_node *root, const struct cl_limits *limits, int options, int *reclev) |
768 | 768 |
{ |
769 | 769 |
const char *tmpdir; |
770 |
- char *dir, *fullname; |
|
771 |
- unsigned char *data; |
|
772 |
- int ret = CL_CLEAN, fd, i, data_len; |
|
773 |
- vba_project_t *vba_project; |
|
770 |
+ char *dir; |
|
771 |
+ int ret = CL_CLEAN; |
|
774 | 772 |
|
775 | 773 |
cli_dbgmsg("in cli_scanole2()\n"); |
776 | 774 |
|
... | ... |
@@ -799,7 +801,7 @@ static int cli_scanole2(int desc, const char **virname, long int *scanned, const |
799 | 799 |
|
800 | 800 |
if((ret = cli_vba_scandir(dir, virname, scanned, root, limits, options, reclev)) != CL_VIRUS) { |
801 | 801 |
if(cli_scandir(dir, virname, scanned, root, limits, options, reclev) == CL_VIRUS) { |
802 |
- ret = CL_VIRUS; |
|
802 |
+ ret = CL_VIRUS; |
|
803 | 803 |
} |
804 | 804 |
} |
805 | 805 |
|