summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSimo Sorce <ssorce@redhat.com>2009-05-28 20:06:20 -0400
committerSimo Sorce <ssorce@redhat.com>2009-05-28 20:22:32 -0400
commit99d12568b3e7e49d27022410790b0f8e0610d5f7 (patch)
tree47cacabce217452b42d3d04decbf9e647a433aa6
parent3223205c56f9b85b483db31ac98590a3f64e40ca (diff)
downloadsssd-99d12568b3e7e49d27022410790b0f8e0610d5f7.tar.gz
sssd-99d12568b3e7e49d27022410790b0f8e0610d5f7.tar.bz2
sssd-99d12568b3e7e49d27022410790b0f8e0610d5f7.zip
Standardize style and fix potential lenght check
We were not subtracting the initial 8 bytes from slen. This could cause us to run past the source buffer in case we received a bad packet.
-rw-r--r--sss_client/passwd.c75
1 files changed, 47 insertions, 28 deletions
diff --git a/sss_client/passwd.c b/sss_client/passwd.c
index a2ffcad6..5239d552 100644
--- a/sss_client/passwd.c
+++ b/sss_client/passwd.c
@@ -72,9 +72,8 @@ struct sss_nss_pw_rep {
static int sss_nss_getpw_readrep(struct sss_nss_pw_rep *pr,
uint8_t *buf, size_t *len)
{
- size_t i, slen;
+ size_t i, slen, dlen;
char *sbuf;
- int err;
if (*len < 13) { /* not enough space for data, bad packet */
return EBADMSG;
@@ -84,70 +83,90 @@ static int sss_nss_getpw_readrep(struct sss_nss_pw_rep *pr,
pr->result->pw_gid = ((uint32_t *)buf)[1];
sbuf = (char *)&buf[8];
- if (*len < pr->buflen) {
- slen = *len;
- err = EBADMSG;
- } else {
- slen = pr->buflen;
- err = ENOMEM;
- }
+ slen = *len - 8;
+ dlen = pr->buflen;
pr->result->pw_name = &(pr->buffer[0]);
i = 0;
- while (i < slen) {
+ while (slen > i && dlen > 0) {
pr->buffer[i] = sbuf[i];
if (pr->buffer[i] == '\0') break;
i++;
+ dlen--;
+ }
+ if (slen <= i) { /* premature end of buf */
+ return EBADMSG;
}
- if (i == slen) { /* premature end of buf */
- return err;
+ if (dlen <= 0) { /* not enough memory */
+ return ERANGE; /* not ENOMEM, ERANGE is what glibc looks for */
}
+ i++;
+ dlen--;
i++;
pr->result->pw_passwd = &(pr->buffer[i]);
- while (i < slen) {
+ while (slen > i && dlen > 0) {
pr->buffer[i] = sbuf[i];
if (pr->buffer[i] == '\0') break;
i++;
+ dlen--;
}
- if (i == slen) { /* premature end of buf */
- return err;
+ if (slen <= i) { /* premature end of buf */
+ return EBADMSG;
+ }
+ if (dlen <= 0) { /* not enough memory */
+ return ERANGE; /* not ENOMEM, ERANGE is what glibc looks for */
}
-
i++;
+ dlen--;
+
pr->result->pw_gecos = &(pr->buffer[i]);
- while (i < slen) {
+ while (slen > i && dlen > 0) {
pr->buffer[i] = sbuf[i];
if (pr->buffer[i] == '\0') break;
i++;
+ dlen--;
+ }
+ if (slen <= i) { /* premature end of buf */
+ return EBADMSG;
}
- if (i == slen) { /* premature end of buf */
- return err;
+ if (dlen <= 0) { /* not enough memory */
+ return ERANGE; /* not ENOMEM, ERANGE is what glibc looks for */
}
-
i++;
+ dlen--;
+
pr->result->pw_dir = &(pr->buffer[i]);
- while (i < slen) {
+ while (slen > i && dlen > 0) {
pr->buffer[i] = sbuf[i];
if (pr->buffer[i] == '\0') break;
i++;
+ dlen--;
}
- if (i == slen) { /* premature end of buf */
- return err;
+ if (slen <= i) { /* premature end of buf */
+ return EBADMSG;
+ }
+ if (dlen <= 0) { /* not enough memory */
+ return ERANGE; /* not ENOMEM, ERANGE is what glibc looks for */
}
-
i++;
+ dlen--;
+
pr->result->pw_shell = &(pr->buffer[i]);
- while (i < slen) {
+ while (slen > i && dlen > 0) {
pr->buffer[i] = sbuf[i];
if (pr->buffer[i] == '\0') break;
i++;
+ dlen--;
+ }
+ if (slen <= i) { /* premature end of buf */
+ return EBADMSG;
}
- if (pr->buffer[i] != '\0') { /* premature end of buf */
- return err;
+ if (dlen <= 0) { /* not enough memory */
+ return ERANGE; /* not ENOMEM, ERANGE is what glibc looks for */
}
- *len = *len -8 -i -1;
+ *len = slen -i -1;
return 0;
}