diff --git a/include/uapi/linux/audit.h b/include/uapi/linux/audit.h
index a1280af20336dc2d4cf288b8703bc38a20358597..c89c6495983d5d9d0f861ea180b8257aca96a453 100644
--- a/include/uapi/linux/audit.h
+++ b/include/uapi/linux/audit.h
@@ -281,6 +281,7 @@
 #define AUDIT_OBJ_GID	110
 #define AUDIT_FIELD_COMPARE	111
 #define AUDIT_EXE	112
+#define AUDIT_SADDR_FAM	113
 
 #define AUDIT_ARG0      200
 #define AUDIT_ARG1      (AUDIT_ARG0+1)
diff --git a/kernel/auditfilter.c b/kernel/auditfilter.c
index d5e54e944f720b542177a2ee000978677f9af84a..e69d136eeaf684fc8a4b6fe2748b75b24b5a1ca7 100644
--- a/kernel/auditfilter.c
+++ b/kernel/auditfilter.c
@@ -391,6 +391,7 @@ static int audit_field_valid(struct audit_entry *entry, struct audit_field *f)
 	case AUDIT_SUBJ_CLR:
 	case AUDIT_OBJ_LEV_LOW:
 	case AUDIT_OBJ_LEV_HIGH:
+	case AUDIT_SADDR_FAM:
 		/* bit ops are only useful on syscall args */
 		if (f->op == Audit_bitmask || f->op == Audit_bittest)
 			return -EINVAL;
@@ -438,6 +439,10 @@ static int audit_field_valid(struct audit_entry *entry, struct audit_field *f)
 		if (f->val > AUDIT_MAX_FIELD_COMPARE)
 			return -EINVAL;
 		break;
+	case AUDIT_SADDR_FAM:
+		if (f->val >= AF_MAX)
+			return -EINVAL;
+		break;
 	default:
 		break;
 	}
diff --git a/kernel/auditsc.c b/kernel/auditsc.c
index 30aa07b0115f57cfa4bf09e02ac82f30cf8576b3..9134fe11ff6c561e960a08402c6ce5e7d9c85687 100644
--- a/kernel/auditsc.c
+++ b/kernel/auditsc.c
@@ -615,6 +615,11 @@ static int audit_filter_rules(struct task_struct *tsk,
 		case AUDIT_LOGINUID_SET:
 			result = audit_comparator(audit_loginuid_set(tsk), f->op, f->val);
 			break;
+		case AUDIT_SADDR_FAM:
+			if (ctx->sockaddr)
+				result = audit_comparator(ctx->sockaddr->ss_family,
+							  f->op, f->val);
+			break;
 		case AUDIT_SUBJ_USER:
 		case AUDIT_SUBJ_ROLE:
 		case AUDIT_SUBJ_TYPE: