Browse code

- cfg.lex: hex & octal numbers are supported now (fifo_mode e.g. 0xab or 0777) - fifo fixes: check for fifo (normal files will not be allowed for reply fifo), check for hardlinks (hardlinked fifos will not be allowed), check for softlink (a softlink to a fifo will not be allowed) [still missing: * ser fifo dir (e.g. /tmp/.ser)]

Andrei Pelinescu-Onciul authored on 07/10/2003 15:43:25
Showing 3 changed files
... ...
@@ -43,7 +43,7 @@ export makefile_defs
43 43
 VERSION = 0
44 44
 PATCHLEVEL = 8
45 45
 SUBLEVEL =   12
46
-EXTRAVERSION = dev-17-cristian
46
+EXTRAVERSION = dev-18-fifo
47 47
 
48 48
 RELEASE=$(VERSION).$(PATCHLEVEL).$(SUBLEVEL)$(EXTRAVERSION)
49 49
 OS = $(shell uname -s | sed -e s/SunOS/solaris/ | tr "[A-Z]" "[a-z]")
... ...
@@ -39,6 +39,7 @@
39 39
  *               require_certificate added (andrei)
40 40
  *  2003-07-06  more tls config. vars added: tls_method, tls_port_no (andrei)
41 41
  *  2003-10-02  added {,set_}advertised_{address,port} (andrei)
42
+ *  2003-10-07  added hex and octal numbers support (andrei)
42 43
  */
43 44
 
44 45
 
... ...
@@ -197,9 +198,11 @@ TLSv1			"tlsv1"|"TLSv1"|"TLSV1"
197 198
 LETTER		[a-zA-Z]
198 199
 DIGIT		[0-9]
199 200
 ALPHANUM	{LETTER}|{DIGIT}|[_]
200
-NUMBER		{DIGIT}+
201
+NUMBER		0|([1-9]{DIGIT}*)
201 202
 ID			{LETTER}{ALPHANUM}*
202 203
 HEX			[0-9a-fA-F]
204
+HEXNUMBER	0x{HEX}+
205
+OCTNUMBER	0[0-7]+
203 206
 HEX4		{HEX}{1,4}
204 207
 IPV6ADDR	({HEX4}":"){7}{HEX4}|({HEX4}":"){1,7}(":"{HEX4}){1,7}|":"(":"{HEX4}){1,7}|({HEX4}":"){1,7}":"|"::"
205 208
 QUOTES		\"
... ...
@@ -342,6 +345,10 @@ EAT_ABLE	[\ \t\b\r]
342 345
 
343 346
 <INITIAL>{IPV6ADDR}		{ count(); yylval.strval=yytext; return IPV6ADDR; }
344 347
 <INITIAL>{NUMBER}		{ count(); yylval.intval=atoi(yytext);return NUMBER; }
348
+<INITIAL>{HEXNUMBER}	{ count(); yylval.intval=(int)strtol(yytext, 0, 16);
349
+							return NUMBER; }
350
+<INITIAL>{OCTNUMBER}	{ count(); yylval.intval=(int)strtol(yytext, 0, 8);
351
+							return NUMBER; }
345 352
 <INITIAL>{YES}			{ count(); yylval.intval=1; return NUMBER; }
346 353
 <INITIAL>{NO}			{ count(); yylval.intval=0; return NUMBER; }
347 354
 <INITIAL>{TCP}			{ count(); yylval.intval=PROTO_TCP; return NUMBER; }
... ...
@@ -56,6 +56,8 @@
56 56
  *  2003-03-29  destroy pkg mem introduced (jiri)
57 57
  *  2003-03-19  replaced all mallocs/frees w/ pkg_malloc/pkg_free (andrei)
58 58
  *  2003-01-29  new built-in fifo commands: arg and pwd (jiri)
59
+ *  2003-10-07  fifo security fixes: permissions, always delete old fifo,
60
+ *               reply fifo checks -- added fifo_check (andrei)
59 61
  */
60 62
 
61 63
 
... ...
@@ -87,8 +89,7 @@
87 89
 
88 90
 /* FIFO server vars */
89 91
 char *fifo=0; /* FIFO name */
90
-int fifo_mode=S_IRUSR | S_IWUSR | S_IRGRP | 
91
-	S_IWGRP | S_IROTH | S_IWOTH;
92
+int fifo_mode=S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP ;
92 93
 pid_t fifo_pid;
93 94
 /* file descriptors */
94 95
 static int fifo_read=0;
... ...
@@ -299,6 +300,60 @@ static char *trim_filename( char * file )
299 300
 	return new_fn;
300 301
 }
301 302
 
303
+
304
+
305
+/* reply fifo security checks:
306
+ * checks if fd is a fifo, is not hardlinked and it's not a softlink
307
+ * opened file descriptor + file name (for soft link check)
308
+ * returns 0 if ok, <0 if not */
309
+static int fifo_check(int fd, char* fname)
310
+{
311
+	struct stat fst;
312
+	struct stat lst;
313
+	
314
+	if (fstat(fd, &fst)<0){
315
+		LOG(L_ERR, "ERROR: fifo_check: fstat failed: %s\n",
316
+				strerror(errno));
317
+		return -1;
318
+	}
319
+	/* check if fifo */
320
+	if (!S_ISFIFO(fst.st_mode)){
321
+		LOG(L_ERR, "ERROR: fifo_check: %s is not a fifo\n", fname);
322
+		return -1;
323
+	}
324
+	/* check if hard-linked */
325
+	if (fst.st_nlink>1){
326
+		LOG(L_ERR, "ERROR: security: fifo_check: %s is hard-linked %d times\n",
327
+				fname, fst.st_nlink);
328
+		return -1;
329
+	}
330
+	
331
+	/* lstat to check for soft links */
332
+	if (lstat(fname, &lst)<0){
333
+		LOG(L_ERR, "ERROR: fifo_check: lstat failed: %s\n",
334
+				strerror(errno));
335
+		return -1;
336
+	}
337
+	if (S_ISLNK(lst.st_mode)){
338
+		LOG(L_ERR, "ERROR: security: fifo_check: %s is a soft link\n",
339
+				fname);
340
+		return -1;
341
+	}
342
+	/* if this is not a symbolic link, check to see if the inode didn't
343
+	 * change to avoid possible sym.link, rm sym.link & replace w/ fifo race
344
+	 */
345
+	if ((lst.st_dev!=fst.st_dev)||(lst.st_ino!=fst.st_ino)){
346
+		LOG(L_ERR, "ERROR: security: fifo_check: inode/dev number differ"
347
+				": %ld %ld (%s)\n",
348
+				 fst.st_ino, lst.st_ino, fname);
349
+		return -1;
350
+	}
351
+	/* success */
352
+	return 0;
353
+}
354
+
355
+
356
+
302 357
 /* tell FIFO client what happened via reply pipe */
303 358
 void fifo_reply( char *reply_fifo, char *reply_fmt, ... )
304 359
 {
... ...
@@ -367,6 +422,10 @@ tryagain:
367 422
 			pipe_name, strerror(errno));
368 423
 		return 0;
369 424
 	}
425
+	/* security checks: is this really a fifo?, is 
426
+	 * it hardlinked? is it a soft link? */
427
+	if (fifo_check(fifofd, pipe_name)<0) goto error;
428
+	
370 429
 	/* we want server blocking for big writes */
371 430
 	if ( (flags=fcntl(fifofd, F_GETFL, 0))<0) {
372 431
 		LOG(L_ERR, "ERROR: open_reply_pipe (%s): getfl failed: %s\n",
... ...
@@ -484,7 +543,15 @@ int open_fifo_server()
484 543
 		return 1;
485 544
 	}
486 545
 	DBG("DBG: open_uac_fifo: opening fifo...\n");
487
-	if (stat(fifo, &filestat)==-1) { /* FIFO doesn't exist yet ... */
546
+	if (stat(fifo, &filestat)==0){
547
+		/* FIFO exist, delete it (safer) */
548
+		if (unlink(fifo)<0){
549
+			LOG(L_ERR, "ERROR: open_fifo_server: cannot delete old fifo (%s):"
550
+					" %s\n", fifo, strerror(errno));
551
+			return -1;
552
+		}
553
+	}
554
+	 /* create FIFO ... */
488 555
 		LOG(L_DBG, "DEBUG: open_fifo_server: FIFO stat failed: %s\n",
489 556
 			strerror(errno));
490 557
 		if ((mkfifo(fifo, fifo_mode)<0)) {
... ...
@@ -500,14 +567,6 @@ int open_fifo_server()
500 567
 					strerror(errno), fifo_mode);
501 568
 			return -1;
502 569
 		}
503
-	} else { /* file can be stat-ed, check if it is really a FIFO */
504
-		if (!(S_ISFIFO(filestat.st_mode))) {
505
-			LOG(L_ERR, "ERROR: open_fifo_server: "
506
-				"the file is not a FIFO: %s\n",
507
-				fifo );
508
-			return -1;
509
-		}
510
-	}
511 570
 	DBG("DEBUG: fifo %s opened, mode=%d\n", fifo, fifo_mode );
512 571
 	time(&up_since);
513 572
 	t=ctime(&up_since);