1 |
diff -up icecast-2.3.2/src/cfgfile.c.CVE-2014-9018b icecast-2.3.2/src/cfgfile.c |
2 |
--- icecast-2.3.2/src/cfgfile.c.CVE-2014-9018b 2008-05-02 04:56:58.000000000 +0200 |
3 |
+++ icecast-2.3.2/src/cfgfile.c 2014-11-21 00:45:55.004000000 +0100 |
4 |
@@ -61,12 +61,14 @@ |
5 |
#define CONFIG_DEFAULT_LOG_DIR "/usr/local/icecast/logs" |
6 |
#define CONFIG_DEFAULT_WEBROOT_DIR "/usr/local/icecast/webroot" |
7 |
#define CONFIG_DEFAULT_ADMINROOT_DIR "/usr/local/icecast/admin" |
8 |
+#define CONFIG_DEFAULT_NULL_FILE "/dev/null" |
9 |
#define MIMETYPESFILE "/etc/mime.types" |
10 |
#else |
11 |
#define CONFIG_DEFAULT_BASE_DIR ".\\" |
12 |
#define CONFIG_DEFAULT_LOG_DIR ".\\logs" |
13 |
#define CONFIG_DEFAULT_WEBROOT_DIR ".\\webroot" |
14 |
#define CONFIG_DEFAULT_ADMINROOT_DIR ".\\admin" |
15 |
+#define CONFIG_DEFAULT_NULL_FILE "nul:" |
16 |
#define MIMETYPESFILE ".\\mime.types" |
17 |
#endif |
18 |
|
19 |
@@ -364,6 +366,7 @@ static void _set_defaults(ice_config_t * |
20 |
configuration->master_password = NULL; |
21 |
configuration->base_dir = (char *)xmlCharStrdup (CONFIG_DEFAULT_BASE_DIR); |
22 |
configuration->log_dir = (char *)xmlCharStrdup (CONFIG_DEFAULT_LOG_DIR); |
23 |
+ configuration->null_file = (char *)xmlCharStrdup (CONFIG_DEFAULT_NULL_FILE); |
24 |
configuration->webroot_dir = (char *)xmlCharStrdup (CONFIG_DEFAULT_WEBROOT_DIR); |
25 |
configuration->adminroot_dir = (char *)xmlCharStrdup (CONFIG_DEFAULT_ADMINROOT_DIR); |
26 |
configuration->playlist_log = (char *)xmlCharStrdup (CONFIG_DEFAULT_PLAYLIST_LOG); |
27 |
@@ -942,6 +945,9 @@ static void _parse_paths(xmlDocPtr doc, |
28 |
} else if (xmlStrcmp (node->name, XMLSTR("pidfile")) == 0) { |
29 |
if (configuration->pidfile) xmlFree(configuration->pidfile); |
30 |
configuration->pidfile = (char *)xmlNodeListGetString(doc, node->xmlChildrenNode, 1); |
31 |
+ } else if (xmlStrcmp (node->name, XMLSTR("nullfile")) == 0) { |
32 |
+ if (configuration->null_file) xmlFree(configuration->null_file); |
33 |
+ configuration->null_file = (char *)xmlNodeListGetString(doc, node->xmlChildrenNode, 1); |
34 |
} else if (xmlStrcmp (node->name, XMLSTR("deny-ip")) == 0) { |
35 |
if (configuration->banfile) xmlFree(configuration->banfile); |
36 |
configuration->banfile = (char *)xmlNodeListGetString(doc, node->xmlChildrenNode, 1); |
37 |
diff -up icecast-2.3.2/src/cfgfile.h.CVE-2014-9018b icecast-2.3.2/src/cfgfile.h |
38 |
--- icecast-2.3.2/src/cfgfile.h.CVE-2014-9018b 2007-10-25 03:15:25.000000000 +0200 |
39 |
+++ icecast-2.3.2/src/cfgfile.h 2014-11-21 00:44:24.620000000 +0100 |
40 |
@@ -157,6 +157,7 @@ typedef struct ice_config_tag |
41 |
char *base_dir; |
42 |
char *log_dir; |
43 |
char *pidfile; |
44 |
+ char *null_file; |
45 |
char *banfile; |
46 |
char *allowfile; |
47 |
char *cert_file; |
48 |
diff -up icecast-2.3.2/src/source.c.CVE-2014-9018b icecast-2.3.2/src/source.c |
49 |
--- icecast-2.3.2/src/source.c.CVE-2014-9018b 2014-11-21 00:44:24.601000000 +0100 |
50 |
+++ icecast-2.3.2/src/source.c 2014-11-21 00:44:24.622000000 +0100 |
51 |
@@ -34,6 +34,7 @@ |
52 |
#endif |
53 |
|
54 |
#ifndef _WIN32 |
55 |
+/* for __setup_empty_script_environment() */ |
56 |
#include <sys/stat.h> |
57 |
#include <fcntl.h> |
58 |
#endif |
59 |
@@ -70,9 +71,9 @@ static int _free_client(void *key); |
60 |
static void _parse_audio_info (source_t *source, const char *s); |
61 |
static void source_shutdown (source_t *source); |
62 |
#ifdef _WIN32 |
63 |
-#define source_run_script(x,y) WARN0("on [dis]connect scripts disabled"); |
64 |
+#define source_run_script(w,x,y,z) WARN0("on [dis]connect scripts disabled"); |
65 |
#else |
66 |
-static void source_run_script (char *command, char *mountpoint); |
67 |
+static void source_run_script (const char *command, source_t *source, mount_proxy *mountinfo, const char *action); |
68 |
#endif |
69 |
|
70 |
/* Allocate a new source with the stated mountpoint, if one already |
71 |
@@ -629,7 +630,7 @@ static void source_init (source_t *sourc |
72 |
if (mountinfo) |
73 |
{ |
74 |
if (mountinfo->on_connect) |
75 |
- source_run_script (mountinfo->on_connect, source->mount); |
76 |
+ source_run_script (mountinfo->on_connect, source, mountinfo, "source-connect"); |
77 |
auth_stream_start (mountinfo, source->mount); |
78 |
} |
79 |
config_release_config(); |
80 |
@@ -833,7 +834,7 @@ static void source_shutdown (source_t *s |
81 |
if (mountinfo) |
82 |
{ |
83 |
if (mountinfo->on_disconnect) |
84 |
- source_run_script (mountinfo->on_disconnect, source->mount); |
85 |
+ source_run_script (mountinfo->on_disconnect, source, mountinfo, "source-disconnect"); |
86 |
auth_stream_end (mountinfo, source->mount); |
87 |
} |
88 |
config_release_config(); |
89 |
@@ -1265,24 +1266,56 @@ void source_client_callback (client_t *c |
90 |
|
91 |
|
92 |
#ifndef _WIN32 |
93 |
-static inline void __setup_empty_script_environment(void) { |
94 |
+/* this sets up the new environment for script execution. |
95 |
+ * We ignore most failtures as we can not handle them anyway. |
96 |
+ */ |
97 |
+static inline void __update_environ(const char *name, const char *value) { |
98 |
+ if (!name || !value) return; |
99 |
+ setenv(name, value, 1); |
100 |
+} |
101 |
+static inline void __setup_empty_script_environment(ice_config_t * config, source_t *source, mount_proxy *mountinfo, const char *action) { |
102 |
int i; |
103 |
|
104 |
+ /* close at least the first 1024 handles */ |
105 |
for (i = 0; i < 1024; i++) |
106 |
close(i); |
107 |
|
108 |
- i = open("/dev/null", O_RDWR); |
109 |
- if (i == -1) |
110 |
- return; |
111 |
- |
112 |
- dup2(i, 0); |
113 |
- dup2(i, 1); |
114 |
- dup2(i, 2); |
115 |
+ /* open null device */ |
116 |
+ i = open(config->null_file, O_RDWR); |
117 |
+ if (i != -1) { |
118 |
+ /* attach null device to stdin, stdout and stderr */ |
119 |
+ if (i != 0) |
120 |
+ dup2(i, 0); |
121 |
+ if (i != 1) |
122 |
+ dup2(i, 1); |
123 |
+ if (i != 2) |
124 |
+ dup2(i, 2); |
125 |
+ |
126 |
+ /* close null device */ |
127 |
+ if (i > 2) |
128 |
+ close(i); |
129 |
+ } |
130 |
+ |
131 |
+#ifdef HAVE_SETENV |
132 |
+ __update_environ("ICECAST_VERSION", ICECAST_VERSION_STRING); |
133 |
+ __update_environ("ICECAST_HOSTNAME", config->hostname); |
134 |
+ __update_environ("ICECAST_ADMIN", config->admin); |
135 |
+ __update_environ("ICECAST_LOGDIR", config->log_dir); |
136 |
+ __update_environ("SOURCE_ACTION", action); |
137 |
+ __update_environ("SOURCE_MOUNTPOINT", source->mount); |
138 |
+ __update_environ("SOURCE_PUBLIC", source->yp_public ? "true" : "false"); |
139 |
+ __update_environ("SROUCE_HIDDEN", source->hidden ? "true" : "false"); |
140 |
+ __update_environ("MOUNT_NAME", mountinfo->stream_name); |
141 |
+ __update_environ("MOUNT_DESCRIPTION", mountinfo->stream_description); |
142 |
+ __update_environ("MOUNT_URL", mountinfo->stream_url); |
143 |
+ __update_environ("MOUNT_GENRE", mountinfo->stream_genre); |
144 |
+#endif |
145 |
} |
146 |
|
147 |
-static void source_run_script (char *command, char *mountpoint) |
148 |
-{ |
149 |
+static void source_run_script (const char *command, source_t *source, mount_proxy *mountinfo, const char *action) { |
150 |
+ const char *mountpoint = source->mount; |
151 |
pid_t pid, external_pid; |
152 |
+ ice_config_t * config; |
153 |
|
154 |
/* do a fork twice so that the command has init as parent */ |
155 |
external_pid = fork(); |
156 |
@@ -1295,11 +1328,17 @@ static void source_run_script (char *com |
157 |
ERROR2 ("Unable to fork %s (%s)", command, strerror (errno)); |
158 |
break; |
159 |
case 0: /* child */ |
160 |
+ if (access(command, R_OK|X_OK) != 0) { |
161 |
+ ERROR2("Unable to run command %s (%s)", command, strerror(errno)); |
162 |
+ exit(1); |
163 |
+ } |
164 |
DEBUG1 ("Starting command %s", command); |
165 |
- __setup_empty_script_environment(); |
166 |
- execl (command, command, mountpoint, (char *)NULL); |
167 |
- //ERROR2 ("Unable to run command %s (%s)", command, strerror (errno)); |
168 |
- exit(0); |
169 |
+ config = config_get_config(); |
170 |
+ __setup_empty_script_environment(config, source, mountinfo, action); |
171 |
+ config_release_config(); |
172 |
+ /* consider to add action here as well */ |
173 |
+ execl(command, command, mountpoint, (char *)NULL); |
174 |
+ exit(1); |
175 |
default: /* parent */ |
176 |
break; |
177 |
} |