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:
parent
f7261d9c5f
commit
cb1f0db9db
@ -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;
|
||||
|
@ -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) {
|
||||
|
@ -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)
|
||||
|
@ -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));
|
||||
|
@ -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_ */
|
||||
|
Loading…
x
Reference in New Issue
Block a user