diff options
author | Bob Beck <beck@cvs.openbsd.org> | 2009-12-14 16:26:20 +0000 |
---|---|---|
committer | Bob Beck <beck@cvs.openbsd.org> | 2009-12-14 16:26:20 +0000 |
commit | 08715c4cca55339b6172439518c6befab992639b (patch) | |
tree | a646f2f31bb00b51f03780fb831e4ebb039d1d00 /usr.sbin | |
parent | 2c1805e867fb1bf521080a933ba332efe85d5da2 (diff) |
Fix buffer overflow possibility, noticed by parfait:
Buffer overflow (CWE 120): In memcpy of msg.msg with length 'size'
Array size is 2048 bytes, size <= 2080
at line 317 of /usr/src/usr.sbin/afs/src/arlad/nnpfs.c in function 'nnpf
s_send_message_wakeup_data'.
tesing by todd@ and jj@ and me
Diffstat (limited to 'usr.sbin')
-rw-r--r-- | usr.sbin/afs/src/arlad/messages.c | 50 | ||||
-rw-r--r-- | usr.sbin/afs/src/arlad/nnpfs.c | 15 |
2 files changed, 39 insertions, 26 deletions
diff --git a/usr.sbin/afs/src/arlad/messages.c b/usr.sbin/afs/src/arlad/messages.c index 458e3ce03d3..068d7aa7cdb 100644 --- a/usr.sbin/afs/src/arlad/messages.c +++ b/usr.sbin/afs/src/arlad/messages.c @@ -2375,8 +2375,11 @@ viocgetvolstat(int fd, struct nnpfs_message_pioctl *h, u_int size) char volumename[AFSNAMEMAX]; char offlinemsg[AFSOPAQUEMAX]; char motd[AFSOPAQUEMAX]; - char out[SYSNAMEMAXLEN]; + char out[NNPFS_MSG_MAX_DATASIZE]; + char * outstr; int32_t outsize = 0; + int32_t os = 0; + int32_t osmax = 0; int error; if (!h->handle.a && !h->handle.b && !h->handle.c && !h->handle.d) @@ -2393,7 +2396,8 @@ viocgetvolstat(int fd, struct nnpfs_message_pioctl *h, u_int size) memset (volumename, 0, AFSNAMEMAX); memset (offlinemsg, 0, AFSOPAQUEMAX); memset (motd, 0, AFSOPAQUEMAX); - memset (out, 0, SYSNAMEMAXLEN); + + memset (out, 0, sizeof(out)); do { error = getvolstat (fid, ce, &volstat, @@ -2409,33 +2413,39 @@ viocgetvolstat(int fd, struct nnpfs_message_pioctl *h, u_int size) memcpy (out, (char *) &volstat, sizeof (AFSFetchVolumeStatus)); outsize = sizeof (AFSFetchVolumeStatus); + outstr = out + outsize; + os = 0; + osmax = sizeof(out) - outsize; - if (volumename[0]) { - strncpy (out+outsize, volumename, AFSNAMEMAX); - outsize += strlen (volumename); - } + if (os < osmax && (volumename[0])) + os = strlcat(outstr, volumename, osmax); else { - out[outsize] = 0; + *outstr++ = '\0'; outsize++; + osmax--; } - - if (offlinemsg[0]) { - strncpy (out+outsize, offlinemsg, AFSOPAQUEMAX); - outsize += strlen (offlinemsg); - } + if (os < osmax && (offlinemsg[0])) + os = strlcat(outstr, offlinemsg, osmax); else { - out[outsize] = 0; + *outstr++ = '\0'; outsize++; + osmax--; } - - if (motd[0]) { - strncpy (out+outsize, motd, AFSOPAQUEMAX); - outsize += strlen (motd); - } + if (os < osmax && (motd[0])) + os = strlcat(outstr, motd, osmax); else { - out[outsize] = 0; + *outstr++ = '\0'; outsize++; + osmax--; } + /* this can potentially truncate the motd.. who cares */ + if (os + outsize >= sizeof(out)) { + /* XXX warn about trucated motd */ + arla_warnx(ADEBMSG, + "truncated motd by %d bytes", os + outsize - sizeof(out)); + outsize = sizeof(out); + } else + outsize += os; nnpfs_send_message_wakeup_data (fd, h->header.sequence_num, error, out, outsize); @@ -3433,7 +3443,7 @@ vioc_fpriostatus (int fd, struct nnpfs_message_pioctl *h, u_int size) error = EINVAL; break; } - + prio = fprio_get(fid); nnpfs_send_message_wakeup_data (fd, h->header.sequence_num, diff --git a/usr.sbin/afs/src/arlad/nnpfs.c b/usr.sbin/afs/src/arlad/nnpfs.c index 9edb5c837ce..ff92528aeb7 100644 --- a/usr.sbin/afs/src/arlad/nnpfs.c +++ b/usr.sbin/afs/src/arlad/nnpfs.c @@ -306,19 +306,22 @@ nnpfs_send_message_wakeup_data (int fd, u_int seqnum, int error, void *data, int size) { struct nnpfs_message_wakeup_data msg; - + msg.header.opcode = NNPFS_MSG_WAKEUP_DATA; msg.sleepers_sequence_num = seqnum; msg.error = error; arla_warnx (ADEBMSG, "sending wakeup: seq = %u, error = %d", seqnum, error); - if (sizeof(msg) >= size && size != 0) { - memcpy(msg.msg, data, size); - } - + if (sizeof(msg.msg) < size || size < 0) { + errno = EINVAL; + arla_warn (ADEBMSG, + "nnpfs_send_message_wakeup_data: invalid message size %d", + size); + return errno; + } else + memcpy(msg.msg, data, size); msg.len = size; - return nnpfs_message_send (fd, (struct nnpfs_message_header *)&msg, sizeof(msg)); } |