tmk: fix out of bounds access - plan9port - [fork] Plan 9 from user space
 (HTM) git clone git://src.adamsgaard.dk/plan9port
 (DIR) Log
 (DIR) Files
 (DIR) Refs
 (DIR) README
 (DIR) LICENSE
       ---
 (DIR) commit c65d179354fd3fd6f9719531f3414cf1c9c5280a
 (DIR) parent 194178b5788a09379e01e8ff8bff391b8a8d5c18
 (HTM) Author: Neven Sajko <nsajko@gmail.com>
       Date:   Tue, 31 Dec 2019 21:32:42 +0000
       
       mk: fix out of bounds access
       
       A loop is added for each structure field instead of accessing the other
       fields through the first one in one loop.
       
       Updates #313
       
       Change-Id: I0e27e15feacb77391bc1decee7cf720d64d14586
       
       Diffstat:
         M src/cmd/mk/archive.c                |      28 +++++++++++++++++++++-------
       
       1 file changed, 21 insertions(+), 7 deletions(-)
       ---
 (DIR) diff --git a/src/cmd/mk/archive.c b/src/cmd/mk/archive.c
       t@@ -1,6 +1,6 @@
        #include        "mk.h"
        #define        ARMAG        "!<arch>\n"
       -#define        SARMAG        8
       +#define        SARMAG        (sizeof(ARMAG) - sizeof(""))
        
        #define        ARFMAG        "`\n"
        #define SARNAME        16
       t@@ -102,7 +102,7 @@ atouch(char *name)
                        LSEEK(fd, SARMAG, 0);
                        while(read(fd, (char *)&h, sizeof(h)) == sizeof(h)){
                                for(i = SARNAME-1; i > 0 && h.name[i] == ' '; i--)
       -                                        ;
       +                                ;
                                h.name[i+1]=0;
                                if(strcmp(member, h.name) == 0){
                                        t = SARNAME-sizeof(h);        /* ughgghh */
       t@@ -118,6 +118,18 @@ atouch(char *name)
                close(fd);
        }
        
       +static int
       +allspaces(char *a, int n)
       +{
       +        int i;
       +        for (i = 0; i < n; i++) {
       +                if (a[i] != ' ') {
       +                        return 0;
       +                }
       +        }
       +        return 1;
       +}
       +
        static void
        atimes(char *ar)
        {
       t@@ -151,11 +163,13 @@ atimes(char *ar)
                                if(readn(fd, name, namelen) != namelen)
                                        break;
                                name[namelen] = 0;
       -                }else if(memcmp(h.name, "// ", 2) == 0){ /* GNU */
       +                }else if(memcmp(h.name, "// ", 3) == 0){ /* GNU */
                                /* date, uid, gid, mode all ' ' */
       -                        for(i=2; i<16+12+6+6+8; i++)
       -                                if(h.name[i] != ' ')
       -                                        goto skip;
       +                        if(!allspaces(&h.name[3], sizeof(h.name) - 3) ||
       +                           !allspaces(h.date, sizeof(h.date)) || !allspaces(h.uid, sizeof(h.uid)) ||
       +                           !allspaces(h.gid, sizeof(h.gid)) || !allspaces(h.mode, sizeof(h.mode))){
       +                                goto skip;
       +                        }
                                t = atol(h.size);
                                if(t&01)
                                        t++;
       t@@ -189,7 +203,7 @@ atimes(char *ar)
                        }else{
                                strncpy(name, h.name, sizeof(h.name));
                                for(i = sizeof(h.name)-1; i > 0 && name[i] == ' '; i--)
       -                                        ;
       +                                ;
                                if(name[i] == '/')                /* system V bug */
                                        i--;
                                name[i+1]=0;