Avoid infinite loop if "secrets file" is used in rsyncd server configuration

and a user attempts login with an invalid username. Bug was introduced in
rsync 3.0.5.  OK espie@
This commit is contained in:
sthen 2014-04-14 13:34:19 +00:00
parent b617fb56ab
commit 7cca3ccc37
2 changed files with 83 additions and 5 deletions

View File

@ -1,8 +1,9 @@
# $OpenBSD: Makefile,v 1.72 2013/10/10 12:01:30 naddy Exp $
# $OpenBSD: Makefile,v 1.73 2014/04/14 13:34:19 sthen Exp $
COMMENT = mirroring/synchronization over low bandwidth links
DISTNAME = rsync-3.1.0
REVISION = 0
CATEGORIES = net
HOMEPAGE = https://rsync.samba.org/

View File

@ -1,7 +1,84 @@
$OpenBSD: patch-authenticate_c,v 1.3 2013/10/10 12:01:31 naddy Exp $
--- authenticate.c.orig Sun Jun 9 21:11:53 2013
+++ authenticate.c Thu Oct 3 15:52:41 2013
@@ -347,7 +347,7 @@ void auth_client(int fd, const char *user, const char
$OpenBSD: patch-authenticate_c,v 1.4 2014/04/14 13:34:19 sthen Exp $
Most hunks are this:-
From 0dedfbce2c1b851684ba658861fe9d620636c56a Mon Sep 17 00:00:00 2001
From: Wayne Davison <wayned@samba.org>
Date: Sun, 13 Apr 2014 13:44:58 -0700
Subject: [PATCH] Avoid infinite wait reading secrets file.
Last hunk changes default privdrop uid from nobody to _rsync.
--- authenticate.c.orig Mon Apr 14 14:13:45 2014
+++ authenticate.c Mon Apr 14 14:13:38 2014
@@ -102,15 +102,16 @@ static const char *check_secret(int module, const char
char pass2[MAX_DIGEST_LEN*2];
const char *fname = lp_secrets_file(module);
STRUCT_STAT st;
- int fd, ok = 1;
+ int ok = 1;
int user_len = strlen(user);
int group_len = group ? strlen(group) : 0;
char *err;
+ FILE *fh;
- if (!fname || !*fname || (fd = open(fname, O_RDONLY)) < 0)
+ if (!fname || !*fname || (fh = fopen(fname, "r")) == NULL)
return "no secrets file";
- if (do_fstat(fd, &st) == -1) {
+ if (do_fstat(fileno(fh), &st) == -1) {
rsyserr(FLOG, errno, "fstat(%s)", fname);
ok = 0;
} else if (lp_strict_modes(module)) {
@@ -123,29 +124,30 @@ static const char *check_secret(int module, const char
}
}
if (!ok) {
- close(fd);
+ fclose(fh);
return "ignoring secrets file";
}
if (*user == '#') {
/* Reject attempt to match a comment. */
- close(fd);
+ fclose(fh);
return "invalid username";
}
/* Try to find a line that starts with the user (or @group) name and a ':'. */
err = "secret not found";
- while ((user || group) && read_line_old(fd, line, sizeof line, 1)) {
- const char **ptr, *s;
+ while ((user || group) && fgets(line, sizeof line, fh) != NULL) {
+ const char **ptr, *s = strtok(line, "\n\r");
int len;
- if (*line == '@') {
+ if (!s)
+ continue;
+ if (*s == '@') {
ptr = &group;
len = group_len;
- s = line+1;
+ s++;
} else {
ptr = &user;
len = user_len;
- s = line;
}
if (!*ptr || strncmp(s, *ptr, len) != 0 || s[len] != ':')
continue;
@@ -158,7 +160,7 @@ static const char *check_secret(int module, const char
*ptr = NULL; /* Don't look for name again. */
}
- close(fd);
+ fclose(fh);
memset(line, 0, sizeof line);
memset(pass2, 0, sizeof pass2);
@@ -347,7 +349,7 @@ void auth_client(int fd, const char *user, const char
char pass2[MAX_DIGEST_LEN*2];
if (!user || !*user)