Hello community,

here is the log from the commit of package permissions for openSUSE:Factory 
checked in at 2020-02-13 10:10:50
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/permissions (Old)
 and      /work/SRC/openSUSE:Factory/.permissions.new.26092 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "permissions"

Thu Feb 13 10:10:50 2020 rev:130 rq:769971 version:unknown

Changes:
--------
--- /work/SRC/openSUSE:Factory/permissions/permissions.changes  2019-12-07 
15:13:59.239807746 +0100
+++ /work/SRC/openSUSE:Factory/.permissions.new.26092/permissions.changes       
2020-02-13 10:10:56.484319996 +0100
@@ -1,0 +2,17 @@
+Tue Feb 04 12:20:43 UTC 2020 - [email protected]
+
+- Update to version 20200204:
+  * mariadb: settings for new auth_pam_tool (bsc#1160285)
+  * chkstat:
+    - add read-only fallback when /proc is not mounted (bsc#1160764)
+    - capability handling fixes (bsc#1161779)
+    - better error message when refusing to fix dir perms (#32)
+
+-------------------------------------------------------------------
+Mon Jan 27 11:58:17 UTC 2020 - [email protected]
+
+- Update to version 20200127:
+  * fix paths of ksysguard whitelisting
+  * fix zero-termination of error message for overly long paths
+
+-------------------------------------------------------------------

Old:
----
  permissions-20191205.tar.xz

New:
----
  permissions-20200204.tar.xz

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ permissions.spec ++++++
--- /var/tmp/diff_new_pack.08lMlz/_old  2020-02-13 10:10:57.008320300 +0100
+++ /var/tmp/diff_new_pack.08lMlz/_new  2020-02-13 10:10:57.012320302 +0100
@@ -1,7 +1,7 @@
 #
 # spec file for package permissions
 #
-# Copyright (c) 2019 SUSE LLC
+# Copyright (c) 2020 SUSE LINUX GmbH, Nuernberg, Germany.
 #
 # All modifications and additions to the file contributed by third parties
 # remain the property of their copyright owners, unless otherwise agreed
@@ -16,7 +16,7 @@
 #
 
 
-%define VERSION 20191205
+%define VERSION 20200204
 
 Name:           permissions
 Version:        %{VERSION}

++++++ _servicedata ++++++
--- /var/tmp/diff_new_pack.08lMlz/_old  2020-02-13 10:10:57.044320321 +0100
+++ /var/tmp/diff_new_pack.08lMlz/_new  2020-02-13 10:10:57.044320321 +0100
@@ -1,4 +1,4 @@
 <servicedata>
 <service name="tar_scm">
             <param 
name="url">https://github.com/openSUSE/permissions.git</param>
-          <param 
name="changesrevision">530cade2a85b318e8cb35261f3d2da5223c11af2</param></service></servicedata>
\ No newline at end of file
+          <param 
name="changesrevision">402e7433e5b8114ea2e591ed6a8eadca8936127d</param></service></servicedata>
\ No newline at end of file

++++++ permissions-20191205.tar.xz -> permissions-20200204.tar.xz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/permissions-20191205/Makefile 
new/permissions-20200204/Makefile
--- old/permissions-20191205/Makefile   2019-12-05 15:28:14.000000000 +0100
+++ new/permissions-20200204/Makefile   2020-02-04 13:19:11.000000000 +0100
@@ -19,6 +19,7 @@
 CPPFLAGS += -DFSCAPS_DEFAULT_ENABLED=$(FSCAPS_DEFAULT_ENABLED)
 
 all: src/chkstat
+       @if grep -o -P '\t' src/chkstat.c ; then echo "error: chkstat.c mixes 
tabs and spaces!" ; touch src/chkstat.c ; exit 1 ; fi ; :
 
 install: all
        @for i in $(bindir) $(man8dir) $(man5dir) $(fillupdir) $(sysconfdir) 
$(zypp_commit_plugins); \
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/permissions-20191205/profiles/permissions.easy 
new/permissions-20200204/profiles/permissions.easy
--- old/permissions-20191205/profiles/permissions.easy  2019-12-05 
15:28:14.000000000 +0100
+++ new/permissions-20200204/profiles/permissions.easy  2020-02-04 
13:19:11.000000000 +0100
@@ -395,5 +395,11 @@
 /var/spool/nagios/                                      nagios:nagcmd   2775
 
 # ksysguard network helper (bsc#1151190)
-/usr/libexec/ksysguard/ksgrd_network_helper             root:root       0755
+/usr/lib/libexec/ksysguard/ksgrd_network_helper             root:root       
0755
  +capabilities cap_net_raw=ep
+/usr/lib64/libexec/ksysguard/ksgrd_network_helper             root:root       
0755
+ +capabilities cap_net_raw=ep
+
+# mariadb auth_pam_tool (bsc#1160285)
+/usr/lib/mysql/plugin/auth_pam_tool_dir/auth_pam_tool    root:root         4755
+/usr/lib64/mysql/plugin/auth_pam_tool_dir/auth_pam_tool  root:root         4755
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/permissions-20191205/profiles/permissions.paranoid 
new/permissions-20200204/profiles/permissions.paranoid
--- old/permissions-20191205/profiles/permissions.paranoid      2019-12-05 
15:28:14.000000000 +0100
+++ new/permissions-20200204/profiles/permissions.paranoid      2020-02-04 
13:19:11.000000000 +0100
@@ -398,4 +398,9 @@
 /var/spool/nagios/                                      nagios:nagcmd   0770
 
 # ksysguard network helper (bsc#1151190)
-/usr/libexec/ksysguard/ksgrd_network_helper             root:root       0755
+/usr/lib/libexec/ksysguard/ksgrd_network_helper             root:root       
0755
+/usr/lib64/libexec/ksysguard/ksgrd_network_helper             root:root       
0755
+
+# mariadb auth_pam_tool (bsc#1160285)
+/usr/lib/mysql/plugin/auth_pam_tool_dir/auth_pam_tool    root:root         0755
+/usr/lib64/mysql/plugin/auth_pam_tool_dir/auth_pam_tool  root:root         0755
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/permissions-20191205/profiles/permissions.secure 
new/permissions-20200204/profiles/permissions.secure
--- old/permissions-20191205/profiles/permissions.secure        2019-12-05 
15:28:14.000000000 +0100
+++ new/permissions-20200204/profiles/permissions.secure        2020-02-04 
13:19:11.000000000 +0100
@@ -434,5 +434,11 @@
 /var/spool/nagios/                                      nagios:nagcmd   2775
 
 # ksysguard network helper (bsc#1151190)
-/usr/libexec/ksysguard/ksgrd_network_helper             root:root       0755
+/usr/lib/libexec/ksysguard/ksgrd_network_helper             root:root       
0755
  +capabilities cap_net_raw=ep
+/usr/lib64/libexec/ksysguard/ksgrd_network_helper             root:root       
0755
+ +capabilities cap_net_raw=ep
+
+# mariadb auth_pam_tool (bsc#1160285)
+/usr/lib/mysql/plugin/auth_pam_tool_dir/auth_pam_tool    root:root         4755
+/usr/lib64/mysql/plugin/auth_pam_tool_dir/auth_pam_tool  root:root         4755
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/permissions-20191205/src/chkstat.c 
new/permissions-20200204/src/chkstat.c
--- old/permissions-20191205/src/chkstat.c      2019-12-05 15:28:14.000000000 
+0100
+++ new/permissions-20200204/src/chkstat.c      2020-02-04 13:19:11.000000000 
+0100
@@ -24,6 +24,8 @@
 #include <grp.h>
 #include <sys/types.h>
 #include <sys/stat.h>
+#include <sys/vfs.h>
+#include <linux/magic.h>
 #include <unistd.h>
 #include <stdlib.h>
 #include <string.h>
@@ -32,6 +34,7 @@
 #include <sys/capability.h>
 #include <fcntl.h>
 #include <stdbool.h>
+#include <sys/param.h>
 
 #define BAD_LINE() \
   fprintf(stderr, "bad permissions line %s:%d\n", permfiles[i], lcnt)
@@ -439,25 +442,59 @@
   exit(x);
 }
 
+enum proc_mount_state {
+  PROC_MOUNT_STATE_UNKNOWN,
+  PROC_MOUNT_STATE_AVAIL,
+  PROC_MOUNT_STATE_UNAVAIL,
+};
+static enum proc_mount_state proc_mount_avail = PROC_MOUNT_STATE_UNKNOWN;
+
+static bool
+check_have_proc(void)
+{
+  if (proc_mount_avail == PROC_MOUNT_STATE_UNKNOWN)
+    {
+      char *override = secure_getenv("CHKSTAT_PRETEND_NO_PROC");
+
+      struct statfs proc;
+      int r = statfs("/proc", &proc);
+      if (override == NULL && r == 0 && proc.f_type == PROC_SUPER_MAGIC)
+        proc_mount_avail = PROC_MOUNT_STATE_AVAIL;
+      else
+        proc_mount_avail = PROC_MOUNT_STATE_UNAVAIL;
+    }
+
+  return proc_mount_avail == PROC_MOUNT_STATE_AVAIL;
+}
+
+
+
+#define _STRINGIFY(s) #s
+#define STRINGIFY(s) _STRINGIFY(s)
+
+#define PROC_FD_PATH_SIZE (sizeof("/proc/self/fd/") + 
sizeof(STRINGIFY(INT_MAX)))
+
+
 int
 safe_open(char *path, struct stat *stb, uid_t target_uid, bool 
*traversed_insecure)
 {
   char pathbuf[PATH_MAX];
-  char *p;
+  char *path_rest;
   int lcnt;
   int pathfd = -1;
   struct stat root_st;
+  bool is_final_path_element = false;
 
   *traversed_insecure = false;
 
   lcnt = 0;
   if ((size_t)snprintf(pathbuf, sizeof(pathbuf), "%s", path + rootl) >= 
sizeof(pathbuf))
     goto fail;
-  p = pathbuf;
-  do
+  path_rest = pathbuf;
+  while (!is_final_path_element)
     {
-      *p = '/';
-      char *cursor = p + 1;
+      *path_rest = '/';
+      char *cursor = path_rest + 1;
 
       if (pathfd == -1)
         {
@@ -476,13 +513,14 @@
           memcpy(stb, &root_st, sizeof(*stb));
         }
 
-      p = strchr(cursor, '/');
-      // p is NULL when we reach the final path element
-      if (p)
-        *p = 0;
+      path_rest = strchr(cursor, '/');
+      // path_rest is NULL when we reach the final path element
+      is_final_path_element = path_rest == NULL || strcmp("/", path_rest) == 0;
+      if (!is_final_path_element)
+        *path_rest = 0;
 
       // multiple consecutive slashes: ignore
-      if (p && *cursor == '\0')
+      if (!is_final_path_element && *cursor == '\0')
         continue;
 
       // never move up from the configured root directory (using the stat 
result from the previous loop iteration)
@@ -502,19 +540,21 @@
 
       /* owner of directories must be trusted for setuid/setgid/capabilities 
as we have no way to verify file contents */
       /* for euid != 0 it is also ok if the owner is euid */
-      if (stb->st_uid && stb->st_uid != euid && p)
+      if (stb->st_uid && stb->st_uid != euid && !is_final_path_element)
         *traversed_insecure = true;
       // path is in a world-writable directory, or file is world-writable 
itself.
-      if (!S_ISLNK(stb->st_mode) && (stb->st_mode & S_IWOTH) && p)
+      if (!S_ISLNK(stb->st_mode) && (stb->st_mode & S_IWOTH) && 
!is_final_path_element)
         *traversed_insecure = true;
       // if parent directory is not owned by root, the file owner must match 
the owner of parent
       if (stb->st_uid && stb->st_uid != target_uid && stb->st_uid != euid)
         {
-          if (p)
-            goto fail_insecure_path;
+          if (is_final_path_element)
+            {
+              fprintf(stderr, "%s: has unexpected owner. refusing to correct 
due to unknown integrity.\n", path+rootl);
+              goto fail;
+            }
           else
-            fprintf(stderr, "%s: has unexpected owner. refusing to correct due 
to unknown integrity.\n", path+rootl);
-          goto fail;
+            goto fail_insecure_path;
         }
 
       if (S_ISLNK(stb->st_mode))
@@ -541,17 +581,18 @@
               pathfd = -1;
             }
           size_t len;
-          char tmp[sizeof(pathbuf)]; // need a temporary buffer because p 
points into pathbuf and snprintf doesn't allow the same buffer as source and 
destination
-          if (p)
-            len = (size_t)snprintf(tmp, sizeof(tmp), "%s/%s", linkbuf, p + 1);
-          else
+          char tmp[sizeof(pathbuf) - 1]; // need a temporary buffer because 
path_rest points into pathbuf and snprintf doesn't allow the same buffer as 
source and destination
+          if (is_final_path_element)
             len = (size_t)snprintf(tmp, sizeof(tmp), "%s", linkbuf);
-          if (len >= sizeof(pathbuf))
+          else
+            len = (size_t)snprintf(tmp, sizeof(tmp), "%s/%s", linkbuf, 
path_rest + 1);
+          if (len >= sizeof(tmp))
             goto fail;
-          strcpy(pathbuf, tmp);
-          p = pathbuf;
+          // the first byte of path_rest is always set to a slash at the start 
of the loop, so we offset by one byte
+          strcpy(pathbuf + 1, tmp);
+          path_rest = pathbuf;
         }
-    } while (p);
+    }
 
   // world-writable file: error out due to unknown file integrity
   if (S_ISREG(stb->st_mode) && (stb->st_mode & S_IWOTH)) {
@@ -563,12 +604,12 @@
 fail_insecure_path:
 
   {
-    char linkpath[PATH_MAX];
-    char procpath[100];
+    char linkpath[PATH_MAX] = "ancestor";
+    char procpath[PROC_FD_PATH_SIZE];
     snprintf(procpath, sizeof(procpath), "/proc/self/fd/%d", pathfd);
     ssize_t l = readlink(procpath, linkpath, sizeof(linkpath) - 1);
-    if (l > 0 && (size_t)l < sizeof(linkpath) - 1)
-      linkpath[l] = '\0';
+    if (l > 0)
+      linkpath[MIN((size_t)l, sizeof(linkpath) - 1)] = '\0';
     fprintf(stderr, "%s: on an insecure path - %s has different non-root owner 
who could tamper with the file.\n", path+rootl, linkpath);
   }
 
@@ -578,6 +619,7 @@
   return -1;
 }
 
+
 /* check /sys/kernel/fscaps, 2.6.39 */
 static int
 check_fscaps_enabled()
@@ -980,8 +1022,17 @@
       //
       // So we use path-based operations (yes!) with /proc/self/fd/xxx. (Since 
safe_open already resolved
       // all symlinks, 'fd' can't refer to a symlink which we'd have to worry 
might get followed.)
-      char fd_path[100];
-      snprintf(fd_path, sizeof(fd_path), "/proc/self/fd/%d", fd);
+      char fd_path_buf[PROC_FD_PATH_SIZE];
+      char *fd_path;
+      if (check_have_proc())
+        {
+          snprintf(fd_path_buf, sizeof(fd_path_buf), "/proc/self/fd/%d", fd);
+          fd_path = fd_path_buf;
+        }
+      else
+        // fall back to plain path-access for read-only operation. (this much 
is fine)
+        // below we make sure that in this case we report errors instead of 
trying to fix policy violations insecurely
+        fd_path = e->file;
 
       caps = cap_get_file(fd_path);
       if (!caps)
@@ -1033,6 +1084,13 @@
             }
         }
 
+      if (do_set && fd_path != fd_path_buf)
+        {
+          fprintf(stderr, "ERROR: /proc is not available - unable to fix 
policy violations.\n");
+          errors++;
+          do_set = false;
+        }
+
       if (!do_set)
         printf("%s should be %s:%s %04o", e->file+rootl, e->owner, e->group, 
e->mode);
       else
@@ -1116,13 +1174,15 @@
           fprintf(stderr, "%s: chmod: %s\n", e->file+rootl, strerror(errno));
           errors++;
         }
-      if (!caps_ok)
+      // chown and - depending on the file system - chmod clear existing 
capabilities
+      // so apply the intended caps even if they were correct previously
+      if (e->caps || !caps_ok)
         {
           if (S_ISREG(stb.st_mode))
             {
               // cap_set_file() tries to be helpful and does a lstat() to 
check that it isn't called on
               // a symlink. So we have to open() it (without O_PATH) and use 
cap_set_fd().
-              int cap_fd = open(fd_path, O_NOATIME | O_CLOEXEC);
+              int cap_fd = open(fd_path, O_NOATIME | O_CLOEXEC | O_RDONLY);
               if (cap_fd == -1)
                 {
                   fprintf(stderr, "%s: open() for changing capabilities: 
%s\n", e->file+rootl, strerror(errno));
@@ -1130,8 +1190,12 @@
                 }
               else if (cap_set_fd(cap_fd, e->caps))
                 {
-                  fprintf(stderr, "%s: cap_set_fd: %s\n", e->file+rootl, 
strerror(errno));
-                  errors++;
+                  // ignore ENODATA when clearing caps - it just means there 
were no caps to remove
+                  if (errno != ENODATA || e->caps)
+                    {
+                      fprintf(stderr, "%s: cap_set_fd: %s\n", e->file+rootl, 
strerror(errno));
+                      errors++;
+                    }
                 }
               if (cap_fd != -1)
                 close(cap_fd);


Reply via email to