potential out-of-bounds memory write in afs_alloc_cell()
Colin Ian King
colin.king at canonical.com
Wed Jun 24 07:00:19 EDT 2020
Hi there,
static analysis with coverity has detected a potential out-of-bounds
memory write in afs_alloc_cell():
Analysis is as follows:
129
1. Condition !!!name, taking false branch.
2. Condition !!!name, taking false branch.
130 ASSERT(name);
3. Condition namelen == 0, taking false branch.
4. cond_at_least: Checking namelen == 0U implies that namelen is at
least 1 on the false branch.
131 if (namelen == 0)
132 return ERR_PTR(-EINVAL);
5. Condition namelen > 256, taking false branch.
6. cond_between: Checking namelen > 256U implies that namelen is
between 1 and 256 (inclusive) on the false branch.
133 if (namelen > AFS_MAXCELLNAME) {
134 _leave(" = -ENAMETOOLONG");
135 return ERR_PTR(-ENAMETOOLONG);
136 }
137
138 /* Prohibit cell names that contain unprintable chars, '/'
and '@' or
139 * that begin with a dot. This also precludes "@cell".
140 */
7. Condition name[0] == '.', taking false branch.
141 if (name[0] == '.')
142 return ERR_PTR(-EINVAL);
8. Condition i < namelen, taking true branch.
13. Condition i < namelen, taking true branch.
18. Condition i < namelen, taking false branch.
143 for (i = 0; i < namelen; i++) {
144 char ch = name[i];
9. Condition !((_ctype[(int)(unsigned char)ch] & (151 /* (((0x10 | 1)
| 2) | 4) | 0x80 */)) != 0), taking false branch.
10. Condition ch == '/', taking false branch.
11. Condition ch == '@', taking false branch.
14. Condition !((_ctype[(int)(unsigned char)ch] & (151 /* (((0x10 |
1) | 2) | 4) | 0x80 */)) != 0), taking false branch.
15. Condition ch == '/', taking false branch.
16. Condition ch == '@', taking false branch.
145 if (!isprint(ch) || ch == '/' || ch == '@')
146 return ERR_PTR(-EINVAL);
12. Jumping back to the beginning of the loop.
17. Jumping back to the beginning of the loop.
147 }
148
19. Condition !!(afs_debug & 1), taking true branch.
20. Condition !!(afs_debug & 1), taking true branch.
149 _enter("%*.*s,%s", namelen, namelen, name, addresses);
150
151 cell = kzalloc(sizeof(struct afs_cell), GFP_KERNEL);
21. Condition !cell, taking false branch.
152 if (!cell) {
153 _leave(" = -ENOMEM");
154 return ERR_PTR(-ENOMEM);
155 }
156
157 cell->net = net;
158 cell->name_len = namelen;
22. Condition i < namelen, taking true branch.
24. Condition i < namelen, taking true branch.
25. cond_at_most: Checking i < namelen implies that i may be up to
255 on the true branch.
159 for (i = 0; i < namelen; i++)
23. Jumping back to the beginning of the loop.
CID (#1 of 1): Out-of-bounds write (OVERRUN)
26. overrun-local: Overrunning array cell->name of 65 bytes at byte
offset 255 using index i (which evaluates to 255).
160 cell->name[i] = tolower(name[i]);
The above write to cell->names[i] occurs because it is declared as a 64
byte char array in fs/afs/internal.h:
char name[64 + 1]; /* Cell name, case-flattened and
NUL-padded */
however we may be indexing beyond this. I was unsure if name should be
AFS_MAXCELLNAME + 1 instead of the hard coded size here, or if this
situation can't happen and the 65 char limit is intentional.
Colin
More information about the linux-afs
mailing list