~ubuntu-branches/ubuntu/gutsy/vnc4/gutsy

« back to all changes in this revision

Viewing changes to unix/xc/util/memleak/getretmips.c

  • Committer: Bazaar Package Importer
  • Author(s): Ola Lundqvist
  • Date: 2006-05-15 20:35:17 UTC
  • mfrom: (1.1.2 upstream)
  • Revision ID: james.westby@ubuntu.com-20060515203517-l4lre1ku942mn26k
Tags: 4.1.1+X4.3.0-10
* Correction of critical security issue. Thanks to Martin Kogler
  <e9925248@student.tuwien.ac.at> that informed me about the issue,
  and provided the patch.
  This flaw was originally found by Steve Wiseman of intelliadmin.com.
* Applied patch from Javier Kohen <jkohen@users.sourceforge.net> that
  inform the user that only 8 first characters of the password will
  actually be used when typing more than 8 characters, closes:
  #355619.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * $Xorg: getretmips.c,v 1.4 2001/02/09 02:06:19 xorgcvs Exp $
 
3
 *
 
4
Copyright 1992, 1998  The Open Group
 
5
 
 
6
Permission to use, copy, modify, distribute, and sell this software and its
 
7
documentation for any purpose is hereby granted without fee, provided that
 
8
the above copyright notice appear in all copies and that both that
 
9
copyright notice and this permission notice appear in supporting
 
10
documentation.
 
11
 
 
12
The above copyright notice and this permission notice shall be included in
 
13
all copies or substantial portions of the Software.
 
14
 
 
15
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 
16
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 
17
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
 
18
OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
 
19
AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
 
20
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 
21
 
 
22
Except as contained in this notice, the name of The Open Group shall not be
 
23
used in advertising or otherwise to promote the sale, use or other dealings
 
24
in this Software without prior written authorization from The Open Group.
 
25
 *
 
26
 * Author:  Keith Packard, MIT X Consortium
 
27
 */
 
28
 
 
29
/* Return stack generation for MIPS processors
 
30
 * This is tricky as MIPS stack frames aren't
 
31
 * easily unrolled -- we look for pc restoration
 
32
 * and stack adjustment instructions beyond the return
 
33
 * address to discover the correct values
 
34
 */
 
35
 
 
36
/* lw $31,const($sp) is : 100 011 11101 11111 const */
 
37
/*                        1000 1111 1011 1111       */
 
38
 
 
39
#define RESTORE_RETURNVAL       0x8fbf0000
 
40
#define RESTORE_RETURNVAL_MASK  0xffff0000
 
41
 
 
42
/* addiu $sp, $sp, const is 001 001 11101 11101 const */
 
43
/*                          0010 0111 1011 1101 const */
 
44
 
 
45
#define ADJUST_STACKP_C         0x27bd0000
 
46
#define ADJUST_STACKP_C_MASK    0xffff0000
 
47
 
 
48
/* addu $sp, $sp, $at is 000 000 11101 00001 11101 00000 100 001  */
 
49
/*                       0000 0011 1010 0001 1110 1000 0010 0001 */
 
50
 
 
51
#define ADJUST_STACKP_V         0x03a1e821
 
52
#define ADJUST_STACKP_V_MASK    0xffffffff
 
53
 
 
54
/* lui $at, const is 001 111 00000 00001 const */
 
55
/*                   0011 1100 0000 0001 const */
 
56
 
 
57
#define SET_UPPER_C             0x3c010000
 
58
#define SET_UPPER_C_MASK        0xffff0000
 
59
 
 
60
/* ori $at, $at, const is 001 101 00001 00001 const */
 
61
/*                        0011 0100 0010 0001 const */
 
62
 
 
63
#define OR_LOWER_C              0x34210000
 
64
#define OR_LOWER_C_MASK         0xffff0000
 
65
 
 
66
/* ori $at, $zero, const is 001 101 00000 00001 const */
 
67
/*                          0011 0100 0000 0001 const */
 
68
 
 
69
#define SET_LOWER_C             0x34010000
 
70
#define SET_LOWER_C_MASK        0xffff0000
 
71
 
 
72
/* jr $ra */
 
73
#define RETURN      0x03e00008
 
74
 
 
75
#define CALL(f)     (0x0c000000 | (((int) (f)) >> 2))
 
76
 
 
77
/*
 
78
 * This computation is expensive, so we cache the results;
 
79
 * a simple hash function and straight-forward replacement.
 
80
 */
 
81
 
 
82
#define HASH_SIZE   256
 
83
 
 
84
typedef struct _returnCache {
 
85
    unsigned long   *returnAddress;
 
86
    long            raOffset;
 
87
    long            spAdjust;
 
88
} ReturnCacheRec, *ReturnCachePtr;
 
89
 
 
90
static ReturnCacheRec   returnCache[HASH_SIZE];
 
91
 
 
92
#define HASH(ra)    ((((int) (ra)) >> 2) & (HASH_SIZE - 1))
 
93
 
 
94
typedef int Bool;
 
95
 
 
96
#define TRUE 1
 
97
#define FALSE 0
 
98
 
 
99
getStackTrace (results, max)
 
100
    unsigned long   *results;
 
101
    int             max;
 
102
{
 
103
    extern unsigned long    *getReturnAddress (), *getStackPointer ();
 
104
    extern int      main ();
 
105
    unsigned long   *ra, *ra_limit;
 
106
    unsigned long   *sp;
 
107
    unsigned long   inst;
 
108
    unsigned long   mainCall;
 
109
    unsigned short  const_upper;
 
110
    unsigned short  const_lower;
 
111
    long            ra_offset;
 
112
    long            sp_adjust;
 
113
    Bool            found_ra_offset, found_sp_adjust;
 
114
    Bool            found_const_upper, found_const_lower;
 
115
    ReturnCachePtr  rc;
 
116
 
 
117
    ra = getReturnAddress ();
 
118
    sp = getStackPointer ();
 
119
    mainCall = CALL(main);
 
120
    while (ra && max) {
 
121
        rc = &returnCache[HASH(ra)];
 
122
        if (rc->returnAddress != ra)
 
123
        {
 
124
            found_ra_offset = FALSE;
 
125
            found_sp_adjust = FALSE;
 
126
            found_const_upper = FALSE;
 
127
            found_const_lower = FALSE;
 
128
            const_upper = 0;
 
129
            const_lower = 0;
 
130
            rc->returnAddress = ra;
 
131
            ra_limit = (unsigned long *) 0x10000000;
 
132
            ra_offset = 0;
 
133
            sp_adjust = -1;
 
134
            while ((!found_ra_offset || !found_sp_adjust) && ra < ra_limit)
 
135
            {
 
136
                inst = *ra;
 
137
                /* look for the offset of the PC in the stack frame */
 
138
                if ((inst & RESTORE_RETURNVAL_MASK) == RESTORE_RETURNVAL)
 
139
                {
 
140
                    ra_offset = inst & ~RESTORE_RETURNVAL_MASK;
 
141
                    found_ra_offset = TRUE;
 
142
                }
 
143
                else if ((inst & ADJUST_STACKP_C_MASK) == ADJUST_STACKP_C)
 
144
                {
 
145
                    sp_adjust = inst & ~ADJUST_STACKP_C_MASK;
 
146
                    found_sp_adjust = TRUE;
 
147
                }
 
148
                else if ((inst & ADJUST_STACKP_V_MASK) == ADJUST_STACKP_V)
 
149
                {
 
150
                    sp_adjust = 0;
 
151
                    found_sp_adjust = TRUE;
 
152
                }
 
153
                else if ((inst & SET_UPPER_C_MASK) == SET_UPPER_C)
 
154
                {
 
155
                    const_upper = inst & ~SET_UPPER_C_MASK;
 
156
                    const_lower = 0;
 
157
                    found_const_upper = TRUE;
 
158
                }
 
159
                else if ((inst & OR_LOWER_C_MASK) == OR_LOWER_C)
 
160
                {
 
161
                    const_lower = inst & ~OR_LOWER_C_MASK;
 
162
                    found_const_lower = TRUE;
 
163
                }
 
164
                else if ((inst & SET_LOWER_C_MASK) == SET_LOWER_C)
 
165
                {
 
166
                    const_lower = inst & ~SET_LOWER_C_MASK;
 
167
                    const_upper = 0;
 
168
                    found_const_lower = TRUE;
 
169
                }
 
170
                else if (inst == RETURN)
 
171
                    ra_limit = ra + 2;
 
172
                ra++;
 
173
            }
 
174
            if (sp_adjust == 0 && (found_const_upper || found_const_lower))
 
175
                sp_adjust = (const_upper << 16) | const_lower;
 
176
            rc->raOffset = ra_offset;
 
177
            rc->spAdjust = sp_adjust;
 
178
        }
 
179
        /* if something went wrong, punt */
 
180
        if (rc->spAdjust <= 0) 
 
181
        {
 
182
            *results++ = 0;
 
183
            break;
 
184
        }
 
185
        ra = (unsigned long *) sp[rc->raOffset>>2];
 
186
        sp += rc->spAdjust >> 2;
 
187
        *results++ = ((unsigned long) ra) - 8;
 
188
        if (ra[-2] == mainCall)
 
189
        {
 
190
            *results++ = 0;
 
191
            break;
 
192
        }
 
193
        max--;
 
194
    }
 
195
}