FreeBSD Bugzilla – Attachment 55120 Details for
Bug 83358
[libcompat] [patch] improper handling of malloc failures within rexec(3)
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Help
|
New Account
|
Log In
Remember
[x]
|
Forgot Password
Login:
[x]
[patch]
4_3_compat_update.patch
4_3_compat_update.patch (text/x-patch), 20.76 KB, created by
Garrett Cooper
on 2008-06-21 06:07:16 UTC
(
hide
)
Description:
4_3_compat_update.patch
Filename:
MIME Type:
Creator:
Garrett Cooper
Created:
2008-06-21 06:07:16 UTC
Size:
20.76 KB
patch
obsolete
>Index: cfree.c >=================================================================== >RCS file: /home/ncvs/src/lib/libcompat/4.3/cfree.c,v >retrieving revision 1.3 >diff -u -r1.3 cfree.c >--- cfree.c 9 Jan 2007 01:02:02 -0000 1.3 >+++ cfree.c 21 Jun 2008 04:52:11 -0000 >@@ -37,8 +37,7 @@ > #include <stdlib.h> > > void >-cfree(p) >- void *p; >+cfree(void *p) > { > free(p); > } >Index: regex.c >=================================================================== >RCS file: /home/ncvs/src/lib/libcompat/4.3/regex.c,v >retrieving revision 1.5 >diff -u -r1.5 regex.c >--- regex.c 9 Jan 2007 01:02:02 -0000 1.5 >+++ regex.c 21 Jun 2008 04:52:12 -0000 >@@ -56,17 +56,16 @@ > static char *re_errstr; > > char * >-re_comp(s) >- char *s; >+re_comp(char *s) > { > if (s == NULL || *s == '\0') { > if (re_regexp == NULL) > return "no previous regular expression"; > return (NULL); > } >- if (re_regexp) >+ if (re_regexp != NULL) > free(re_regexp); >- if (re_errstr) >+ if (re_errstr != NULL) > free(re_errstr); > re_goterr = 0; > re_regexp = regcomp(s); >@@ -89,7 +88,7 @@ > const char *s; > { > re_goterr = 1; >- if (re_errstr) >+ if (re_errstr != NULL) > free(re_errstr); > re_errstr = strdup(s); > } >Index: rexec.c >=================================================================== >RCS file: /home/ncvs/src/lib/libcompat/4.3/rexec.c,v >retrieving revision 1.7 >diff -u -r1.7 rexec.c >--- rexec.c 9 Jan 2007 01:02:02 -0000 1.7 >+++ rexec.c 21 Jun 2008 04:52:13 -0000 >@@ -30,7 +30,7 @@ > */ > > #if defined(LIBC_SCCS) && !defined(lint) >-static char sccsid[] = "@(#)rexec.c 8.1 (Berkeley) 6/4/93"; >+static char sccsid[] = "@(#)rexec.c 8.1 (Berkeley) 6/4/93"; > #endif /* LIBC_SCCS and not lint */ > > #include <sys/types.h> >@@ -51,339 +51,369 @@ > #include <stdlib.h> > #include <unistd.h> > >-int rexecoptions; >-char *getpass(), *getlogin(); >+char *getpass(); >+char *getlogin(); > > /* > * Options and other state info. > */ > struct macel { >- char mac_name[9]; /* macro name */ >- char *mac_start; /* start of macro in macbuf */ >- char *mac_end; /* end of macro in macbuf */ >+ char mac_name[9]; /* macro name */ >+ char *mac_start; /* start of macro in macbuf */ >+ char *mac_end; /* end of macro in macbuf */ > }; > >-int macnum; /* number of defined macros */ >+int macnum; /* number of defined macros */ > struct macel macros[16]; > char macbuf[4096]; > >-static FILE *cfile; >+static FILE *cfile; > > #define DEFAULT 1 > #define LOGIN 2 > #define PASSWD 3 >-#define ACCOUNT 4 >-#define MACDEF 5 >+#define ACCOUNT 4 >+#define MACDEF 5 > #define ID 10 > #define MACH 11 > > static char tokval[100]; > > static struct toktab { >- char *tokstr; >- int tval; >+ char *tokstr; >+ int tval; > } toktab[]= { >- { "default", DEFAULT }, >- { "login", LOGIN }, >- { "password", PASSWD }, >- { "passwd", PASSWD }, >- { "account", ACCOUNT }, >- { "machine", MACH }, >- { "macdef", MACDEF }, >- { NULL, 0 } >+ { "default", DEFAULT }, >+ { "login", LOGIN }, >+ { "password", PASSWD }, >+ { "passwd", PASSWD }, >+ { "account", ACCOUNT }, >+ { "machine", MACH }, >+ { "macdef", MACDEF }, >+ { NULL, 0 } > }; > > static int > token() > { >- char *cp; >- int c; >- struct toktab *t; >- >- if (feof(cfile) || ferror(cfile)) >- return (0); >- while ((c = getc(cfile)) != EOF && >- (c == '\n' || c == '\t' || c == ' ' || c == ',')) >- continue; >- if (c == EOF) >- return (0); >- cp = tokval; >- if (c == '"') { >- while ((c = getc(cfile)) != EOF && c != '"') { >- if (c == '\\') >- c = getc(cfile); >- *cp++ = c; >- } >- } else { >- *cp++ = c; >- while ((c = getc(cfile)) != EOF >- && c != '\n' && c != '\t' && c != ' ' && c != ',') { >- if (c == '\\') >- c = getc(cfile); >- *cp++ = c; >- } >- } >- *cp = 0; >- if (tokval[0] == 0) >- return (0); >- for (t = toktab; t->tokstr; t++) >- if (!strcmp(t->tokstr, tokval)) >- return (t->tval); >- return (ID); >+ char *cp; >+ int c; >+ struct toktab *t; >+ >+ if (feof(cfile) || ferror(cfile)) >+ return (0); >+ while ((c = getc(cfile)) != EOF && >+ (c == '\n' || c == '\t' || c == ' ' || c == ',')) >+ continue; >+ if (c == EOF) >+ return (0); >+ cp = tokval; >+ if (c == '"') { >+ while ((c = getc(cfile)) != EOF && c != '"') { >+ if (c == '\\') >+ c = getc(cfile); >+ *cp++ = c; >+ } >+ } else { >+ *cp++ = c; >+ while ((c = getc(cfile)) != EOF >+ && c != '\n' && c != '\t' && c != ' ' && c != ',') { >+ if (c == '\\') >+ c = getc(cfile); >+ *cp++ = c; >+ } >+ } >+ *cp = 0; >+ if (tokval[0] == 0) >+ return (0); >+ for (t = toktab; t->tokstr; t++) >+ if (!strcmp(t->tokstr, tokval)) >+ return (t->tval); >+ return (ID); > } > > static int >-ruserpass(host, aname, apass, aacct) >- char *host, **aname, **apass, **aacct; >+ruserpass(char *host, char **aname, char **apass, char **aacct) > { >- char *hdir, buf[BUFSIZ], *tmp; >- char myname[MAXHOSTNAMELEN], *mydomain; >- int t, i, c, usedefault = 0; >- struct stat stb; >- >- hdir = getenv("HOME"); >- if (hdir == NULL) >- hdir = "."; >- if (strlen(hdir) + 8 > sizeof(buf)) >- return (0); >- (void) sprintf(buf, "%s/.netrc", hdir); >- cfile = fopen(buf, "r"); >- if (cfile == NULL) { >- if (errno != ENOENT) >- warn("%s", buf); >- return (0); >- } >- if (gethostname(myname, sizeof(myname)) < 0) >- myname[0] = '\0'; >- if ((mydomain = strchr(myname, '.')) == NULL) >- mydomain = ""; >+ char *hdir, buf[BUFSIZ], *tmp; >+ char myname[MAXHOSTNAMELEN], *mydomain; >+ int t, i, c, usedefault = 0; >+ int ret_code = 0; >+ struct stat stb; >+ >+ hdir = getenv("HOME"); >+ if (hdir == NULL) >+ hdir = "."; >+ if (strlen(hdir) + 8 > sizeof(buf)) >+ return (0); >+ sprintf(buf, "%s/.netrc", hdir); >+ cfile = fopen(buf, "r"); >+ if (cfile == NULL) { >+ if (errno != ENOENT) >+ warn("%s", buf); >+ return (0); >+ } >+ if (gethostname(myname, sizeof(myname)) < 0) >+ myname[0] = '\0'; >+ if ((mydomain = strchr(myname, '.')) == NULL) >+ mydomain = ""; > next: >- while ((t = token())) switch(t) { >+ while ((t = token()) != 0) { >+ >+ switch(t) { >+ case DEFAULT: >+ usedefault = 1; >+ /* FALL THROUGH */ >+ >+ case MACH: >+ if (!usedefault) { >+ if (token() != ID) >+ continue; >+ /* >+ * Allow match either for user's input host >+ * name or official hostname. Also allow match >+ * of incompletely-specified host in local >+ * domain. >+ */ >+ if (strcasecmp(host, tokval) == 0) >+ goto match; >+ if ((tmp = strchr(host, '.')) != NULL && >+ strcasecmp(tmp, mydomain) == 0 && >+ strncasecmp(host, tokval, tmp-host) == 0 && >+ tokval[tmp - host] == '\0') { >+ goto match; >+ } >+ continue; >+ } >+ match: >+ while ((t = token()) && t != MACH && t != DEFAULT) { >+ switch(t) { >+ case LOGIN: >+ if (token()) { >+ if (*aname == 0) { >+ *aname = malloc(strlen(tokval)+1); >+ if (*aname == NULL) { >+ warnx("malloc for aname failed\n"); >+ goto bad; >+ } >+ strcpy(*aname, tokval); >+ } else { >+ if (strcmp(*aname, tokval)) >+ goto next; >+ } >+ } >+ break; >+ case PASSWD: >+ if ((*aname == 0 || strcmp(*aname, "anonymous")) && >+ fstat(fileno(cfile), &stb) >= 0 && >+ (stb.st_mode & 077) != 0) { >+ warnx("Error: .netrc file is readable" >+ " by others.\nRemove password" >+ " or make file unreadable by" >+ " others.\n"); >+ goto bad; >+ } >+ if (token() && *apass == NULL) { >+ *apass = malloc(strlen(tokval)+1); >+ if (*apass == NULL) { >+ warnx("malloc for apass failed\n"); >+ goto bad; >+ } >+ strcpy(*apass, tokval); >+ } >+ break; >+ case ACCOUNT: >+ if (fstat(fileno(cfile), &stb) >= 0 >+ && (stb.st_mode & 077) != 0) { >+ warnx("Error: .netrc file is readable" >+ " by others.\nRemove account" >+ " or make file unreadable by" >+ " others.\n"); >+ goto bad; >+ } >+ if (token() && *aacct == NULL) { >+ *aacct = malloc(strlen(tokval)+1); >+ if (*aacct == NULL) { >+ warnx("malloc for aacct failed\n"); >+ goto bad; >+ } >+ strcpy(*aacct, tokval); >+ } >+ break; >+ case MACDEF: >+ while ((c=getc(cfile)) != EOF && >+ (c == ' ' || c == '\t')) { >+ /* Null loop body */ >+ } >+ if (c == EOF || c == '\n') { >+ warnx("Missing macdef name argument.\n"); >+ goto bad; >+ } >+ if (macnum == 16) { >+ warnx("Limit of 16 macros have already been defined\n"); >+ goto bad; >+ } >+ tmp = macros[macnum].mac_name; >+ *tmp++ = c; >+ for (i=0; i < 8 && (c=getc(cfile)) != EOF && !isspace(c); ++i) { >+ *tmp++ = c; >+ } >+ if (c == EOF) { >+ warnx("Macro definition missing null" >+ " line terminator.\n"); >+ goto bad; >+ } >+ *tmp = '\0'; >+ if (c != '\n') { >+ while ((c=getc(cfile)) != EOF && c != '\n') ; >+ } >+ if (c == EOF) { >+ warnx("Macro definition missing null" >+ " line terminator.\n"); >+ goto bad; >+ } >+ if (macnum == 0) { >+ macros[macnum].mac_start = macbuf; >+ } >+ else { >+ macros[macnum].mac_start = >+ macros[macnum-1].mac_end + 1; >+ } >+ tmp = macros[macnum].mac_start; >+ while (tmp != macbuf + 4096) { >+ if ((c=getc(cfile)) == EOF) { >+ warnx("Macro definition missing" >+ " null line" >+ " terminator.\n"); >+ goto bad; >+ } >+ *tmp = c; >+ if (*tmp == '\n') { >+ if (*(tmp-1) == '\0') { >+ macros[macnum++].mac_end = tmp-1; >+ break; >+ } >+ *tmp = '\0'; >+ } >+ tmp++; >+ } >+ if (tmp == macbuf + 4096) { >+ warnx("4K macro buffer exceeded\n"); >+ goto bad; >+ } >+ break; >+ default: >+ warnx("Unknown .netrc keyword %s", tokval); >+ break; >+ >+ } >+ >+ } >+ >+ } >+ >+ goto done; >+ >+ } >+ >+ goto done; > >- case DEFAULT: >- usedefault = 1; >- /* FALL THROUGH */ >- >- case MACH: >- if (!usedefault) { >- if (token() != ID) >- continue; >- /* >- * Allow match either for user's input host name >- * or official hostname. Also allow match of >- * incompletely-specified host in local domain. >- */ >- if (strcasecmp(host, tokval) == 0) >- goto match; >- if ((tmp = strchr(host, '.')) != NULL && >- strcasecmp(tmp, mydomain) == 0 && >- strncasecmp(host, tokval, tmp - host) == 0 && >- tokval[tmp - host] == '\0') >- goto match; >- continue; >- } >- match: >- while ((t = token()) && t != MACH && t != DEFAULT) switch(t) { >- >- case LOGIN: >- if (token()) >- if (*aname == 0) { >- *aname = malloc((unsigned) strlen(tokval) + 1); >- (void) strcpy(*aname, tokval); >- } else { >- if (strcmp(*aname, tokval)) >- goto next; >- } >- break; >- case PASSWD: >- if ((*aname == 0 || strcmp(*aname, "anonymous")) && >- fstat(fileno(cfile), &stb) >= 0 && >- (stb.st_mode & 077) != 0) { >- warnx("Error: .netrc file is readable by others."); >- warnx("Remove password or make file unreadable by others."); >- goto bad; >- } >- if (token() && *apass == 0) { >- *apass = malloc((unsigned) strlen(tokval) + 1); >- (void) strcpy(*apass, tokval); >- } >- break; >- case ACCOUNT: >- if (fstat(fileno(cfile), &stb) >= 0 >- && (stb.st_mode & 077) != 0) { >- warnx("Error: .netrc file is readable by others."); >- warnx("Remove account or make file unreadable by others."); >- goto bad; >- } >- if (token() && *aacct == 0) { >- *aacct = malloc((unsigned) strlen(tokval) + 1); >- (void) strcpy(*aacct, tokval); >- } >- break; >- case MACDEF: >- while ((c=getc(cfile)) != EOF && >- (c == ' ' || c == '\t')) >- ; >- if (c == EOF || c == '\n') { >- printf("Missing macdef name argument.\n"); >- goto bad; >- } >- if (macnum == 16) { >- printf("Limit of 16 macros have already been defined\n"); >- goto bad; >- } >- tmp = macros[macnum].mac_name; >- *tmp++ = c; >- for (i=0; i < 8 && (c=getc(cfile)) != EOF && >- !isspace(c); ++i) { >- *tmp++ = c; >- } >- if (c == EOF) { >- printf("Macro definition missing null line terminator.\n"); >- goto bad; >- } >- *tmp = '\0'; >- if (c != '\n') { >- while ((c=getc(cfile)) != EOF && c != '\n'); >- } >- if (c == EOF) { >- printf("Macro definition missing null line terminator.\n"); >- goto bad; >- } >- if (macnum == 0) { >- macros[macnum].mac_start = macbuf; >- } >- else { >- macros[macnum].mac_start = macros[macnum-1].mac_end + 1; >- } >- tmp = macros[macnum].mac_start; >- while (tmp != macbuf + 4096) { >- if ((c=getc(cfile)) == EOF) { >- printf("Macro definition missing null line terminator.\n"); >- goto bad; >- } >- *tmp = c; >- if (*tmp == '\n') { >- if (*(tmp-1) == '\0') { >- macros[macnum++].mac_end = tmp - 1; >- break; >- } >- *tmp = '\0'; >- } >- tmp++; >- } >- if (tmp == macbuf + 4096) { >- printf("4K macro buffer exceeded\n"); >- goto bad; >- } >- break; >- default: >- warnx("Unknown .netrc keyword %s", tokval); >- break; >- } >- goto done; >- } >-done: >- (void) fclose(cfile); >- return (0); > bad: >- (void) fclose(cfile); >- return (-1); >+ ret_code = -1; >+done: >+ fclose(cfile); >+ return ret_code; > } > > int >-rexec(ahost, rport, name, pass, cmd, fd2p) >- char **ahost; >- int rport; >- char *name, *pass, *cmd; >- int *fd2p; >+rexec(char **ahost, int rport, char *name, char *pass, char *cmd, int *fd2p) > { >- struct sockaddr_in sin, sin2, from; >- struct hostent *hp; >- u_short port; >- int s, timo = 1, s3; >- char c; >- >- hp = gethostbyname(*ahost); >- if (hp == 0) { >- herror(*ahost); >- return (-1); >- } >- *ahost = hp->h_name; >- ruserpass(hp->h_name, &name, &pass); >+ struct sockaddr_in sin, sin2, from; >+ struct hostent *hp; >+ u_short port; >+ int s, timo = 1, s3; >+ char c; >+ >+ hp = gethostbyname(*ahost); >+ if (hp == NULL) { >+ herror(*ahost); >+ return -1; >+ } >+ *ahost = hp->h_name; >+ ruserpass(hp->h_name, &name, &pass); > retry: >- s = socket(AF_INET, SOCK_STREAM, 0); >- if (s < 0) { >- perror("rexec: socket"); >- return (-1); >- } >- sin.sin_family = hp->h_addrtype; >- sin.sin_port = rport; >- bcopy(hp->h_addr, (caddr_t)&sin.sin_addr, hp->h_length); >- if (connect(s, (struct sockaddr *)&sin, sizeof(sin)) < 0) { >- if (errno == ECONNREFUSED && timo <= 16) { >- (void) close(s); >- sleep(timo); >- timo *= 2; >- goto retry; >- } >- perror(hp->h_name); >- return (-1); >- } >- if (fd2p == 0) { >- (void) write(s, "", 1); >- port = 0; >- } else { >- char num[8]; >- int s2, sin2len; >- >- s2 = socket(AF_INET, SOCK_STREAM, 0); >- if (s2 < 0) { >- (void) close(s); >- return (-1); >- } >- listen(s2, 1); >- sin2len = sizeof (sin2); >- if (getsockname(s2, (struct sockaddr *)&sin2, &sin2len) < 0 || >- sin2len != sizeof (sin2)) { >- perror("getsockname"); >- (void) close(s2); >- goto bad; >- } >- port = ntohs((u_short)sin2.sin_port); >- (void) sprintf(num, "%u", port); >- (void) write(s, num, strlen(num)+1); >- { int len = sizeof (from); >- s3 = accept(s2, (struct sockaddr *)&from, &len); >- close(s2); >- if (s3 < 0) { >- perror("accept"); >- port = 0; >- goto bad; >- } >- } >- *fd2p = s3; >- } >- (void) write(s, name, strlen(name) + 1); >- /* should public key encypt the password here */ >- (void) write(s, pass, strlen(pass) + 1); >- (void) write(s, cmd, strlen(cmd) + 1); >- if (read(s, &c, 1) != 1) { >- perror(*ahost); >- goto bad; >- } >- if (c != 0) { >- while (read(s, &c, 1) == 1) { >- (void) write(2, &c, 1); >- if (c == '\n') >- break; >- } >- goto bad; >- } >- return (s); >+ s = socket(AF_INET, SOCK_STREAM, 0); >+ if (s < 0) { >+ perror("rexec: socket"); >+ return -1; >+ } >+ sin.sin_family = hp->h_addrtype; >+ sin.sin_port = rport; >+ bcopy(hp->h_addr, (caddr_t)&sin.sin_addr, hp->h_length); >+ if (connect(s, (struct sockaddr *)&sin, sizeof(sin)) < 0) { >+ if (errno == ECONNREFUSED && timo <= 16) { >+ close(s); >+ sleep(timo); >+ timo *= 2; >+ goto retry; >+ } >+ perror(hp->h_name); >+ return -1; >+ } >+ if (fd2p == NULL) { >+ write(s, "", 1); >+ port = 0; >+ } else { >+ char num[8]; >+ int s2, sin2len; >+ >+ s2 = socket(AF_INET, SOCK_STREAM, 0); >+ if (s2 < 0) { >+ close(s); >+ return -1; >+ } >+ listen(s2, 1); >+ sin2len = sizeof (sin2); >+ if (getsockname(s2, (struct sockaddr *)&sin2, &sin2len) < 0 || >+ sin2len != sizeof (sin2)) { >+ perror("getsockname"); >+ close(s2); >+ goto bad; >+ } >+ port = ntohs((u_short)sin2.sin_port); >+ sprintf(num, "%u", port); >+ write(s, num, strlen(num)+1); >+ { int len = sizeof (from); >+ s3 = accept(s2, (struct sockaddr *)&from, &len); >+ close(s2); >+ if (s3 < 0) { >+ perror("accept"); >+ port = 0; >+ goto bad; >+ } >+ } >+ *fd2p = s3; >+ } >+ write(s, name, strlen(name) + 1); >+ /* should public key encypt the password here */ >+ write(s, pass, strlen(pass) + 1); >+ write(s, cmd, strlen(cmd) + 1); >+ if (read(s, &c, 1) != 1) { >+ perror(*ahost); >+ goto bad; >+ } >+ if (c != 0) { >+ while (read(s, &c, 1) == 1) { >+ write(2, &c, 1); >+ if (c == '\n') >+ break; >+ } >+ goto bad; >+ } >+ return s; > bad: >- if (port) >- (void) close(*fd2p); >- (void) close(s); >- return (-1); >+ if (port) >+ close(*fd2p); >+ close(s); >+ return -1; > }
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Diff
Attachments on
bug 83358
:
55119
| 55120