Пример #1
0
asmlinkage int sys_setrlimit(unsigned int resource, struct rlimit *rlim)
{
	struct rlimit new_rlim, *old_rlim;
	int err;

	if (resource >= RLIM_NLIMITS)
		return -EINVAL;
	err = verify_area(VERIFY_READ, rlim, sizeof(*rlim));
	if (err)
		return err;
	memcpy_fromfs(&new_rlim, rlim, sizeof(*rlim));
	if (new_rlim.rlim_cur < 0 || new_rlim.rlim_max < 0)
		return -EINVAL;
	old_rlim = current->rlim + resource;
	if (((new_rlim.rlim_cur > old_rlim->rlim_max) ||
	     (new_rlim.rlim_max > old_rlim->rlim_max)) &&
	    !suser())
		return -EPERM;
	if (resource == RLIMIT_NOFILE) {
		if (new_rlim.rlim_cur > NR_OPEN || new_rlim.rlim_max > NR_OPEN)
			return -EPERM;
	}
	*old_rlim = new_rlim;
	return 0;
}
Пример #2
0
int
cnioctl(dev_t dev, u_long cmd, caddr_t data, int flag,
    struct proc *p)
{
	int error;

	/*
	 * Superuser can always use this to wrest control of console
	 * output from the "virtual" console.
	 */
	if (cmd == TIOCCONS && constty != NULL) {
		error = suser(p, SUSER_NOACCT);
		if (error)
			return (error);
		constty = NULL;
		return (0);
	}

	/*
	 * Redirect the ioctl, if that's appropriate.
	 * Note that strange things can happen, if a program does
	 * ioctls on /dev/console, then the console is redirected
	 * out from under it.
	 */
	if (constty != NULL)
		dev = constty->t_dev;
	else if (cn_tab == NULL)
		return ENXIO;
	else
		dev = cn_tab->cn_dev;
	return ((*cdevsw[major(dev)].d_ioctl)(dev, cmd, data, flag, p));
}
Пример #3
0
int minix_rmdir(register struct inode *dir, char *name, size_t len)
{
    int retval;
    register struct inode *inode;
    struct buffer_head *bh;
    struct minix_dir_entry *de;

    inode = NULL;
    bh = minix_find_entry(dir, name, len, &de);
    retval = -ENOENT;
    if (!bh)
	goto end_rmdir;
    retval = -EPERM;
    if (!(inode = iget(dir->i_sb, (ino_t) de->inode)))
	goto end_rmdir;
    if ((dir->i_mode & S_ISVTX) && !suser() &&
	current->euid != inode->i_uid && current->euid != dir->i_uid)
	goto end_rmdir;
    if (inode->i_dev != dir->i_dev)
	goto end_rmdir;
    if (inode == dir)		/* we may not delete ".", but "../dir" is ok */
	goto end_rmdir;
    if (!S_ISDIR(inode->i_mode)) {
	retval = -ENOTDIR;
	goto end_rmdir;
    }
    if (!empty_dir(inode)) {
	retval = -ENOTEMPTY;
	goto end_rmdir;
    }
    if (de->inode != inode->i_ino) {
	retval = -ENOENT;
	goto end_rmdir;
    }
    if (inode->i_count > 1) {
	retval = -EBUSY;
	goto end_rmdir;
    }
    if (inode->i_nlink != 2)
	printk("empty directory has nlink!=2 (%u)\n", inode->i_nlink);
    de->inode = 0;

#ifdef BLOAT_FS
    dir->i_version = ++event;
#endif

    mark_buffer_dirty(bh, 1);
    inode->i_nlink = 0;
    inode->i_dirt = 1;
    inode->i_ctime = dir->i_ctime = dir->i_mtime = CURRENT_TIME;
    dir->i_nlink--;
    dir->i_dirt = 1;
    retval = 0;

  end_rmdir:
    iput(dir);
    iput(inode);
    unmap_brelse(bh);
    return retval;
}
Пример #4
0
/*
 * Reboot system call: for obvious reasons only root may call it,
 * and even root needs to set up some magic numbers in the registers
 * so that some mistake won't make this reboot the whole machine.
 * You can also set the meaning of the ctrl-alt-del-key here.
 *
 * reboot doesn't sync: do that yourself before calling this.
 */
asmlinkage int sys_reboot(int magic, int magic_too, int flag)
{
	if (!suser())
		return -EPERM;
	if (magic != 0xfee1dead || magic_too != 672274793)
		return -EINVAL;
	if (flag == 0x01234567) {
#ifdef CONFIG_SCSI_GDTH
		gdth_halt();
#endif
		hard_reset_now();
	} else if (flag == 0x89ABCDEF)
		C_A_D = 1;
	else if (!flag)
		C_A_D = 0;
	else if (flag == 0xCDEF0123) {
#ifdef CONFIG_SCSI_GDTH
		gdth_halt();
#endif
		printk(KERN_EMERG "System halted\n");
		sys_kill(-1, SIGKILL);
#if defined(CONFIG_APM) && defined(CONFIG_APM_POWER_OFF)
		apm_power_off();
#endif
		do_exit(0);
	} else
		return -EINVAL;
	return (0);
}
Пример #5
0
/*
 * Perform process accounting functions.
 */
void sysacct(void)
{
	register struct inode *ip;
	register struct a {
		char	*fname;
	} *uap;

	uap = (struct a *)u.u_ap;
	if (suser()) {
		if (uap->fname==NULL) {
			if (acctp) {
				plock(acctp);
				iput(acctp);
				acctp = NULL;
			}
			return;
		}
		if (acctp) {
			u.u_error = EBUSY;
			return;
		}
		u.u_dirp = uap->fname;
		ip = namei(uchar, 0);
		if (ip == NULL) {
			return;
		}
		if ((ip->i_mode & IFMT) != IFREG) {
			u.u_error = EACCES;
			iput(ip);
			return;
		}
		acctp = ip;
		prele(ip);
	}
}
Пример #6
0
/* afs_put_super
 * Called from unmount to release super_block. */
static void
afs_put_super(struct super_block *sbp)
{
    AFS_GLOCK();
    AFS_STATCNT(afs_unmount);

    if (!suser()) {
	AFS_GUNLOCK();
	return;
    }

    afs_globalVFS = 0;
    afs_globalVp = 0;

    afs_shutdown();
#if defined(AFS_LINUX24_ENV)
    mntput(afs_cacheMnt);
#endif

    osi_linux_verify_alloced_memory();
    AFS_GUNLOCK();

    sbp->s_dev = 0;
    MOD_DEC_USE_COUNT;
}
Пример #7
0
int
sys_munlock(struct proc *p, void *v, register_t *retval)
{
	struct sys_munlock_args /* {
		syscallarg(const void *) addr;
		syscallarg(size_t) len;
	} */ *uap = v;
	vaddr_t addr;
	vsize_t size, pageoff;
	int error;

	/*
	 * extract syscall args from uap
	 */

	addr = (vaddr_t)SCARG(uap, addr);
	size = (vsize_t)SCARG(uap, len);

	/*
	 * align the address to a page boundary, and adjust the size accordingly
	 */
	ALIGN_ADDR(addr, size, pageoff);
	if (addr > SIZE_MAX - size)
		return (EINVAL);		/* disallow wrap-around. */

#ifndef pmap_wired_count
	if ((error = suser(p, 0)) != 0)
		return (error);
#endif

	error = uvm_map_pageable(&p->p_vmspace->vm_map, addr, addr+size, TRUE,
	    0);
	return (error == 0 ? 0 : ENOMEM);
}
Пример #8
0
static int
wan_ioctl(struct ifnet *ifp, int cmd, struct ifreq *ifr)
{
	sdla_t			*card;
	wanpipe_common_t	*common = WAN_IFP_TO_COMMON(ifp);
	int			err;

	SAN_ASSERT(common == NULL);
	SAN_ASSERT(common->card == NULL);

	if ((err = suser(curproc, 0)) != 0)
		return err;

	switch (cmd) {
	case SIOC_WANPIPE_HWPROBE:
		err = wan_ioctl_hwprobe(ifp, ifr->ifr_data);
		break;

	case SIOC_WANPIPE_DUMP:
		err = wan_ioctl_dump(card, ifr->ifr_data);
		break;

	default:
		err = ENOTTY;
		break;
	}
	return err;
}
Пример #9
0
static int lpx_USER_r_attach( struct socket *so,
                            int proto,
                            struct proc *td )
{
    int error = 0;
    int s;
    struct lpxpcb *lpxp = sotolpxpcb(so);


        if (td != NULL && (error = suser(td->p_ucred, &td->p_acflag)) != 0)
        return (error);

    s = splnet();
    error = Lpx_PCB_alloc(so, &lpxrawpcb, td);
    splx(s);
    if (error)
        return (error);
    error = soreserve(so, lpxsendspace, lpxrecvspace);
    if (error)
        return (error);
    lpxp = sotolpxpcb(so);
    lpxp->lpxp_faddr.x_host = lpx_broadhost;
    lpxp->lpxp_flags = LPXP_RAWIN | LPXP_RAWOUT;
    return (error);
}
Пример #10
0
int send_sig(unsigned long sig,struct task_struct * p,int priv)
{
	if (!p || sig > 32)
		return -EINVAL;
	if (!priv && ((sig != SIGCONT) || (current->session != p->session)) &&
	    (current->euid ^ p->suid) && (current->euid ^ p->uid) &&
	    (current->uid ^ p->suid) && (current->uid ^ p->uid) &&
	    !suser())
		return -EPERM;
	if (!sig)
		return 0;
	/*
	 * Forget it if the process is already zombie'd.
	 */
	if (!p->sig)
		return 0;
	if ((sig == SIGKILL) || (sig == SIGCONT)) {
		if (p->state == TASK_STOPPED)
			wake_up_process(p);
		p->exit_code = 0;
		p->signal &= ~( (1<<(SIGSTOP-1)) | (1<<(SIGTSTP-1)) |
				(1<<(SIGTTIN-1)) | (1<<(SIGTTOU-1)) );
	}
	if (sig == SIGSTOP || sig == SIGTSTP || sig == SIGTTIN || sig == SIGTTOU)
		p->signal &= ~(1<<(SIGCONT-1));
	/* Actually generate the signal */
	generate(sig,p);
	return 0;
}
Пример #11
0
int
sbbcopen(dev_t dev, int flag, int mode, struct proc *p)
{
	struct sbbc_softc *sc;
	struct tty *tp;
	int unit = minor(dev);

	if (unit >= sbbc_cd.cd_ndevs)
		return (ENXIO);
	sc = sbbc_cd.cd_devs[unit];
	if (sc == NULL)
		return (ENXIO);

	if (sc->sc_tty)
		tp = sc->sc_tty;
	else
		tp = sc->sc_tty = ttymalloc(0);

	tp->t_oproc = sbbcstart;
	tp->t_param = sbbcparam;
	tp->t_dev = dev;
	if ((tp->t_state & TS_ISOPEN) == 0) {
		ttychars(tp);
		tp->t_iflag = TTYDEF_IFLAG;
		tp->t_oflag = TTYDEF_OFLAG;
		tp->t_cflag = TTYDEF_CFLAG;
		tp->t_lflag = TTYDEF_LFLAG;
		tp->t_ispeed = tp->t_ospeed = TTYDEF_SPEED;
		ttsetwater(tp);
	} else if ((tp->t_state & TS_XCLUDE) && suser(p, 0))
		return (EBUSY);
	tp->t_state |= TS_CARR_ON;

	return ((*linesw[tp->t_line].l_open)(dev, tp, p));
}
Пример #12
0
/* afs_put_super
 * Called from unmount to release super_block. */
static void
afs_put_super(struct super_block *sbp)
{
    AFS_GLOCK();
    AFS_STATCNT(afs_unmount);

    if (!suser()) {
	AFS_GUNLOCK();
	return;
    }

    afs_globalVFS = 0;
    afs_globalVp = 0;

    osi_linux_free_inode_pages();	/* invalidate and release remaining AFS inodes. */
    afs_shutdown();
#if defined(AFS_LINUX24_ENV)
    mntput(afs_cacheMnt);
#endif

    osi_linux_verify_alloced_memory();
    AFS_GUNLOCK();

    sbp->s_dev = 0;
    MOD_DEC_USE_COUNT;
}
Пример #13
0
int
reboot(struct proc *p, register struct reboot_args *uap, __unused int32_t *retval)
{
	char command[64];
	int error=0;
	size_t dummy=0;
#if CONFIG_MACF
	kauth_cred_t my_cred;
#endif

	AUDIT_ARG(cmd, uap->opt);

	command[0] = '\0';

	if ((error = suser(kauth_cred_get(), &p->p_acflag)))
		return(error);	
	
	if (uap->opt & RB_COMMAND)
		error = copyinstr(uap->command,
					(void *)command, sizeof(command), (size_t *)&dummy);
#if CONFIG_MACF
	if (error)
		return (error);
	my_cred = kauth_cred_proc_ref(p);
	error = mac_system_check_reboot(my_cred, uap->opt);
	kauth_cred_unref(&my_cred);
#endif
	if (!error) {
		OSBitOrAtomic(P_REBOOT, &p->p_flag);  /* No more signals for this proc */
		boot(RB_BOOT, uap->opt, command);
	}
	return(error);
}
Пример #14
0
int scull_u_open (struct inode *inode, struct file *filp)
{
    Scull_Dev *dev = &scull_u_device; /* device information */
    int num = NUM(inode->i_rdev);

    if (num > 0) return -ENODEV; /* 1 device only */
    if (scull_u_count && 
        (scull_u_owner != current->uid) &&  /* allow user */
        (scull_u_owner != current->euid) && /* allow whoever did su */
        !suser()) /* still allow root */
         return -EBUSY;   /* -EPERM would confuse the user */

    if (scull_u_count == 0)
        scull_u_owner = current->uid; /* grab it */

    scull_u_count++;

    /* then, everything else is copied from the bare scull device */

    if ( (filp->f_flags & O_ACCMODE) == O_WRONLY)
        scull_trim(dev);
    filp->private_data = dev;
    MOD_INC_USE_COUNT;
    return 0;          /* success */
}
Пример #15
0
/*ARGSUSED*/
int
mmopen(dev_t dev, int flag, int mode, struct proc *p)
{
	switch (minor(dev)) {
	case 0:
	case 1:
	case 2:
	case 12:
		break;
#ifdef APERTURE
	case 4:
	        if (suser(p, 0) != 0 || !allowaperture)
			return (EPERM);

		/* authorize only one simultaneous open() */
		if (ap_open_count > 0)
			return(EPERM);
		ap_open_count++;
		break;
#endif
	default:
		return (ENXIO);
	}
	return (0);
}
Пример #16
0
static int
ip_proto_bind (struct socket *sock, struct sockaddr *uaddr,
	       int addr_len)
{
  struct sockaddr_in addr;
  volatile struct sock *sk, *sk2;
  unsigned short snum;
  sk = sock->data;
   if (sk == NULL)
     {
	printk ("Warning: sock->data = NULL: %d\n" ,__LINE__);
	return (0);
     }
  /* check this error. */
  if (sk->state != TCP_CLOSE) return (-EIO);
  verify_area (uaddr, addr_len);
  memcpy_fromfs (&addr, uaddr, min (sizeof (addr), addr_len));
  if (addr.sin_family && addr.sin_family != AF_INET)
    return (-EIO); /* this needs to be changed. */
  snum = net16(addr.sin_port);
  PRINTK ("bind sk =%X to port = %d\n", sk, snum);
  print_sk (sk);
  sk = sock->data;

  /* we can't just leave the socket bound wherever it is, it might be bound
     to a priveledged port. However, since there seems to be a bug here,
     we will leave it if the port is not priveledged(sp?) */

  if (snum == 0)
    {
       if ( sk->num > PROT_SOCK) return (0);
       snum = get_new_socknum (sk->prot, 0);
    }

  if (snum <= PROT_SOCK && !suser())
    return (-EPERM);

  if (my_ip_addr(addr.sin_addr.s_addr) || addr.sin_addr.s_addr == 0)
    sk->saddr = addr.sin_addr.s_addr;
  PRINTK ("sock_array[%d] = %X:\n", snum & (SOCK_ARRAY_SIZE -1),
	  sk->prot->sock_array[snum & (SOCK_ARRAY_SIZE -1)]);
  print_sk (sk->prot->sock_array[snum & (SOCK_ARRAY_SIZE -1)]);

  /* make sure we are allowed to bind here. */
  for (sk2 = sk->prot->sock_array[snum & (SOCK_ARRAY_SIZE -1)];
       sk2 != NULL;
       sk2 = sk2->next)
    {
       if (sk2->num != snum) continue;
       if (sk2->saddr != sk->saddr) continue;
       if (!sk->reuse) return (-EADDRINUSE);
       if (!sk2->reuse) return (-EADDRINUSE);
    }
  remove_sock (sk);
  put_sock(snum, sk);
  sk->dummy_th.source = net16(sk->num);
  sk->daddr = 0;
  sk->dummy_th.dest = 0;
  return (0);
}
Пример #17
0
/* ARGSUSED */
int
sys_setegid(struct proc *p, void *v, register_t *retval)
{
	struct sys_setegid_args /* {
		syscallarg(gid_t) egid;
	} */ *uap = v;
	struct pcred *pc = p->p_cred;
	gid_t egid;
	int error;

	egid = SCARG(uap, egid);

	if (pc->pc_ucred->cr_gid == egid)
		return (0);

	if (egid != pc->p_rgid && egid != pc->p_svgid &&
	    (error = suser(p, 0)))
		return (error);

	/*
	 * Copy credentials so other references do not see our changes.
	 */
	pc->pc_ucred = crcopy(pc->pc_ucred);
	pc->pc_ucred->cr_gid = egid;
	atomic_setbits_int(&p->p_p->ps_flags, PS_SUGID);
	return (0);
}
Пример #18
0
int
afmioctl(dev_t dev, ioctlcmd_t cmd, void *addr, int flag,
    struct lwp *l)
{
	int	error = 0;
	struct atm_flowmap *flowmap;
	struct ifnet *ifp;

	/* check cmd for superuser only */
	switch (cmd) {
	case AFM_GETFMAP:
		break;
	default:
#if (__FreeBSD_version > 400000)
		error = suser(p);
#else
		error = kauth_authorize_network(l->l_cred, KAUTH_NETWORK_ALTQ,
		    KAUTH_REQ_NETWORK_ALTQ_AFMAP, NULL, NULL, NULL);
#endif
		if (error)
			return (error);
		break;
	}

	/* lookup interface */
	flowmap = (struct atm_flowmap *)addr;
	flowmap->af_ifname[IFNAMSIZ-1] = '\0';
	ifp = ifunit(flowmap->af_ifname);
	if (ifp == NULL || (ifp->if_flags & IFF_RUNNING) == 0)
		error = ENXIO;
	else
		error = ifp->if_ioctl(ifp, cmd, addr);

	return error;
}
Пример #19
0
/*
 * Credential check based on process requesting service, and per-attribute
 * permissions.
 */
static int
ufs_extattr_credcheck(struct vnode *vp, struct ufs_extattr_list_entry *uele,
    struct ucred *cred, struct proc *p, int access)
{

	/*
	 * Kernel-invoked always succeeds.
	 */
	if (cred == NULL)
		return (0);

	/*
	 * Do not allow privileged processes in jail to directly
	 * manipulate system attributes.
	 *
	 * XXX What capability should apply here?
	 * Probably CAP_SYS_SETFFLAG.
	 */
	switch (uele->uele_attrnamespace) {
	case EXTATTR_NAMESPACE_SYSTEM:
		return (suser(cred, &p->p_acflag));
	case EXTATTR_NAMESPACE_USER:
		return (VOP_ACCESS(vp, access, cred, p));
	default:
		return (EPERM);
	}
}
Пример #20
0
int
sys_mlockall(struct proc *p, void *v, register_t *retval)
{
	struct sys_mlockall_args /* {
		syscallarg(int) flags;
	} */ *uap = v;
	int error, flags;

	flags = SCARG(uap, flags);

	if (flags == 0 ||
	    (flags & ~(MCL_CURRENT|MCL_FUTURE)) != 0)
		return (EINVAL);

#ifndef pmap_wired_count
	if ((error = suser(p, 0)) != 0)
		return (error);
#endif

	error = uvm_map_pageable_all(&p->p_vmspace->vm_map, flags,
	    p->p_rlimit[RLIMIT_MEMLOCK].rlim_cur);
	if (error != 0 && error != ENOMEM)
		return (EAGAIN);
	return (error);
}
Пример #21
0
/*
 * Written 01/25/92 by Simmule Turner, heavily changed by Linus.
 *
 * The swapon system call
 */
asmlinkage int sys_swapon(const char * specialfile, int swap_flags)
{
	struct swap_info_struct * p;
	struct inode * swap_inode;
	unsigned int type;
	int i, j, prev;
	int error;
	struct file filp;
	static int least_priority = 0;

	memset(&filp, 0, sizeof(filp));
	if (!suser())
		return -EPERM;
	p = swap_info;
	for (type = 0 ; type < nr_swapfiles ; type++,p++)
		if (!(p->flags & SWP_USED))
			break;
	if (type >= MAX_SWAPFILES)
		return -EPERM;
	if (type >= nr_swapfiles)
		nr_swapfiles = type+1;
	p->flags = SWP_USED;
	p->swap_file = NULL;
	p->swap_device = 0;
	p->swap_map = NULL;
	p->swap_lockmap = NULL;
	p->lowest_bit = 0;
	p->highest_bit = 0;
	p->cluster_nr = 0;
	p->max = 1;
	p->next = -1;
	if (swap_flags & SWAP_FLAG_PREFER) {
		p->prio =
		  (swap_flags & SWAP_FLAG_PRIO_MASK)>>SWAP_FLAG_PRIO_SHIFT;
	} else {
Пример #22
0
int
i386_iopl(struct proc *p, void *args, register_t *retval)
{
    int error;
    struct trapframe *tf = p->p_md.md_regs;
    struct i386_iopl_args ua;

    if ((error = suser(p, 0)) != 0)
        return error;
#ifdef APERTURE
    if (!allowaperture && securelevel > 0)
        return EPERM;
#else
    if (securelevel > 0)
        return EPERM;
#endif

    if ((error = copyin(args, &ua, sizeof(ua))) != 0)
        return error;

    if (ua.iopl)
        tf->tf_eflags |= PSL_IOPL;
    else
        tf->tf_eflags &= ~PSL_IOPL;

    return 0;
}
Пример #23
0
/* Some basic sanity checks on the arguments passed to divert_ioctl() */
int check_args(struct divert_cf *div_cf, struct net_device **dev)
{
	char devname[32];
		
	if (dev == NULL)
		return -EFAULT;
	
	/* GETVERSION: all other args are unused */
	if (div_cf->cmd == DIVCMD_GETVERSION)
		return 0;
	
	/* Network device index should reasonably be between 0 and 1000 :) */
	if (div_cf->dev_index < 0 || div_cf->dev_index > 1000) 
		return -EINVAL;
			
	/* Let's try to find the ifname */
	sprintf(devname, "eth%d", div_cf->dev_index);
	*dev = dev_get_by_name(devname);
	
	/* dev should NOT be null */
	if (*dev == NULL)
		return -EINVAL;
	
	/* user issuing the ioctl must be a super one :) */
	if (!suser())
		return -EPERM;

	/* Device must have a divert_blk member NOT null */
	if ((*dev)->divert == NULL)
		return -EFAULT;

	return 0;
}
Пример #24
0
/* ARGSUSED */
int
sys_setgroups(struct proc *p, void *v, register_t *retval)
{
	struct sys_setgroups_args /* {
		syscallarg(int) gidsetsize;
		syscallarg(const gid_t *) gidset;
	} */ *uap = v;
	struct pcred *pc = p->p_cred;
	u_int ngrp;
	int error;

	if ((error = suser(p, 0)) != 0)
		return (error);
	ngrp = SCARG(uap, gidsetsize);
	if (ngrp > NGROUPS)
		return (EINVAL);
	pc->pc_ucred = crcopy(pc->pc_ucred);
	error = copyin((caddr_t)SCARG(uap, gidset),
	    (caddr_t)pc->pc_ucred->cr_groups, ngrp * sizeof(gid_t));
	if (error)
		return (error);
	pc->pc_ucred->cr_ngroups = ngrp;
	atomic_setbits_int(&p->p_p->ps_flags, PS_SUGID);
	return (0);
}
Пример #25
0
int sys_stime(long * tptr)
{
	if (!suser())
		return -EPERM;
	startup_time = get_fs_long((unsigned long *)tptr) - jiffies/HZ;
	return 0;
}
Пример #26
0
/*
 *	Routine:	macx_backing_store_recovery
 *	Function:
 *		Syscall interface to set a tasks privilege
 *		level so that it is not subject to 
 *		macx_backing_store_suspend
 */
int
macx_backing_store_recovery(
	struct macx_backing_store_recovery_args *args)
{
	int		pid = args->pid;
	int		error;
	struct proc	*p =  current_proc();
	boolean_t	funnel_state;

	funnel_state = thread_funnel_set(kernel_flock, TRUE);
	if ((error = suser(kauth_cred_get(), 0)))
		goto backing_store_recovery_return;

	/* for now restrict backing_store_recovery */
	/* usage to only present task */
	if(pid != proc_selfpid()) {
		error = EINVAL;
		goto backing_store_recovery_return;
	}

	task_backing_store_privileged(p->task);

backing_store_recovery_return:
	(void) thread_funnel_set(kernel_flock, FALSE);
	return(error);
}
Пример #27
0
/* these should be distributed to the different protocol routines. */
static int
ip_proto_ioctl (struct socket *sock, unsigned int cmd, 
		unsigned long arg)
{
   volatile struct sock *sk;
   sk = sock->data;
   if (sk == NULL)
     {
	printk ("Warning: sock->data = NULL: %d\n" ,__LINE__);
	return (0);
     }

  PRINTK ("in ip_proto_ioctl\n");
  switch (cmd)
    {

      case IP_SET_DEV:
       if (!suser())
	 return (-EPERM);
       return (ip_set_dev((struct ip_config *)arg));
#if 0
    case IP_ADD_ROUTE:
      ip_add_route ((struct rtable *) arg);
      return (0);
#endif
    default:
       if (!sk->prot->ioctl)
	 return (-EINVAL);
       return (sk->prot->ioctl (sk, cmd, arg));
    }
}
Пример #28
0
int scull_w_open (struct inode *inode, struct file *filp)
{
    Scull_Dev *dev = &scull_w_device; /* device information */
    int num = NUM(inode->i_rdev);

    if (num > 0) return -ENODEV; /* 1 device only */
    while (scull_w_count && 
      (scull_w_owner != current->uid) &&  /* allow user */
      (scull_w_owner != current->euid) && /* allow whoever did su */
      !suser()) {
        if (filp->f_flags & O_NONBLOCK) return -EAGAIN; 
        interruptible_sleep_on(&scull_w_wait);
        if (current->signal & ~current->blocked) /* a signal arrived */
          return -ERESTARTSYS; /* tell the fs layer to handle it */
        /* else, loop */
    }
    if (scull_w_count == 0)
        scull_w_owner = current->uid; /* grab it */
    scull_w_count++;

    /* then, everything else is copied from the bare scull device */

    if ( (filp->f_flags & O_ACCMODE) == O_WRONLY)
        scull_trim(dev);
    filp->private_data = dev;
    MOD_INC_USE_COUNT;
    return 0;          /* success */
}
Пример #29
0
/* ARGSUSED */
int
sys_setuid(struct proc *p, void *v, register_t *retval)
{
	struct sys_setuid_args /* {
		syscallarg(uid_t) uid;
	} */ *uap = v;
	struct pcred *pc = p->p_cred;
	uid_t uid;
	int error;

	uid = SCARG(uap, uid);

	if (pc->pc_ucred->cr_uid == uid &&
	    pc->p_ruid == uid &&
	    pc->p_svuid == uid)
		return (0);

	if (uid != pc->p_ruid &&
	    uid != pc->p_svuid &&
	    uid != pc->pc_ucred->cr_uid &&
	    (error = suser(p, 0)))
		return (error);

	/*
	 * Everything's okay, do it.
	 */
	if (uid == pc->pc_ucred->cr_uid ||
	    suser(p, 0) == 0) {
		/*
		 * Transfer proc count to new user.
		 */
		if (uid != pc->p_ruid) {
			(void)chgproccnt(pc->p_ruid, -p->p_p->ps_refcnt);
			(void)chgproccnt(uid, p->p_p->ps_refcnt);
		}
		pc->p_ruid = uid;
		pc->p_svuid = uid;
	}

	/*
	 * Copy credentials so other references do not see our changes.
	 */
	pc->pc_ucred = crcopy(pc->pc_ucred);
	pc->pc_ucred->cr_uid = uid;
	atomic_setbits_int(&p->p_p->ps_flags, PS_SUGID);
	return (0);
}
Пример #30
0
static int rtmac_chrdev_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
{
	struct rtmac_config cfg;
	struct rtnet_device *rtdev;

	if( !suser() )
		return -EPERM;

	if( copy_from_user(&cfg, (void*)arg, sizeof(struct rtmac_config)) )
		return -EFAULT;

	rtdev = rtdev_get_by_name(cfg.if_name);

	if( !rtdev ) {
		rt_printk("RTmac: invalid interface %s\n", cfg.if_name);
		return -ENODEV;
	}

	if( !(rtdev->rtmac && rtdev->rtmac->ioctl_ops) ) {
		return -ENOTTY;
	}

	switch( cmd ) {
	case RTMAC_IOC_CLIENT:
		return rtmac_ioctl_client(rtdev);
		break;
	case RTMAC_IOC_MASTER:
		return rtmac_ioctl_master(rtdev, cfg.cycle, cfg.mtu);
		break;
	case RTMAC_IOC_UP:
		return rtmac_ioctl_up(rtdev);
		break;
	case RTMAC_IOC_DOWN:
		return rtmac_ioctl_down(rtdev);
		break;
	case RTMAC_IOC_ADD:
		return rtmac_ioctl_add(rtdev, cfg.ip_addr);
		break;
	case RTMAC_IOC_REMOVE:
		return rtmac_ioctl_remove(rtdev, cfg.ip_addr);
		break;
	case RTMAC_IOC_ADD_NRT:
		return rtmac_ioctl_add_nrt(rtdev, cfg.ip_addr);
		break;
	case RTMAC_IOC_REMOVE_NRT:
		return rtmac_ioctl_remove_nrt(rtdev, cfg.ip_addr);
		break;
	case RTMAC_IOC_CYCLE:
		return rtmac_ioctl_cycle(rtdev, cfg.cycle);
		break;
	case RTMAC_IOC_MTU:
		return rtmac_ioctl_mtu(rtdev, cfg.mtu);
		break;
	case RTMAC_IOC_OFFSET:
		return rtmac_ioctl_offset(rtdev, cfg.ip_addr, cfg.offset);
	default:
		return -ENOTTY;
	}
}