Sec Patch

Steve G <[email protected]> Sat, 14 Feb 2004 12:59:13 -0800 (PST)
Newsgroups gmane.network.zeroconf.workers
Message-ID <[email protected]>
--0-1361386445-1076792353=:38985
Content-Type: text/plain; charset=us-ascii
Content-Id: 
Content-Disposition: inline

Hello,

The attached patch has some important updates:

-Buffer overflow protection parsing config
-unlink pid file if getifaddr fails
-pid_file was not getting chown'd
-Supplemental groups were not being dropped
-Session was not being init'd.
-Pid file needs to be created exclusively

And a few const cleanups.

-Steve Grubb

__________________________________
Do you Yahoo!?
Yahoo! Finance: Get your refund fast by filing online.
http://taxes.yahoo.com/filing.html
--0-1361386445-1076792353=:38985
Content-Type: text/plain; name="tmdns-patch12b.txt"
Content-Description: tmdns-patch12b.txt
Content-Disposition: inline; filename="tmdns-patch12b.txt"

diff -ur tmdns/server/conf.c tmdns.f/server/conf.c
--- tmdns/server/conf.c	2004-02-14 07:49:24.000000000 -0500
+++ tmdns.f/server/conf.c	2004-02-14 15:28:04.000000000 -0500
@@ -299,7 +299,8 @@
 	  return 0;
       }
   } else if (config.config_file != conf_file) {
-      strcpy(config.config_file, conf_file);
+      strncpy(config.config_file, conf_file, sizeof(config.config_file));
+      config.config_file[sizeof(config.config_file)-1] = 0;
   }
   while (fgets(line, 1024 , fp)) {
 	 if (!(line[0]=='#')) {	/* skip lines with comment */
@@ -358,9 +359,7 @@
 	i++;
   }
 
-  fprintf( stderr, "Unkown config option: \"%s\"\n", cmd ); 
-  return;
-
+  fprintf( stderr, "Unknown config option: \"%s\"\n", cmd ); 
 }
 
 /************************************************************************
@@ -506,7 +505,7 @@
    fprintf(fd,"#\n");
    while( config_params[i].param_name != NULL ) {
      if( ((void *)config_params[i].print == NULL) ||
-	 ((void *)config_params[i].print == (void *)print_dummy)) 
+	 ((const void *)config_params[i].print == (const void *)print_dummy)) 
       {
 	fprintf(fd, "%s", config_params[i].comment);
       } else {
diff -ur tmdns/server/info.c tmdns.f/server/info.c
--- tmdns/server/info.c	2004-02-14 07:49:24.000000000 -0500
+++ tmdns.f/server/info.c	2004-02-14 15:32:57.000000000 -0500
@@ -683,7 +683,8 @@
         if ( *now =='#') { continue; } /* skip lines with comment */
         if ( *now == 0 ) { continue; } /* skip empty lines */
 
-	fields = sscanf(now,"%s %n", proto, &name_ofs);
+        // NOTE: if the sizeof proto changes, the 1023 needs to be updated.
+	fields = sscanf(now,"%1023s %n", proto, &name_ofs);
 
 	if( fields != 1 ) {
 	    debug("syntax error in line %d\n",lineno);
@@ -726,7 +727,8 @@
 	    ll_add(records,ptr_rr);
 
         } else {
-	    fields = sscanf(now,"%d %s %d %d %n", &port, service, &prio, &weight , &name_ofs );
+            // NOTE: if the sizeof service changes, 1023 needs to be updated.
+	    fields = sscanf(now,"%d %1023s %d %d %n", &port, service, &prio, &weight , &name_ofs );
 	
 	    if( ( fields < 4 ) && ( fields > 0 ) ) {
 	        debug("syntax error in line %d\n",lineno);
@@ -788,7 +790,7 @@
  *
  *****************************************************************************/
 
-void info_init(void) {
+int info_init(void) {
 
     struct ifaddrs * ifs = NULL;
     struct ifaddrs * ifnow = NULL;
@@ -823,8 +825,8 @@
      * Also add PTR records for the reverse zone.
      */
     if (getifaddrs(&ifs) < 0) {
-        syslog(LOG_ERR,"getifaddrs failed...exiting.");
-        exit(1);
+	syslog(LOG_ERR, "getifaddrs failed...exiting.");
+	return -1;
     }
 
     for(ifnow = ifs; ifnow; ifnow = ifnow->ifa_next) {
@@ -874,7 +876,8 @@
 		{
 		    struct in6_addr inaddr;
 		    dns_rr * rr = NULL;
-		    /* reverse addres needs (128/4) * 2 (for .) + ip6.arpa(8) + \0 chars*/
+		    /* reverse address needs:
+                          (128/4) * 2 (for .) + ip6.arpa(8) + \0 chars */
 		    char revname[73];
 		    int n = 0;
 		    int i = 0;
@@ -928,6 +931,7 @@
 
     free(raw_namebuf);
     free(namebuf);
+    return 0;
 }
 
 /*****************************************************************************
@@ -1122,13 +1126,13 @@
     switch( type ) {
 	case T_A:
 	    if( rr_len == sizeof(struct in_addr) ) {
-	      result_rr = newARec( domain, (struct in_addr *)rr_data );
+	      result_rr = newARec( domain, (const struct in_addr *)rr_data );
 	    }
 	    break;
 
 	case T_AAAA:
 	    if( rr_len == sizeof(struct in6_addr) ) {
-	      result_rr = newAAAARec( domain, (struct in6_addr *)rr_data );
+	      result_rr = newAAAARec( domain, (const struct in6_addr *)rr_data );
 	    }
 	    break;
 
@@ -1165,18 +1169,18 @@
 	    {
 		char cpu[MAXDSTRING + 1];
 		char os[MAXDSTRING + 1 ];
-		u_char * now = (u_char *)rr_data;
+		const u_char * now = (const u_char *)rr_data;
 
 		memset(cpu,0,sizeof(cpu));
 		memset(os,0,sizeof(os));
 
-		if( (void *)(now + 1 + *now) < buf_end ) {
+		if( (const void *)(now + 1 + *now) < buf_end ) {
 
 		    memcpy(cpu, now + 1, *now );
 		    now += *now;
 		    now += 1;
 
-		    if( (void*)(now + 1 + *now) < buf_end) {
+		    if( (const void*)(now + 1 + *now) < buf_end) {
 		        memcpy(os, now + 1, *now );
 
 		        result_rr = newHinfoRec( domain, cpu, os );
@@ -1188,12 +1192,12 @@
 	case T_TXT:
 	    {
 		char string[MAXDSTRING + 1];
-		u_char * now = (u_char *)rr_data;
+		const u_char * now = (const u_char *)rr_data;
 		const u_char * end = rr_data + rr_len;
 
 		result_rr = newTxtRec(domain);
 
-		while( (now < end) && ((void*)(now + 1 + *now) < buf_end)) {
+		while((now<end) && ((const void*)(now + 1 + *now) < buf_end)) {
 		    
 		    memset(string,0,sizeof(string));
 		    memcpy(string, now + 1, *now);
@@ -1214,7 +1218,7 @@
 		char decoded[MAXDNAME + 1];
 		ssize_t count = 0;
 
-		u_char * now = (u_char *)rr_data;
+		const u_char * now = (const u_char *)rr_data;
 
 		GETSHORT(prio,now);
 		GETSHORT(weight,now);
@@ -1402,7 +1406,7 @@
 
 static decoded_message_t * info_decode_message( const u_char * buf, int len ) {
     decoded_message_t * result = info_new_message();
-    const HEADER * hdr         = (HEADER *)buf;
+    const HEADER * hdr         = (const HEADER *)buf;
 
     if( result != NULL ) {
         if( dns_walk_buf( buf, len, decode_packet_cb, result ) < 0 ) {
diff -ur tmdns/server/info.h tmdns.f/server/info.h
--- tmdns/server/info.h	2004-02-09 06:04:09.000000000 -0500
+++ tmdns.f/server/info.h	2004-02-14 14:50:38.000000000 -0500
@@ -39,7 +39,7 @@
   list_t * additional;
 } decoded_message_t;
 
-void info_init(void);
+int info_init(void);
 void info_destroy(void);
 
 void info_init_search( search_state * state, const char * query, int type );
diff -ur tmdns/server/serv_udp.c tmdns.f/server/serv_udp.c
--- tmdns/server/serv_udp.c	2004-02-10 05:56:58.000000000 -0500
+++ tmdns.f/server/serv_udp.c	2004-02-14 15:34:27.000000000 -0500
@@ -420,7 +420,7 @@
   return(fd);
 }
 /*****************************************************************************/
-void udp_close_sockets() {
+void udp_close_sockets(void) {
 
     int i = 0;
 
@@ -637,7 +637,7 @@
 void udp_copy_answer_address(dns_t * answer,const struct udp_packet * udp_pkt) {
 
     memcpy( (void *)&(answer->dst_address),
-            (void *)&(udp_pkt->src_address),
+            (const void *)&(udp_pkt->src_address),
                       udp_pkt->src_len);
     answer->dst_len  = udp_pkt->src_len;
 
@@ -665,12 +665,15 @@
 #ifdef HAVE_INET_NTOP
         case AF_INET:
 	case AF_INET6:
-	    inet_ntop(addr->sa_family, &(((struct sockaddr_in *)addr)->sin_addr),result,INET6_ADDRSTRLEN);
+	    inet_ntop(addr->sa_family, 
+                      &(((const struct sockaddr_in *)addr)->sin_addr),
+                      result,INET6_ADDRSTRLEN);
 #else
         case AF_INET:
-	    strncpy(result,inet_ntoa((struct sockaddr_in *)addr),INET6_ADDRSTRLEN);
+	    strncpy(result,inet_ntoa((const struct sockaddr_in *)addr),
+                    INET6_ADDRSTRLEN);
 #endif
-	    addr_port = htons(((struct sockaddr_in *)addr)->sin_port);
+	    addr_port = htons(((const struct sockaddr_in *)addr)->sin_port);
 	    snprintf(port_s,PORT_LEN,"#%d",addr_port);
 	    strncat(result,port_s,INET6_ADDRSTRLEN+PORT_LEN+2);
 	    return result;
diff -ur tmdns/server/tmdns.c tmdns.f/server/tmdns.c
--- tmdns/server/tmdns.c	2004-02-10 05:56:58.000000000 -0500
+++ tmdns.f/server/tmdns.c	2004-02-14 15:11:44.000000000 -0500
@@ -18,6 +18,9 @@
 
 #include <sys/time.h>
 #include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <grp.h>
 
 #include <assert.h>
 
@@ -198,7 +201,7 @@
     /* change ownership of the pid file so we can unlink it later */
     if( config.pid_file[0] != 0) {
 	debug("set ownership of the pid file %s", config.pid_file );
-	chown( config.debug_file , pw->pw_uid, pw->pw_gid );
+	chown( config.pid_file , pw->pw_uid, pw->pw_gid );
     }
 
     /* change ownership of the log file */
@@ -207,10 +210,11 @@
 	chown( config.debug_file , pw->pw_uid, pw->pw_gid );
     }
 
-    debug("drop privilegs: new uid = %d, new gid = %d\n",
+    debug("drop privileges: new uid = %d, new gid = %d\n",
 	  pw->pw_uid, pw->pw_gid);
 
     setgid(pw->pw_gid);
+    setgroups( 0, NULL );
     setuid(pw->pw_uid);
     return;
 }
@@ -249,7 +253,8 @@
   openlog("tmdns", LOG_PID , LOG_DAEMON );
 
   /* initialize the RRs to announce */
-  info_init();
+  if (info_init() < 0)
+      exit(1);
 
   debug("going to open sockets ...\n");
   usedifs = udp_open_sockets( &sockfds );
@@ -276,7 +281,6 @@
 		close(0);
 		close(1);
 		close(2);
-		setpgrp();
 		break;
 	 default:	/* Parent: Just exit */
 		exit(0);
@@ -285,20 +289,31 @@
 
   /* create pid file */
   {
+    int pidfd;
     FILE * pidfp = NULL;
-    pidfp = fopen( config.pid_file , "w" );
-    if( pidfp != NULL ) {
-	fprintf(pidfp,"%d\n", getpid());
-	fclose(pidfp);
-    } else {
+
+    pidfd = open(config.pid_file, O_EXCL|O_CREAT|O_WRONLY,
+         S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH);
+    if (pidfd >= 0) 
+        pidfp = fdopen( pidfd , "w" );
+    
+    if (pidfp == NULL) {
 	syslog(LOG_ERR,"can't open pid file %s : %s\n",
 		config.pid_file , debug_errmsg(errno) );
 	debug("can not open pid file %s : %s\n",
 		config.pid_file , debug_errmsg(errno) );
-    }
+
+        // We must exit or the init scripts will not be able to
+        // find us later.
+        exit(1); 
+    } else {
+	 fprintf(pidfp,"%d\n", getpid());
+         fclose(pidfp);
+     }
   }
 
   /* drop su privilegs */
+  setsid();
   change_id();
 
   signal(SIGHUP, sig_hup);
@@ -346,7 +360,10 @@
 	     */
   	    conf_load (config.config_file);
 	    info_destroy();
-	    info_init();
+	    if (info_init() < 0) {
+                unlink(config.pid_file);
+                exit(1);
+            }
 	    do_config = 0;
 	    probing = 3;
 	    config.daemon_mode = 0;
@@ -488,7 +505,7 @@
 /*****************************************************************************
  * Sleep for a random delay between 20-120 msec.
  *****************************************************************************/
-static void random_sleep() {
+static void random_sleep(void) {
     unsigned long rdelay = 0;
     rdelay = 20000 + (100000.0*rand()/(RAND_MAX+1.0));
     debug("random sleep for %lu usec\n" , rdelay );
@@ -1245,4 +1262,3 @@
     return 0;
 }
 
-

--0-1361386445-1076792353=:38985--


-------------------------------------------------------
SF.Net is sponsored by: Speed Start Your Linux Apps Now.
Build and deploy apps & Web services for Linux with
a free DVD software kit from IBM. Click Now!
http://ads.osdn.com/?ad_id=1356&alloc_id=3438&op=click