wok-next annotate arj/stuff/patches/CVE-2015-0556-symlink-traversal.patch @ rev 19715

Fix building: pciutils, pcmanfm-legacy, arj
author Aleksej Bobylev <al.bobylev@gmail.com>
date Sat May 13 17:25:31 2017 +0300 (2017-05-13)
parents
children
rev   line source
al@19715 1 Description: Fix symlink directory traversal.
al@19715 2 Do not allow symlinks that traverse the current directoru, nor absolute
al@19715 3 symlinks.
al@19715 4 .
al@19715 5 Fixes CVE-2015-0556.
al@19715 6 Author: Guillem Jover <guillem@debian.org>
al@19715 7 Origin: vendor
al@19715 8 Bug-Debian: https://bugs.debian.org/774434
al@19715 9 Forwarded: no
al@19715 10 Last-Update: 2015-03-28
al@19715 11
al@19715 12 ---
al@19715 13 uxspec.c | 54 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
al@19715 14 1 file changed, 54 insertions(+)
al@19715 15
al@19715 16 --- a/uxspec.c
al@19715 17 +++ b/uxspec.c
al@19715 18 @@ -120,6 +120,58 @@ int query_uxspecial(char FAR **dest, cha
al@19715 19 }
al@19715 20 #endif
al@19715 21
al@19715 22 +#if TARGET==UNIX
al@19715 23 +static int is_link_traversal(const char *name)
al@19715 24 +{
al@19715 25 + enum {
al@19715 26 + STATE_NONE,
al@19715 27 + STATE_DOTS,
al@19715 28 + STATE_NAME,
al@19715 29 + } state = STATE_NONE;
al@19715 30 + int ndir = 0;
al@19715 31 + int dots = 0;
al@19715 32 +
al@19715 33 + while(*name) {
al@19715 34 + int c = *name++;
al@19715 35 +
al@19715 36 + if (c == '/')
al@19715 37 + {
al@19715 38 + if ((state == STATE_DOTS) && (dots == 2))
al@19715 39 + ndir--;
al@19715 40 + if (ndir < 0)
al@19715 41 + return 1;
al@19715 42 + if ((state == STATE_DOTS && dots == 1) && ndir == 0)
al@19715 43 + return 1;
al@19715 44 + if (state == STATE_NONE && ndir == 0)
al@19715 45 + return 1;
al@19715 46 + if ((state == STATE_DOTS) && (dots > 2))
al@19715 47 + ndir++;
al@19715 48 + state = STATE_NONE;
al@19715 49 + dots = 0;
al@19715 50 + }
al@19715 51 + else if (c == '.')
al@19715 52 + {
al@19715 53 + if (state == STATE_NONE)
al@19715 54 + state = STATE_DOTS;
al@19715 55 + dots++;
al@19715 56 + }
al@19715 57 + else
al@19715 58 + {
al@19715 59 + if (state == STATE_NONE)
al@19715 60 + ndir++;
al@19715 61 + state = STATE_NAME;
al@19715 62 + }
al@19715 63 + }
al@19715 64 +
al@19715 65 + if ((state == STATE_DOTS) && (dots == 2))
al@19715 66 + ndir--;
al@19715 67 + if ((state == STATE_DOTS) && (dots > 2))
al@19715 68 + ndir++;
al@19715 69 +
al@19715 70 + return ndir < 0;
al@19715 71 +}
al@19715 72 +#endif
al@19715 73 +
al@19715 74 /* Restores the UNIX special file data */
al@19715 75
al@19715 76 int set_uxspecial(char FAR *storage, char *name)
al@19715 77 @@ -156,6 +208,8 @@ int set_uxspecial(char FAR *storage, cha
al@19715 78 l=sizeof(tmp_name)-1;
al@19715 79 far_memmove((char FAR *)tmp_name, dptr, l);
al@19715 80 tmp_name[l]='\0';
al@19715 81 + if (is_link_traversal(tmp_name))
al@19715 82 + return(UXSPEC_RC_ERROR);
al@19715 83 rc=(id==UXSB_HLNK)?link(tmp_name, name):symlink(tmp_name, name);
al@19715 84 if(!rc)
al@19715 85 return(0);