o Deny access to System V IPC from within jail by default, as in the

current implementation, jail neither virtualizes the Sys V IPC namespace,
  nor provides inter-jail protections on IPC objects.
o Support for System V IPC can be enabled by setting jail.sysvipc_allowed=1
  using sysctl.
o This is not the "real fix" which involves virtualizing the System V
  IPC namespace, but prevents processes within jail from influencing those
  outside of jail when not approved by the administrator.

Reported by:	Paulo Fragoso <paulo@nlink.com.br>
This commit is contained in:
Robert Watson 2000-10-31 01:34:00 +00:00
parent f7261d9c5f
commit cb1f0db9db
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=68024
5 changed files with 54 additions and 0 deletions

View File

@ -39,6 +39,11 @@ SYSCTL_INT(_jail, OID_AUTO, socket_unixiproute_only, CTLFLAG_RW,
&jail_socket_unixiproute_only, 0,
"Processes in jail are limited to creating UNIX/IPv4/route sockets only");
int jail_sysvipc_allowed = 0;
SYSCTL_INT(_jail, OID_AUTO, sysvipc_allowed, CTLFLAG_RW,
&jail_sysvipc_allowed, 0,
"Processes in jail can use System V IPC primitives");
int
jail(p, uap)
struct proc *p;

View File

@ -30,6 +30,7 @@
#include <sys/sysent.h>
#include <sys/sysctl.h>
#include <sys/malloc.h>
#include <sys/jail.h>
static MALLOC_DEFINE(M_MSG, "msg", "SVID compatible message queues");
@ -210,6 +211,9 @@ msgsys(p, uap)
} */ *uap;
{
if (!jail_sysvipc_allowed && p->p_prison != NULL)
return (ENOSYS);
if (uap->which >= sizeof(msgcalls)/sizeof(msgcalls[0]))
return (EINVAL);
return ((*msgcalls[uap->which])(p, &uap->a2));
@ -263,6 +267,9 @@ msgctl(p, uap)
printf("call to msgctl(%d, %d, 0x%x)\n", msqid, cmd, user_msqptr);
#endif
if (!jail_sysvipc_allowed && p->p_prison != NULL)
return (ENOSYS);
msqid = IPCID_TO_IX(msqid);
if (msqid < 0 || msqid >= msginfo.msgmni) {
@ -399,6 +406,9 @@ msgget(p, uap)
printf("msgget(0x%x, 0%o)\n", key, msgflg);
#endif
if (!jail_sysvipc_allowed && p->p_prison != NULL)
return (ENOSYS);
if (key != IPC_PRIVATE) {
for (msqid = 0; msqid < msginfo.msgmni; msqid++) {
msqptr = &msqids[msqid];
@ -511,6 +521,9 @@ msgsnd(p, uap)
msgflg);
#endif
if (!jail_sysvipc_allowed && p->p_prison != NULL)
return (ENOSYS);
msqid = IPCID_TO_IX(msqid);
if (msqid < 0 || msqid >= msginfo.msgmni) {
@ -835,6 +848,9 @@ msgrcv(p, uap)
msgsz, msgtyp, msgflg);
#endif
if (!jail_sysvipc_allowed && p->p_prison != NULL)
return (ENOSYS);
msqid = IPCID_TO_IX(msqid);
if (msqid < 0 || msqid >= msginfo.msgmni) {

View File

@ -19,6 +19,7 @@
#include <sys/sysent.h>
#include <sys/sysctl.h>
#include <sys/malloc.h>
#include <sys/jail.h>
static MALLOC_DEFINE(M_SEM, "sem", "SVID compatible semaphores");
@ -201,6 +202,9 @@ semsys(p, uap)
} */ *uap;
{
if (!jail_sysvipc_allowed && p->p_prison != NULL)
return (ENOSYS);
if (uap->which >= sizeof(semcalls)/sizeof(semcalls[0]))
return (EINVAL);
return ((*semcalls[uap->which])(p, &uap->a2));
@ -407,6 +411,9 @@ __semctl(p, uap)
printf("call to semctl(%d, %d, %d, 0x%x)\n", semid, semnum, cmd, arg);
#endif
if (!jail_sysvipc_allowed && p->p_prison != NULL)
return (ENOSYS);
semid = IPCID_TO_IX(semid);
if (semid < 0 || semid >= seminfo.semmsl)
return(EINVAL);
@ -567,6 +574,9 @@ semget(p, uap)
printf("semget(0x%x, %d, 0%o)\n", key, nsems, semflg);
#endif
if (!jail_sysvipc_allowed && p->p_prison != NULL)
return (ENOSYS);
if (key != IPC_PRIVATE) {
for (semid = 0; semid < seminfo.semmni; semid++) {
if ((sema[semid].sem_perm.mode & SEM_ALLOC) &&
@ -685,6 +695,9 @@ semop(p, uap)
printf("call to semop(%d, 0x%x, %d)\n", semid, sops, nsops);
#endif
if (!jail_sysvipc_allowed && p->p_prison != NULL)
return (ENOSYS);
semid = IPCID_TO_IX(semid); /* Convert back to zero origin */
if (semid < 0 || semid >= seminfo.semmsl)

View File

@ -46,6 +46,7 @@
#include <sys/mman.h>
#include <sys/stat.h>
#include <sys/sysent.h>
#include <sys/jail.h>
#include <vm/vm.h>
#include <vm/vm_param.h>
@ -223,6 +224,9 @@ shmdt(p, uap)
struct shmmap_state *shmmap_s;
int i;
if (!jail_sysvipc_allowed && p->p_prison != NULL)
return (ENOSYS);
shmmap_s = (struct shmmap_state *)p->p_vmspace->vm_shm;
if (shmmap_s == NULL)
return EINVAL;
@ -257,6 +261,9 @@ shmat(p, uap)
vm_size_t size;
int rv;
if (!jail_sysvipc_allowed && p->p_prison != NULL)
return (ENOSYS);
shmmap_s = (struct shmmap_state *)p->p_vmspace->vm_shm;
if (shmmap_s == NULL) {
size = shminfo.shmseg * sizeof(struct shmmap_state);
@ -348,6 +355,9 @@ oshmctl(p, uap)
struct shmid_ds *shmseg;
struct oshmid_ds outbuf;
if (!jail_sysvipc_allowed && p->p_prison != NULL)
return (ENOSYS);
shmseg = shm_find_segment_by_shmid(uap->shmid);
if (shmseg == NULL)
return EINVAL;
@ -396,6 +406,9 @@ shmctl(p, uap)
struct shmid_ds inbuf;
struct shmid_ds *shmseg;
if (!jail_sysvipc_allowed && p->p_prison != NULL)
return (ENOSYS);
shmseg = shm_find_segment_by_shmid(uap->shmid);
if (shmseg == NULL)
return EINVAL;
@ -572,6 +585,9 @@ shmget(p, uap)
{
int segnum, mode, error;
if (!jail_sysvipc_allowed && p->p_prison != NULL)
return (ENOSYS);
mode = uap->shmflg & ACCESSPERMS;
if (uap->key != IPC_PRIVATE) {
again:
@ -600,6 +616,9 @@ shmsys(p, uap)
} */ *uap;
{
if (!jail_sysvipc_allowed && p->p_prison != NULL)
return (ENOSYS);
if (uap->which >= sizeof(shmcalls)/sizeof(shmcalls[0]))
return EINVAL;
return ((*shmcalls[uap->which])(p, &uap->a2));

View File

@ -48,6 +48,7 @@ struct prison {
*/
extern int jail_set_hostname_allowed;
extern int jail_socket_unixiproute_only;
extern int jail_sysvipc_allowed;
#endif /* !_KERNEL */
#endif /* !_SYS_JAIL_H_ */