[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Bug#849865: marked as done (jessie-pu: package postgresql-common/165+deb8u2)



Your message dated Sat, 14 Jan 2017 12:37:03 +0000
with message-id <1484397423.1091.25.camel@adam-barratt.org.uk>
and subject line Closing requests included in today's point release
has caused the Debian Bug report #849865,
regarding jessie-pu: package postgresql-common/165+deb8u2
to be marked as done.

This means that you claim that the problem has been dealt with.
If this is not the case it is now your responsibility to reopen the
Bug report if necessary, and/or fix the problem forthwith.

(NB: If you are a system administrator and have no idea what this
message is talking about, this may indicate a serious mail system
misconfiguration somewhere. Please contact owner@bugs.debian.org
immediately.)


-- 
849865: http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=849865
Debian Bug Tracking System
Contact owner@bugs.debian.org with problems
--- Begin Message ---
Package: release.debian.org
Severity: normal
Tags: jessie
User: release.debian.org@packages.debian.org
Usertags: pu

Hi,

I would like to upload postgresql-common/165+deb8u2 with the diff
quoted below to jessie. It's fixing a data-loss bug, and a security
issue. The issues are already addresses in unstable (both in 178).

Is that ok?

diff --git a/debian/changelog b/debian/changelog
index 0d6bd4f..1d583cb 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,3 +1,15 @@
+postgresql-common (165+deb8u2) jessie; urgency=medium
+
+  * pg_upgradecluster: Properly upgrade databases with non-login role owners.
+    (Closes: #614374, #838812)
+  * pg_ctlcluster, t/020_create_sql_remove.t: Protect against symlink in
+    /var/log/postgresql/ allowing the creation of arbitrary files elsewhere.
+    Discovered by Dawid Golunski, thanks! (CVE-2016-1255)
+  * t/TestLib.pm: Cherry-pick program_ok() from master for use in
+    t/020_create_sql_remove.t.
+
+ -- Christoph Berg <myon@debian.org>  Sun, 01 Jan 2017 18:48:30 +0100
+
 postgresql-common (165+deb8u1) jessie; urgency=medium
 
   * pg_upgradecluster: Set default dynamic_shared_memory_type = mmap.
diff --git a/pg_ctlcluster b/pg_ctlcluster
index 924f878..d2bb897 100755
--- a/pg_ctlcluster
+++ b/pg_ctlcluster
@@ -23,7 +23,7 @@ use warnings;
 use Getopt::Long;
 use POSIX qw/setsid dup2 setlocale LC_ALL :sys_wait_h/;
 use PgCommon;
-use Fcntl 'SEEK_SET';
+use Fcntl qw(SEEK_SET O_RDWR O_CREAT O_EXCL);
 
 my ($version, $cluster, $pg_ctl, $force);
 my (@postmaster_auxoptions, @pg_ctl_opts_from_cli);
@@ -394,17 +394,20 @@ if ($> == 0 && ! -e '/var/log/postgresql' &&
 
 # recreate missing log file
 if ($action ne 'stop' && $info{'logfile'} && ! -e $info{'logfile'}) {
-    open L, '>', $info{'logfile'} or 
+    if ($> == 0) { # drop privileges; this is important if logfile
+        # was determined via an /etc/postgresql/.../log symlink
+        change_ugid $info{'owneruid'}, $info{'ownergid'};
+    }
+    sysopen (L, $info{'logfile'}, O_RDWR|O_CREAT|O_EXCL) or
 	error 'Could not create log file ' . $info{'logfile'};
+    close L;
     chmod 0640, $info{'logfile'};
-    my $g;
+    $< = $> = 0; # will silently fail if we were not root before, that's intended
+    $( = $) = 0;
     if ($info{'owneruid'} < 500) {
-	$g = (getgrnam 'adm')[2];
-    } else {
-	$g = $info{'ownergid'};
+        my $g = (getgrnam 'adm')[2];
+        chown $info{'owneruid'}, $g, $info{'logfile'} if (defined $g);
     }
-    chown $info{'owneruid'}, $g, $info{'logfile'};
-    close L;
 }
 
 # recreate /var/run/postgresql
diff --git a/pg_upgradecluster b/pg_upgradecluster
index 876a0af..04c59c6 100755
--- a/pg_upgradecluster
+++ b/pg_upgradecluster
@@ -433,18 +433,16 @@ if (!fork) {
 	    error 'automatic upgrade of tablespaces is not supported';
 	}
 
-	# get list of databases, owners, and allowed connections
+	# get list of databases (value = datallowconn)
 	my %databases;
 	open F, '-|', $oldpsql, '-h', $oldsocket, '-p', $info{'port'}, 
 	    '-F|', '-d', 'template1', '-Atc', 
-	    'SELECT datname, datallowconn, pg_catalog.pg_encoding_to_char(encoding), usename FROM pg_database, pg_user WHERE datdba = usesysid' or 
+	    'SELECT datname, datallowconn FROM pg_database' or
 	    error 'Could not get pg_database list';
 	while (<F>) {
 	    chomp;
-	    my ($n, $a, $e, $o) = split '\|';
-	    ($o) = $o =~ /^(.*)$/; # untaint
-	    ($e) = $e =~ /^([\w_]+)$/; # untaint
-	    $databases{$n} = [$a eq 't', $o, $e];
+	    my ($n, $a) = split '\|';
+	    $databases{$n} = ($a eq 't');
 	}
 	close F;
 	error 'could not get list of databases' if $?;
@@ -453,7 +451,7 @@ if (!fork) {
 	for my $db (keys %databases) {
 	    next if $db eq 'template0';
 
-	    unless (${$databases{$db}}[0]) {
+	    unless ($databases{$db}) {
 		print "Temporarily enabling access to database $db\n";
 		(system $oldpsql, '-h', $oldsocket, '-p', $info{'port'}, '-q', 
 		    '-d', 'template1', '-c', 
@@ -546,8 +544,8 @@ if (!fork) {
 		'-d', $db, '-c', 'ANALYZE') == 0 or
 		error 'Could not ANALZYE database';
 
-	    unless (${$databases{$db}}[0]) {
-		print "Disabling access to database $db\n";
+	    unless ($databases{$db}) {
+		print "Disabling access to database $db again\n";
 		(system $oldpsql, '-h', $oldsocket, '-p', $info{'port'}, '-q', 
 		    '-d', 'template1', '-c', 
 		    "BEGIN READ WRITE; UPDATE pg_database SET datallowconn = 'f' where datname = '$db'; COMMIT") == 0 or
diff --git a/t/020_create_sql_remove.t b/t/020_create_sql_remove.t
index 457bf9a..f71b4cf 100644
--- a/t/020_create_sql_remove.t
+++ b/t/020_create_sql_remove.t
@@ -10,7 +10,7 @@ use lib 't';
 use TestLib;
 use PgCommon;
 
-use Test::More tests => 127 * ($#MAJORS+1);
+use Test::More tests => 131 * ($#MAJORS+1);
 
 sub check_major {
     my $v = $_[0];
@@ -142,6 +142,15 @@ sub check_major {
     PgCommon::disable_conf_value $v, 'main', 'postgresql.conf', 'log_filename', '';
     unlink "/etc/postgresql/$v/main/log";
 
+    # check that log creation does not escalate privileges
+    program_ok 'root', "pg_ctlcluster $v main stop", 0, 'stopping cluster';
+    unlink $default_log;
+    symlink "/etc/postgres-hack", $default_log;
+    program_ok 'root', "pg_ctlcluster $v main start", 1, 'starting cluster with rouge /var/log/postgresql symlink fails';
+    ok !-f "/etc/postgres-hack", "/etc/postgres-hack was not created";
+    unlink $default_log;
+    program_ok 'root', "pg_ctlcluster $v main start", 0, 'restarting cluster';
+
     # verify that the postmaster does not have an associated terminal
     unlike_program_out 0, 'ps -o tty -U postgres h', 0, qr/tty|pts/,
         'postmaster processes do not have an associated terminal';
diff --git a/t/TestLib.pm b/t/TestLib.pm
index 2c9a9d0..62f2268 100644
--- a/t/TestLib.pm
+++ b/t/TestLib.pm
@@ -22,7 +22,7 @@ use PgCommon qw/get_versions change_ugid/;
 our $VERSION = 1.00;
 our @ISA = ('Exporter');
 our @EXPORT = qw/ps ok_dir exec_as deb_installed rpm_installed package_version
-    version_ge is_program_out like_program_out unlike_program_out pidof pid_env check_clean
+    version_ge program_ok is_program_out like_program_out unlike_program_out pidof pid_env check_clean
     @ALL_MAJORS @MAJORS $delay/;
 
 our @ALL_MAJORS = sort (get_versions()); # not affected by PG_VERSIONS/-v
@@ -177,6 +177,16 @@ sub exec_as {
     return $result;
 }
 
+# Execute a command as a particular user, and check the exit code
+# Arguments: <user> <command> [<expected exit code>] [<description>]
+sub program_ok {
+    my ($user, $cmd, $exit, $description) = @_;
+    $exit ||= 0;
+    $description ||= $cmd;
+    my $outref;
+    ok ((exec_as $user, $cmd, \$outref, $exit) == $exit, $description);
+}
+
 # Execute a command as a particular user, and check the exit code and output
 # (merged stdout/stderr).
 # Arguments: <user> <command> <expected exit code> <expected output> [<description>]


Thanks,
Christoph

Attachment: signature.asc
Description: PGP signature


--- End Message ---
--- Begin Message ---
Version: 8.7

Hi,

Each of these bugs refers to an update that was included in today's 8.7
point release.

Regards,

Adam

--- End Message ---

Reply to: