pledge_sockopt_check is shared between setsockopt/getsockopt. nicm
authorderaadt <deraadt@openbsd.org>
Sun, 25 Oct 2015 17:45:29 +0000 (17:45 +0000)
committerderaadt <deraadt@openbsd.org>
Sun, 25 Oct 2015 17:45:29 +0000 (17:45 +0000)
found the first case of "get allowed, set not allowed".  Tiny
refactoring of that.

sys/kern/kern_pledge.c
sys/kern/uipc_syscalls.c
sys/sys/pledge.h

index 1ca6490..7e8a6f9 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: kern_pledge.c,v 1.72 2015/10/25 11:09:28 semarie Exp $        */
+/*     $OpenBSD: kern_pledge.c,v 1.73 2015/10/25 17:45:29 deraadt Exp $        */
 
 /*
  * Copyright (c) 2015 Nicholas Marriott <nicm@openbsd.org>
@@ -1141,7 +1141,7 @@ pledge_ioctl_check(struct proc *p, long com, void *v)
 }
 
 int
-pledge_sockopt_check(struct proc *p, int level, int optname)
+pledge_sockopt_check(struct proc *p, int set, int level, int optname)
 {
        if ((p->p_p->ps_flags & PS_PLEDGE) == 0)
                return (0);
@@ -1149,12 +1149,12 @@ pledge_sockopt_check(struct proc *p, int level, int optname)
        /* Always allow these, which are too common to reject */
        switch (level) {
        case SOL_SOCKET:
-               switch (optname) {
-               case SO_RCVBUF:
+               switch (optname) {
+               case SO_RCVBUF:
                case SO_ERROR:
-                       return 0;
-               }
-               break;
+                       return 0;
+               }
+               break;
        }
 
        if ((p->p_p->ps_pledge & (PLEDGE_INET|PLEDGE_UNIX|PLEDGE_DNS)) == 0)
@@ -1162,11 +1162,11 @@ pledge_sockopt_check(struct proc *p, int level, int optname)
        /* In use by some service libraries */
        switch (level) {
        case SOL_SOCKET:
-               switch (optname) {
-               case SO_TIMESTAMP:
-                       return 0;
-               }
-               break;
+               switch (optname) {
+               case SO_TIMESTAMP:
+                       return 0;
+               }
+               break;
        }
 
        if ((p->p_p->ps_pledge & (PLEDGE_INET|PLEDGE_UNIX)) == 0)
@@ -1196,7 +1196,7 @@ pledge_sockopt_check(struct proc *p, int level, int optname)
        case IPPROTO_IP:
                switch (optname) {
                case IP_OPTIONS:
-                       if (p->p_pledge_syscall == SYS_getsockopt)
+                       if (!set)
                                return (0);
                        break;
                case IP_TOS:
index cbebf61..7789352 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: uipc_syscalls.c,v 1.117 2015/10/20 18:04:03 deraadt Exp $     */
+/*     $OpenBSD: uipc_syscalls.c,v 1.118 2015/10/25 17:45:29 deraadt Exp $     */
 /*     $NetBSD: uipc_syscalls.c,v 1.19 1996/02/09 19:00:48 christos Exp $      */
 
 /*
@@ -943,7 +943,7 @@ sys_setsockopt(struct proc *p, void *v, register_t *retval)
 
        if ((error = getsock(p, SCARG(uap, s), &fp)) != 0)
                return (error);
-       error = pledge_sockopt_check(p, SCARG(uap, level), SCARG(uap, name));
+       error = pledge_sockopt_check(p, 1, SCARG(uap, level), SCARG(uap, name));
        if (error) {
                error = pledge_fail(p, error, PLEDGE_INET);
                goto bad;
@@ -999,7 +999,7 @@ sys_getsockopt(struct proc *p, void *v, register_t *retval)
 
        if ((error = getsock(p, SCARG(uap, s), &fp)) != 0)
                return (error);
-       error = pledge_sockopt_check(p, SCARG(uap, level), SCARG(uap, name));
+       error = pledge_sockopt_check(p, 0, SCARG(uap, level), SCARG(uap, name));
        if (error) {
                error = pledge_fail(p, error, PLEDGE_INET);
                goto out;
index a781041..5af42c1 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: pledge.h,v 1.10 2015/10/23 01:10:01 deraadt Exp $     */
+/*     $OpenBSD: pledge.h,v 1.11 2015/10/25 17:45:29 deraadt Exp $     */
 
 /*
  * Copyright (c) 2015 Nicholas Marriott <nicm@openbsd.org>
@@ -71,7 +71,7 @@ int   pledge_chown_check(struct proc *p, uid_t, gid_t);
 int    pledge_adjtime_check(struct proc *p, const void *v);
 int    pledge_sendit_check(struct proc *p, const void *to);
 int    pledge_socket_check(struct proc *p, int domain);
-int    pledge_sockopt_check(struct proc *p, int level, int optname);
+int    pledge_sockopt_check(struct proc *p, int set, int level, int optname);
 int    pledge_socket_check(struct proc *p, int dns);
 int    pledge_ioctl_check(struct proc *p, long com, void *);
 int    pledge_flock_check(struct proc *p);