summaryrefslogtreecommitdiff
path: root/sshbuf-getput-basic.c
diff options
context:
space:
mode:
authordjm@openbsd.org <djm@openbsd.org>2019-07-14 23:32:27 +0000
committerDamien Miller <djm@mindrot.org>2019-07-15 09:39:34 +1000
commit101d164723ffbc38f8036b6f3ea3bfef771ba250 (patch)
tree960920c2529e0b33eeade7b8e73785c38b283571 /sshbuf-getput-basic.c
parent7250879c72d28275a53f2f220e49646c3e42ef18 (diff)
upstream: add some functions to perform random-access read/write
operations inside buffers with bounds checking. Intended to replace manual pointer arithmetic wherever possible. feedback and ok markus@ OpenBSD-Commit-ID: 91771fde7732738f1ffed078aa5d3bee6d198409
Diffstat (limited to 'sshbuf-getput-basic.c')
-rw-r--r--sshbuf-getput-basic.c163
1 files changed, 162 insertions, 1 deletions
diff --git a/sshbuf-getput-basic.c b/sshbuf-getput-basic.c
index 50648258f..27058d5bb 100644
--- a/sshbuf-getput-basic.c
+++ b/sshbuf-getput-basic.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: sshbuf-getput-basic.c,v 1.7 2017/06/01 04:51:58 djm Exp $ */ 1/* $OpenBSD: sshbuf-getput-basic.c,v 1.8 2019/07/14 23:32:27 djm Exp $ */
2/* 2/*
3 * Copyright (c) 2011 Damien Miller 3 * Copyright (c) 2011 Damien Miller
4 * 4 *
@@ -93,6 +93,93 @@ sshbuf_get_u8(struct sshbuf *buf, u_char *valp)
93 return 0; 93 return 0;
94} 94}
95 95
96static int
97check_offset(const struct sshbuf *buf, int wr, size_t offset, size_t len)
98{
99 if (sshbuf_ptr(buf) == NULL) /* calls sshbuf_check_sanity() */
100 return SSH_ERR_INTERNAL_ERROR;
101 if (offset >= SIZE_MAX - len)
102 return SSH_ERR_INVALID_ARGUMENT;
103 if (offset + len > sshbuf_len(buf)) {
104 return wr ?
105 SSH_ERR_NO_BUFFER_SPACE : SSH_ERR_MESSAGE_INCOMPLETE;
106 }
107 return 0;
108}
109
110static int
111check_roffset(const struct sshbuf *buf, size_t offset, size_t len,
112 const u_char **p)
113{
114 int r;
115
116 *p = NULL;
117 if ((r = check_offset(buf, 0, offset, len)) != 0)
118 return r;
119 *p = sshbuf_ptr(buf) + offset;
120 return 0;
121}
122
123int
124sshbuf_peek_u64(const struct sshbuf *buf, size_t offset, u_int64_t *valp)
125{
126 const u_char *p = NULL;
127 int r;
128
129 if (valp != NULL)
130 *valp = 0;
131 if ((r = check_roffset(buf, offset, 8, &p)) != 0)
132 return r;
133 if (valp != NULL)
134 *valp = PEEK_U64(p);
135 return 0;
136}
137
138int
139sshbuf_peek_u32(const struct sshbuf *buf, size_t offset, u_int32_t *valp)
140{
141 const u_char *p = NULL;
142 int r;
143
144 if (valp != NULL)
145 *valp = 0;
146 if ((r = check_roffset(buf, offset, 4, &p)) != 0)
147 return r;
148 if (valp != NULL)
149 *valp = PEEK_U32(p);
150 return 0;
151}
152
153int
154sshbuf_peek_u16(const struct sshbuf *buf, size_t offset, u_int16_t *valp)
155{
156 const u_char *p = NULL;
157 int r;
158
159 if (valp != NULL)
160 *valp = 0;
161 if ((r = check_roffset(buf, offset, 2, &p)) != 0)
162 return r;
163 if (valp != NULL)
164 *valp = PEEK_U16(p);
165 return 0;
166}
167
168int
169sshbuf_peek_u8(const struct sshbuf *buf, size_t offset, u_char *valp)
170{
171 const u_char *p = NULL;
172 int r;
173
174 if (valp != NULL)
175 *valp = 0;
176 if ((r = check_roffset(buf, offset, 1, &p)) != 0)
177 return r;
178 if (valp != NULL)
179 *valp = *p;
180 return 0;
181}
182
96int 183int
97sshbuf_get_string(struct sshbuf *buf, u_char **valp, size_t *lenp) 184sshbuf_get_string(struct sshbuf *buf, u_char **valp, size_t *lenp)
98{ 185{
@@ -344,6 +431,80 @@ sshbuf_put_u8(struct sshbuf *buf, u_char val)
344 return 0; 431 return 0;
345} 432}
346 433
434static int
435check_woffset(struct sshbuf *buf, size_t offset, size_t len, u_char **p)
436{
437 int r;
438
439 *p = NULL;
440 if ((r = check_offset(buf, 1, offset, len)) != 0)
441 return r;
442 if (sshbuf_mutable_ptr(buf) == NULL)
443 return SSH_ERR_BUFFER_READ_ONLY;
444 *p = sshbuf_mutable_ptr(buf) + offset;
445 return 0;
446}
447
448int
449sshbuf_poke_u64(struct sshbuf *buf, size_t offset, u_int64_t val)
450{
451 u_char *p = NULL;
452 int r;
453
454 if ((r = check_woffset(buf, offset, 8, &p)) != 0)
455 return r;
456 POKE_U64(p, val);
457 return 0;
458}
459
460int
461sshbuf_poke_u32(struct sshbuf *buf, size_t offset, u_int32_t val)
462{
463 u_char *p = NULL;
464 int r;
465
466 if ((r = check_woffset(buf, offset, 4, &p)) != 0)
467 return r;
468 POKE_U32(p, val);
469 return 0;
470}
471
472int
473sshbuf_poke_u16(struct sshbuf *buf, size_t offset, u_int16_t val)
474{
475 u_char *p = NULL;
476 int r;
477
478 if ((r = check_woffset(buf, offset, 2, &p)) != 0)
479 return r;
480 POKE_U16(p, val);
481 return 0;
482}
483
484int
485sshbuf_poke_u8(struct sshbuf *buf, size_t offset, u_char val)
486{
487 u_char *p = NULL;
488 int r;
489
490 if ((r = check_woffset(buf, offset, 1, &p)) != 0)
491 return r;
492 *p = val;
493 return 0;
494}
495
496int
497sshbuf_poke(struct sshbuf *buf, size_t offset, void *v, size_t len)
498{
499 u_char *p = NULL;
500 int r;
501
502 if ((r = check_woffset(buf, offset, len, &p)) != 0)
503 return r;
504 memcpy(p, v, len);
505 return 0;
506}
507
347int 508int
348sshbuf_put_string(struct sshbuf *buf, const void *v, size_t len) 509sshbuf_put_string(struct sshbuf *buf, const void *v, size_t len)
349{ 510{