Disallowed emulated drives for superuser, allowed stdio:/dev/null for all

This commit is contained in:
Thomas Schmitt 2007-09-27 08:34:26 +00:00
parent ff9715aa78
commit 06ec817caa
5 changed files with 143 additions and 59 deletions

View File

@ -347,6 +347,9 @@ permissions.
Addresses of emulated drives begin with prefix "stdio:". E.g.
dev=stdio:/tmp/my_pseudo_drive
For safety reasons the superuser is only allowed to use /dev/null as emulated
drive. See man page section FILES for a way to lift that ban.
------------------------------------------------------------------------------

View File

@ -31,7 +31,7 @@ via libburn.
\fBcdrskin\fP is a program that provides some of cdrecord's options
in a compatible way for CD media. With DVD it has its own ways.
You do not need to be superuser for its daily usage.
.PP
.SS
.B Overview of features:
.br
Blanking of CD-RW and DVD-RW.
@ -57,7 +57,7 @@ or on data file or block device.
Bus scan, burnfree, speed options, retrieving media info, padding, fifo.
.br
See section EXAMPLES at the end of this text.
.PP
.SS
.B General information paragraphs:
.br
Track recording model
@ -71,7 +71,9 @@ Sequentially Recordable DVD Media
Overwriteable DVD Media
.br
Drive preparation and addressing
.PP
.br
Emulated drives
.SS
.B Track recording model:
.br
The input-output entities which get processed are called tracks.
@ -113,7 +115,7 @@ Another type of data track content are archive formats which originally
have been developed for magnetic tapes. Only formats which mark a detectable
end-of-archive in their data are suitable, though. Well tested are
the archivers afio and star. Not suitable seems GNU tar.
.PP
.SS
.B Write mode selection:
.br
In general there are two approaches for writing media:
@ -136,7 +138,7 @@ the capabilities of the drive and the state of the present media.
So the mentioning of write modes in the following paragraphs and in the
examples is not so much a demand that the user shall choose one explicitely,
but rather an illustration of what to expect with particular media types.
.PP
.SS
.B Recordable CD Media:
.br
CD-R can be initially written only once and eventually extended until they
@ -158,7 +160,7 @@ is the appropriate option.
Blanking damages the previous content but does not
make it completely unreadable. It is no effective privacy precaution.
Multiple cycles of blanking and overwriting with random numbers might be.
.PP
.SS
.B Sequentially Recordable DVD Media:
.br
Currently DVD-RW, DVD-R and DVD+R can be used for the Sequential recording
@ -208,7 +210,7 @@ allows appendable media.
Option -multi might make DVD media unreadable in some DVD-ROM drives.
Best reader compatibility is achieved without it
(i.e. by single session media).
.PP
.SS
.B Overwriteable DVD Media:
.br
Currently types DVD+RW, DVD-RW and DVD-RAM can be overwritten via cdrskin.
@ -237,7 +239,7 @@ can be done by option
Several programs like dvd+rw-format, cdrecord, wodim, or cdrskin
can bring a DVD-RW out of overwriteable state so
that it has to be formatted again. If in doubt, just give it a try.
.PP
.SS
.B Drive preparation and addressing:
.br
The drives, either CD burners or DVD burners, are accessed via addresses which
@ -273,7 +275,9 @@ Further are accepted on Linux: links to libburn-suitable device files,
device files which have the same major and minor device number,
and device files which have the same SCSI address parameters (e.g. /dev/sg0).
.br
.PP
.SS
.B Emulated drives:
.br
Option --allow_emulated_drives enables addressing of pseudo-drives
which get emulated on top of filesystem objects. Regular data files and
block devices result in pseudo-drives which behave much like DVD-RAM.
@ -285,12 +289,6 @@ The target file address is given after prefix "stdio:".
.br
E.g.: dev=stdio:/tmp/my_pseudo_drive
.br
Note: --allow_emulated_drives will not work if cdrskin has changed user
identity via the setuid bit of its access permissions.
.br
Warning: Superusers must take care not to spoil their hard disk via its raw
block device (like /dev/hda or /dev/sd0).
.br
Addresses of the form "stdio:/dev/fd/<number>" are treated special. The
number is read literally and used as open file descriptor. With
dev="stdio:/dev/fd/1" the normal standard output of the program is
@ -299,7 +297,15 @@ redirected to stderr and the stream data of a burn run will appear on stdout.
Not good for terminals ! Redirect it.
.br
Pseudo-drives allow -dummy. Their reply with --tell_media_space can be utopic.
Note: -dummy burn runs touch the file but do not modify its data content.
-dummy burn runs touch the file but do not modify its data content.
.br
Note: --allow_emulated_drives is restricted to stdio:/dev/null if cdrskin
is run by the
.B superuser
or if it has changed user identity via the
.B setuid
bit of its access permissions. The ban for the superuser can be lifted by a
skillfully created file. See section FILES below.
.br
.SH OPTIONS
.TP
@ -1154,6 +1160,9 @@ cdrskin -v dev=ATA:1,0,0 speed=48 -sao \\
track1.wav track2.au -audio -swab track3.raw
.br
.SH FILES
.SS
Startup files:
.br
If not --no_rc is given as the first argument then cdrskin attempts on
startup to read the arguments from the following files:
.PP
@ -1171,23 +1180,32 @@ The files are read in the sequence given above, but none of them is
required for cdrskin to function properly. Each readable line is treated
as one single argument. No extra blanks.
A first character '#' marks a comment, empty lines are ignored.
.SS
.B Example content of a startup file:
.br
Example content of a startup file:
.br
# This is the default device
.br
dev=0,1,0
.br
# To accomodate to remnant cdrskin-0.2.2 addresses
.br
dev_translation=+1,0,0+0,1,0
.br
# Some more options
.br
fifo_start_at=0
.br
fs=16m
.br
.SS
Disabling superuser safety precautions:
The superuser is normally banned from using any other emulated drive but
/dev/null. This ban can be lifted by the existence of file
.PP
.B /root/cdrskin_permissions/allow_emulated_drives
.PP
where the directory must be owned by the superuser and must not offer
w-permissions for group or others.
.br
Warning: Superusers must take care not to spoil their hard disk via its raw
block device (like stdio:/dev/hda or stdio:/dev/sd0).
.SH SEE ALSO
.TP
Formatting data track sources for cdrskin:

View File

@ -845,10 +845,10 @@ struct CdrtracK {
/** Eventually detected data image size */
double data_image_size;
char *iso_fs_descr; /* eventually block 16 to 31 of input during detection */
/** Wether to demand a detected data image size and use it (or else abort) */
/** Whether to demand a detected data image size and use it (or else abort) */
int use_data_image_size; /* 0=no, 1=size not defined yet, 2=size defined */
/* wether the data source is a container of defined size with possible tail */
/* Whether the data source is a container of defined size with possible tail*/
int extracting_container;
/** Optional fifo between input fd and libburn. It uses a pipe(2) to transfer
@ -1056,7 +1056,7 @@ int Cdrtrack_get_fifo(struct CdrtracK *track, struct CdrfifO **fifo, int flag)
}
/** Try wether automatic audio extraction is appropriate and eventually open
/** Try whether automatic audio extraction is appropriate and eventually open
a file descriptor to the raw data.
@return -3 identified as .wav but with cdrecord-inappropriate parameters
-2 could not open track source, no use in retrying
@ -1661,7 +1661,7 @@ struct CdrpreskiN {
char queue_severity[81];
char print_severity[81];
/** Wether to wait for available standard input data before touching drives */
/** Whether to wait for available standard input data before touching drives*/
int do_waiti;
/** Stores eventually given absolute device address before translation */
@ -1686,41 +1686,44 @@ struct CdrpreskiN {
*/
int abort_handler;
/** Wether to allow getuid()!=geteuid() */
/** Whether to allow getuid()!=geteuid() */
int allow_setuid;
/** Wether to allow user provided addresses like #4 */
/** Whether to allow user provided addresses like #4 */
int allow_fd_source;
/** Wether to support media types which are implemented but yet untested */
/** Whether to support media types which are implemented but yet untested */
int allow_untested_media;
/** Wether to allow libburn pseudo-drives "stdio:<path>" */
/** Whether to allow libburn pseudo-drives "stdio:<path>" .
0=forbidden, 1=seems ok,
2=potentially forbidden (depends on uid, euid, file type)
*/
int allow_emulated_drives;
/** Wether an option is given which needs a full bus scan */
/** Whether an option is given which needs a full bus scan */
int no_whitelist;
/** Wether the translated device address shall not follow softlinks, device
/** Whether the translated device address shall not follow softlinks, device
clones and SCSI addresses */
int no_convert_fs_adr;
/** Wether Bus,Target,Lun addresses shall be converted literally as old
/** Whether Bus,Target,Lun addresses shall be converted literally as old
Pseudo SCSI-Adresses. New default is to use (possibly system emulated)
real SCSI addresses via burn_drive_convert_scsi_adr() and literally
emulated and cdrecord-incompatible ATA: addresses. */
int old_pseudo_scsi_adr;
/** Wether bus scans shall exit!=0 if no drive was found */
/** Whether bus scans shall exit!=0 if no drive was found */
int scan_demands_drive;
/** Wether to abort when a busy drive is encountered during bus scan */
/** Whether to abort when a busy drive is encountered during bus scan */
int abort_on_busy_drive;
/** Linux specific : Wether to try to avoid collisions when opening drives */
/** Linux specific : Whether to try to avoid collisions when opening drives */
int drive_exclusive;
/** Linux specific : Wether to obtain an exclusive drive lock via fcntl() */
/** Linux specific : Whether to obtain an exclusive drive lock via fcntl() */
int drive_fcntl_f_setlk;
/** Linux specific : Device file address family to use :
@ -1728,7 +1731,7 @@ struct CdrpreskiN {
int drive_scsi_dev_family;
/** Wether to try to wait for unwilling drives to become willing to open */
/** Whether to try to wait for unwilling drives to become willing to open */
int drive_blocking;
/** Explicit write mode option is determined before skin processes
@ -1946,6 +1949,52 @@ int Cdrpreskin_queue_msgs(struct CdrpreskiN *o, int flag)
}
/** Evaluate whether the user would be allowed in any case to use device_adr
as pseudo-drive */
int Cdrpreskin__allows_emulated_drives(char *device_adr, char reason[4096],
int flag)
{
struct stat stbuf;
reason[0]= 0;
if(device_adr[0]) {
if(strcmp(device_adr,"/dev/null")==0)
return(1);
strcat(reason,"File object is not /dev/null. ");
}
if(getuid()!=geteuid()) {
strcat(reason,"UID and EUID differ");
return(0);
}
if(getuid()!=0)
return(1);
strcat(reason,"UID is 0. ");
/* Directory must be owned by root and write protected against any others*/
if(lstat("/root/cdrskin_permissions",&stbuf)==-1 || !S_ISDIR(stbuf.st_mode)) {
strcat(reason, "No directory /root/cdrskin_permissions exists");
return(0);
}
if(stbuf.st_uid!=0) {
strcat(reason, "Directory /root/cdrskin_permissions not owned by UID 0");
return(0);
}
if(stbuf.st_mode & (S_IWGRP | S_IWOTH)) {
strcat(reason,
"Directory /root/cdrskin_permissions has w-permission for group or others");
return(0);
}
if(stat("/root/cdrskin_permissions/allow_emulated_drives",&stbuf)==-1) {
strcat(reason,
"No file /root/cdrskin_permissions/allow_emulated_drives exists");
return(0);
}
reason[0]= 0;
return(1);
}
int Cdrpreskin_consider_normal_user(int flag)
{
fprintf(stderr,
@ -2177,7 +2226,7 @@ return:
*/
{
int i,ret;
char *value_pt;
char *value_pt, reason[4096];
#ifndef Cdrskin_extra_leaN
if(argc>1) {
@ -2220,10 +2269,12 @@ return:
o->abort_handler= 3;
} else if(strcmp(argv[i],"--allow_emulated_drives")==0) {
if(getuid()!=geteuid()) {
if(Cdrpreskin__allows_emulated_drives("",reason,0)<=0) {
fprintf(stderr,"cdrskin: WARNING : %s.\n",reason);
fprintf(stderr,
"cdrskin: SORRY : uid and euid differ. Will not --allow_emulated_drives\n");
"cdrskin: WARNING : Only /dev/null will be available with \"stdio:\".\n");
Cdrpreskin_consider_normal_user(0);
o->allow_emulated_drives= 2;
} else
o->allow_emulated_drives= 1;
@ -2360,15 +2411,18 @@ set_dev:;
}
if(o->allow_emulated_drives) {
fprintf(stderr,"\nTransport name:\t\tlibburn on standard i/o\n");
fprintf(stderr,
"Transport descr.:\twrite into data files and block devices\n");
if(o->allow_emulated_drives==2)
fprintf(stderr, "Transport descr.:\troot or setuid may only write into /dev/null\n");
else
fprintf(stderr, "Transport descr.:\twrite into file objects\n");
fprintf(stderr,"Transp. layer ind.:\tstdio:\n");
fprintf(stderr,"Target specifier:\tpath\n");
fprintf(stderr,"Target example:\t\tstdio:/tmp/pseudo_drive\n");
fprintf(stderr,"SCSI Bus scanning:\tnot supported\n");
fprintf(stderr,"Open via UNIX device:\tsupported\n");
} else {
printf("\ncdrskin: NOTE : Option --allow_emulated_drives would allow dev=stdio:<path>\n");
if(Cdrpreskin__allows_emulated_drives("",reason,0)>0)
printf("\ncdrskin: NOTE : Option --allow_emulated_drives would allow dev=stdio:<path>\n");
}
#else /* ! Cdrskin_extra_leaN */
@ -2450,8 +2504,7 @@ set_dev:;
printf(
" --adjust_speed_to_drive set only speeds offered by drive and media\n");
#endif
printf(
" --allow_emulated_drives dev=stdio:<path> on files and block devices\n");
printf(" --allow_emulated_drives dev=stdio:<path> on file objects\n");
printf(
" --allow_setuid disable setuid warning (setuid is insecure !)\n");
printf(
@ -3031,7 +3084,7 @@ struct CdrskiN {
char device_adr[Cdrskin_adrleN];
/** Progress state info: wether libburn is actually processing payload data */
/** Progress state info: whether libburn is actually processing payload data*/
int is_writing;
/** Previously detected drive state */
enum burn_drive_status previous_drive_status;
@ -3043,7 +3096,7 @@ struct CdrskiN {
int lib_is_initialized;
pid_t control_pid; /* pid of the thread that calls libburn */
int drive_is_grabbed;
int drive_is_busy; /* Wether drive was told to do something cancel-worthy */
int drive_is_busy; /* Whether drive was told to do something cancel-worthy */
struct burn_drive *grabbed_drive;
#ifndef Cdrskin_extra_leaN
@ -3981,7 +4034,7 @@ adr_translation:;
/* user defined address translation */
if(!(flag&1)) {
if(ret>0) {
/* try wether a translation points to loc */
/* try whether a translation points to loc */
hret= Cdradrtrn_translate(skin->adr_trn,loc,driveno,buf,1);
if(hret==2) {
still_untranslated= 0;
@ -5292,7 +5345,7 @@ ex:;
#ifdef Cdrskin_libburn_write_mode_ruleS
/** After everything else about burn_write_opts and burn_disc is set up, this
call determines the effective write mode and checks wether the drive
call determines the effective write mode and checks whether the drive
promises to support it.
*/
int Cdrskin_activate_write_mode(struct CdrskiN *skin,
@ -5367,7 +5420,7 @@ report_failure:;
#else /* Cdrskin_libburn_write_mode_ruleS */
/** Determines the effective write mode and checks wether the drive promises
/** Determines the effective write mode and checks whether the drive promises
to support it.
@param s state of target media, obtained from burn_disc_get_status(),
submit BURN_DISC_BLANK if no real state is available
@ -5473,7 +5526,7 @@ int Cdrskin_activate_write_mode(struct CdrskiN *skin, enum burn_disc_status s,
skin->block_type= BURN_BLOCK_SAO;
}
/* check wether desired type combination is available with drive */
/* check whether desired type combination is available with drive */
if(skin->driveno<0 || skin->driveno>skin->n_drives) {
if(skin->verbosity>=Cdrskin_verbose_debuG)
ClN(printf("cdrskin_debug: WARNING : No drive selected with Cdrskin_activate_write_mode\n"));
@ -7518,7 +7571,7 @@ ignore_unknown:;
/** Initialize libburn, create a CdrskiN program run control object,
set eventual device whitelist, and obtain the list of available drives.
@param o Returns the CdrskiN object created
@param lib_initialized Returns wether libburn was initialized here
@param lib_initialized Returns whether libburn was initialized here
@param exit_value Returns after error the proposal for an exit value
@param flag Unused yet
@return <=0 error, 1 success
@ -7528,6 +7581,7 @@ int Cdrskin_create(struct CdrskiN **o, struct CdrpreskiN **preskin,
{
int ret, stdio_drive= 0;
struct CdrskiN *skin;
char reason[4096];
*o= NULL;
*exit_value= 0;
@ -7538,15 +7592,23 @@ int Cdrskin_create(struct CdrskiN **o, struct CdrpreskiN **preskin,
(*preskin)->device_adr));
burn_drive_add_whitelist((*preskin)->device_adr);
if(strncmp((*preskin)->device_adr, "stdio:", 6)==0) {
if((*preskin)->allow_emulated_drives) {
ret= Cdrpreskin__allows_emulated_drives((*preskin)->device_adr+6,reason,0);
if((*preskin)->allow_emulated_drives && ret>0) {
stdio_drive= 1;
(*preskin)->demands_cdrskin_caps= 1;
} else if((*preskin)->allow_emulated_drives) {
fprintf(stderr,"cdrskin: SORRY : dev=stdio:... rejected despite --allow_emulated_drives\n");
fprintf(stderr,"cdrskin: SORRY : Reason: %s.\n", reason);
} else {
fprintf(stderr,"cdrskin: SORRY : dev=stdio:... works only with option --allow_emulated_drives\n");
if(getuid()!=geteuid()) {
fprintf(stderr,"cdrskin: SORRY : but uid and euid differ. So this option will be rejected.\n");
Cdrpreskin_consider_normal_user(0);
if(ret<=0) {
fprintf(stderr,"cdrskin: SORRY : but: %s.\n", reason);
fprintf(stderr,
"cdrskin: SORRY : So this option would not help anyway.\n");
}
}
if(!stdio_drive) {
Cdrpreskin_consider_normal_user(0);
{*exit_value= 2; goto ex;}
}
}

View File

@ -1 +1 @@
#define Cdrskin_timestamP "2007.09.26.173840"
#define Cdrskin_timestamP "2007.09.27.083351"

View File

@ -54,9 +54,10 @@ then
-e 's/^The write modes for DVD+R/\&nbsp;<BR>The write modes for DVD+R/' \
-e 's/<b>Drive preparation and addressing:<\/b>/\&nbsp;<BR><b>Drive preparation and addressing:<\/b>/' \
-e 's/^If you only got one CD capable drive/\&nbsp;<BR>If you only got one CD capable drive/' \
-e 's/^Option --allow_emulated_drives enables/\&nbsp;<BR>Option --allow_emulated_drives enables/' \
-e 's/<b>Emulated drives:<\/b>/\&nbsp;<BR><b>Emulated drives:<\/b>/' \
-e 's/^Alphabetical list of options/\&nbsp;<BR>Alphabetical list of options/' \
-e 's/and for all others\.<\/td><\/table>/and for all others.<\/td><\/table> <BR><HR><FONT SIZE=-1><CENTER>(HTML generated from '"$manpage"'.1 on '"$(date)"' by '$(basename "$0")' )<\/CENTER><\/FONT>/' \
-e 's/See section FILES/See section <A HREF="#FILES">FILES<\/A>/' \
-e 's/See section EXAMPLES/See section <A HREF="#EXAMPLES">EXAMPLES<\/A>/' \
<"$2" >"$htmlpage"