1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
| | Fix CVE-2018-8779:
https://www.ruby-lang.org/en/news/2018/03/28/poisoned-nul-byte-unixsocket-cve-2018-8779/
https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2018-8779
https://security-tracker.debian.org/tracker/CVE-2018-8779
Patch copied from snapshot.debian.org:
https://snapshot.debian.org/archive/debian-security/20180423T104456Z/pool/updates/main/r/ruby1.8/ruby1.8_1.8.7.358-7.1%2Bdeb7u6.debian.tar.gz
Origin: backport, 47165eed264d357e78e27371cfef20d5c2bde5d9
Reviewed-by: Santiago R.R <santiagorr@riseup.net>
From 47165eed264d357e78e27371cfef20d5c2bde5d9 Mon Sep 17 00:00:00 2001
From: usa <usa@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>
Date: Wed, 28 Mar 2018 14:36:23 +0000
Subject: [PATCH 3/4] merge revision(s) 62991,63000:
unixsocket.c: check NUL bytes
* ext/socket/unixsocket.c (rsock_init_unixsock): check NUL bytes.
https://hackerone.com/reports/302997
unixsocket.c: abstract namespace
* ext/socket/unixsocket.c (unixsock_path_value): fix r62991 for
Linux abstract namespace.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/branches/ruby_2_2@63018 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
---
ChangeLog | 12 ++++++++++++
ext/socket/unixsocket.c | 24 +++++++++++++++++++++++-
test/socket/test_unix.rb | 10 ++++++++++
version.h | 2 +-
4 files changed, 46 insertions(+), 2 deletions(-)
Index: ruby1.8/test/socket/test_unix.rb
===================================================================
--- ruby1.8.orig/test/socket/test_unix.rb
+++ ruby1.8/test/socket/test_unix.rb
@@ -39,6 +39,16 @@ class TestUNIXSocket < Test::Unit::TestC
File.unlink path if path && File.socket?(path)
end
+ def test_open_nul_byte
+ tmpfile = Tempfile.new("s")
+ path = tmpfile.path
+ tmpfile.close(true)
+ assert_raise(ArgumentError) {UNIXServer.open(path+"\0")}
+ assert_raise(ArgumentError) {UNIXSocket.open(path+"\0")}
+ ensure
+ File.unlink path if path && File.socket?(path)
+ end
+
def test_addr
bound_unix_socket(UNIXServer) {|serv, path|
c = UNIXSocket.new(path)
Index: ruby1.8/ext/socket/socket.c
===================================================================
--- ruby1.8.orig/ext/socket/socket.c
+++ ruby1.8/ext/socket/socket.c
@@ -1623,6 +1623,28 @@ unixsock_connect_internal(arg)
}
static VALUE
+unixsock_path_value(VALUE path)
+{
+#ifdef __linux__
+#define TO_STR_FOR_LINUX_ABSTRACT_NAMESPACE 0
+
+ VALUE name = path;
+#if TO_STR_FOR_LINUX_ABSTRACT_NAMESPACE
+ const int isstr = !NIL_P(name = rb_check_string_type(name));
+#else
+ const int isstr = RB_TYPE_P(name, T_STRING);
+#endif
+ if (isstr) {
+ if (RSTRING_LEN(name) == 0 || RSTRING_PTR(name)[0] == '\0') {
+ rb_check_safe_obj(name);
+ return name; /* ignore encoding */
+ }
+ }
+#endif
+ return rb_get_path(path);
+}
+
+static VALUE
init_unixsock(sock, path, server)
VALUE sock;
VALUE path;
@@ -1632,7 +1654,7 @@ init_unixsock(sock, path, server)
int fd, status;
rb_io_t *fptr;
- SafeStringValue(path);
+ path = unixsock_path_value(path);
fd = ruby_socket(AF_UNIX, SOCK_STREAM, 0);
if (fd < 0) {
rb_sys_fail("socket(2)");
|