From 31b884cf16ff81fd11571f627cb001439aaa9389 Mon Sep 17 00:00:00 2001 From: Thomas Schmitt Date: Sun, 20 Jan 2008 13:13:01 +0000 Subject: [PATCH] Made -outdev stdio:/dev/fd/1 safe for single session runs --- libisoburn/trunk/test/ng_xorrisoburn.c | 38 +++++++++++++++++---- libisoburn/trunk/test/xorriso.1 | 16 +++++++++ libisoburn/trunk/test/xorriso.c | 41 ++++++++++++++++++++--- libisoburn/trunk/test/xorriso.h | 2 +- libisoburn/trunk/test/xorriso_private.h | 3 ++ libisoburn/trunk/test/xorriso_timestamp.h | 2 +- 6 files changed, 89 insertions(+), 13 deletions(-) diff --git a/libisoburn/trunk/test/ng_xorrisoburn.c b/libisoburn/trunk/test/ng_xorrisoburn.c index 81870c81..fbc0e69a 100644 --- a/libisoburn/trunk/test/ng_xorrisoburn.c +++ b/libisoburn/trunk/test/ng_xorrisoburn.c @@ -256,6 +256,7 @@ int Xorriso_aquire_drive(struct XorrisO *xorriso, char *adr, int flag) enum burn_disc_status state; IsoImage *volset = NULL; struct isoburn_read_opts ropts; + char adr_data[SfileadrL], *libburn_adr; if((flag&3)==0) { sprintf(xorriso->info_text, @@ -267,12 +268,25 @@ int Xorriso_aquire_drive(struct XorrisO *xorriso, char *adr, int flag) if(ret<=0) return(ret); + libburn_adr= adr; + if(strcmp(adr,"stdio:/dev/fd/1")==0) { + if(xorriso->dev_fd_1<0) { + sprintf(xorriso->info_text, + "\"stdio:/dev/fd/1\" was not a start argument. stdout possibly already tainted."); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "SORRY", 0); + {ret= 0; goto ex;} + } else { + sprintf(adr_data, "stdio:/dev/fd/%d", xorriso->dev_fd_1); + libburn_adr= adr_data; + } + } + if((flag&3)==1 && xorriso->out_drive_handle!=NULL) { ret= Xorriso_get_drive_handles(xorriso, &out_dinfo, &out_drive, "on attempt to compare new indev with outdev", 2); if(ret<=0) goto ex; - ret= burn_drive_equals_adr(out_drive, adr, 1); + ret= burn_drive_equals_adr(out_drive, libburn_adr, 1); if(ret==1) dinfo= out_dinfo; } else if((flag&3)==2 && xorriso->in_drive_handle!=NULL) { @@ -280,13 +294,13 @@ int Xorriso_aquire_drive(struct XorrisO *xorriso, char *adr, int flag) "on attempt to compare new indev with outdev", 0); if(ret<=0) goto ex; - ret= burn_drive_equals_adr(in_drive, adr, 1); + ret= burn_drive_equals_adr(in_drive, libburn_adr, 1); if(ret==1) dinfo= in_dinfo; } if(dinfo==NULL) { - ret= isoburn_drive_scan_and_grab(&dinfo, adr, 1); + ret= isoburn_drive_scan_and_grab(&dinfo, libburn_adr, 1); Xorriso_process_msg_queues(xorriso,0); if(ret<=0) { sprintf(xorriso->info_text,"Cannot aquire drive '%s'", adr); @@ -471,6 +485,8 @@ int Xorriso_make_write_options( struct XorrisO *xorriso, struct burn_drive *drive, struct burn_write_opts **burn_options, int flag) { + int drive_role; + *burn_options= burn_write_opts_new(drive); if(*burn_options==NULL) { Xorriso_process_msg_queues(xorriso,0); @@ -479,7 +495,9 @@ int Xorriso_make_write_options( return(0); } burn_write_opts_set_simulate(*burn_options, !!xorriso->do_dummy); - burn_write_opts_set_multi(*burn_options, !xorriso->do_close); + drive_role= burn_drive_get_drive_role(drive); + burn_write_opts_set_multi(*burn_options, + !(xorriso->do_close || drive_role==0 || drive_role==3)); burn_drive_set_speed(drive, xorriso->speed, xorriso->speed); burn_write_opts_set_underrun_proof(*burn_options, 1); return(1); @@ -1353,7 +1371,7 @@ int Xorriso_toc(struct XorrisO *xorriso, int flag) int num_sessions= 0, num_tracks= 0, lba= 0, nwa= -1, pmin, psec, pframe, ret; int track_count= 0, session_no, track_no, profile_no= -1; int last_track_start= 0, last_track_size= -1, num_data= 0, is_data= 0; - int is_inout_drive= 0; + int is_inout_drive= 0, drive_role; char profile_name[80],*respt,*devadr; struct burn_disc *disc= NULL; struct burn_session **sessions; @@ -1390,9 +1408,15 @@ int Xorriso_toc(struct XorrisO *xorriso, int flag) ret= burn_disc_get_profile(drive, &profile_no, profile_name); if (profile_no > 0 && ret > 0) { if (profile_name[0]) - sprintf(respt+strlen(respt), "%s\n", profile_name); + sprintf(respt+strlen(respt), "%s", profile_name); else - sprintf(respt+strlen(respt), "%4.4Xh\n", profile_no); + sprintf(respt+strlen(respt), "%4.4Xh", profile_no); + drive_role= burn_drive_get_drive_role(drive); + if(drive_role==2) + sprintf(respt+strlen(respt), ", overwriteable"); + else if(drive_role==0 || drive_role==3) + sprintf(respt+strlen(respt), ", sequential"); + strcat(respt, "\n"); } else sprintf(respt+strlen(respt), "is not recognizable\n"); Xorriso_result(xorriso,0); diff --git a/libisoburn/trunk/test/xorriso.1 b/libisoburn/trunk/test/xorriso.1 index a78d6423..a19177aa 100644 --- a/libisoburn/trunk/test/xorriso.1 +++ b/libisoburn/trunk/test/xorriso.1 @@ -262,6 +262,22 @@ already contains a valid ISO 9660 image. Any other file type is not readable via "stdio:" and can only be used as target for the method of modifying. Non existing paths in existing directories are handled as empty regular files. .PP +A very special kind of pseudo drive are open file descriptors. They are +depicted by "stdio:/dev/fd/" and descriptor number (see man 2 open). +.br +Addresses "-" or "stdio:/dev/fd/1" depict standard output, which normally is +the output channel for result texts. +To prevent a fatal intermingling of ISO image and text messages, all result +texts get redirected to stderr if -*dev "-" or "stdio:/dev/fd/1" is among +the start arguments of the program. +.br +It is not allowed to use standard output as pseudo drive if it was not +among the start arguments. Do not try to fool this ban via backdoor addresses +to stdout. +.br +If stdout is used as drive, then -use_readline is permanently disabled. +Use of backdoors will cause severe memory and/or terminal corruption. +.PP Be aware that especially the superuser can write into any accessible file or device by using its path with the "stdio:" prefix. Addresses without prefix "stdio:" will only work if they lead to a MMC drive. diff --git a/libisoburn/trunk/test/xorriso.c b/libisoburn/trunk/test/xorriso.c index 7118ea1a..71b887da 100644 --- a/libisoburn/trunk/test/xorriso.c +++ b/libisoburn/trunk/test/xorriso.c @@ -2871,6 +2871,7 @@ int Xorriso_new(struct XorrisO ** xorriso,char *progname, int flag) m->volset_change_pending= 0; m->outdev[0]= 0; m->out_drive_handle= NULL; + m->dev_fd_1= -1; m->ban_stdio_write= 0; m->do_dummy= 0; m->do_close= 0; @@ -2999,7 +3000,7 @@ int Xorriso_dialog_input(struct XorrisO *xorriso, char line[], int linesize, #ifdef Xorriso_with_readlinE - if(xorriso->use_stdin) { + if(xorriso->use_stdin || xorriso->dev_fd_1>=0) { if(flag&2) {ret= 1; goto ex;} if(Sfile_fgets(line,linesize-1,stdin)==NULL) { @@ -6559,11 +6560,14 @@ int Xorriso_option_cut_out(struct XorrisO *xorriso, char *disk_path, /* Options -dev , -indev, -outdev */ /** @param flag bit0=use as indev , bit1= use as outdev */ -int Xorriso_option_dev(struct XorrisO *xorriso, char *adr, int flag) +int Xorriso_option_dev(struct XorrisO *xorriso, char *in_adr, int flag) { int ret; - char sfe[5*SfileadrL]; + char sfe[5*SfileadrL], *adr; + adr= in_adr; + if(strcmp(in_adr, "-")==0) + adr= "stdio:/dev/fd/1"; if(xorriso->ban_stdio_write && strncmp(adr, "stdio:", 6)==0) { sprintf(xorriso->info_text, "Drive address banned by -ban_stdio_write : '%s'", @@ -8773,6 +8777,17 @@ ex:; } +int Xorriso_protect_stdout(struct XorrisO *xorriso, int flag) +{ + if(xorriso->dev_fd_1>=0) + return(2); + xorriso->dev_fd_1= dup(1); + close(1); + dup2(2,1); + return(1); +} + + int Xorriso_prescan_args(struct XorrisO *xorriso, int argc, char **argv, int flag) /* @@ -8815,10 +8830,28 @@ int Xorriso_prescan_args(struct XorrisO *xorriso, int argc, char **argv, xorriso->did_something_useful= 1; return(0); } - } else if(strcmp(cmd,"no_rc")==0) { + } else if(i==1 && strcmp(cmd,"no_rc")==0) { ret= Xorriso_option_no_rc(xorriso, 0); if(ret<=0) return(ret); + + } else if((strcmp(cmd,"dev")==0 || strcmp(cmd,"outdev")==0 || + strcmp(cmd,"indev")==0) && + (strcmp(arg1,"stdio:/dev/fd/1")==0 || strcmp(arg1,"-")==0) && + xorriso->dev_fd_1<0) { + /* Detach fd 1 from externally perceived stdout and attach it to stderr. + Keep dev_fd_1 connected to external stdout. dev_fd_1 is to be used when + "stdio:/dev/fd/1" is interpreted as drive address. + */ + Xorriso_protect_stdout(xorriso, 0); + sprintf(xorriso->info_text, + "Encountered - or stdio:/dev/fd/1 as possible write target."); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "NOTE", 0); + sprintf(xorriso->info_text, + "Redirecting any text message output to stderr."); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "NOTE", 0); + sprintf(xorriso->info_text, "Disabling use of libreadline."); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "NOTE", 0); } } return(1); diff --git a/libisoburn/trunk/test/xorriso.h b/libisoburn/trunk/test/xorriso.h index d00e3810..b89717d1 100644 --- a/libisoburn/trunk/test/xorriso.h +++ b/libisoburn/trunk/test/xorriso.h @@ -124,7 +124,7 @@ int Xorriso_get_problem_status(struct XorrisO *xorriso, char severity[80], the severity of the library events like the severity of a message submitted via Xorriso_msgs_submit(). xorriso sets the message queues of the libraries to queuing "ALL". - So it is essential that they get + So it is essential that they get drained regularly. @param xorriso The environment handle @param flag Unused yet. Submit 0. @return 1 on success, <=0 if failure diff --git a/libisoburn/trunk/test/xorriso_private.h b/libisoburn/trunk/test/xorriso_private.h index df327210..8c326549 100644 --- a/libisoburn/trunk/test/xorriso_private.h +++ b/libisoburn/trunk/test/xorriso_private.h @@ -96,6 +96,9 @@ struct XorrisO { /* the global context of xorriso */ char outdev[SfileadrL]; void *out_drive_handle; /* interpreted only by xorrisoburn.c */ + int dev_fd_1; /* The fd which substitutes for /dev/fd/1 and is + connected to externaly perveived stdout. + */ int ban_stdio_write; int do_dummy; diff --git a/libisoburn/trunk/test/xorriso_timestamp.h b/libisoburn/trunk/test/xorriso_timestamp.h index 19211539..3d91fc48 100644 --- a/libisoburn/trunk/test/xorriso_timestamp.h +++ b/libisoburn/trunk/test/xorriso_timestamp.h @@ -1 +1 @@ -#define Xorriso_timestamP "2008.01.20.102946" +#define Xorriso_timestamP "2008.01.20.131050"