summaryrefslogtreecommitdiff
path: root/misc.c
diff options
context:
space:
mode:
authorColin Watson <cjwatson@debian.org>2014-02-09 16:09:58 +0000
committerColin Watson <cjwatson@debian.org>2018-04-03 08:21:37 +0100
commit9e45701c5d6105444cc2f4f5d6c44b0f69969479 (patch)
tree9df3ccd6a8eee5c69d410a69d06be927bc7284fd /misc.c
parent027619c6b05713e3f08a51e7232389383900e5d8 (diff)
Allow harmless group-writability
Allow secure files (~/.ssh/config, ~/.ssh/authorized_keys, etc.) to be group-writable, provided that the group in question contains only the file's owner. Rejected upstream for IMO incorrect reasons (e.g. a misunderstanding about the contents of gr->gr_mem). Given that per-user groups and umask 002 are the default setup in Debian (for good reasons - this makes operating in setgid directories with other groups much easier), we need to permit this by default. Bug: https://bugzilla.mindrot.org/show_bug.cgi?id=1060 Bug-Debian: http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=314347 Last-Update: 2017-10-04 Patch-Name: user-group-modes.patch
Diffstat (limited to 'misc.c')
-rw-r--r--misc.c58
1 files changed, 53 insertions, 5 deletions
diff --git a/misc.c b/misc.c
index 874dcc8a2..75c4113f0 100644
--- a/misc.c
+++ b/misc.c
@@ -57,8 +57,9 @@
57#include <netdb.h> 57#include <netdb.h>
58#ifdef HAVE_PATHS_H 58#ifdef HAVE_PATHS_H
59# include <paths.h> 59# include <paths.h>
60#include <pwd.h>
61#endif 60#endif
61#include <pwd.h>
62#include <grp.h>
62#ifdef SSH_TUN_OPENBSD 63#ifdef SSH_TUN_OPENBSD
63#include <net/if.h> 64#include <net/if.h>
64#endif 65#endif
@@ -1031,6 +1032,55 @@ read_keyfile_line(FILE *f, const char *filename, char *buf, size_t bufsz,
1031} 1032}
1032 1033
1033int 1034int
1035secure_permissions(struct stat *st, uid_t uid)
1036{
1037 if (!platform_sys_dir_uid(st->st_uid) && st->st_uid != uid)
1038 return 0;
1039 if ((st->st_mode & 002) != 0)
1040 return 0;
1041 if ((st->st_mode & 020) != 0) {
1042 /* If the file is group-writable, the group in question must
1043 * have exactly one member, namely the file's owner.
1044 * (Zero-member groups are typically used by setgid
1045 * binaries, and are unlikely to be suitable.)
1046 */
1047 struct passwd *pw;
1048 struct group *gr;
1049 int members = 0;
1050
1051 gr = getgrgid(st->st_gid);
1052 if (!gr)
1053 return 0;
1054
1055 /* Check primary group memberships. */
1056 while ((pw = getpwent()) != NULL) {
1057 if (pw->pw_gid == gr->gr_gid) {
1058 ++members;
1059 if (pw->pw_uid != uid)
1060 return 0;
1061 }
1062 }
1063 endpwent();
1064
1065 pw = getpwuid(st->st_uid);
1066 if (!pw)
1067 return 0;
1068
1069 /* Check supplementary group memberships. */
1070 if (gr->gr_mem[0]) {
1071 ++members;
1072 if (strcmp(pw->pw_name, gr->gr_mem[0]) ||
1073 gr->gr_mem[1])
1074 return 0;
1075 }
1076
1077 if (!members)
1078 return 0;
1079 }
1080 return 1;
1081}
1082
1083int
1034tun_open(int tun, int mode, char **ifname) 1084tun_open(int tun, int mode, char **ifname)
1035{ 1085{
1036#if defined(CUSTOM_SYS_TUN_OPEN) 1086#if defined(CUSTOM_SYS_TUN_OPEN)
@@ -1797,8 +1847,7 @@ safe_path(const char *name, struct stat *stp, const char *pw_dir,
1797 snprintf(err, errlen, "%s is not a regular file", buf); 1847 snprintf(err, errlen, "%s is not a regular file", buf);
1798 return -1; 1848 return -1;
1799 } 1849 }
1800 if ((!platform_sys_dir_uid(stp->st_uid) && stp->st_uid != uid) || 1850 if (!secure_permissions(stp, uid)) {
1801 (stp->st_mode & 022) != 0) {
1802 snprintf(err, errlen, "bad ownership or modes for file %s", 1851 snprintf(err, errlen, "bad ownership or modes for file %s",
1803 buf); 1852 buf);
1804 return -1; 1853 return -1;
@@ -1813,8 +1862,7 @@ safe_path(const char *name, struct stat *stp, const char *pw_dir,
1813 strlcpy(buf, cp, sizeof(buf)); 1862 strlcpy(buf, cp, sizeof(buf));
1814 1863
1815 if (stat(buf, &st) < 0 || 1864 if (stat(buf, &st) < 0 ||
1816 (!platform_sys_dir_uid(st.st_uid) && st.st_uid != uid) || 1865 !secure_permissions(&st, uid)) {
1817 (st.st_mode & 022) != 0) {
1818 snprintf(err, errlen, 1866 snprintf(err, errlen,
1819 "bad ownership or modes for directory %s", buf); 1867 "bad ownership or modes for directory %s", buf);
1820 return -1; 1868 return -1;