]> git.lizzy.rs Git - plan9front.git/blob - sys/src/libauth/attr.c
libauth: fix out of bounds memory access in _parseattr()
[plan9front.git] / sys / src / libauth / attr.c
1 #include <u.h>
2 #include <libc.h>
3 #include <auth.h>
4
5 int
6 _attrfmt(Fmt *fmt)
7 {
8         char *b, buf[1024], *ebuf;
9         Attr *a;
10
11         ebuf = buf+sizeof buf;
12         b = buf;
13         strcpy(buf, " ");
14         for(a=va_arg(fmt->args, Attr*); a; a=a->next){
15                 if(a->name == nil)
16                         continue;
17                 switch(a->type){
18                 case AttrQuery:
19                         b = seprint(b, ebuf, " %q?", a->name);
20                         break;
21                 case AttrNameval:
22                         b = seprint(b, ebuf, " %q=%q", a->name, a->val);
23                         break;
24                 case AttrDefault:
25                         b = seprint(b, ebuf, " %q:=%q", a->name, a->val);
26                         break;
27                 }
28         }
29         return fmtstrcpy(fmt, buf+1);
30 }
31
32 Attr*
33 _copyattr(Attr *a)
34 {
35         Attr **la, *na;
36
37         na = nil;
38         la = &na;
39         for(; a; a=a->next){
40                 *la = _mkattr(a->type, a->name, a->val, nil);
41                 setmalloctag(*la, getcallerpc(&a));
42                 la = &(*la)->next;
43         }
44         *la = nil;
45         return na;
46 }
47
48 Attr*
49 _delattr(Attr *a, char *name)
50 {
51         Attr *fa;
52         Attr **la;
53
54         for(la=&a; *la; ){
55                 if(strcmp((*la)->name, name) == 0){
56                         fa = *la;
57                         *la = (*la)->next;
58                         fa->next = nil;
59                         _freeattr(fa);
60                 }else
61                         la=&(*la)->next;
62         }
63         return a;
64 }
65
66 Attr*
67 _findattr(Attr *a, char *n)
68 {
69         for(; a; a=a->next)
70                 if(strcmp(a->name, n) == 0 && a->type != AttrQuery)
71                         return a;
72         return nil;
73 }
74
75 void
76 _freeattr(Attr *a)
77 {
78         Attr *anext;
79
80         for(; a; a=anext){
81                 anext = a->next;
82                 free(a->name);
83                 free(a->val);
84                 a->name = (void*)~0;
85                 a->val = (void*)~0;
86                 a->next = (void*)~0;
87                 free(a);
88         }
89 }
90
91 Attr*
92 _mkattr(int type, char *name, char *val, Attr *next)
93 {
94         Attr *a;
95
96         a = malloc(sizeof(*a));
97         if(a==nil)
98                 sysfatal("_mkattr malloc: %r");
99         a->type = type;
100         a->name = strdup(name);
101         a->val = strdup(val);
102         if(a->name==nil || a->val==nil)
103                 sysfatal("_mkattr malloc: %r");
104         a->next = next;
105         setmalloctag(a, getcallerpc(&type));
106         return a;
107 }
108
109 static Attr*
110 cleanattr(Attr *a)
111 {
112         Attr *fa;
113         Attr **la;
114
115         for(la=&a; *la; ){
116                 if((*la)->type==AttrQuery && _findattr(a, (*la)->name)){
117                         fa = *la;
118                         *la = (*la)->next;
119                         fa->next = nil;
120                         _freeattr(fa);
121                 }else
122                         la=&(*la)->next;
123         }
124         return a;
125 }
126
127 Attr*
128 _parseattr(char *s)
129 {
130         char *p, *t, *tok[256];
131         int i, ntok;
132         Attr *a;
133
134         s = strdup(s);
135         if(s == nil)
136                 sysfatal("_parseattr strdup: %r");
137
138         ntok = tokenize(s, tok, nelem(tok));
139         a = nil;
140         for(i=ntok-1; i>=0; i--){
141                 t = tok[i];
142                 if((p = strchr(t, '=')) != nil){
143                         *p++ = '\0';
144                         a = _mkattr(AttrNameval, t, p, a);
145                 }else if((p = strchr(t, '\0')-1) >= t && *p == '?'){
146                         *p = '\0';
147                         a = _mkattr(AttrQuery, t, "", a);
148                 }else{
149                         /* really a syntax error, but better to provide some indication */
150                         a = _mkattr(AttrNameval, t, "", a);
151                 }
152                 setmalloctag(a, getcallerpc(&s));
153         }
154         free(s);
155         return cleanattr(a);
156 }
157
158 char*
159 _strfindattr(Attr *a, char *n)
160 {
161         a = _findattr(a, n);
162         if(a == nil)
163                 return nil;
164         return a->val;
165 }
166