| Patch for bug 286102 from upstream git. It includes the following 5 commits: |
| |
| commit 3826963e65d8c4c68bcd3e4066505f63ef734b95 |
| Author: Benjamin Otte <otte@gnome.org> |
| Date: Tue Sep 1 21:53:35 2009 +0200 |
| |
| commit 48e0af0157f52ac12b904bd92540432a18b139c7 |
| Author: Benjamin Otte <otte@gnome.org> |
| Date: Tue Sep 1 21:26:08 2009 +0200 |
| |
| commit bb7852e34b1845e516290e1b45a960a345ee8a43 |
| Author: Benjamin Otte <otte@gnome.org> |
| Date: Tue Sep 1 20:36:31 2009 +0200 |
| |
| commit fc44bf40a4eff8e122b223e97ee5efcbc548be03 |
| Author: Benjamin Otte <otte@gnome.org> |
| Date: Tue Sep 1 12:48:55 2009 +0200 |
| |
| commit e695c0932f5d02f3b222f0b7a3de1f8c00ba7b81 |
| Author: Benjamin Otte <otte@gnome.org> |
| Date: Tue Sep 1 11:54:48 2009 +0200 |
| |
| Patch generated by a3li@gentoo.org, |
| CVE available for 2.20.5 only (see timeline). |
| |
| diff --git a/configure.in b/configure.in |
| index 7bda924..e2a33b5 100644 |
| --- a/configure.in |
| +++ b/configure.in |
| @@ -952,7 +952,7 @@ AC_MSG_RESULT(unsigned $glib_size_type) |
| |
| # Check for some functions |
| AC_CHECK_FUNCS(lstat strerror strsignal memmove vsnprintf stpcpy strcasecmp strncasecmp poll getcwd vasprintf setenv unsetenv getc_unlocked readlink symlink fdwalk) |
| -AC_CHECK_FUNCS(chown lchown fchmod fchown link statvfs statfs utimes getgrgid getpwuid) |
| +AC_CHECK_FUNCS(chown lchmod lchown fchmod fchown link statvfs statfs utimes getgrgid getpwuid) |
| AC_CHECK_FUNCS(getmntent_r setmntent endmntent hasmntopt getmntinfo) |
| # Check for high-resolution sleep functions |
| AC_CHECK_FUNCS(nanosleep nsleep) |
| diff --git a/gio/glocalfileinfo.c b/gio/glocalfileinfo.c |
| index 72a59b5..a61cc55 100644 |
| --- a/gio/glocalfileinfo.c |
| +++ b/gio/glocalfileinfo.c |
| @@ -1869,15 +1869,40 @@ get_string (const GFileAttributeValue *value, |
| |
| static gboolean |
| set_unix_mode (char *filename, |
| + GFileQueryInfoFlags flags, |
| const GFileAttributeValue *value, |
| GError **error) |
| { |
| guint32 val; |
| + int res = 0; |
| |
| if (!get_uint32 (value, &val, error)) |
| return FALSE; |
| - |
| - if (g_chmod (filename, val) == -1) |
| + |
| +#ifdef HAVE_SYMLINK |
| + if (flags & G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS) { |
| +#ifdef HAVE_LCHMOD |
| + res = lchmod (filename, val); |
| +#else |
| + struct stat statbuf; |
| + /* Calling chmod on a symlink changes permissions on the symlink. |
| + * We don't want to do this, so we need to check for a symlink */ |
| + res = g_lstat (filename, &statbuf); |
| + if (res == 0 && S_ISLNK (statbuf.st_mode)) |
| + { |
| + g_set_error_literal (error, G_IO_ERROR, |
| + G_IO_ERROR_NOT_SUPPORTED, |
| + _("Cannot set permissions on symlinks")); |
| + return FALSE; |
| + } |
| + else if (res == 0) |
| + res = g_chmod (filename, val); |
| +#endif |
| + } else |
| +#endif |
| + res = g_chmod (filename, val); |
| + |
| + if (res == -1) |
| { |
| int errsv = errno; |
| |
| @@ -2172,7 +2197,7 @@ _g_local_file_info_set_attribute (char *filename, |
| _g_file_attribute_value_set_from_pointer (&value, type, value_p, FALSE); |
| |
| if (strcmp (attribute, G_FILE_ATTRIBUTE_UNIX_MODE) == 0) |
| - return set_unix_mode (filename, &value, error); |
| + return set_unix_mode (filename, flags, &value, error); |
| |
| #ifdef HAVE_CHOWN |
| else if (strcmp (attribute, G_FILE_ATTRIBUTE_UNIX_UID) == 0) |
| @@ -2316,7 +2341,7 @@ _g_local_file_info_set_attributes (char *filename, |
| value = _g_file_info_get_attribute_value (info, G_FILE_ATTRIBUTE_UNIX_MODE); |
| if (value) |
| { |
| - if (!set_unix_mode (filename, value, error)) |
| + if (!set_unix_mode (filename, flags, value, error)) |
| { |
| value->status = G_FILE_ATTRIBUTE_STATUS_ERROR_SETTING; |
| res = FALSE; |