souza@telesoft.UUCP (Steve Souza @eldest) (11/24/87)
We've seen a strange symptom in a network software package that, until SunOS version 3.4 (on a Sun 160), functioned normally. The basic scenario is a server process that accepts network socket connection requests from a client process, executes a specified command, and sends the output back to the client process, not unlike the r-shell software. Under 3.4, huge pieces of /etc/group randomly appear in the output of the client process, often in a repeating pattern of usernames. Here are excerpts from the code [pardon the crudity of the i/o -- I'm still working on it!]: ----------------------------------------------------------------Server: write_output(s, cmd) int s; /* `s' is a socket of type AF_INET */ char *cmd; /* `cmd' is the command line */ { FILE *pp; char buf[BUFSIZ]; pp = popen(cmd, "r"); ... while (fgets(buf, BUFSIZ, pp) != NULL) if (write(s, buf, BUFSIZ) < 0) { pclose(pp); return(1<<8); } return(pclose(pp)); } ----------------------------------------------------------------Client: read_output() { /* `sock' is the other end of the AF_INET socket */ extern int sock; char obuf[BUFSIZ]; while (1) { if (read(sock, obuf, BUFSIZ) > 0) write(1, obuf, strlen(obuf)); else break; } } ----------------------------------------------------------------------- Anybody know of changes in 3.4 that might cause this? We don't run YP, BTW. Also, the server process calls initgroups(). Could that be related? Any suggestions would be m u c h appreciated... Thanks! Steve Souza ...sdcsvax!telesoft!souza TELESOFT Inc., San Diego, CA (619)457-2700 x277
chris@mimsy.UUCP (11/25/87)
In article <126@telesoft.UUCP> souza@telesoft.UUCP (Steve Souza @eldest) writes: > FILE *pp; > char buf[BUFSIZ]; > ... > while (fgets(buf, BUFSIZ, pp) != NULL) > if (write(s, buf, BUFSIZ) < 0) { > pclose(pp); > return(1<<8); > } > char obuf[BUFSIZ]; > > while (1) { > if (read(sock, obuf, BUFSIZ) > 0) > write(1, obuf, strlen(obuf)); > else > break; > } 0. fgets gets a NUL-terminated string, which may be < BUFSIZ bytes. Writing BUFSIZ bytes down `s' writes whatever other trash is in buf[]. 1. read returns a byte count, which you ignore. It does not guarantee that obuf will be NUL-terminated, yet you call strlen on obuf. 2. There is no guarantee that the read(sock) will always read exactly as many bytes as the write(s) wrote. It could read fewer; it could read more (although in this case it cannot, since writer writes BUFSIZ and reader reads BUFSIZ). 3. You neither check nor cast to void the return value from write(1). Clearly you have not used lint. Four bugs in 15 lines of code ... not bad. (Well, there were more lines in the original posting, but they had more bugs too.) -- In-Real-Life: Chris Torek, Univ of MD Comp Sci Dept (+1 301 454 7690) Domain: chris@mimsy.umd.edu Path: uunet!mimsy!chris