[sudo-workers] dead condition

Radovan Sroka rsroka at redhat.com
Tue Aug 18 06:17:58 MDT 2015


Hi,

I'm resolving some issues and I encountered a dead condition in plugins/sudoers/visudo.c.

Output of static analysis:

Error: DEADCODE (CWE-561): [#def67]
sudo-1.8.14p3/plugins/sudoers/visudo.c:444: cond_at_most: Condition "(nread = read(sp->fd, buf, 4096UL)) > 0L", taking false branch. Now the value of "nread" is at most 0.
sudo-1.8.14p3/plugins/sudoers/visudo.c:449: at_most: At condition "nread > 0L", the value of "nread" must be at most 0.
sudo-1.8.14p3/plugins/sudoers/visudo.c:449: dead_error_condition: The condition "nread > 0L" cannot be true.
sudo-1.8.14p3/plugins/sudoers/visudo.c:449: dead_error_line: Execution cannot reach the expression "buf[nread - 1L] != 10" inside this statement: "if (nread > 0L && buf[nread...".
#  447|   
#  448|   	    /* Add missing newline at EOF if needed. */
#  449|-> 	    if (nread > 0 && buf[nread - 1] != '\n') {
#  450|   		buf[0] = '\n';
#  451|   		if (write(tfd, buf, 1) != 1)


Code:

 if (sp->tpath == NULL) {
	if (asprintf(&sp->tpath, "%s.tmp", sp->path) == -1)
	    sudo_fatalx(U_("%s: %s"), __func__, U_("unable to allocate memory"));
	tfd = open(sp->tpath, O_WRONLY | O_CREAT | O_TRUNC, 0600);
	if (tfd < 0)
	    sudo_fatal("%s", sp->tpath);

	/* Copy sp->path -> sp->tpath and reset the mtime. */
	if (orig_size != 0) {
	    (void) lseek(sp->fd, (off_t)0, SEEK_SET);
	    while ((nread = read(sp->fd, buf, sizeof(buf))) > 0)
		if (write(tfd, buf, nread) != nread)
		    sudo_fatal(U_("write error"));

	    /* Add missing newline at EOF if needed. */
	    if (nread > 0 && buf[nread - 1] != '\n') {
		buf[0] = '\n';
		if (write(tfd, buf, 1) != 1)
		    sudo_fatal(U_("write error"));
	    }
	}
	(void) close(tfd);
}

I think when while ends then nread will be 0 or -1 and next "if" condition never execute.

Here is my patch:

  1 diff -up ./plugins/sudoers/visudo.c.fix ./plugins/sudoers/visudo.c
  2 --- ./plugins/sudoers/visudo.c.fix      2015-08-17 14:56:33.048310054 +0200
  3 +++ ./plugins/sudoers/visudo.c  2015-08-17 15:09:29.471611089 +0200
  4 @@ -440,13 +440,16 @@ edit_sudoers(struct sudoersfile *sp, cha
  5 
  6         /* Copy sp->path -> sp->tpath and reset the mtime. */
  7         if (orig_size != 0) {
  8 +           ssize_t last_valid_nread = 0;
  9             (void) lseek(sp->fd, (off_t)0, SEEK_SET);
 10 -           while ((nread = read(sp->fd, buf, sizeof(buf))) > 0)
 11 +           while ((nread = read(sp->fd, buf, sizeof(buf))) > 0) {
 12                 if (write(tfd, buf, nread) != nread)
 13                     sudo_fatal(U_("write error"));
 14 +               last_valid_nread = nread;
 15 +           }
 16 
 17             /* Add missing newline at EOF if needed. */
 18 -           if (nread > 0 && buf[nread - 1] != '\n') {
 19 +           if (last_valid_nread > 0 && buf[last_valid_nread - 1] != '\n') {
 20                 buf[0] = '\n';
 21                 if (write(tfd, buf, 1) != 1)
 22                     sudo_fatal(U_("write error"));


It's OK? or I missed something ?



Radovan Sroka
-------------- next part --------------
A non-text attachment was scrubbed...
Name: sudo-1.8.14p3-deadcode_visudo_c.patch
Type: text/x-patch
Size: 929 bytes
Desc: not available
URL: <http://www.sudo.ws/pipermail/sudo-workers/attachments/20150818/8ee110ea/attachment.bin>


More information about the sudo-workers mailing list