diff options
author | Simo Sorce <ssorce@redhat.com> | 2009-05-28 20:06:20 -0400 |
---|---|---|
committer | Simo Sorce <ssorce@redhat.com> | 2009-05-28 20:22:32 -0400 |
commit | 99d12568b3e7e49d27022410790b0f8e0610d5f7 (patch) | |
tree | 47cacabce217452b42d3d04decbf9e647a433aa6 | |
parent | 3223205c56f9b85b483db31ac98590a3f64e40ca (diff) | |
download | sssd-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.c | 75 |
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; } |