From: Karel Zak Date: Wed, 6 Dec 2006 23:26:03 +0000 (+0100) Subject: Imported from util-linux-2.11w tarball. X-Git-Url: https://err.no/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=24f4bbff7f0a9b01f5a9fb0a4c1eff5b05b15f6f;p=util-linux Imported from util-linux-2.11w tarball. --- diff --git a/HISTORY b/HISTORY index 2fc05fc4..953dd111 100644 --- a/HISTORY +++ b/HISTORY @@ -1,3 +1,13 @@ +util-linux 2.11w + +* cfdisk, fdisk: allow slightly larger disk sizes +* fdisk: Makefile: also for m68 (sun3) (Kaj-Michael Lang) +* fdisk: allow to use the last partial cylinder, change display format +* fdisk: do not ask partition number in case there is only one choice +* fdisk: new sunlabel fix +* login: fix possible local root exploit (Wojciech Purczynski) +* more: bigendian fix + util-linux 2.11v * Catalan messages (Antoni Bella Perez) diff --git a/VERSION b/VERSION index 63057a6f..ae899e83 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -2.11v +2.11w diff --git a/fdisk/Makefile b/fdisk/Makefile index a2a75dad..6dfaa3e8 100644 --- a/fdisk/Makefile +++ b/fdisk/Makefile @@ -18,9 +18,6 @@ NOTMADE=cfdisk endif endif -ifeq "$(ARCH)" "m68k" -# It seems the m68k people do not want *fdisk -else SBIN:=$(SBIN) fdisk MAN8:=$(MAN8) fdisk.8 @@ -28,7 +25,6 @@ ifneq "$(ARCH)" "sparc" SBIN:=$(SBIN) $(CFDISK) sfdisk MAN8:=$(MAN8) cfdisk.8 sfdisk.8 endif -endif all: $(SBIN) $(NOTMADE) diff --git a/fdisk/cfdisk.c b/fdisk/cfdisk.c index e6007766..69b8b994 100644 --- a/fdisk/cfdisk.c +++ b/fdisk/cfdisk.c @@ -200,7 +200,7 @@ int sectors = 0; int cylinders = 0; int cylinder_size = 0; /* heads * sectors */ int total_size = 0; /* actual_size rounded down */ -long actual_size = 0; /* set using ioctl */ +unsigned long actual_size = 0; /* set using ioctl */ /* explicitly given user values */ int user_heads = 0, user_sectors = 0, user_cylinders = 0; /* kernel values; ignore the cylinders */ diff --git a/fdisk/fdisk.c b/fdisk/fdisk.c index a1d84e56..30e908ea 100644 --- a/fdisk/fdisk.c +++ b/fdisk/fdisk.c @@ -172,6 +172,8 @@ uint heads, display_in_cyl_units = 1, extended_offset = 0; /* offset of link pointers */ +unsigned long total_number_of_sectors; + #define dos_label (!sun_label && !sgi_label && !aix_label && !osf_label) int sun_label = 0; /* looking at sun disklabel */ int sgi_label = 0; /* looking at sgi disklabel */ @@ -807,7 +809,7 @@ get_partition_table_geometry(void) { void get_geometry(int fd, struct geom *g) { int sec_fac; - long longsectors; + unsigned long longsectors; get_sectorsize(fd); sec_fac = sector_size / 512; @@ -843,6 +845,8 @@ get_geometry(int fd, struct geom *g) { g->sectors = sectors; g->cylinders = cylinders; } + + total_number_of_sectors = longsectors; } /* @@ -867,12 +871,13 @@ get_boot(enum action what) { pe->changed = (what == create_empty_dos); } + if (what == create_empty_sun && check_sun_label()) + return 0; + memset(MBRbuffer, 0, 512); if (what == create_empty_dos) goto got_dos_table; /* skip reading disk */ - if (what == create_empty_sun) - goto got_table; if ((fd = open(disk_device, type_open)) < 0) { if ((fd = open(disk_device, O_RDONLY)) < 0) { @@ -894,8 +899,6 @@ get_boot(enum action what) { update_units(); -got_table: - if (check_sun_label()) return 0; @@ -1136,16 +1139,72 @@ get_partition(int warn, int max) { i = read_int(1, 0, max, 0, _("Partition number")) - 1; pe = &ptes[i]; - if (warn - && ((!sun_label && !sgi_label && !pe->part_table->sys_ind) - || (sun_label && - (!sunlabel->partitions[i].num_sectors || - !sunlabel->infos[i].id)) - || (sgi_label && (!sgi_get_num_sectors(i)))) - ) fprintf(stderr, _("Warning: partition %d has empty type\n"), i+1); + if (warn) { + if ((!sun_label && !sgi_label && !pe->part_table->sys_ind) + || (sun_label && + (!sunlabel->partitions[i].num_sectors || + !sunlabel->infos[i].id)) + || (sgi_label && (!sgi_get_num_sectors(i))) + ) + fprintf(stderr, + _("Warning: partition %d has empty type\n"), + i+1); + } return i; } +static int +get_existing_partition(int warn, int max) { + int pno = -1; + int i; + + for (i = 0; i < max; i++) { + struct pte *pe = &ptes[i]; + struct partition *p = pe->part_table; + + if (p && !is_cleared_partition(p)) { + if (pno >= 0) + goto not_unique; + pno = i; + } + } + if (pno >= 0) { + printf(_("Selected partition %d\n"), pno+1); + return pno; + } + printf(_("No partition is defined yet!\n")); + return -1; + + not_unique: + return get_partition(warn, max); +} + +static int +get_nonexisting_partition(int warn, int max) { + int pno = -1; + int i; + + for (i = 0; i < max; i++) { + struct pte *pe = &ptes[i]; + struct partition *p = pe->part_table; + + if (p && is_cleared_partition(p)) { + if (pno >= 0) + goto not_unique; + pno = i; + } + } + if (pno >= 0) { + printf(_("Selected partition %d\n"), pno+1); + return pno; + } + printf(_("All primary partitions have been defined already!\n")); + return -1; + + not_unique: + return get_partition(warn, max); +} + char * const str_units(int n) { /* n==1: use singular */ if (n == 1) @@ -1264,9 +1323,13 @@ delete_partition(int i) { static void change_sysid(void) { char *temp; - int i = get_partition(0, partitions), sys, origsys; - struct partition *p = ptes[i].part_table; + int i, sys, origsys; + struct partition *p; + i = get_existing_partition(0, partitions); + if (i == -1) + return; + p = ptes[i].part_table; origsys = sys = get_sysid(i); /* if changing types T to 0 is allowed, then @@ -1396,17 +1459,34 @@ static void check_consistency(struct partition *p, int partition) { if (peh != (heads - 1) || pes != sectors) { printf(_("Partition %i does not end on cylinder boundary:\n"), partition + 1); +#if 0 printf(_(" phys=(%d, %d, %d) "), pec, peh, pes); printf(_("should be (%d, %d, %d)\n"), pec, heads - 1, sectors); +#endif } } static void list_disk_geometry(void) { - printf(_("\nDisk %s: %d heads, %d sectors, %d cylinders\nUnits = " - "%s of %d * %d bytes\n\n"), disk_device, heads, sectors, - cylinders, str_units(PLURAL), units_per_sector, sector_size); + long long bytes = (long long) total_number_of_sectors * 512; + long megabytes = bytes/1000000; + + if (megabytes < 10000) + printf(_("\nDisk %s: %ld MB, %lld bytes\n"), + disk_device, megabytes, bytes); + else + printf(_("\nDisk %s: %ld.%ld GB, %lld bytes\n"), + disk_device, megabytes/1000, (megabytes/100)%10, bytes); + printf(_("%d heads, %d sectors/track, %d cylinders"), + heads, sectors, cylinders); + if (units_per_sector == 1) + printf(_(", total %lu sectors"), + total_number_of_sectors / (sector_size/512)); + printf("\n"); + printf(_("Units = %s of %d * %d = %d bytes\n\n"), + str_units(PLURAL), + units_per_sector, sector_size, units_per_sector * sector_size); } /* @@ -1579,7 +1659,7 @@ list_table(int xtra) { printf(_("%*s Boot Start End Blocks Id System\n"), w+1, _("Device")); - for (i = 0 ; i < partitions; i++) { + for (i = 0; i < partitions; i++) { struct pte *pe = &ptes[i]; p = pe->part_table; @@ -1777,7 +1857,10 @@ add_partition(int n, int sys) { fill_bounds(first, last); if (n < 4) { start = sector_offset; - limit = heads * sectors * cylinders - 1; + if (display_in_cyl_units) + limit = heads * sectors * cylinders - 1; + else + limit = total_number_of_sectors - 1; if (extended_offset) { first[ext_index] = extended_offset; last[ext_index] = get_start_sect(q) + @@ -1945,8 +2028,9 @@ new_partition(void) { _("l logical (5 or over)") : _("e extended")); while (1) { if ((c = tolower(read_char(line))) == 'p') { - add_partition(get_partition(0, 4), - LINUX_NATIVE); + int i = get_nonexisting_partition(0, 4); + if (i >= 0) + add_partition(i, LINUX_NATIVE); return; } else if (c == 'l' && extended_offset) { @@ -1954,8 +2038,9 @@ new_partition(void) { return; } else if (c == 'e' && !extended_offset) { - add_partition(get_partition(0, 4), - EXTENDED); + int i = get_nonexisting_partition(0, 4); + if (i >= 0) + add_partition(i, EXTENDED); return; } else @@ -2480,8 +2565,9 @@ main(int argc, char **argv) { unknown_command(c); break; case 'd': - delete_partition( - get_partition(1, partitions)); + j = get_existing_partition(1, partitions); + if (j >= 0) + delete_partition(j); break; case 'i': if (sgi_label) diff --git a/fdisk/fdisksunlabel.c b/fdisk/fdisksunlabel.c index 25f07b52..1827fb06 100644 --- a/fdisk/fdisksunlabel.c +++ b/fdisk/fdisksunlabel.c @@ -117,7 +117,7 @@ int check_sun_label(void) { unsigned short *ush; int csum; - + if (sunlabel->magic != SUN_LABEL_MAGIC && sunlabel->magic != SUN_LABEL_MAGIC_SWAPPED) { sun_label = 0; diff --git a/login-utils/login.c b/login-utils/login.c index 0d2b1123..0ec16ad5 100644 --- a/login-utils/login.c +++ b/login-utils/login.c @@ -183,10 +183,6 @@ static void sigint (int); static void motd (void); static void dolastlog (int quiet); -#ifndef __linux__ -static char *stypeof (char *ttyid); -#endif - #ifdef CRYPTOCARD #include "cryptocard.h" #endif @@ -280,6 +276,24 @@ opentty(const char * tty) { close(fd); } +/* In case login is suid it was possible to use a hardlink as stdin + and exploit races for a local root exploit. (Wojciech Purczynski). */ +/* More precisely, the problem is ttyn := ttyname(0); ...; chown(ttyn); + here ttyname() might return "/tmp/x", a hardlink to a pseudotty. */ +/* All of this is a problem only when login is suid, which it isnt. */ +static void +check_ttyname(char *ttyn) { + struct stat statbuf; + + if (lstat(ttyn, &statbuf) + || !S_ISCHR(statbuf.st_mode) + || (statbuf.st_nlink > 1 && strncmp(ttyn, "/dev/", 5))) { + syslog(LOG_ERR, _("FATAL: bad tty")); + sleep(1); + exit(1); + } +} + /* true if the filedescriptor fd is a console tty, very Linux specific */ static int consoletty(int fd) { @@ -350,8 +364,8 @@ main(int argc, char **argv) char *domain, *ttyn; char tbuf[MAXPATHLEN + 2], tname[sizeof(_PATH_TTY) + 10]; char *termenv; - char * childArgv[10]; - char * buff; + char *childArgv[10]; + char *buff; int childArgc = 0; #ifdef USE_PAM int retcode; @@ -364,9 +378,6 @@ main(int argc, char **argv) #ifdef CHOWNVCS char vcsn[20], vcsan[20]; #endif -#ifndef __linux__ - int ioctlval; -#endif pid = getpid(); @@ -451,38 +462,21 @@ main(int argc, char **argv) while(*p) *p++ = ' '; } else - ask = 1; + ask = 1; -#ifndef __linux__ - ioctlval = 0; - ioctl(0, TIOCLSET, &ioctlval); - ioctl(0, TIOCNXCL, 0); - fcntl(0, F_SETFL, ioctlval); - ioctl(0, TIOCGETP, &sgttyb); - sgttyb.sg_erase = CERASE; - sgttyb.sg_kill = CKILL; - ioctl(0, TIOCSLTC, <c); - ioctl(0, TIOCSETC, &tc); - ioctl(0, TIOCSETP, &sgttyb); - - /* - * Be sure that we're in blocking mode!!! - * This is really for HPUX - */ - ioctlval = 0; - ioctl(0, FIOSNBIO, &ioctlval); -#endif /* ! __linux__ */ - for (cnt = getdtablesize(); cnt > 2; cnt--) close(cnt); ttyn = ttyname(0); + if (ttyn == NULL || *ttyn == '\0') { /* no snprintf required - see definition of tname */ sprintf(tname, "%s??", _PATH_TTY); ttyn = tname; } + check_ttyname(ttyn); + if (strncmp(ttyn, "/dev/", 5) == 0) tty_name = ttyn+5; else @@ -704,10 +698,6 @@ main(int argc, char **argv) #else /* ! USE_PAM */ for (cnt = 0;; ask = 1) { -# ifndef __linux__ - ioctlval = 0; - ioctl(0, TIOCSETD, &ioctlval); -# endif if (ask) { fflag = 0; @@ -1284,13 +1274,6 @@ timedout(int sig) { #ifndef USE_PAM int rootterm(char * ttyn) -#ifndef __linux__ -{ - struct ttyent *t; - - return((t = getttynam(ttyn)) && (t->ty_status&TTY_SECURE)); -} -#else { int fd; char buf[100],*p; @@ -1318,7 +1301,6 @@ rootterm(char * ttyn) } } } -#endif /* !__linux__ */ #endif /* !USE_PAM */ jmp_buf motdinterrupt; @@ -1411,18 +1393,6 @@ badlogin(const char *name) { } } -#undef UNKNOWN -#define UNKNOWN "su" - -#ifndef __linux__ -char * -stypeof(char *ttyid) { - struct ttyent *t; - - return(ttyid && (t = getttynam(ttyid)) ? t->ty_type : UNKNOWN); -} -#endif - /* Should not be called from PAM code... */ void sleepexit(int eval) { diff --git a/text-utils/more.c b/text-utils/more.c index 452e4ff8..364c747b 100644 --- a/text-utils/more.c +++ b/text-utils/more.c @@ -1915,7 +1915,7 @@ int readch () { static char *BS = "\b"; static char *BSB = "\b \b"; static char *CARAT = "^"; -#define ERACEONECOLUMN \ +#define ERASEONECOLUMN \ if (docrterase) \ errwrite(BSB); \ else \ @@ -1926,7 +1926,6 @@ void ttyin (unsigned char buf[], register int nmax, char pchar) { int c; int slash = 0; int maxlen; - int cbuf; sp = buf; maxlen = 0; @@ -1964,14 +1963,14 @@ void ttyin (unsigned char buf[], register int nmax, char pchar) { } if (mblength == 1) { - ERACEONECOLUMN + ERASEONECOLUMN } else { int wc_width; wc_width = wcwidth (wc); wc_width = (wc_width < 1) ? 1 : wc_width; while (wc_width--) { - ERACEONECOLUMN + ERASEONECOLUMN } } @@ -1984,13 +1983,13 @@ void ttyin (unsigned char buf[], register int nmax, char pchar) { #endif { --promptlen; - ERACEONECOLUMN + ERASEONECOLUMN --sp; } if ((*sp < ' ' && *sp != '\n') || *sp == RUBOUT) { --promptlen; - ERACEONECOLUMN + ERASEONECOLUMN } continue; } @@ -2021,7 +2020,7 @@ void ttyin (unsigned char buf[], register int nmax, char pchar) { } if (slash && ((cc_t) c == otty.c_cc[VKILL] || (cc_t) c == otty.c_cc[VERASE])) { - ERACEONECOLUMN + ERASEONECOLUMN --sp; } if (c != '\\') @@ -2032,9 +2031,9 @@ void ttyin (unsigned char buf[], register int nmax, char pchar) { errwrite(CARAT); promptlen++; } - cbuf = c; if (c != '\n' && c != ESC) { - errwrite1((char *)(&cbuf)); + char cbuf = c; + errwrite1(&cbuf); promptlen++; } else