Merge "init: update permissions for VPN."
diff --git a/include/cutils/qtaguid.h b/include/cutils/qtaguid.h
new file mode 100644
index 0000000..8aa34ea
--- /dev/null
+++ b/include/cutils/qtaguid.h
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef __CUTILS_QTAGUID_H
+#define __CUTILS_QTAGUID_H
+
+#include <stdint.h>
+#include <sys/types.h>
+#include <unistd.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * Set tags (and owning UIDs) for network sockets.
+*/
+extern int set_qtaguid(int sockfd, int tag, uid_t uid);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __CUTILS_QTAG_UID_H */
diff --git a/include/netutils/ifc.h b/include/netutils/ifc.h
index 36827ee..575e72e 100644
--- a/include/netutils/ifc.h
+++ b/include/netutils/ifc.h
@@ -34,7 +34,7 @@
 extern int ifc_enable(const char *ifname);
 extern int ifc_disable(const char *ifname);
 
-extern int ifc_reset_connections(const char *ifname);
+extern int ifc_reset_connections(const char *ifname, const int reset_mask);
 
 extern int ifc_get_addr(const char *name, in_addr_t *addr);
 extern int ifc_set_addr(const char *name, in_addr_t addr);
diff --git a/include/system/window.h b/include/system/window.h
index eef567d..a990a09 100644
--- a/include/system/window.h
+++ b/include/system/window.h
@@ -165,6 +165,8 @@
     NATIVE_WINDOW_SET_BUFFERS_GEOMETRY,
     NATIVE_WINDOW_SET_BUFFERS_TRANSFORM,
     NATIVE_WINDOW_SET_BUFFERS_TIMESTAMP,
+    NATIVE_WINDOW_SET_BUFFERS_DIMENSIONS,
+    NATIVE_WINDOW_SET_BUFFERS_FORMAT,
 };
 
 /* parameter for NATIVE_WINDOW_[DIS]CONNECT */
@@ -306,6 +308,8 @@
      *     NATIVE_WINDOW_SET_BUFFERS_GEOMETRY
      *     NATIVE_WINDOW_SET_BUFFERS_TRANSFORM
      *     NATIVE_WINDOW_SET_BUFFERS_TIMESTAMP
+     *     NATIVE_WINDOW_SET_BUFFERS_DIMENSIONS
+     *     NATIVE_WINDOW_SET_BUFFERS_FORMAT
      *
      */
 
@@ -404,16 +408,12 @@
 
 /*
  * native_window_set_buffers_geometry(..., int w, int h, int format)
- * All buffers dequeued after this call will have the geometry specified.
- * In particular, all buffers will have a fixed-size, independent form the
- * native-window size. They will be appropriately scaled to the window-size
- * upon composition.
+ * All buffers dequeued after this call will have the dimensions and format
+ * specified.  A successful call to this function has the same effect as calling
+ * native_window_set_buffers_size and native_window_set_buffers_format.
  *
- * If all parameters are 0, the normal behavior is restored. That is,
- * dequeued buffers following this call will be sized to the window's size.
- *
- * Calling this function will reset the window crop to a NULL value, which
- * disables cropping of the buffers.
+ * XXX: This function is deprecated.  The native_window_set_buffers_dimensions
+ * and native_window_set_buffers_format functions should be used instead.
  */
 static inline int native_window_set_buffers_geometry(
         struct ANativeWindow* window,
@@ -424,6 +424,40 @@
 }
 
 /*
+ * native_window_set_buffers_dimensions(..., int w, int h)
+ * All buffers dequeued after this call will have the dimensions specified.
+ * In particular, all buffers will have a fixed-size, independent form the
+ * native-window size. They will be appropriately scaled to the window-size
+ * upon window composition.
+ *
+ * If w and h are 0, the normal behavior is restored. That is, dequeued buffers
+ * following this call will be sized to match the window's size.
+ *
+ * Calling this function will reset the window crop to a NULL value, which
+ * disables cropping of the buffers.
+ */
+static inline int native_window_set_buffers_dimensions(
+        struct ANativeWindow* window,
+        int w, int h)
+{
+    return window->perform(window, NATIVE_WINDOW_SET_BUFFERS_DIMENSIONS,
+            w, h);
+}
+
+/*
+ * native_window_set_buffers_format(..., int format)
+ * All buffers dequeued after this call will have the format specified.
+ *
+ * If the specified format is 0, the default buffer format will be used.
+ */
+static inline int native_window_set_buffers_format(
+        struct ANativeWindow* window,
+        int format)
+{
+    return window->perform(window, NATIVE_WINDOW_SET_BUFFERS_FORMAT, format);
+}
+
+/*
  * native_window_set_buffers_transform(..., int transform)
  * All buffers queued after this call will be displayed transformed according
  * to the transform parameter specified.
diff --git a/libcutils/Android.mk b/libcutils/Android.mk
index 29864b2..260a0f3 100644
--- a/libcutils/Android.mk
+++ b/libcutils/Android.mk
@@ -111,7 +111,7 @@
 # ========================================================
 include $(CLEAR_VARS)
 LOCAL_MODULE := libcutils
-LOCAL_SRC_FILES := $(commonSources) ashmem-dev.c mq.c android_reboot.c partition_utils.c uevent.c
+LOCAL_SRC_FILES := $(commonSources) ashmem-dev.c mq.c android_reboot.c partition_utils.c uevent.c qtaguid.c
 
 ifeq ($(TARGET_ARCH),arm)
 LOCAL_SRC_FILES += arch-arm/memset32.S
diff --git a/libcutils/qtaguid.c b/libcutils/qtaguid.c
new file mode 100644
index 0000000..517e784
--- /dev/null
+++ b/libcutils/qtaguid.c
@@ -0,0 +1,44 @@
+/* libcutils/qtaguid.c
+**
+** Copyright 2011, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+
+#define LOG_TAG "qtaguid"
+
+#include <cutils/qtaguid.h>
+#include <cutils/log.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
+
+extern int set_qtaguid(int sockfd, int tag, uid_t uid) {
+    char lineBuf[128];
+    int fd, cnt = 0;
+    uint64_t kTag = (uint64_t)tag << 32;
+    snprintf(lineBuf, sizeof(lineBuf), "t %d %llu %d", sockfd, kTag, uid);
+
+    LOGV("Tagging Socket with command %s\n", lineBuf);
+    /* TODO: Enable after the kernel module is fixed.
+       fd = open("/proc/net/xt_qtaguid/ctrl", O_WRONLY);
+       if (fd < 0) {
+           return -1;
+       }
+
+       cnt = write(fd, lineBuf, strlen(lineBuf));
+       close(fd);
+    */
+    return (cnt>0?0:-1);
+}
diff --git a/libnetutils/ifc_utils.c b/libnetutils/ifc_utils.c
index 208402c..04b0dfa 100644
--- a/libnetutils/ifc_utils.c
+++ b/libnetutils/ifc_utils.c
@@ -394,7 +394,11 @@
     return result;
 }
 
-int ifc_reset_connections(const char *ifname)
+#define RESET_IPV4_ADDRESSES 0x01
+#define RESET_IPV6_ADDRESSES 0x02
+#define RESET_ALL_ADDRESSES  (RESET_IPV4_ADDRESSES | RESET_IPV6_ADDRESSES)
+
+int ifc_reset_connections(const char *ifname, const int reset_mask)
 {
 #ifdef HAVE_ANDROID_OS
     int result, success;
@@ -402,28 +406,34 @@
     struct ifreq ifr;
     struct in6_ifreq ifr6;
 
-    /* IPv4. Clear connections on the IP address. */
-    ifc_init();
-    ifc_get_info(ifname, &myaddr, NULL, NULL);
-    ifc_init_ifr(ifname, &ifr);
-    init_sockaddr_in(&ifr.ifr_addr, myaddr);
-    result = ioctl(ifc_ctl_sock, SIOCKILLADDR,  &ifr);
-    ifc_close();
-
-    /*
-     * IPv6. On Linux, when an interface goes down it loses all its IPv6
-     * addresses, so we don't know which connections belonged to that interface
-     * So we clear all unused IPv6 connections on the device by specifying an
-     * empty IPv6 address.
-     */
-    ifc_init6();
-    // This implicitly specifies an address of ::, i.e., kill all IPv6 sockets.
-    memset(&ifr6, 0, sizeof(ifr6));
-    success = ioctl(ifc_ctl_sock6, SIOCKILLADDR,  &ifr6);
-    if (result == 0) {
-        result = success;
+    if (reset_mask & RESET_IPV4_ADDRESSES) {
+        /* IPv4. Clear connections on the IP address. */
+        ifc_init();
+        ifc_get_info(ifname, &myaddr, NULL, NULL);
+        ifc_init_ifr(ifname, &ifr);
+        init_sockaddr_in(&ifr.ifr_addr, myaddr);
+        result = ioctl(ifc_ctl_sock, SIOCKILLADDR,  &ifr);
+        ifc_close();
+    } else {
+        result = 0;
     }
-    ifc_close6();
+
+    if (reset_mask & RESET_IPV6_ADDRESSES) {
+        /*
+         * IPv6. On Linux, when an interface goes down it loses all its IPv6
+         * addresses, so we don't know which connections belonged to that interface
+         * So we clear all unused IPv6 connections on the device by specifying an
+         * empty IPv6 address.
+         */
+        ifc_init6();
+        // This implicitly specifies an address of ::, i.e., kill all IPv6 sockets.
+        memset(&ifr6, 0, sizeof(ifr6));
+        success = ioctl(ifc_ctl_sock6, SIOCKILLADDR,  &ifr6);
+        if (result == 0) {
+            result = success;
+        }
+        ifc_close6();
+    }
 
     return result;
 #else
diff --git a/libnl_2/socket.c b/libnl_2/socket.c
index 1a2255e..3bcf210 100644
--- a/libnl_2/socket.c
+++ b/libnl_2/socket.c
@@ -33,12 +33,14 @@
 /* Allocate new netlink socket. */
 struct nl_sock *nl_socket_alloc(void)
 {
-	struct nl_sock *sk = (struct nl_sock *) malloc(sizeof(struct nl_sock));
+	struct nl_sock *sk;
 	struct timeval tv;
 	struct nl_cb *cb;
 
+	sk = (struct nl_sock *) malloc(sizeof(struct nl_sock));
 	if (!sk)
 		goto fail;
+	memset(sk, 0, sizeof(*sk));
 
 	/* Get current time */
 
@@ -49,7 +51,7 @@
 
 	/* Create local socket */
 	sk->s_local.nl_family = AF_NETLINK;
-	sk->s_local.nl_pid = getpid();
+	sk->s_local.nl_pid = 0; /* Kernel fills in pid */
 	sk->s_local.nl_groups = 0; /* No groups */
 
 	/* Create peer socket */
@@ -76,14 +78,13 @@
 {
 	struct nl_sock *sk = nl_socket_alloc();
 	if (!sk)
-		goto fail;
+		return NULL;
 
 	sk->s_cb = cb;
 	nl_cb_get(cb);
 
 	return sk;
-fail:
-	return NULL;
+
 }
 
 /* Free a netlink socket. */
diff --git a/rootdir/init.rc b/rootdir/init.rc
index 3055bbb..8dd858f 100644
--- a/rootdir/init.rc
+++ b/rootdir/init.rc
@@ -424,7 +424,8 @@
 service media /system/bin/mediaserver
     class main
     user media
-    group audio camera inet net_bt net_bt_admin
+    # STOPSHIP: remove system from mediaserver groups
+    group audio camera inet net_bt net_bt_admin system
     ioprio rt 4
 
 service bootanim /system/bin/bootanimation