From samba!concert!gatech!darwin.sura.net!Sirius.dfn.de!chx400!bernina!almesber Mon Sep 7 17:16:12 EDT 1992 Article: 9854 of comp.os.linux Newsgroups: comp.os.linux Path: samba!concert!gatech!darwin.sura.net!Sirius.dfn.de!chx400!bernina!almesber From: almesber@nessie.cs.id.ethz.ch (Werner Almesberger) Subject: Re: suid for fdformat? Message-ID: <1992Sep6.130207.11486@bernina.ethz.ch> Sender: news@bernina.ethz.ch (USENET News System) Organization: Swiss Federal Institute of Technology (ETH), Zurich, CH References: <1992Aug30.062444.346@athena.mit.edu> Date: Sun, 6 Sep 1992 13:02:07 GMT Lines: 136 In article <1992Aug30.062444.346@athena.mit.edu> hammond@kwhpc.caseng.com (Kevin W. Hammond) writes: > Should fdformat be installed as a suid program so regular users can format > floppies, or is it more typically found installed so only root can format > floppies? It depends. Formatting is inherently more timing-critical than regular floppy accesses because some errors can only be detected in the verification pass. Therefore, it's considered an operation that needs some awareness on the user's part. If you can live with users creating bad media on a loaded system, running fdformat suid isn't a problem. However, you should use the slightly modified version I've appended to this posting. It assures that only floppy devices can be formatted (the ioctls may have some random effect on other devices) and only if the user has write access to them. - Werner ---------------------------------- cut here ----------------------------------- /* fdformat.c - Low-level formats a floppy disk. */ #include #include #include #include #include #include #include static int ctrl; struct floppy_struct param; #define FLOPPY_MAJOR 2 #define SECTOR_SIZE 512 #define PERROR(msg) { perror(msg); exit(1); } static void format_disk(char *name) { struct format_descr descr; int track; char dummy; printf("Formatting ... "); fflush(stdout); if (ioctl(ctrl,FDFMTBEG,NULL) < 0) PERROR("\nioctl(FDFMTBEG)"); for (track = 0; track < param.track; track++) { descr.track = track; descr.head = 0; if (ioctl(ctrl,FDFMTTRK,(int) &descr) < 0) PERROR("\nioctl(FDFMTTRK)"); printf("%3d\b\b\b",track); fflush(stdout); if (param.head == 2) { descr.head = 1; if (ioctl(ctrl,FDFMTTRK,(int) &descr) < 0) PERROR("\nioctl(FDFMTTRK)"); } } if (ioctl(ctrl,FDFMTEND,NULL) < 0) PERROR("\nioctl(FDFMTEND)"); printf("done\n"); } static void verify_disk(char *name) { unsigned char *data; int fd,cyl_size,cyl,count; cyl_size = param.sect*param.head*512; if ((data = (unsigned char *) malloc(cyl_size)) == NULL) PERROR("malloc"); printf("Verifying ... "); fflush(stdout); if ((fd = open(name,O_RDONLY)) < 0) PERROR(name); for (cyl = 0; cyl < param.track; cyl++) { printf("%3d\b\b\b",cyl); fflush(stdout); if (read(fd,data,cyl_size) != cyl_size) PERROR("read"); for (count = 0; count < cyl_size; count++) if (data[count] != FD_FILL_BYTE) { printf("bad data in cyl %d\nContinuing ... ",cyl); fflush(stdout); break; } } printf("done\n"); if (close(fd) < 0) PERROR("close"); } static void usage(char *name) { char *this; if (this = strrchr(name,'/')) name = this+1; fprintf(stderr,"usage: %s [ -n ] device\n",name); exit(1); } main(int argc,char **argv) { int verify; char *name; struct stat st; name = argv[0]; verify = 1; if (argc > 1 && argv[1][0] == '-') { if (argv[1][1] != 'n') usage(name); verify = 0; argc--; argv++; } if (argc != 2) usage(name); if (lstat(argv[1],&st) < 0) PERROR(argv[1]); if (!S_ISBLK(st.st_mode) || st.st_rdev >> 8 != FLOPPY_MAJOR) { fprintf(stderr,"%s: not a floppy device\n",argv[1]); exit(1); } if (access(argv[1],W_OK) < 0) PERROR(argv[1]); if ((ctrl = open(argv[1],3)) < 0) PERROR(argv[1]); if (ioctl(ctrl,FDGETPRM,(int) ¶m) < 0) PERROR("ioctl(FDGETPRM)"); printf("%sle-sided, %d tracks, %d sec/track. Total capacity %d kB.\n", param.head ? "Doub" : "Sing",param.track,param.sect,param.size >> 1); format_disk(argv[1]); if (verify) verify_disk(argv[1]); } -- _________________________________________________________________________ / Werner Almesberger, ETH Zuerich, CH almesber@nessie.cs.id.ethz.ch / / IFW A44 Tel. +41 1 254 7213 almesberger@rzvax.ethz.ch / /_BITNET:_ALMESBER@CZHETH5A__HEPNET/CHADNET:_[20579::]57414::ALMESBERGER_/