#include <linux/capability.h>
#include <linux/ptrace.h>
#include <linux/seq_file.h>
+#include <linux/mutex.h>
#include <asm/uaccess.h>
static inline void shm_inc (int id) {
struct shmid_kernel *shp;
- if(!(shp = shm_lock(id)))
- BUG();
+ shp = shm_lock(id);
+ BUG_ON(!shp);
shp->shm_atim = get_seconds();
shp->shm_lprid = current->tgid;
shp->shm_nattch++;
*
* @shp: struct to free
*
- * It has to be called with shp and shm_ids.sem locked,
+ * It has to be called with shp and shm_ids.mutex locked,
* but returns with shp unlocked and freed.
*/
static void shm_destroy (struct shmid_kernel *shp)
int id = file->f_dentry->d_inode->i_ino;
struct shmid_kernel *shp;
- down (&shm_ids.sem);
+ mutex_lock(&shm_ids.mutex);
/* remove from the list of attaches of the shm segment */
- if(!(shp = shm_lock(id)))
- BUG();
+ shp = shm_lock(id);
+ BUG_ON(!shp);
shp->shm_lprid = current->tgid;
shp->shm_dtim = get_seconds();
shp->shm_nattch--;
shm_destroy (shp);
else
shm_unlock(shp);
- up (&shm_ids.sem);
+ mutex_unlock(&shm_ids.mutex);
}
static int shm_mmap(struct file * file, struct vm_area_struct * vma)
ret = shmem_mmap(file, vma);
if (ret == 0) {
vma->vm_ops = &shm_vm_ops;
+ if (!(vma->vm_flags & VM_WRITE))
+ vma->vm_flags &= ~VM_MAYWRITE;
shm_inc(file->f_dentry->d_inode->i_ino);
}
struct shmid_kernel *shp;
int err, id = 0;
- down(&shm_ids.sem);
+ mutex_lock(&shm_ids.mutex);
if (key == IPC_PRIVATE) {
err = newseg(key, shmflg, size);
} else if ((id = ipc_findkey(&shm_ids, key)) == -1) {
err = -EEXIST;
} else {
shp = shm_lock(id);
- if(shp==NULL)
- BUG();
+ BUG_ON(shp==NULL);
if (shp->shm_segsz < size)
err = -EINVAL;
else if (ipcperms(&shp->shm_perm, shmflg))
}
shm_unlock(shp);
}
- up(&shm_ids.sem);
+ mutex_unlock(&shm_ids.mutex);
return err;
}
return err;
memset(&shm_info,0,sizeof(shm_info));
- down(&shm_ids.sem);
+ mutex_lock(&shm_ids.mutex);
shm_info.used_ids = shm_ids.in_use;
shm_get_stat (&shm_info.shm_rss, &shm_info.shm_swp);
shm_info.shm_tot = shm_tot;
shm_info.swap_attempts = 0;
shm_info.swap_successes = 0;
err = shm_ids.max_id;
- up(&shm_ids.sem);
+ mutex_unlock(&shm_ids.mutex);
if(copy_to_user (buf, &shm_info, sizeof(shm_info))) {
err = -EFAULT;
goto out;
* Instead we set a destroyed flag, and then blow
* the name away when the usage hits zero.
*/
- down(&shm_ids.sem);
+ mutex_lock(&shm_ids.mutex);
shp = shm_lock(shmid);
err = -EINVAL;
if (shp == NULL)
shm_unlock(shp);
} else
shm_destroy (shp);
- up(&shm_ids.sem);
+ mutex_unlock(&shm_ids.mutex);
goto out;
}
err = -EFAULT;
goto out;
}
- if ((err = audit_ipc_perms(0, setbuf.uid, setbuf.gid, setbuf.mode)))
- return err;
- down(&shm_ids.sem);
+ mutex_lock(&shm_ids.mutex);
shp = shm_lock(shmid);
err=-EINVAL;
if(shp==NULL)
goto out_up;
+ if ((err = audit_ipc_perms(0, setbuf.uid, setbuf.gid,
+ setbuf.mode, &(shp->shm_perm))))
+ goto out_unlock_up;
err = shm_checkid(shp,shmid);
if(err)
goto out_unlock_up;
out_unlock_up:
shm_unlock(shp);
out_up:
- up(&shm_ids.sem);
+ mutex_unlock(&shm_ids.mutex);
goto out;
out_unlock:
shm_unlock(shp);
invalid:
up_write(¤t->mm->mmap_sem);
- down (&shm_ids.sem);
- if(!(shp = shm_lock(shmid)))
- BUG();
+ mutex_lock(&shm_ids.mutex);
+ shp = shm_lock(shmid);
+ BUG_ON(!shp);
shp->shm_nattch--;
if(shp->shm_nattch == 0 &&
shp->shm_perm.mode & SHM_DEST)
shm_destroy (shp);
else
shm_unlock(shp);
- up (&shm_ids.sem);
+ mutex_unlock(&shm_ids.mutex);
*raddr = (unsigned long) user_addr;
err = 0;
loff_t size = 0;
int retval = -EINVAL;
+ if (addr & ~PAGE_MASK)
+ return retval;
+
down_write(&mm->mmap_sem);
/*