From stu@icecold.stu.ipng.org.uk  Wed Feb 26 16:06:42 2003
Return-Path: <stu@icecold.stu.ipng.org.uk>
Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125])
	by hub.freebsd.org (Postfix) with ESMTP id C5B3337B401
	for <FreeBSD-gnats-submit@freebsd.org>; Wed, 26 Feb 2003 16:06:42 -0800 (PST)
Received: from icecold.stu.ipng.org.uk (thegeekhouse.org [193.108.218.98])
	by mx1.FreeBSD.org (Postfix) with ESMTP id 210AF43FAF
	for <FreeBSD-gnats-submit@freebsd.org>; Wed, 26 Feb 2003 16:06:41 -0800 (PST)
	(envelope-from stu@icecold.stu.ipng.org.uk)
Received: from icecold.stu.ipng.org.uk (localhost.stu.ipng.org.uk [127.0.0.1])
	by icecold.stu.ipng.org.uk (8.12.6/8.12.6) with ESMTP id h1R06Zta000871;
	Thu, 27 Feb 2003 00:06:35 GMT
	(envelope-from stu@icecold.stu.ipng.org.uk)
Received: (from stu@localhost)
	by icecold.stu.ipng.org.uk (8.12.6/8.12.6/Submit) id h1R06Yew000870;
	Thu, 27 Feb 2003 00:06:34 GMT
Message-Id: <200302270006.h1R06Yew000870@icecold.stu.ipng.org.uk>
Date: Thu, 27 Feb 2003 00:06:34 GMT
From: Stuart Walsh <stu@ipng.org.uk>
Reply-To: Stuart Walsh <s.walsh@student.umist.ac.uk>
To: FreeBSD-gnats-submit@freebsd.org
Cc:
Subject: burncd does not handle signals and causes damage
X-Send-Pr-Version: 3.113
X-GNATS-Notify:

>Number:         48730
>Category:       bin
>Synopsis:       [patch] burncd(8) does not handle signals and causes damage
>Confidential:   no
>Severity:       serious
>Priority:       high
>Responsible:    obrien
>State:          closed
>Quarter:        
>Keywords:       
>Date-Required:  
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Wed Feb 26 16:10:12 PST 2003
>Closed-Date:    Tue Aug 24 20:54:31 UTC 2010
>Last-Modified:  Tue Aug 24 20:54:31 UTC 2010
>Originator:     Stuart Walsh
>Release:        FreeBSD 5.0-RELEASE-p1 i386
>Organization:
IPng-UK
>Environment:
System: FreeBSD icecold.stu.ipng.org.uk 5.0-RELEASE-p1 FreeBSD 5.0-RELEASE-p1 #2: Fri Feb 14 00:45:07 GMT 2003 root@icecold.stu.ipng.org.uk:/usr/obj/usr/src/sys/ICECOLD i386

Machine is an AMD XP2000+ with a LITE-ON 40x12x48 CDRW, see below for dmesg output:

acd0: CD-RW <LITE-ON LTR-40125S> at ata1-slave PIO4

>Description:
	burncd does _not_ behave sanely to signals and can damage cd writers.
	If one ctrl-c's burncd mid write, for whatever reason, it just exits
        without either completing its task or even powering down the cd writer.
        With my cd writer(I assume because of BURN-Proof) the writer stays
        powered up spinning at full speed with the yellow(waiting for data) 
        LED illuminated.  Since this incident, my cd writer has failed to write
        to any CD since, even under other applications and in other environments
        and has had to be replaced under warrenty.
>How-To-Repeat:
        Prepare a cd for writing in the normal way and hit ctrl-c mid write.
>Fix:
        Add some signal handling to shut down the writer on an exit signal!
>Release-Note:
>Audit-Trail:
Responsible-Changed-From-To: freebsd-bugs->sos 
Responsible-Changed-By: kris 
Responsible-Changed-When: Sat Jul 12 23:44:07 PDT 2003 
Responsible-Changed-Why:  
Assign to the burncd maintainer 

http://www.freebsd.org/cgi/query-pr.cgi?pr=48730 

From: Jaakko Heinonen <jh@saunalahti.fi>
To: bug-followup@FreeBSD.org, s.walsh@student.umist.ac.uk
Cc:  
Subject: Re: bin/48730: burncd does not handle signals and causes damage
Date: Sun, 17 Feb 2008 12:01:35 +0200

 --mP3DRpeJDSE+ciuQ
 Content-Type: text/plain; charset=us-ascii
 Content-Disposition: inline
 
 
 Following patch implements signal handling for burncd. It does
 CDRIOCFLUSH ioctl to leave burner sane state when burning is
 interrupted.
 
 Blanking (and probably fixating) will still continue after interrupt but
 AFAIK blanking still finishes correctly. Another approach would be to
 completely ignore signals.
 
 -- 
 Jaakko
 
 --mP3DRpeJDSE+ciuQ
 Content-Type: text/x-diff; charset=us-ascii
 Content-Disposition: attachment; filename="burncd-signal-handling.diff"
 
 Index: burncd.c
 ===================================================================
 RCS file: /home/ncvs/src/usr.sbin/burncd/burncd.c,v
 retrieving revision 1.45
 diff -p -u -r1.45 burncd.c
 --- burncd.c	13 May 2005 20:06:44 -0000	1.45
 +++ burncd.c	17 Feb 2008 09:31:54 -0000
 @@ -36,6 +36,7 @@
  #include <err.h>
  #include <sysexits.h>
  #include <fcntl.h>
 +#include <signal.h>
  #include <sys/errno.h>
  #include <sys/ioctl.h>
  #include <sys/stat.h>
 @@ -67,6 +68,7 @@ int write_file(int fd, struct track_info
  int roundup_blocks(struct track_info *);
  void cue_ent(struct cdr_cue_entry *, int, int, int, int, int, int, int);
  void cleanup(int);
 +void signal_cleanup(int);
  void usage(void);
  
  int
 @@ -157,6 +159,9 @@ main(int argc, char **argv)
  
  	global_fd_for_cleanup = fd;
  	err_set_exit(cleanup);
 +	signal(SIGHUP, signal_cleanup);
 +	signal(SIGINT, signal_cleanup);
 +	signal(SIGTERM, signal_cleanup);
  
  	for (arg = 0; arg < argc; arg++) {
  		if (!strcasecmp(argv[arg], "fixate")) {
 @@ -319,6 +324,10 @@ main(int argc, char **argv)
  	if (eject)
  		if (ioctl(fd, CDIOCEJECT) < 0)
  			err(EX_IOERR, "ioctl(CDIOCEJECT)");
 +
 +	signal(SIGHUP, SIG_DFL);
 +	signal(SIGINT, SIG_DFL);
 +	signal(SIGTERM, SIG_DFL);
  	close(fd);
  	exit(EX_OK);
  }
 @@ -690,6 +699,15 @@ cleanup(int dummy __unused)
  	if (ioctl(global_fd_for_cleanup, CDRIOCSETBLOCKSIZE,
  	    &saved_block_size) < 0)
  		err(EX_IOERR, "ioctl(CDRIOCSETBLOCKSIZE)");
 +}
 +
 +void
 +signal_cleanup(int sig __unused)
 +{
 +	if (ioctl(global_fd_for_cleanup, CDRIOCFLUSH) < 0)
 +		err(EX_IOERR, "ioctl(CDRIOCFLUSH)");
 +	fprintf(stderr, "\n");
 +	errx(EXIT_FAILURE, "Aborted");
  }
  
  void
 
 --mP3DRpeJDSE+ciuQ--

From: Jaakko Heinonen <jh@saunalahti.fi>
To: bug-followup@FreeBSD.org
Cc:  
Subject: bin/48730: burncd does not handle signals and causes damage
Date: Thu, 3 Apr 2008 15:22:23 +0300

 --a8Wt8u1KmwUX3Y2C
 Content-Type: text/plain; charset=us-ascii
 Content-Disposition: inline
 
 
 Attach the updated patch also to this PR so that the patch won't get
 lost.
 
 ----- Forwarded message from Jaakko Heinonen <jh@saunalahti.fi> -----
 
 Date: Tue, 4 Mar 2008 14:53:03 +0200
 From: Jaakko Heinonen <jh@saunalahti.fi>
 To: sos@FreeBSD.org, freebsd-current@freebsd.org
 Subject: [patch] burncd(8) signal and error handling improvements
 User-Agent: Mutt/1.5.17 (2007-11-01)
 
 
 Hi,
 
 burncd(8) doesn't handle signals and interrupting burncd during
 operation for example with SIGINT (^C) may leave the drive spinning and
 locked. This may happen also if you try to write a too large image to a
 disc and burncd(8) exits with an I/O error.
 
 Attached patch implements signal handling for burncd(8). It does
 CDRIOCFLUSH ioctl to attempt leave burner sane state when burning is
 interrupted with SIGHUP, SIGINT, SIGTERM or in case an I/O error occurs
 during write. Blanking will still continue after interrupt but it seems
 to finish correctly even after burncd(8) has quit.
 
 Relevant PR is bin/48730 which has an older version of the patch.
 
 -- 
 Jaakko
 
 --a8Wt8u1KmwUX3Y2C
 Content-Type: text/x-diff; charset=us-ascii
 Content-Disposition: attachment; filename="burncd-signal-handling.diff"
 
 Index: burncd.c
 ===================================================================
 RCS file: /home/ncvs/src/usr.sbin/burncd/burncd.c,v
 retrieving revision 1.45
 diff -p -u -r1.45 burncd.c
 --- burncd.c	13 May 2005 20:06:44 -0000	1.45
 +++ burncd.c	3 Mar 2008 10:16:48 -0000
 @@ -36,6 +36,7 @@
  #include <err.h>
  #include <sysexits.h>
  #include <fcntl.h>
 +#include <signal.h>
  #include <sys/errno.h>
  #include <sys/ioctl.h>
  #include <sys/stat.h>
 @@ -67,6 +68,8 @@ int write_file(int fd, struct track_info
  int roundup_blocks(struct track_info *);
  void cue_ent(struct cdr_cue_entry *, int, int, int, int, int, int, int);
  void cleanup(int);
 +void cleanup_flush(void);
 +void cleanup_signal(int);
  void usage(void);
  
  int
 @@ -157,6 +160,9 @@ main(int argc, char **argv)
  
  	global_fd_for_cleanup = fd;
  	err_set_exit(cleanup);
 +	signal(SIGHUP, cleanup_signal);
 +	signal(SIGINT, cleanup_signal);
 +	signal(SIGTERM, cleanup_signal);
  
  	for (arg = 0; arg < argc; arg++) {
  		if (!strcasecmp(argv[arg], "fixate")) {
 @@ -319,6 +325,10 @@ main(int argc, char **argv)
  	if (eject)
  		if (ioctl(fd, CDIOCEJECT) < 0)
  			err(EX_IOERR, "ioctl(CDIOCEJECT)");
 +
 +	signal(SIGHUP, SIG_DFL);
 +	signal(SIGINT, SIG_DFL);
 +	signal(SIGTERM, SIG_DFL);
  	close(fd);
  	exit(EX_OK);
  }
 @@ -469,8 +479,10 @@ do_DAO(int fd, int test_write, int multi
  		err(EX_IOERR, "ioctl(CDRIOCSENDCUE)");
  
  	for (i = 0; i < notracks; i++) {
 -		if (write_file(fd, &tracks[i]))
 +		if (write_file(fd, &tracks[i])) {
 +			cleanup_flush();
  			err(EX_IOERR, "write_file");
 +		}
  	}
  
  	ioctl(fd, CDRIOCFLUSH);
 @@ -499,8 +511,10 @@ do_TAO(int fd, int test_write, int preem
  		if (!quiet)
  			fprintf(stderr, "next writeable LBA %d\n",
  				tracks[i].addr);
 -		if (write_file(fd, &tracks[i]))
 +		if (write_file(fd, &tracks[i])) {
 +			cleanup_flush();
  			err(EX_IOERR, "write_file");
 +		}
  		if (ioctl(fd, CDRIOCFLUSH) < 0)
  			err(EX_IOERR, "ioctl(CDRIOCFLUSH)");
  	}
 @@ -630,9 +644,11 @@ write_file(int fd, struct track_info *tr
  				track_info->block_size;
  		}
  		if ((res = write(fd, buf, count)) != count) {
 -			if (res == -1)
 -				fprintf(stderr, "\n%s\n", strerror(errno));
 -			else
 +			if (res == -1) {
 +				fprintf(stderr, "\n");
 +				close(track_info->file);
 +				return errno;
 +			} else
  				fprintf(stderr, "\nonly wrote %d of %jd"
  				    " bytes\n", res, (intmax_t)count);
  			break;
 @@ -690,6 +706,21 @@ cleanup(int dummy __unused)
  	if (ioctl(global_fd_for_cleanup, CDRIOCSETBLOCKSIZE,
  	    &saved_block_size) < 0)
  		err(EX_IOERR, "ioctl(CDRIOCSETBLOCKSIZE)");
 +}
 +
 +void
 +cleanup_flush(void)
 +{
 +	if (ioctl(global_fd_for_cleanup, CDRIOCFLUSH) < 0)
 +		err(EX_IOERR, "ioctl(CDRIOCFLUSH)");
 +}
 +
 +void
 +cleanup_signal(int sig __unused)
 +{
 +	cleanup_flush();
 +	fprintf(stderr, "\n");
 +	errx(EXIT_FAILURE, "Aborted");
  }
  
  void
 
 --a8Wt8u1KmwUX3Y2C--

From: Jaakko Heinonen <jh@saunalahti.fi>
To: bug-followup@FreeBSD.org
Cc:  
Subject: Re: bin/48730: burncd does not handle signals and causes damage
Date: Tue, 7 Oct 2008 18:38:20 +0300

 --uZ3hkaAS1mZxFaxD
 Content-Type: text/plain; charset=us-ascii
 Content-Disposition: inline
 
 
 Here is an updated patch which uses only safe functions in the signal
 handler. Previous patch used potentially unsafe fprintf(), errx()/err()
 and exit() in the signal handler.
 
 -- 
 Jaakko
 
 --uZ3hkaAS1mZxFaxD
 Content-Type: text/x-diff; charset=us-ascii
 Content-Disposition: attachment; filename="burncd-signal-handling.diff"
 
 PR: bin/48730
 
 Index: usr.sbin/burncd/burncd.c
 ===================================================================
 --- usr.sbin/burncd/burncd.c	(revision 182545)
 +++ usr.sbin/burncd/burncd.c	(working copy)
 @@ -36,6 +36,7 @@
  #include <err.h>
  #include <sysexits.h>
  #include <fcntl.h>
 +#include <signal.h>
  #include <sys/errno.h>
  #include <sys/ioctl.h>
  #include <sys/stat.h>
 @@ -67,6 +68,8 @@ int write_file(int fd, struct track_info
  int roundup_blocks(struct track_info *);
  void cue_ent(struct cdr_cue_entry *, int, int, int, int, int, int, int);
  void cleanup(int);
 +void cleanup_flush(void);
 +void cleanup_signal(int);
  void usage(void);
  
  int
 @@ -157,6 +160,9 @@ main(int argc, char **argv)
  
  	global_fd_for_cleanup = fd;
  	err_set_exit(cleanup);
 +	signal(SIGHUP, cleanup_signal);
 +	signal(SIGINT, cleanup_signal);
 +	signal(SIGTERM, cleanup_signal);
  
  	for (arg = 0; arg < argc; arg++) {
  		if (!strcasecmp(argv[arg], "fixate")) {
 @@ -319,6 +325,10 @@ main(int argc, char **argv)
  	if (eject)
  		if (ioctl(fd, CDIOCEJECT) < 0)
  			err(EX_IOERR, "ioctl(CDIOCEJECT)");
 +
 +	signal(SIGHUP, SIG_DFL);
 +	signal(SIGINT, SIG_DFL);
 +	signal(SIGTERM, SIG_DFL);
  	close(fd);
  	exit(EX_OK);
  }
 @@ -469,8 +479,10 @@ do_DAO(int fd, int test_write, int multi
  		err(EX_IOERR, "ioctl(CDRIOCSENDCUE)");
  
  	for (i = 0; i < notracks; i++) {
 -		if (write_file(fd, &tracks[i]))
 +		if (write_file(fd, &tracks[i])) {
 +			cleanup_flush();
  			err(EX_IOERR, "write_file");
 +		}
  	}
  
  	ioctl(fd, CDRIOCFLUSH);
 @@ -499,8 +511,10 @@ do_TAO(int fd, int test_write, int preem
  		if (!quiet)
  			fprintf(stderr, "next writeable LBA %d\n",
  				tracks[i].addr);
 -		if (write_file(fd, &tracks[i]))
 +		if (write_file(fd, &tracks[i])) {
 +			cleanup_flush();
  			err(EX_IOERR, "write_file");
 +		}
  		if (ioctl(fd, CDRIOCFLUSH) < 0)
  			err(EX_IOERR, "ioctl(CDRIOCFLUSH)");
  	}
 @@ -630,9 +644,11 @@ write_file(int fd, struct track_info *tr
  				track_info->block_size;
  		}
  		if ((res = write(fd, buf, count)) != count) {
 -			if (res == -1)
 -				fprintf(stderr, "\n%s\n", strerror(errno));
 -			else
 +			if (res == -1) {
 +				fprintf(stderr, "\n");
 +				close(track_info->file);
 +				return errno;
 +			} else
  				fprintf(stderr, "\nonly wrote %d of %jd"
  				    " bytes\n", res, (intmax_t)count);
  			break;
 @@ -693,6 +709,22 @@ cleanup(int dummy __unused)
  }
  
  void
 +cleanup_flush(void)
 +{
 +	if (ioctl(global_fd_for_cleanup, CDRIOCFLUSH) < 0)
 +		err(EX_IOERR, "ioctl(CDRIOCFLUSH)");
 +}
 +
 +void
 +cleanup_signal(int sig)
 +{
 +	signal(sig, SIG_IGN);
 +	ioctl(global_fd_for_cleanup, CDRIOCFLUSH);
 +	write(STDERR_FILENO, "\nAborted\n", 10);
 +	_exit(EXIT_FAILURE);
 +}
 +
 +void
  usage(void)
  {
  	fprintf(stderr,
 
 --uZ3hkaAS1mZxFaxD--
State-Changed-From-To: open->patched  
State-Changed-By: brucec 
State-Changed-When: Tue Dec 30 14:34:19 UTC 2008 
State-Changed-Why:  
A fix has been committed to HEAD. 

http://www.freebsd.org/cgi/query-pr.cgi?pr=48730 
Responsible-Changed-From-To: sos->obrien 
Responsible-Changed-By: linimon 
Responsible-Changed-When: Mon May 11 21:46:31 UTC 2009 
Responsible-Changed-Why:  
Over to committer as MFC reminder. 

http://www.freebsd.org/cgi/query-pr.cgi?pr=48730 

From: Alexander Best <alexbestms@math.uni-muenster.de>
To: <bug-followup@FreeBSD.org>
Cc:  
Subject: Re: bin/48730: [patch] burncd(8) does not handle signals and causes
 damage
Date: Sun, 08 Nov 2009 02:23:15 +0100 (CET)

 changes have been mfc'ed to 8-stable (r186337/r186444/186784) and 7-stable
 (190356). not in 6-stable yet.
 
 alex
State-Changed-From-To: patched->closed 
State-Changed-By: arundel 
State-Changed-When: Tue Aug 24 20:21:43 UTC 2010 
State-Changed-Why:  
RELENG_6 will go EoL soon. No need to keep this open any longer since it's 
highly unlikely that this will get fixed until November 30, 2010. 

http://www.freebsd.org/cgi/query-pr.cgi?pr=48730 
>Unformatted:
