Bug 515361
Summary: | tftp FORTIFY_SOURCE strcpy crash | ||
---|---|---|---|
Product: | [Fedora] Fedora | Reporter: | Warren Togami <wtogami> |
Component: | tftp | Assignee: | Jiri Skala <jskala> |
Status: | CLOSED RAWHIDE | QA Contact: | Fedora Extras Quality Assurance <extras-qa> |
Severity: | medium | Docs Contact: | |
Priority: | low | ||
Version: | rawhide | CC: | aglotov, jakub, jskala, pertusus |
Target Milestone: | --- | ||
Target Release: | --- | ||
Hardware: | All | ||
OS: | Linux | ||
Whiteboard: | |||
Fixed In Version: | Doc Type: | Bug Fix | |
Doc Text: | Story Points: | --- | |
Clone Of: | Environment: | ||
Last Closed: | 2009-08-05 14:31:53 UTC | Type: | --- |
Regression: | --- | Mount Type: | --- |
Documentation: | --- | CRM: | |
Verified Versions: | Category: | --- | |
oVirt Team: | --- | RHEL 7.3 requirements from Atomic Host: | |
Cloudforms Team: | --- | Target Upstream Version: | |
Embargoed: | |||
Bug Depends On: | |||
Bug Blocks: | 473303 |
Description
Warren Togami
2009-08-03 21:10:00 UTC
tftp-hpa-0.49/tftp/tftp.c static int makerequest(int request, const char *name, struct tftphdr *tp, const char *mode) { char *cp; tp->th_opcode = htons((u_short) request); cp = (char *)&(tp->th_stuff); strcpy(cp, name); cp += strlen(name); *cp++ = '\0'; strcpy(cp, mode); cp += strlen(mode); *cp++ = '\0'; return (cp - (char *)tp); } The first strcpy() is where it crashes. This function pre-processed. static int makerequest(int request, const char *name, struct tftphdr *tp, const char *mode) { char *cp; tp->th_opcode = (__extension__ ({ register unsigned short int __v, __x = ((u_short) request); if (__builtin_constant_p (__x)) __v = ((((__x) >> 8) & 0xff) | (((__x) & 0xff) << 8)); else __asm__ ("rorw $8, %w0" : "=r" (__v) : "0" (__x) : "cc"); __v; })); cp = (char *)&(tp->th_u.tu_stuff); strcpy(cp, name); cp += strlen(name); *cp++ = '\0'; strcpy(cp, mode); cp += strlen(mode); *cp++ = '\0'; return (cp - (char *)tp); } /usr/include/arpa/tftp.h contains the definition of struct tftphdr. struct tftphdr { short th_opcode; /* packet type */ union { unsigned short tu_block; /* block # */ short tu_code; /* error code */ char tu_stuff[1]; /* request packet stuff */ } __attribute__ ((__packed__)) th_u; char th_data[1]; /* data or error string */ } __attribute__ ((__packed__)); #define th_block th_u.tu_block #define th_code th_u.tu_code #define th_stuff th_u.tu_stuff #define th_msg th_data jakub, do you need any more? th_u isn't the last field in the struct, so flexible array member and similar exception definitely doesn't apply here. You can use memcpy instead of strcpy (memcpy is always allowed to cross field boundaries), after all you are computing strlen (name) immediately afterwards anyway, so just trplacing strcpy(cp, name); cp += strlen(name); *cp++ = '\0'; with size_t name_len = strlen(name) + 1; memcpy(cp, name, name_len); cp += name_len; and similarly for mode should work. |