From 2b130d1bae79a71402d678f828e61e94195ab27d Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Fri, 23 Nov 2007 15:09:38 -0500 Subject: [PATCH] Import 1.1.44 --- Makefile | 2 +- drivers/block/floppy.c | 2 +- drivers/block/hd.c | 2 +- drivers/char/console.c | 4 +-- drivers/char/serial.c | 32 +++++++++---------- drivers/char/tpqic02.c | 2 +- drivers/char/tty_io.c | 18 +++++------ drivers/char/vt.c | 2 +- drivers/net/8390.c | 13 ++------ drivers/net/plip.c | 4 +-- drivers/net/ppp.c | 4 +-- drivers/net/slip.c | 2 +- drivers/scsi/hosts.c | 2 +- drivers/scsi/scsicam.c | 2 +- drivers/sound/soundcard.c | 2 +- fs/buffer.c | 2 +- fs/exec.c | 7 ++-- fs/ext/freelists.c | 4 +-- fs/ext/namei.c | 22 ++++++------- fs/ext2/acl.c | 4 +-- fs/ext2/balloc.c | 2 +- fs/ext2/ialloc.c | 4 +-- fs/ext2/ioctl.c | 4 +-- fs/ext2/namei.c | 22 ++++++------- fs/inode.c | 4 +-- fs/minix/bitmap.c | 4 +-- fs/minix/namei.c | 22 ++++++------- fs/namei.c | 11 ++++--- fs/nfs/proc.c | 32 +++++++++---------- fs/open.c | 67 ++++++++++++++++----------------------- fs/sysv/ialloc.c | 4 +-- fs/sysv/namei.c | 22 ++++++------- fs/umsdos/namei.c | 8 ++--- fs/xiafs/bitmap.c | 4 +-- fs/xiafs/namei.c | 22 ++++++------- include/asm/segment.h | 2 +- include/linux/kernel.h | 5 +++ include/linux/sched.h | 6 ++-- include/linux/skbuff.h | 2 +- include/linux/string.h | 6 ++++ include/linux/unistd.h | 2 ++ kernel/sys.c | 41 +++++++++++++++++++++--- kernel/sys_call.S | 2 ++ mm/mmap.c | 3 +- mm/mprotect.c | 44 ++++++++++++------------- net/inet/eth.c | 2 +- 46 files changed, 253 insertions(+), 226 deletions(-) diff --git a/Makefile b/Makefile index e7943d4edbeb..605f7d2550a0 100644 --- a/Makefile +++ b/Makefile @@ -1,6 +1,6 @@ VERSION = 1 PATCHLEVEL = 1 -SUBLEVEL = 43 +SUBLEVEL = 44 all: Version zImage diff --git a/drivers/block/floppy.c b/drivers/block/floppy.c index adadc829ccb3..01e48216468e 100644 --- a/drivers/block/floppy.c +++ b/drivers/block/floppy.c @@ -1523,7 +1523,7 @@ static void setup_format_params(void) { struct fparm { unsigned char track,head,sect,size; - } *here = (void *)floppy_track_buffer; + } *here = (struct fparm *)floppy_track_buffer; int ssize,il,n; int count,head_shift,track_shift; diff --git a/drivers/block/hd.c b/drivers/block/hd.c index 4064c32369af..ee25e9b24365 100644 --- a/drivers/block/hd.c +++ b/drivers/block/hd.c @@ -278,7 +278,7 @@ static void identify_intr(void) id.cyls*id.heads*id.sectors/2048, id.buf_size/2, hd_info[dev].cyl, hd_info[dev].head, hd_info[dev].sect, id.max_multsect); /* save drive info for later query via HDIO_GETIDENTITY */ - if (NULL != (hd_ident_info[dev] = kmalloc(sizeof(id),GFP_ATOMIC))) + if (NULL != (hd_ident_info[dev] = (struct hd_driveid *)kmalloc(sizeof(id),GFP_ATOMIC))) *hd_ident_info[dev] = id; /* flush remaining 384 (reserved/undefined) ID bytes: */ diff --git a/drivers/char/console.c b/drivers/char/console.c index abe9af4ad74e..213daad3c842 100644 --- a/drivers/char/console.c +++ b/drivers/char/console.c @@ -1103,7 +1103,7 @@ static int con_write(struct tty_struct * tty, int from_user, { int c, n = 0; unsigned int currcons; - struct vt_struct *vt = tty->driver_data; + struct vt_struct *vt = (struct vt_struct *)tty->driver_data; currcons = vt->vc_num; if (currcons >= NR_CONSOLES) { @@ -1834,7 +1834,7 @@ static void highlight(const int currcons, const int s, const int e) static void highlight_pointer(const int currcons, const int where) { unsigned char *p; - static char *prev=NULL; + static unsigned char *prev=NULL; if (where==-1) /* remove the pointer */ { diff --git a/drivers/char/serial.c b/drivers/char/serial.c index 4aaa21d40dfd..e5dfea2a0153 100644 --- a/drivers/char/serial.c +++ b/drivers/char/serial.c @@ -290,7 +290,7 @@ static inline void serial_outp(struct async_struct *info, int offset, */ static void rs_stop(struct tty_struct *tty) { - struct async_struct *info = tty->driver_data; + struct async_struct *info = (struct async_struct *)tty->driver_data; unsigned long flags; if (serial_paranoia_check(info, tty->device, "rs_stop")) @@ -306,7 +306,7 @@ static void rs_stop(struct tty_struct *tty) static void rs_start(struct tty_struct *tty) { - struct async_struct *info = tty->driver_data; + struct async_struct *info = (struct async_struct *)tty->driver_data; unsigned long flags; if (serial_paranoia_check(info, tty->device, "rs_start")) @@ -694,9 +694,9 @@ static void do_serial_bh(void *unused) run_task_queue(&tq_serial); } -static void do_softint(void *private) +static void do_softint(void *private_) { - struct async_struct *info = (struct async_struct *) private; + struct async_struct *info = (struct async_struct *) private_; struct tty_struct *tty; tty = info->tty; @@ -1185,7 +1185,7 @@ static void change_speed(struct async_struct *info) static void rs_put_char(struct tty_struct *tty, unsigned char ch) { - struct async_struct *info = tty->driver_data; + struct async_struct *info = (struct async_struct *)tty->driver_data; unsigned long flags; if (serial_paranoia_check(info, tty->device, "rs_put_char")) @@ -1208,7 +1208,7 @@ static void rs_put_char(struct tty_struct *tty, unsigned char ch) static void rs_flush_chars(struct tty_struct *tty) { - struct async_struct *info = tty->driver_data; + struct async_struct *info = (struct async_struct *)tty->driver_data; unsigned long flags; if (serial_paranoia_check(info, tty->device, "rs_flush_chars")) @@ -1228,7 +1228,7 @@ static int rs_write(struct tty_struct * tty, int from_user, unsigned char *buf, int count) { int c, total = 0; - struct async_struct *info = tty->driver_data; + struct async_struct *info = (struct async_struct *)tty->driver_data; unsigned long flags; if (serial_paranoia_check(info, tty->device, "rs_write")) @@ -1272,7 +1272,7 @@ static int rs_write(struct tty_struct * tty, int from_user, static int rs_write_room(struct tty_struct *tty) { - struct async_struct *info = tty->driver_data; + struct async_struct *info = (struct async_struct *)tty->driver_data; int ret; if (serial_paranoia_check(info, tty->device, "rs_write_room")) @@ -1285,7 +1285,7 @@ static int rs_write_room(struct tty_struct *tty) static int rs_chars_in_buffer(struct tty_struct *tty) { - struct async_struct *info = tty->driver_data; + struct async_struct *info = (struct async_struct *)tty->driver_data; if (serial_paranoia_check(info, tty->device, "rs_chars_in_buffer")) return 0; @@ -1294,7 +1294,7 @@ static int rs_chars_in_buffer(struct tty_struct *tty) static void rs_flush_buffer(struct tty_struct *tty) { - struct async_struct *info = tty->driver_data; + struct async_struct *info = (struct async_struct *)tty->driver_data; if (serial_paranoia_check(info, tty->device, "rs_flush_buffer")) return; @@ -1317,7 +1317,7 @@ static void rs_flush_buffer(struct tty_struct *tty) */ static void rs_throttle(struct tty_struct * tty) { - struct async_struct *info = tty->driver_data; + struct async_struct *info = (struct async_struct *)tty->driver_data; #ifdef SERIAL_DEBUG_THROTTLE char buf[64]; @@ -1340,7 +1340,7 @@ static void rs_throttle(struct tty_struct * tty) static void rs_unthrottle(struct tty_struct * tty) { - struct async_struct *info = tty->driver_data; + struct async_struct *info = (struct async_struct *)tty->driver_data; #ifdef SERIAL_DEBUG_THROTTLE char buf[64]; @@ -1627,7 +1627,7 @@ static int rs_ioctl(struct tty_struct *tty, struct file * file, unsigned int cmd, unsigned long arg) { int error; - struct async_struct * info = tty->driver_data; + struct async_struct * info = (struct async_struct *)tty->driver_data; int retval; if (serial_paranoia_check(info, tty->device, "rs_ioctl")) @@ -1718,7 +1718,7 @@ static int rs_ioctl(struct tty_struct *tty, struct file * file, static void rs_set_termios(struct tty_struct *tty, struct termios *old_termios) { - struct async_struct *info = tty->driver_data; + struct async_struct *info = (struct async_struct *)tty->driver_data; if (tty->termios->c_cflag == old_termios->c_cflag) return; @@ -1748,7 +1748,7 @@ static void rs_set_termios(struct tty_struct *tty, struct termios *old_termios) */ static void rs_close(struct tty_struct *tty, struct file * filp) { - struct async_struct * info = tty->driver_data; + struct async_struct * info = (struct async_struct *)tty->driver_data; if (!info || serial_paranoia_check(info, tty->device, "rs_close")) return; @@ -1822,7 +1822,7 @@ static void rs_close(struct tty_struct *tty, struct file * filp) */ void rs_hangup(struct tty_struct *tty) { - struct async_struct * info = tty->driver_data; + struct async_struct * info = (struct async_struct *)tty->driver_data; if (serial_paranoia_check(info, tty->device, "rs_hangup")) return; diff --git a/drivers/char/tpqic02.c b/drivers/char/tpqic02.c index 0b0120004e00..67aadf74b924 100644 --- a/drivers/char/tpqic02.c +++ b/drivers/char/tpqic02.c @@ -2832,7 +2832,7 @@ static int qic02_get_resources(void) */ /* get IRQ */ - if (request_irq(QIC02_TAPE_IRQ, qic02_tape_interrupt, SA_INTERRUP, "QIC-02")) { + if (request_irq(QIC02_TAPE_IRQ, qic02_tape_interrupt, SA_INTERRUPT, "QIC-02")) { printk(TPQIC02_NAME ": can't allocate IRQ%d for QIC-02 tape\n", QIC02_TAPE_IRQ); status_zombie = YES; diff --git a/drivers/char/tty_io.c b/drivers/char/tty_io.c index 6c670c376607..1cdaf1de996a 100644 --- a/drivers/char/tty_io.c +++ b/drivers/char/tty_io.c @@ -634,7 +634,7 @@ static int tty_read(struct inode * inode, struct file * file, char * buf, int co int i; struct tty_struct * tty; - tty = file->private_data; + tty = (struct tty_struct *)file->private_data; if (tty_paranoia_check(tty, inode->i_rdev, "tty_read")) return -EIO; if (!tty || (tty->flags & (1 << TTY_IO_ERROR))) @@ -676,7 +676,7 @@ static int tty_write(struct inode * inode, struct file * file, char * buf, int c if (is_console && redirect) tty = redirect; else - tty = file->private_data; + tty = (struct tty_struct *)file->private_data; if (tty_paranoia_check(tty, inode->i_rdev, "tty_write")) return -EIO; if (!tty || !tty->driver.write || (tty->flags & (1 << TTY_IO_ERROR))) @@ -886,7 +886,7 @@ static void release_dev(struct file * filp) int idx; - tty = filp->private_data; + tty = (struct tty_struct *)filp->private_data; if (tty_paranoia_check(tty, filp->f_inode->i_rdev, "release_dev")) return; @@ -1136,7 +1136,7 @@ static int tty_select(struct inode * inode, struct file * filp, int sel_type, se { struct tty_struct * tty; - tty = filp->private_data; + tty = (struct tty_struct *)filp->private_data; if (tty_paranoia_check(tty, inode->i_rdev, "tty_select")) return 0; @@ -1150,7 +1150,7 @@ static int tty_fasync(struct inode * inode, struct file * filp, int on) struct tty_struct * tty; struct fasync_struct *fa, *prev; - tty = filp->private_data; + tty = (struct tty_struct *)filp->private_data; if (tty_paranoia_check(tty, inode->i_rdev, "tty_fasync")) return 0; @@ -1162,7 +1162,7 @@ static int tty_fasync(struct inode * inode, struct file * filp, int on) if (on) { if (fa) return 0; - fa = kmalloc(sizeof(struct fasync_struct), GFP_KERNEL); + fa = (struct fasync_struct *)kmalloc(sizeof(struct fasync_struct), GFP_KERNEL); if (!fa) return -ENOMEM; fa->magic = FASYNC_MAGIC; @@ -1228,7 +1228,7 @@ static int tty_ioctl(struct inode * inode, struct file * file, unsigned char ch; char mbz = 0; - tty = file->private_data; + tty = (struct tty_struct *)file->private_data; if (tty_paranoia_check(tty, inode->i_rdev, "tty_ioctl")) return -EINVAL; @@ -1466,9 +1466,9 @@ void do_SAK( struct tty_struct *tty) * This routine is called out of the software interrupt to flush data * from the flip buffer to the line discipline. */ -static void flush_to_ldisc(void *private) +static void flush_to_ldisc(void *private_) { - struct tty_struct *tty = private; + struct tty_struct *tty = (struct tty_struct *) private_; unsigned char *cp; char *fp; int count; diff --git a/drivers/char/vt.c b/drivers/char/vt.c index cdc60b09bd00..107eb727824f 100644 --- a/drivers/char/vt.c +++ b/drivers/char/vt.c @@ -121,7 +121,7 @@ int vt_ioctl(struct tty_struct *tty, struct file * file, int console, i; unsigned char ucval; struct kbd_struct * kbd; - struct vt_struct *vt = tty->driver_data; + struct vt_struct *vt = (struct vt_struct *)tty->driver_data; console = vt->vc_num; diff --git a/drivers/net/8390.c b/drivers/net/8390.c index aae2bdd32035..e811fd1c6135 100644 --- a/drivers/net/8390.c +++ b/drivers/net/8390.c @@ -134,15 +134,12 @@ static int ei_start_xmit(struct sk_buff *skb, struct device *dev) the board has died and kick it. */ if (dev->tbusy) { /* Do timeouts, just like the 8003 driver. */ - int txsr = inb(e8390_base+EN0_TSR), isr, cmd; + int txsr = inb(e8390_base+EN0_TSR), isr; int tickssofar = jiffies - dev->trans_start; if (tickssofar < 10 || (tickssofar < 15 && ! (txsr & ENTSR_PTX))) { return 1; } isr = inb(e8390_base+EN0_ISR); - cmd = inb(e8390_base+E8390_CMD) & (E8390_STOP|E8390_START); - if ((cmd == 0) || (cmd == (E8390_STOP|E8390_START))) - return 1; printk(KERN_DEBUG "%s: transmit timed out, TX status %#2x, ISR %#2x.\n", dev->name, txsr, isr); /* Does the 8390 thinks it has posted an interrupt? */ @@ -245,7 +242,7 @@ void ei_interrupt(int reg_ptr) int irq = -(((struct pt_regs *)reg_ptr)->orig_eax+2); struct device *dev = (struct device *)(irq2dev_map[irq]); int e8390_base; - int interrupts, cmd, boguscount = 0; + int interrupts, boguscount = 0; struct ei_device *ei_local; if (dev == NULL) { @@ -277,12 +274,6 @@ void ei_interrupt(int reg_ptr) /* !!Assumption!! -- we stay in page 0. Don't break this. */ while ((interrupts = inb_p(e8390_base + EN0_ISR)) != 0 && ++boguscount < 9) { - cmd = inb(e8390_base+E8390_CMD) & (E8390_STOP|E8390_START); - if ((cmd == 0) || (cmd == (E8390_STOP|E8390_START))) { - printk("%s: card not present\n", dev->name); - interrupts = 0; - break; - } if (interrupts & ENISR_RDC) { /* Ack meaningless DMA complete. */ outb_p(ENISR_RDC, e8390_base + EN0_ISR); diff --git a/drivers/net/plip.c b/drivers/net/plip.c index 7b3d10550a95..3cb276b64ee9 100644 --- a/drivers/net/plip.c +++ b/drivers/net/plip.c @@ -232,7 +232,7 @@ plip_init(struct device *dev) dev->priv = kmalloc(sizeof (struct net_local), GFP_KERNEL); memset(dev->priv, 0, sizeof(struct net_local)); - pl=dev->priv; + pl = (struct net_local *) dev->priv; pl->trigger_us = PLIP_TRIGGER_WAIT; pl->nibble_us = PLIP_NIBBLE_WAIT; @@ -693,7 +693,7 @@ static void plip_interrupt(int reg_ptr) { int irq = -(((struct pt_regs *)reg_ptr)->orig_eax+2); - struct device *dev = irq2dev_map[irq]; + struct device *dev = (struct device *) irq2dev_map[irq]; struct net_local *lp = (struct net_local *)dev->priv; struct plip_local *rcv = &lp->rcv_data; struct plip_local *snd = &lp->snd_data; diff --git a/drivers/net/ppp.c b/drivers/net/ppp.c index 0bfdd719c113..7e57d304e831 100644 --- a/drivers/net/ppp.c +++ b/drivers/net/ppp.c @@ -550,7 +550,7 @@ ppp_open(struct tty_struct *tty) } /* Allocate a user-level receive buffer */ - ppp->us_rbuff = kmalloc (RBUFSIZE, GFP_KERNEL); + ppp->us_rbuff = (unsigned char *) kmalloc (RBUFSIZE, GFP_KERNEL); if (ppp->us_rbuff == NULL) { PRINTKN (1,(KERN_ERR "ppp: no space for user receive buffer\n")); ppp_release (ppp); @@ -2013,7 +2013,7 @@ static void ppp_print_buffer(const char *name, char *buf, int count, int seg) set_fs (seg); - if (name != (char *) NULL) + if (name != NULL) PRINTK ((KERN_DEBUG "ppp: %s, count = %d\n", name, count)); while (count > 8) { diff --git a/drivers/net/slip.c b/drivers/net/slip.c index 0237b5694d12..e84569836886 100644 --- a/drivers/net/slip.c +++ b/drivers/net/slip.c @@ -986,7 +986,7 @@ slip_ioctl(struct tty_struct *tty, void *file, int cmd, void *arg) /* Allow stty to read, but not set, the serial port */ case TCGETS: case TCGETA: - return n_tty_ioctl(tty, file, cmd, (unsigned long) arg); + return n_tty_ioctl(tty, (struct file *) file, cmd, (unsigned long) arg); default: return -ENOIOCTLCMD; diff --git a/drivers/scsi/hosts.c b/drivers/scsi/hosts.c index a926d2b243b5..dc1a936f2225 100644 --- a/drivers/scsi/hosts.c +++ b/drivers/scsi/hosts.c @@ -197,7 +197,7 @@ scsi_unregister(struct Scsi_Host * sh){ struct Scsi_Host * scsi_register(Scsi_Host_Template * tpnt, int j){ struct Scsi_Host * retval, *shpnt; - retval = scsi_init_malloc(sizeof(struct Scsi_Host) + j); + retval = (struct Scsi_Host *)scsi_init_malloc(sizeof(struct Scsi_Host) + j); retval->host_busy = 0; if(j > 0xffff) panic("Too many extra bytes requested\n"); retval->extra_bytes = j; diff --git a/drivers/scsi/scsicam.c b/drivers/scsi/scsicam.c index 3ae85e92d83a..2b0e3cdf62c8 100644 --- a/drivers/scsi/scsicam.c +++ b/drivers/scsi/scsicam.c @@ -182,7 +182,7 @@ static int setsize(unsigned long capacity,unsigned int *cyls,unsigned int *hds, cylinders = capacity / temp;/* Compute number of cylinders */ } } - if (cylinders == 0) rv=-1; /* Give error if 0 cylinders */ + if (cylinders == 0) rv=(unsigned)-1;/* Give error if 0 cylinders */ *cyls = (unsigned int) cylinders; /* Stuff return values */ *secs = (unsigned int) sectors; diff --git a/drivers/sound/soundcard.c b/drivers/sound/soundcard.c index 15eeca8ce56f..aa87c3eba430 100644 --- a/drivers/sound/soundcard.c +++ b/drivers/sound/soundcard.c @@ -219,7 +219,7 @@ snd_set_irq_handler (int interrupt_level, void (*hndlr) (int)) { int retcode; - retcode = request_irq(interrupt_level, &hndlr, + retcode = request_irq(interrupt_level, hndlr, #ifdef SND_SA_INTERRUPT SA_INTERRUPT, #else diff --git a/fs/buffer.c b/fs/buffer.c index b19070a379ec..bcabae8f7b1b 100644 --- a/fs/buffer.c +++ b/fs/buffer.c @@ -880,7 +880,7 @@ static void put_unused_buffer_head(struct buffer_head * bh) struct wait_queue * wait; wait = ((volatile struct buffer_head *) bh)->b_wait; - memset((void *) bh,0,sizeof(*bh)); + memset(bh,0,sizeof(*bh)); ((volatile struct buffer_head *) bh)->b_wait = wait; bh->b_next_free = unused_list; unused_list = bh; diff --git a/fs/exec.c b/fs/exec.c index ec78844cacf9..f11678877782 100644 --- a/fs/exec.c +++ b/fs/exec.c @@ -612,8 +612,7 @@ restart_interp: } i = bprm.inode->i_mode; if (IS_NOSUID(bprm.inode) && (((i & S_ISUID) && bprm.inode->i_uid != current-> - euid) || ((i & S_ISGID) && !in_group_p(bprm.inode->i_gid))) && - !suser()) { + euid) || ((i & S_ISGID) && !in_group_p(bprm.inode->i_gid))) && !suser()) { retval = -EPERM; goto exec_error2; } @@ -816,8 +815,8 @@ static int load_aout_binary(struct linux_binprm * bprm, struct pt_regs * regs) (current->mm->start_code = N_TXTADDR(ex))))); current->mm->rss = 0; current->mm->mmap = NULL; - current->suid = current->euid = bprm->e_uid; - current->sgid = current->egid = bprm->e_gid; + current->suid = current->euid = current->fsuid = bprm->e_uid; + current->sgid = current->egid = current->fsgid = bprm->e_gid; if (N_MAGIC(ex) == OMAGIC) { do_mmap(NULL, 0, ex.a_text+ex.a_data, PROT_READ|PROT_WRITE|PROT_EXEC, diff --git a/fs/ext/freelists.c b/fs/ext/freelists.c index 8d9fe7acf280..8bc8e67e3405 100644 --- a/fs/ext/freelists.c +++ b/fs/ext/freelists.c @@ -289,8 +289,8 @@ printk("ext_free_inode: inode empty, skipping to %d\n", efi->next); inode->i_count = 1; inode->i_nlink = 1; inode->i_dev = sb->s_dev; - inode->i_uid = current->euid; - inode->i_gid = (dir->i_mode & S_ISGID) ? dir->i_gid : current->egid; + inode->i_uid = current->fsuid; + inode->i_gid = (dir->i_mode & S_ISGID) ? dir->i_gid : current->fsgid; inode->i_dirt = 1; inode->i_ino = j; inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME; diff --git a/fs/ext/namei.c b/fs/ext/namei.c index 2b54034de0c3..324af160b5e4 100644 --- a/fs/ext/namei.c +++ b/fs/ext/namei.c @@ -361,7 +361,7 @@ int ext_mknod(struct inode * dir, const char * name, int len, int mode, int rdev iput(dir); return -ENOSPC; } - inode->i_uid = current->euid; + inode->i_uid = current->fsuid; inode->i_mode = mode; inode->i_op = NULL; if (S_ISREG(inode->i_mode)) @@ -544,9 +544,9 @@ int ext_rmdir(struct inode * dir, const char * name, int len) retval = -EPERM; if (!(inode = iget(dir->i_sb, de->inode))) goto end_rmdir; - if ((dir->i_mode & S_ISVTX) && !suser() && - current->euid != inode->i_uid && - current->euid != dir->i_uid) + if ((dir->i_mode & S_ISVTX) && !fsuser() && + current->fsuid != inode->i_uid && + current->fsuid != dir->i_uid) goto end_rmdir; if (inode->i_dev != dir->i_dev) goto end_rmdir; @@ -598,9 +598,9 @@ int ext_unlink(struct inode * dir, const char * name, int len) if (!(inode = iget(dir->i_sb, de->inode))) goto end_unlink; retval = -EPERM; - if ((dir->i_mode & S_ISVTX) && !suser() && - current->euid != inode->i_uid && - current->euid != dir->i_uid) + if ((dir->i_mode & S_ISVTX) && !fsuser() && + current->fsuid != inode->i_uid && + current->fsuid != dir->i_uid) goto end_unlink; if (S_ISDIR(inode->i_mode)) goto end_unlink; @@ -791,8 +791,8 @@ start_up: goto end_rename; retval = -EPERM; if ((old_dir->i_mode & S_ISVTX) && - current->euid != old_inode->i_uid && - current->euid != old_dir->i_uid && !suser()) + current->fsuid != old_inode->i_uid && + current->fsuid != old_dir->i_uid && !fsuser()) goto end_rename; new_bh = ext_find_entry(new_dir,new_name,new_len,&new_de,NULL,NULL); if (new_bh) { @@ -812,8 +812,8 @@ start_up: } retval = -EPERM; if (new_inode && (new_dir->i_mode & S_ISVTX) && - current->euid != new_inode->i_uid && - current->euid != new_dir->i_uid && !suser()) + current->fsuid != new_inode->i_uid && + current->fsuid != new_dir->i_uid && !fsuser()) goto end_rename; if (S_ISDIR(old_inode->i_mode)) { retval = -EEXIST; diff --git a/fs/ext2/acl.c b/fs/ext2/acl.c index 421fc11fc88d..80a112845ae0 100644 --- a/fs/ext2/acl.c +++ b/fs/ext2/acl.c @@ -29,12 +29,12 @@ int ext2_permission (struct inode * inode, int mask) /* * Special case, access is always granted for root */ - if (suser ()) + if (fsuser()) return 1; /* * If no ACL, checks using the file mode */ - else if (current->euid == inode->i_uid) + else if (current->fsuid == inode->i_uid) mode >>= 6; else if (in_group_p (inode->i_gid)) mode >>= 3; diff --git a/fs/ext2/balloc.c b/fs/ext2/balloc.c index 67b10c4b95c2..626ae9c68e95 100644 --- a/fs/ext2/balloc.c +++ b/fs/ext2/balloc.c @@ -352,7 +352,7 @@ int ext2_new_block (struct super_block * sb, unsigned long goal, } lock_super (sb); es = sb->u.ext2_sb.s_es; - if (es->s_free_blocks_count <= es->s_r_blocks_count && !suser()) { + if (es->s_free_blocks_count <= es->s_r_blocks_count && !fsuser()) { unlock_super (sb); return 0; } diff --git a/fs/ext2/ialloc.c b/fs/ext2/ialloc.c index 561a7b5465bc..f598fdecafbf 100644 --- a/fs/ext2/ialloc.c +++ b/fs/ext2/ialloc.c @@ -475,7 +475,7 @@ repeat: inode->i_count = 1; inode->i_nlink = 1; inode->i_dev = sb->s_dev; - inode->i_uid = current->euid; + inode->i_uid = current->fsuid; if (test_opt (sb, GRPID)) inode->i_gid = dir->i_gid; else if (dir->i_mode & S_ISGID) { @@ -483,7 +483,7 @@ repeat: if (S_ISDIR(mode)) mode |= S_ISGID; } else - inode->i_gid = current->egid; + inode->i_gid = current->fsgid; inode->i_dirt = 1; inode->i_ino = j; inode->i_blksize = sb->s_blocksize; diff --git a/fs/ext2/ioctl.c b/fs/ext2/ioctl.c index 871af3324420..c562f333dab0 100644 --- a/fs/ext2/ioctl.c +++ b/fs/ext2/ioctl.c @@ -28,7 +28,7 @@ int ext2_ioctl (struct inode * inode, struct file * filp, unsigned int cmd, put_fs_long (inode->u.ext2_i.i_flags, (long *) arg); return 0; case EXT2_IOC_SETFLAGS: - if ((current->euid != inode->i_uid) && !suser()) + if ((current->fsuid != inode->i_uid) && !fsuser()) return -EPERM; if (IS_RDONLY(inode)) return -EROFS; @@ -42,7 +42,7 @@ int ext2_ioctl (struct inode * inode, struct file * filp, unsigned int cmd, put_fs_long (inode->u.ext2_i.i_version, (long *) arg); return 0; case EXT2_IOC_SETVERSION: - if ((current->euid != inode->i_uid) && !suser()) + if ((current->fsuid != inode->i_uid) && !fsuser()) return -EPERM; if (IS_RDONLY(inode)) return -EROFS; diff --git a/fs/ext2/namei.c b/fs/ext2/namei.c index a2f35d2f4930..06c5457f735d 100644 --- a/fs/ext2/namei.c +++ b/fs/ext2/namei.c @@ -430,7 +430,7 @@ int ext2_mknod (struct inode * dir, const char * name, int len, int mode, iput (dir); return -ENOSPC; } - inode->i_uid = current->euid; + inode->i_uid = current->fsuid; inode->i_mode = mode; inode->i_op = NULL; if (S_ISREG(inode->i_mode)) @@ -630,9 +630,9 @@ repeat: schedule(); goto repeat; } - if ((dir->i_mode & S_ISVTX) && !suser() && - current->euid != inode->i_uid && - current->euid != dir->i_uid) + if ((dir->i_mode & S_ISVTX) && !fsuser() && + current->fsuid != inode->i_uid && + current->fsuid != dir->i_uid) goto end_rmdir; if (inode == dir) /* we may not delete ".", but "../dir" is ok */ goto end_rmdir; @@ -711,9 +711,9 @@ repeat: schedule(); goto repeat; } - if ((dir->i_mode & S_ISVTX) && !suser() && - current->euid != inode->i_uid && - current->euid != dir->i_uid) + if ((dir->i_mode & S_ISVTX) && !fsuser() && + current->fsuid != inode->i_uid && + current->fsuid != dir->i_uid) goto end_unlink; if (!inode->i_nlink) { ext2_warning (inode->i_sb, "ext2_unlink", @@ -946,8 +946,8 @@ start_up: goto end_rename; retval = -EPERM; if ((old_dir->i_mode & S_ISVTX) && - current->euid != old_inode->i_uid && - current->euid != old_dir->i_uid && !suser()) + current->fsuid != old_inode->i_uid && + current->fsuid != old_dir->i_uid && !fsuser()) goto end_rename; new_bh = ext2_find_entry (new_dir, new_name, new_len, &new_de); if (new_bh) { @@ -977,8 +977,8 @@ start_up: } retval = -EPERM; if (new_inode && (new_dir->i_mode & S_ISVTX) && - current->euid != new_inode->i_uid && - current->euid != new_dir->i_uid && !suser()) + current->fsuid != new_inode->i_uid && + current->fsuid != new_dir->i_uid && !fsuser()) goto end_rename; if (S_ISDIR(old_inode->i_mode)) { retval = -ENOTDIR; diff --git a/fs/inode.c b/fs/inode.c index 9f4e9abc8f1d..535318f498dd 100644 --- a/fs/inode.c +++ b/fs/inode.c @@ -414,8 +414,8 @@ struct inode * get_pipe_inode(void) PIPE_LOCK(*inode) = 0; inode->i_pipe = 1; inode->i_mode |= S_IFIFO | S_IRUSR | S_IWUSR; - inode->i_uid = current->euid; - inode->i_gid = current->egid; + inode->i_uid = current->fsuid; + inode->i_gid = current->fsgid; inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME; return inode; } diff --git a/fs/minix/bitmap.c b/fs/minix/bitmap.c index 1502e1bc06b5..53ff26cecb12 100644 --- a/fs/minix/bitmap.c +++ b/fs/minix/bitmap.c @@ -213,8 +213,8 @@ struct inode * minix_new_inode(const struct inode * dir) inode->i_count = 1; inode->i_nlink = 1; inode->i_dev = sb->s_dev; - inode->i_uid = current->euid; - inode->i_gid = (dir->i_mode & S_ISGID) ? dir->i_gid : current->egid; + inode->i_uid = current->fsuid; + inode->i_gid = (dir->i_mode & S_ISGID) ? dir->i_gid : current->fsgid; inode->i_dirt = 1; inode->i_ino = j; inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME; diff --git a/fs/minix/namei.c b/fs/minix/namei.c index fe2e7fb64269..dcd32db29be9 100644 --- a/fs/minix/namei.c +++ b/fs/minix/namei.c @@ -265,7 +265,7 @@ int minix_mknod(struct inode * dir, const char * name, int len, int mode, int rd iput(dir); return -ENOSPC; } - inode->i_uid = current->euid; + inode->i_uid = current->fsuid; inode->i_mode = mode; inode->i_op = NULL; if (S_ISREG(inode->i_mode)) @@ -443,9 +443,9 @@ int minix_rmdir(struct inode * dir, const char * name, int len) retval = -EPERM; if (!(inode = iget(dir->i_sb, de->inode))) goto end_rmdir; - if ((dir->i_mode & S_ISVTX) && !suser() && - current->euid != inode->i_uid && - current->euid != dir->i_uid) + if ((dir->i_mode & S_ISVTX) && !fsuser() && + current->fsuid != inode->i_uid && + current->fsuid != dir->i_uid) goto end_rmdir; if (inode->i_dev != dir->i_dev) goto end_rmdir; @@ -509,9 +509,9 @@ repeat: schedule(); goto repeat; } - if ((dir->i_mode & S_ISVTX) && !suser() && - current->euid != inode->i_uid && - current->euid != dir->i_uid) + if ((dir->i_mode & S_ISVTX) && !fsuser() && + current->fsuid != inode->i_uid && + current->fsuid != dir->i_uid) goto end_unlink; if (de->inode != inode->i_ino) { retval = -ENOENT; @@ -700,8 +700,8 @@ start_up: goto end_rename; retval = -EPERM; if ((old_dir->i_mode & S_ISVTX) && - current->euid != old_inode->i_uid && - current->euid != old_dir->i_uid && !suser()) + current->fsuid != old_inode->i_uid && + current->fsuid != old_dir->i_uid && !fsuser()) goto end_rename; new_bh = minix_find_entry(new_dir,new_name,new_len,&new_de); if (new_bh) { @@ -731,8 +731,8 @@ start_up: } retval = -EPERM; if (new_inode && (new_dir->i_mode & S_ISVTX) && - current->euid != new_inode->i_uid && - current->euid != new_dir->i_uid && !suser()) + current->fsuid != new_inode->i_uid && + current->fsuid != new_dir->i_uid && !fsuser()) goto end_rename; if (S_ISDIR(old_inode->i_mode)) { retval = -ENOTDIR; diff --git a/fs/namei.c b/fs/namei.c index fc0f1732ae8b..9dc66a77a627 100644 --- a/fs/namei.c +++ b/fs/namei.c @@ -68,8 +68,9 @@ void putname(char * name) * permission() * * is used to check for read/write/execute permissions on a file. - * I don't know if we should look at just the euid or both euid and - * uid, but that should be easily changed. + * We use "fsuid" for this, letting us set arbitrary permissions + * permissions for filesystem access without changing the "normal" + * uids which are used for other things.. */ int permission(struct inode * inode,int mask) { @@ -77,11 +78,11 @@ int permission(struct inode * inode,int mask) if (inode->i_op && inode->i_op->permission) return inode->i_op->permission(inode, mask); - else if (current->euid == inode->i_uid) + else if (current->fsuid == inode->i_uid) mode >>= 6; else if (in_group_p(inode->i_gid)) mode >>= 3; - if (((mode & mask & 0007) == mask) || suser()) + if (((mode & mask & 0007) == mask) || fsuser()) return 1; return 0; } @@ -418,7 +419,7 @@ asmlinkage int sys_mknod(const char * filename, int mode, dev_t dev) int error; char * tmp; - if (S_ISDIR(mode) || (!S_ISFIFO(mode) && !suser())) + if (S_ISDIR(mode) || (!S_ISFIFO(mode) && !fsuser())) return -EPERM; switch (mode & S_IFMT) { case 0: diff --git a/fs/nfs/proc.c b/fs/nfs/proc.c index c6335e766292..f49963aa2104 100644 --- a/fs/nfs/proc.c +++ b/fs/nfs/proc.c @@ -225,7 +225,7 @@ retry: PRINTK("NFS reply getattr\n"); } else { - if (!ruid && current->euid == 0 && current->uid != 0) { + if (!ruid && current->fsuid == 0 && current->uid != 0) { ruid = 1; goto retry; } @@ -260,7 +260,7 @@ retry: PRINTK("NFS reply setattr\n"); } else { - if (!ruid && current->euid == 0 && current->uid != 0) { + if (!ruid && current->fsuid == 0 && current->uid != 0) { ruid = 1; goto retry; } @@ -300,7 +300,7 @@ retry: PRINTK("NFS reply lookup\n"); } else { - if (!ruid && current->euid == 0 && current->uid != 0) { + if (!ruid && current->fsuid == 0 && current->uid != 0) { ruid = 1; goto retry; } @@ -338,7 +338,7 @@ retry: PRINTK("NFS reply readlink %s\n", res); } else { - if (!ruid && current->euid == 0 && current->uid != 0) { + if (!ruid && current->fsuid == 0 && current->uid != 0) { ruid = 1; goto retry; } @@ -381,7 +381,7 @@ retry: PRINTK("NFS reply read %d\n", len); } else { - if (!ruid && current->euid == 0 && current->uid != 0) { + if (!ruid && current->fsuid == 0 && current->uid != 0) { ruid = 1; goto retry; } @@ -419,7 +419,7 @@ retry: PRINTK("NFS reply write\n"); } else { - if (!ruid && current->euid == 0 && current->uid != 0) { + if (!ruid && current->fsuid == 0 && current->uid != 0) { ruid = 1; goto retry; } @@ -457,7 +457,7 @@ retry: PRINTK("NFS reply create\n"); } else { - if (!ruid && current->euid == 0 && current->uid != 0) { + if (!ruid && current->fsuid == 0 && current->uid != 0) { ruid = 1; goto retry; } @@ -490,7 +490,7 @@ retry: PRINTK("NFS reply remove\n"); } else { - if (!ruid && current->euid == 0 && current->uid != 0) { + if (!ruid && current->fsuid == 0 && current->uid != 0) { ruid = 1; goto retry; } @@ -527,7 +527,7 @@ retry: PRINTK("NFS reply rename\n"); } else { - if (!ruid && current->euid == 0 && current->uid != 0) { + if (!ruid && current->fsuid == 0 && current->uid != 0) { ruid = 1; goto retry; } @@ -562,7 +562,7 @@ retry: PRINTK("NFS reply link\n"); } else { - if (!ruid && current->euid == 0 && current->uid != 0) { + if (!ruid && current->fsuid == 0 && current->uid != 0) { ruid = 1; goto retry; } @@ -598,7 +598,7 @@ retry: PRINTK("NFS reply symlink\n"); } else { - if (!ruid && current->euid == 0 && current->uid != 0) { + if (!ruid && current->fsuid == 0 && current->uid != 0) { ruid = 1; goto retry; } @@ -636,7 +636,7 @@ retry: PRINTK("NFS reply mkdir\n"); } else { - if (!ruid && current->euid == 0 && current->uid != 0) { + if (!ruid && current->fsuid == 0 && current->uid != 0) { ruid = 1; goto retry; } @@ -669,7 +669,7 @@ retry: PRINTK("NFS reply rmdir\n"); } else { - if (!ruid && current->euid == 0 && current->uid != 0) { + if (!ruid && current->fsuid == 0 && current->uid != 0) { ruid = 1; goto retry; } @@ -723,7 +723,7 @@ retry: } } else { - if (!ruid && current->euid == 0 && current->uid != 0) { + if (!ruid && current->fsuid == 0 && current->uid != 0) { ruid = 1; goto retry; } @@ -757,7 +757,7 @@ retry: PRINTK("NFS reply statfs\n"); } else { - if (!ruid && current->euid == 0 && current->uid != 0) { + if (!ruid && current->fsuid == 0 && current->uid != 0) { ruid = 1; goto retry; } @@ -792,7 +792,7 @@ static int *nfs_rpc_header(int *p, int procedure, int ruid) p1 = p++; *p++ = htonl(CURRENT_TIME); /* traditional, could be anything */ p = xdr_encode_string(p, (char *) sys); - *p++ = htonl(ruid ? current->uid : current->euid); + *p++ = htonl(ruid ? current->uid : current->fsuid); *p++ = htonl(current->egid); p2 = p++; for (i = 0; i < 16 && i < NGROUPS && current->groups[i] != NOGROUP; i++) diff --git a/fs/open.c b/fs/open.c index 893af39a96d7..227abce548e4 100644 --- a/fs/open.c +++ b/fs/open.c @@ -128,7 +128,7 @@ asmlinkage int sys_utime(char * filename, struct utimbuf * times) return -EROFS; } if (times) { - if ((current->euid != inode->i_uid) && !suser()) { + if ((current->fsuid != inode->i_uid) && !fsuser()) { iput(inode); return -EPERM; } @@ -136,7 +136,7 @@ asmlinkage int sys_utime(char * filename, struct utimbuf * times) modtime = get_fs_long((unsigned long *) ×->modtime); inode->i_ctime = CURRENT_TIME; } else { - if ((current->euid != inode->i_uid) && + if ((current->fsuid != inode->i_uid) && !permission(inode,MAY_WRITE)) { iput(inode); return -EACCES; @@ -152,41 +152,30 @@ asmlinkage int sys_utime(char * filename, struct utimbuf * times) } /* - * XXX we should use the real ids for checking _all_ components of the - * path. Now we only use them for the final component of the path. + * access() needs to use the real uid/gid, not the effective uid/gid. + * We do this by temporarily setting fsuid/fsgid to the wanted values */ -asmlinkage int sys_access(const char * filename,int mode) +asmlinkage int sys_access(const char * filename, int mode) { struct inode * inode; - int res, i_mode; + int old_fsuid, old_fsgid; + int res; if (mode != (mode & S_IRWXO)) /* where's F_OK, X_OK, W_OK, R_OK? */ return -EINVAL; + old_fsuid = current->fsuid; + old_fsgid = current->fsgid; + current->fsuid = current->uid; + current->fsgid = current->gid; res = namei(filename,&inode); - if (res) - return res; - i_mode = inode->i_mode; - res = i_mode & S_IRWXUGO; - if (current->uid == inode->i_uid) - res >>= 6; /* needs cleaning? */ - else if (in_group_p(inode->i_gid)) - res >>= 3; /* needs cleaning? */ - iput(inode); - if ((res & mode) == mode) - return 0; - /* - * XXX we are doing this test last because we really should be - * swapping the effective with the real user id (temporarily), - * and then calling suser() routine. If we do call the - * suser() routine, it needs to be called last. - * - * XXX nope. suser() is inappropriate and swapping the ids while - * decomposing the path would be racy. - */ - if ((!current->uid) && - (S_ISDIR(i_mode) || !(mode & S_IXOTH) || (i_mode & S_IXUGO))) - return 0; - return -EACCES; + if (!res) { + if (!permission(inode, mode)) + res = -EACCES; + iput(inode); + } + current->fsuid = old_fsuid; + current->fsgid = old_fsgid; + return res; } asmlinkage int sys_chdir(const char * filename) @@ -241,7 +230,7 @@ asmlinkage int sys_chroot(const char * filename) iput(inode); return -ENOTDIR; } - if (!suser()) { + if (!fsuser()) { iput(inode); return -EPERM; } @@ -259,14 +248,14 @@ asmlinkage int sys_fchmod(unsigned int fd, mode_t mode) return -EBADF; if (!(inode = file->f_inode)) return -ENOENT; - if ((current->euid != inode->i_uid) && !suser()) + if ((current->fsuid != inode->i_uid) && !fsuser()) return -EPERM; if (IS_RDONLY(inode)) return -EROFS; if (mode == (mode_t) -1) mode = inode->i_mode; inode->i_mode = (mode & S_IALLUGO) | (inode->i_mode & ~S_IALLUGO); - if (!suser() && !in_group_p(inode->i_gid)) + if (!fsuser() && !in_group_p(inode->i_gid)) inode->i_mode &= ~S_ISGID; inode->i_ctime = CURRENT_TIME; inode->i_dirt = 1; @@ -281,7 +270,7 @@ asmlinkage int sys_chmod(const char * filename, mode_t mode) error = namei(filename,&inode); if (error) return error; - if ((current->euid != inode->i_uid) && !suser()) { + if ((current->fsuid != inode->i_uid) && !fsuser()) { iput(inode); return -EPERM; } @@ -292,7 +281,7 @@ asmlinkage int sys_chmod(const char * filename, mode_t mode) if (mode == (mode_t) -1) mode = inode->i_mode; inode->i_mode = (mode & S_IALLUGO) | (inode->i_mode & ~S_IALLUGO); - if (!suser() && !in_group_p(inode->i_gid)) + if (!fsuser() && !in_group_p(inode->i_gid)) inode->i_mode &= ~S_ISGID; inode->i_ctime = CURRENT_TIME; inode->i_dirt = 1; @@ -316,9 +305,9 @@ asmlinkage int sys_fchown(unsigned int fd, uid_t user, gid_t group) user = inode->i_uid; if (group == (gid_t) -1) group = inode->i_gid; - if ((current->euid == inode->i_uid && user == inode->i_uid && + if ((current->fsuid == inode->i_uid && user == inode->i_uid && (in_group_p(group) || group == inode->i_gid)) || - suser()) { + fsuser()) { inode->i_uid = user; inode->i_gid = group; inode->i_ctime = CURRENT_TIME; @@ -344,9 +333,9 @@ asmlinkage int sys_chown(const char * filename, uid_t user, gid_t group) user = inode->i_uid; if (group == (gid_t) -1) group = inode->i_gid; - if ((current->euid == inode->i_uid && user == inode->i_uid && + if ((current->fsuid == inode->i_uid && user == inode->i_uid && (in_group_p(group) || group == inode->i_gid)) || - suser()) { + fsuser()) { inode->i_uid = user; inode->i_gid = group; inode->i_ctime = CURRENT_TIME; diff --git a/fs/sysv/ialloc.c b/fs/sysv/ialloc.c index b0e389441566..8fd5b4a4a00a 100644 --- a/fs/sysv/ialloc.c +++ b/fs/sysv/ialloc.c @@ -135,8 +135,8 @@ struct inode * sysv_new_inode(const struct inode * dir) inode->i_count = 1; inode->i_nlink = 1; inode->i_dev = sb->s_dev; - inode->i_uid = current->euid; - inode->i_gid = (dir->i_mode & S_ISGID) ? dir->i_gid : current->egid; + inode->i_uid = current->fsuid; + inode->i_gid = (dir->i_mode & S_ISGID) ? dir->i_gid : current->fsgid; inode->i_dirt = 1; inode->i_ino = ino; inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME; diff --git a/fs/sysv/namei.c b/fs/sysv/namei.c index 56d148bdab33..2bf21afdd8fd 100644 --- a/fs/sysv/namei.c +++ b/fs/sysv/namei.c @@ -265,7 +265,7 @@ int sysv_mknod(struct inode * dir, const char * name, int len, int mode, int rde iput(dir); return -ENOSPC; } - inode->i_uid = current->euid; + inode->i_uid = current->fsuid; inode->i_mode = mode; inode->i_op = NULL; if (S_ISREG(inode->i_mode)) @@ -447,9 +447,9 @@ int sysv_rmdir(struct inode * dir, const char * name, int len) retval = -EPERM; if (!(inode = iget(dir->i_sb, de->inode))) goto end_rmdir; - if ((dir->i_mode & S_ISVTX) && !suser() && - current->euid != inode->i_uid && - current->euid != dir->i_uid) + if ((dir->i_mode & S_ISVTX) && !fsuser() && + current->fsuid != inode->i_uid && + current->fsuid != dir->i_uid) goto end_rmdir; if (inode->i_dev != dir->i_dev) goto end_rmdir; @@ -513,9 +513,9 @@ repeat: schedule(); goto repeat; } - if ((dir->i_mode & S_ISVTX) && !suser() && - current->euid != inode->i_uid && - current->euid != dir->i_uid) + if ((dir->i_mode & S_ISVTX) && !fsuser() && + current->fsuid != inode->i_uid && + current->fsuid != dir->i_uid) goto end_unlink; if (de->inode != inode->i_ino) { retval = -ENOENT; @@ -708,8 +708,8 @@ start_up: goto end_rename; retval = -EPERM; if ((old_dir->i_mode & S_ISVTX) && - current->euid != old_inode->i_uid && - current->euid != old_dir->i_uid && !suser()) + current->fsuid != old_inode->i_uid && + current->fsuid != old_dir->i_uid && !fsuser()) goto end_rename; new_bh = sysv_find_entry(new_dir,new_name,new_len,&new_de); if (new_bh) { @@ -739,8 +739,8 @@ start_up: } retval = -EPERM; if (new_inode && (new_dir->i_mode & S_ISVTX) && - current->euid != new_inode->i_uid && - current->euid != new_dir->i_uid && !suser()) + current->fsuid != new_inode->i_uid && + current->fsuid != new_dir->i_uid && !fsuser()) goto end_rename; if (S_ISDIR(old_inode->i_mode)) { retval = -ENOTDIR; diff --git a/fs/umsdos/namei.c b/fs/umsdos/namei.c index 7cfac9efb89a..3ec2ff6178be 100644 --- a/fs/umsdos/namei.c +++ b/fs/umsdos/namei.c @@ -216,9 +216,9 @@ static int umsdos_create_any ( info.entry.mode = mode; info.entry.rdev = rdev; info.entry.flags = flags; - info.entry.uid = current->euid; + info.entry.uid = current->fsuid; info.entry.gid = (dir->i_mode & S_ISGID) - ? dir->i_gid : current->egid; + ? dir->i_gid : current->fsgid; info.entry.ctime = info.entry.atime = info.entry.mtime = CURRENT_TIME; info.entry.nlink = 1; @@ -659,9 +659,9 @@ int UMSDOS_mkdir( if (ret == 0){ info.entry.mode = mode | S_IFDIR; info.entry.rdev = 0; - info.entry.uid = current->euid; + info.entry.uid = current->fsuid; info.entry.gid = (dir->i_mode & S_ISGID) - ? dir->i_gid : current->egid; + ? dir->i_gid : current->fsgid; info.entry.ctime = info.entry.atime = info.entry.mtime = CURRENT_TIME; info.entry.flags = 0; diff --git a/fs/xiafs/bitmap.c b/fs/xiafs/bitmap.c index d3735621f2ee..e91f63cd3682 100644 --- a/fs/xiafs/bitmap.c +++ b/fs/xiafs/bitmap.c @@ -329,8 +329,8 @@ struct inode * xiafs_new_inode(struct inode * dir) inode->i_count = 1; inode->i_nlink = 1; inode->i_dev = sb->s_dev; - inode->i_uid = current->euid; - inode->i_gid = (dir->i_mode & S_ISGID) ? dir->i_gid : current->egid; + inode->i_uid = current->fsuid; + inode->i_gid = (dir->i_mode & S_ISGID) ? dir->i_gid : current->fsgid; inode->i_dirt = 1; inode->i_ino = tmp; inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME; diff --git a/fs/xiafs/namei.c b/fs/xiafs/namei.c index 0cd7c0835b83..0532b17545f8 100644 --- a/fs/xiafs/namei.c +++ b/fs/xiafs/namei.c @@ -294,7 +294,7 @@ int xiafs_mknod(struct inode *dir, const char *name, int len, int mode, int rdev iput(dir); return -ENOSPC; } - inode->i_uid = current->euid; + inode->i_uid = current->fsuid; inode->i_mode = mode; inode->i_op = NULL; if (S_ISREG(inode->i_mode)) @@ -496,9 +496,9 @@ int xiafs_rmdir(struct inode * dir, const char * name, int len) retval = -EPERM; if (!(inode = iget(dir->i_sb, de->d_ino))) goto end_rmdir; - if ((dir->i_mode & S_ISVTX) && !suser() && - current->euid != inode->i_uid && - current->euid != dir->i_uid) + if ((dir->i_mode & S_ISVTX) && !fsuser() && + current->fsuid != inode->i_uid && + current->fsuid != dir->i_uid) goto end_rmdir; if (inode->i_dev != dir->i_dev) goto end_rmdir; @@ -558,9 +558,9 @@ repeat: schedule(); goto repeat; } - if ((dir->i_mode & S_ISVTX) && !suser() && - current->euid != inode->i_uid && - current->euid != dir->i_uid) + if ((dir->i_mode & S_ISVTX) && !fsuser() && + current->fsuid != inode->i_uid && + current->fsuid != dir->i_uid) goto end_unlink; if (!inode->i_nlink) { printk("XIA-FS: Deleting nonexistent file (%s %d)\n", WHERE_ERR); @@ -730,8 +730,8 @@ try_again: goto end_rename; retval = -EPERM; if ((old_dir->i_mode & S_ISVTX) && - current->euid != old_inode->i_uid && - current->euid != old_dir->i_uid && !suser()) + current->fsuid != old_inode->i_uid && + current->fsuid != old_dir->i_uid && !fsuser()) goto end_rename; new_bh = xiafs_find_entry(new_dir, new_name, new_len, &new_de, NULL); if (new_bh) { @@ -751,8 +751,8 @@ try_again: } retval = -EPERM; if (new_inode && (new_dir->i_mode & S_ISVTX) && - current->euid != new_inode->i_uid && - current->euid != new_dir->i_uid && !suser()) + current->fsuid != new_inode->i_uid && + current->fsuid != new_dir->i_uid && !fsuser()) goto end_rename; if (S_ISDIR(old_inode->i_mode)) { retval = -EEXIST; diff --git a/include/asm/segment.h b/include/asm/segment.h index 76dfe6401682..f5f981234904 100644 --- a/include/asm/segment.h +++ b/include/asm/segment.h @@ -149,7 +149,7 @@ static inline void __constant_memcpy_fromfs(void * to, const void * from, unsign return; case 3: *(short *) to = get_user_word((const short *) from); - *(char *) to = get_user_byte(2+(const char *) from); + *((char *) to + 2) = get_user_byte(2+(const char *) from); return; case 4: *(int *) to = get_user_long((const int *) from); diff --git a/include/linux/kernel.h b/include/linux/kernel.h index e64cb78eff72..f4d1d4963138 100644 --- a/include/linux/kernel.h +++ b/include/linux/kernel.h @@ -60,8 +60,13 @@ asmlinkage int printk(const char * fmt, ...) * BSD-style accounting where the process is flagged if it uses root * privs). The implication of this is that you should do normal * permissions checks first, and check suser() last. + * + * "suser()" checks against the effective user id, while "fsuser()" + * is used for file permission checking and checks against the fsuid.. */ #define suser() (current->euid == 0) +#define fsuser() (current->fsuid == 0) + extern int splx (int new_ipl); #endif /* __KERNEL__ */ diff --git a/include/linux/sched.h b/include/linux/sched.h index 8a703211546e..d565d506ca72 100644 --- a/include/linux/sched.h +++ b/include/linux/sched.h @@ -270,8 +270,8 @@ struct task_struct { */ struct task_struct *p_opptr, *p_pptr, *p_cptr, *p_ysptr, *p_osptr; struct wait_queue *wait_chldexit; /* for wait4() */ - unsigned short uid,euid,suid; - unsigned short gid,egid,sgid; + unsigned short uid,euid,suid,fsuid; + unsigned short gid,egid,sgid,fsgid; unsigned long timeout; unsigned long it_real_value, it_prof_value, it_virt_value; unsigned long it_real_incr, it_prof_incr, it_virt_incr; @@ -332,7 +332,7 @@ struct task_struct { /* pid etc.. */ 0,0,0,0, \ /* suppl grps*/ {NOGROUP,}, \ /* proc links*/ &init_task,&init_task,NULL,NULL,NULL,NULL, \ -/* uid etc */ 0,0,0,0,0,0, \ +/* uid etc */ 0,0,0,0,0,0,0,0, \ /* timeout */ 0,0,0,0,0,0,0,0,0,0,0,0, \ /* rlimits */ { {LONG_MAX, LONG_MAX}, {LONG_MAX, LONG_MAX}, \ {LONG_MAX, LONG_MAX}, {LONG_MAX, LONG_MAX}, \ diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h index e1256bb464c2..fca7ba7cdc78 100644 --- a/include/linux/skbuff.h +++ b/include/linux/skbuff.h @@ -46,7 +46,7 @@ struct sk_buff { volatile unsigned long when; /* used to compute rtt's */ struct timeval stamp; struct device *dev; - void *mem_addr; + struct sk_buff *mem_addr; union { struct tcphdr *th; struct ethhdr *eth; diff --git a/include/linux/string.h b/include/linux/string.h index 6eeb71a7105a..f493bb0f29a3 100644 --- a/include/linux/string.h +++ b/include/linux/string.h @@ -11,8 +11,12 @@ extern "C" { #endif +#ifdef i386 + #include /* inline functions for i386.. */ +#else + extern char * strcpy(char *, const char *); extern char * strncpy(char *, const char *, size_t); extern char * strcat(char *, const char *); @@ -33,6 +37,8 @@ extern int memcmp(const void *, const void *, size_t); extern void * memchr(const void *, char, size_t); extern void * memset(void *, char, size_t); +#endif + #ifdef __cplusplus } #endif diff --git a/include/linux/unistd.h b/include/linux/unistd.h index c17a1aed54db..c2ab12934754 100644 --- a/include/linux/unistd.h +++ b/include/linux/unistd.h @@ -144,6 +144,8 @@ #define __NR_sysfs 135 #define __NR_personality 136 #define __NR_afs_syscall 137 /* Syscall for Andrew File System */ +#define __NR_setfsuid 138 +#define __NR_setfsgid 139 extern int errno; diff --git a/kernel/sys.c b/kernel/sys.c index e9c6a85836db..f76f5b98f796 100644 --- a/kernel/sys.c +++ b/kernel/sys.c @@ -233,6 +233,7 @@ asmlinkage int sys_setregid(gid_t rgid, gid_t egid) if (rgid != (gid_t) -1 || (egid != (gid_t) -1 && egid != old_rgid)) current->sgid = current->egid; + current->fsgid = current->egid; return 0; } @@ -242,9 +243,9 @@ asmlinkage int sys_setregid(gid_t rgid, gid_t egid) asmlinkage int sys_setgid(gid_t gid) { if (suser()) - current->gid = current->egid = current->sgid = gid; + current->gid = current->egid = current->sgid = current->fsgid = gid; else if ((gid == current->gid) || (gid == current->sgid)) - current->egid = gid; + current->egid = current->fsgid = gid; else return -EPERM; return 0; @@ -321,6 +322,7 @@ asmlinkage int sys_setreuid(uid_t ruid, uid_t euid) if (ruid != (uid_t) -1 || (euid != (uid_t) -1 && euid != old_ruid)) current->suid = current->euid; + current->fsuid = euid; return 0; } @@ -338,14 +340,43 @@ asmlinkage int sys_setreuid(uid_t ruid, uid_t euid) asmlinkage int sys_setuid(uid_t uid) { if (suser()) - current->uid = current->euid = current->suid = uid; + current->uid = current->euid = current->suid = current->fsuid = uid; else if ((uid == current->uid) || (uid == current->suid)) - current->euid = uid; + current->fsuid = current->euid = uid; else return -EPERM; return(0); } +/* + * "setfsuid()" sets the fsuid - the uid used for filesystem checks. This + * is used for "access()" and for the NFS deamon (letting nfsd stay at + * whatever uid it wants to). It normally shadows "euid", except when + * explicitly set by setfsuid() or for access.. + */ +asmlinkage int sys_setfsuid(uid_t uid) +{ + int old_fsuid = current->fsuid; + + if (uid == current->uid || uid == current->euid || + uid == current->suid || uid == current->fsuid || suser()) + current->fsuid = uid; + return old_fsuid; +} + +/* + * Samma på svenska.. + */ +asmlinkage int sys_setfsgid(gid_t gid) +{ + int old_fsgid = current->fsgid; + + if (gid == current->gid || gid == current->egid || + gid == current->sgid || gid == current->fsgid || suser()) + current->fsgid = gid; + return old_fsgid; +} + asmlinkage int sys_times(struct tms * tbuf) { if (tbuf) { @@ -542,7 +573,7 @@ int in_group_p(gid_t grp) { int i; - if (grp == current->egid) + if (grp == current->fsgid) return 1; for (i = 0; i < NGROUPS; i++) { diff --git a/kernel/sys_call.S b/kernel/sys_call.S index 587ccd4af741..ae1102c4ed67 100644 --- a/kernel/sys_call.S +++ b/kernel/sys_call.S @@ -538,5 +538,7 @@ _sys_call_table: .long _sys_sysfs /* 135 */ .long _sys_personality .long 0 /* for afs_syscall */ + .long _sys_setfsuid + .long _sys_setfsgid .space (NR_syscalls-137)*4 diff --git a/mm/mmap.c b/mm/mmap.c index 3a4005b9faad..605eb33706b5 100644 --- a/mm/mmap.c +++ b/mm/mmap.c @@ -121,7 +121,8 @@ int do_mmap(struct file * file, unsigned long addr, unsigned long len, else mask |= PAGE_SHARED; - vma = kmalloc(sizeof(struct vm_area_struct), GFP_KERNEL); + vma = (struct vm_area_struct *)kmalloc(sizeof(struct vm_area_struct), + GFP_KERNEL); if (!vma) return -ENOMEM; diff --git a/mm/mprotect.c b/mm/mprotect.c index 472a799adabb..b539c41f0610 100644 --- a/mm/mprotect.c +++ b/mm/mprotect.c @@ -63,20 +63,20 @@ static inline int mprotect_fixup_start(struct vm_area_struct * vma, unsigned long end, int newflags, int prot) { - struct vm_area_struct * new; + struct vm_area_struct * n; - new = kmalloc(sizeof(struct vm_area_struct), GFP_KERNEL); - if (!new) + n = (struct vm_area_struct *) kmalloc(sizeof(struct vm_area_struct), GFP_KERNEL); + if (!n) return -ENOMEM; - *new = *vma; + *n = *vma; vma->vm_start = end; - new->vm_end = end; - vma->vm_offset += vma->vm_start - new->vm_start; - new->vm_flags = newflags; - new->vm_page_prot = prot; - if (new->vm_inode) - new->vm_inode->i_count++; - insert_vm_struct(current, new); + n->vm_end = end; + vma->vm_offset += vma->vm_start - n->vm_start; + n->vm_flags = newflags; + n->vm_page_prot = prot; + if (n->vm_inode) + n->vm_inode->i_count++; + insert_vm_struct(current, n); merge_segments(current->mm->mmap); return 0; } @@ -85,20 +85,20 @@ static inline int mprotect_fixup_end(struct vm_area_struct * vma, unsigned long start, int newflags, int prot) { - struct vm_area_struct * new; + struct vm_area_struct * n; - new = kmalloc(sizeof(struct vm_area_struct), GFP_KERNEL); - if (!new) + n = (struct vm_area_struct *) kmalloc(sizeof(struct vm_area_struct), GFP_KERNEL); + if (!n) return -ENOMEM; - *new = *vma; + *n = *vma; vma->vm_end = start; - new->vm_start = start; - new->vm_offset += new->vm_start - vma->vm_start; - new->vm_flags = newflags; - new->vm_page_prot = prot; - if (new->vm_inode) - new->vm_inode->i_count++; - insert_vm_struct(current, new); + n->vm_start = start; + n->vm_offset += n->vm_start - vma->vm_start; + n->vm_flags = newflags; + n->vm_page_prot = prot; + if (n->vm_inode) + n->vm_inode->i_count++; + insert_vm_struct(current, n); merge_segments(current->mm->mmap); return 0; } diff --git a/net/inet/eth.c b/net/inet/eth.c index cd7ca1ef6aff..550e0f8f0cc2 100644 --- a/net/inet/eth.c +++ b/net/inet/eth.c @@ -166,7 +166,7 @@ int eth_rebuild_header(void *buff, struct device *dev, unsigned long dst, unsigned short eth_type_trans(struct sk_buff *skb, struct device *dev) { struct ethhdr *eth = (struct ethhdr *) skb->data; - char *rawp; + unsigned char *rawp; if(*eth->h_dest&1) { -- 2.39.5