Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
openanolis
dragonwell8_jdk
提交
bfeb9cc9
D
dragonwell8_jdk
项目概览
openanolis
/
dragonwell8_jdk
通知
4
Star
2
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
D
dragonwell8_jdk
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
提交
bfeb9cc9
编写于
8月 27, 2019
作者:
M
mbalao
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
8229366: JFR backport allows unchecked writing to memory
Reviewed-by: jbachorik
上级
0366f169
变更
11
隐藏空白更改
内联
并排
Showing
11 changed file
with
589 addition
and
15 deletion
+589
-15
src/share/classes/jdk/jfr/internal/EventHandlerCreator.java
src/share/classes/jdk/jfr/internal/EventHandlerCreator.java
+6
-5
src/share/classes/jdk/jfr/internal/EventHandlerProxyCreator.java
...re/classes/jdk/jfr/internal/EventHandlerProxyCreator.java
+124
-0
src/share/classes/jdk/jfr/internal/EventInstrumentation.java
src/share/classes/jdk/jfr/internal/EventInstrumentation.java
+5
-4
src/share/classes/jdk/jfr/internal/JVM.java
src/share/classes/jdk/jfr/internal/JVM.java
+1
-0
src/share/classes/jdk/jfr/internal/handlers/EventHandler.java
...share/classes/jdk/jfr/internal/handlers/EventHandler.java
+7
-1
src/share/lib/security/java.security-aix
src/share/lib/security/java.security-aix
+4
-1
src/share/lib/security/java.security-linux
src/share/lib/security/java.security-linux
+4
-1
src/share/lib/security/java.security-macosx
src/share/lib/security/java.security-macosx
+4
-1
src/share/lib/security/java.security-solaris
src/share/lib/security/java.security-solaris
+4
-1
src/share/lib/security/java.security-windows
src/share/lib/security/java.security-windows
+4
-1
test/jdk/jfr/security/JFRSecurityTestSuite.java
test/jdk/jfr/security/JFRSecurityTestSuite.java
+426
-0
未找到文件。
src/share/classes/jdk/jfr/internal/EventHandlerCreator.java
浏览文件 @
bfeb9cc9
...
...
@@ -63,10 +63,11 @@ final class EventHandlerCreator {
private
static
final
String
FIELD_EVENT_TYPE
=
"platformEventType"
;
private
static
final
String
FIELD_PREFIX_STRING_POOL
=
"stringPool"
;
private
final
static
Class
<?
extends
EventHandler
>
eventHandlerProxy
=
EventHandlerProxyCreator
.
proxyClass
;
private
final
static
Type
TYPE_STRING_POOL
=
Type
.
getType
(
StringPool
.
class
);
private
final
static
Type
TYPE_EVENT_WRITER
=
Type
.
getType
(
EventWriter
.
class
);
private
final
static
Type
TYPE_PLATFORM_EVENT_TYPE
=
Type
.
getType
(
PlatformEventType
.
class
);
private
final
static
Type
TYPE_EVENT_HANDLER
=
Type
.
getType
(
EventHandler
.
class
);
private
final
static
Type
TYPE_EVENT_HANDLER
=
Type
.
getType
(
eventHandlerProxy
);
private
final
static
Type
TYPE_SETTING_CONTROL
=
Type
.
getType
(
SettingControl
.
class
);
private
final
static
Type
TYPE_EVENT_TYPE
=
Type
.
getType
(
EventType
.
class
);
private
final
static
Type
TYPE_EVENT_CONTROL
=
Type
.
getType
(
EventControl
.
class
);
...
...
@@ -90,7 +91,7 @@ final class EventHandlerCreator {
}
public
static
String
makeEventHandlerName
(
long
id
)
{
return
EventHandler
.
class
.
getName
()
+
id
+
SUFFIX
;
return
eventHandlerProxy
.
getName
()
+
id
+
SUFFIX
;
}
public
EventHandlerCreator
(
long
id
,
List
<
SettingInfo
>
settingInfos
,
EventType
type
,
Class
<?
extends
Event
>
eventClass
)
{
...
...
@@ -168,7 +169,7 @@ final class EventHandlerCreator {
mv
.
visitVarInsn
(
Opcodes
.
ILOAD
,
1
);
// registered
mv
.
visitVarInsn
(
Opcodes
.
ALOAD
,
2
);
// event type
mv
.
visitVarInsn
(
Opcodes
.
ALOAD
,
3
);
// event control
mv
.
visitMethodInsn
(
Opcodes
.
INVOKESPECIAL
,
Type
.
getInternalName
(
EventHandler
.
class
),
METHOD_EVENT_HANDLER_CONSTRUCTOR
.
getName
(),
METHOD_EVENT_HANDLER_CONSTRUCTOR
.
getDescriptor
(),
false
);
mv
.
visitMethodInsn
(
Opcodes
.
INVOKESPECIAL
,
Type
.
getInternalName
(
eventHandlerProxy
),
METHOD_EVENT_HANDLER_CONSTRUCTOR
.
getName
(),
METHOD_EVENT_HANDLER_CONSTRUCTOR
.
getDescriptor
(),
false
);
for
(
SettingInfo
si
:
settingInfos
)
{
mv
.
visitVarInsn
(
Opcodes
.
ALOAD
,
0
);
// this
mv
.
visitVarInsn
(
Opcodes
.
ALOAD
,
si
.
index
+
4
);
// Setting Control
...
...
@@ -180,7 +181,7 @@ final class EventHandlerCreator {
if
(
field
.
isString
())
{
mv
.
visitVarInsn
(
Opcodes
.
ALOAD
,
0
);
mv
.
visitVarInsn
(
Opcodes
.
ALOAD
,
0
);
mv
.
visitMethodInsn
(
Opcodes
.
INVOKEVIRTUAL
,
Type
.
getInternalName
(
EventHandler
.
class
),
"createStringFieldWriter"
,
"()"
+
TYPE_STRING_POOL
.
getDescriptor
(),
false
);
mv
.
visitMethodInsn
(
Opcodes
.
INVOKEVIRTUAL
,
Type
.
getInternalName
(
eventHandlerProxy
),
"createStringFieldWriter"
,
"()"
+
TYPE_STRING_POOL
.
getDescriptor
(),
false
);
mv
.
visitFieldInsn
(
Opcodes
.
PUTFIELD
,
internalClassName
,
FIELD_PREFIX_STRING_POOL
+
fieldIndex
,
TYPE_STRING_POOL
.
getDescriptor
());
}
fieldIndex
++;
...
...
@@ -191,7 +192,7 @@ final class EventHandlerCreator {
}
private
void
buildClassInfo
()
{
String
internalSuperName
=
ASMToolkit
.
getInternalName
(
EventHandler
.
class
.
getName
());
String
internalSuperName
=
ASMToolkit
.
getInternalName
(
eventHandlerProxy
.
getName
());
classWriter
.
visit
(
CLASS_VERSION
,
Opcodes
.
ACC_PUBLIC
+
Opcodes
.
ACC_FINAL
+
Opcodes
.
ACC_SUPER
,
internalClassName
,
null
,
internalSuperName
,
null
);
for
(
SettingInfo
si
:
settingInfos
)
{
classWriter
.
visitField
(
Opcodes
.
ACC_PUBLIC
+
Opcodes
.
ACC_FINAL
,
si
.
fieldName
,
TYPE_SETTING_CONTROL
.
getDescriptor
(),
null
,
null
);
...
...
src/share/classes/jdk/jfr/internal/EventHandlerProxyCreator.java
0 → 100644
浏览文件 @
bfeb9cc9
/*
* Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2019, Red Hat, Inc.
*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package
jdk.jfr.internal
;
import
java.util.StringJoiner
;
import
jdk.internal.org.objectweb.asm.ClassWriter
;
import
jdk.internal.org.objectweb.asm.MethodVisitor
;
import
jdk.internal.org.objectweb.asm.Opcodes
;
import
jdk.internal.org.objectweb.asm.Type
;
import
jdk.internal.org.objectweb.asm.commons.Method
;
import
jdk.jfr.Event
;
import
jdk.jfr.EventType
;
import
jdk.jfr.internal.handlers.EventHandler
;
/*
* Generates an EventHandler subclass dynamically, named EventHandlerProxy.
* EventHandlerProxy is located in a publicly accessible package (jdk.jfr)
* and is used as a superclass for classes generated by EventHandlerCreator.
* The rationale behind this scheme is to block access to jdk.jfr.internal
* package and sub-packages when there is a SecurityManager installed, while
* allowing application-defined event classes to invoke the required internal
* APIs.
*/
final
class
EventHandlerProxyCreator
{
private
static
final
int
CLASS_VERSION
=
52
;
private
final
static
Type
TYPE_EVENT_TYPE
=
Type
.
getType
(
EventType
.
class
);
private
final
static
Type
TYPE_EVENT_CONTROL
=
Type
.
getType
(
EventControl
.
class
);
private
final
static
String
DESCRIPTOR_EVENT_HANDLER
=
"("
+
Type
.
BOOLEAN_TYPE
.
getDescriptor
()
+
TYPE_EVENT_TYPE
.
getDescriptor
()
+
TYPE_EVENT_CONTROL
.
getDescriptor
()
+
")V"
;
private
final
static
Method
METHOD_EVENT_HANDLER_CONSTRUCTOR
=
new
Method
(
"<init>"
,
DESCRIPTOR_EVENT_HANDLER
);
private
final
static
String
DESCRIPTOR_TIME_STAMP
=
"()"
+
Type
.
LONG_TYPE
.
getDescriptor
();
private
final
static
Method
METHOD_TIME_STAMP
=
new
Method
(
"timestamp"
,
DESCRIPTOR_TIME_STAMP
);
private
final
static
String
DESCRIPTOR_DURATION
=
"("
+
Type
.
LONG_TYPE
.
getDescriptor
()
+
")"
+
Type
.
LONG_TYPE
.
getDescriptor
();
private
final
static
Method
METHOD_DURATION
=
new
Method
(
"duration"
,
DESCRIPTOR_DURATION
);
private
final
static
ClassWriter
classWriter
=
new
ClassWriter
(
ClassWriter
.
COMPUTE_FRAMES
|
ClassWriter
.
COMPUTE_MAXS
);
private
final
static
String
className
=
"jdk.jfr.proxy.internal.EventHandlerProxy"
;
private
final
static
String
internalClassName
=
ASMToolkit
.
getInternalName
(
className
);
// Create the Proxy class instance after all the previous static fields were initialized (textual order)
static
final
Class
<?
extends
EventHandler
>
proxyClass
=
EventHandlerProxyCreator
.
makeEventHandlerProxyClass
();
static
void
ensureInitialized
()
{
// trigger clinit which will setup the EventHandlerProxy class.
}
public
static
Class
<?
extends
EventHandler
>
makeEventHandlerProxyClass
()
{
buildClassInfo
();
buildConstructor
();
buildTimestampMethod
();
buildDurationMethod
();
byte
[]
bytes
=
classWriter
.
toByteArray
();
ASMToolkit
.
logASM
(
className
,
bytes
);
return
SecuritySupport
.
defineClass
(
className
,
bytes
,
Event
.
class
.
getClassLoader
()).
asSubclass
(
EventHandler
.
class
);
}
private
static
void
buildConstructor
()
{
MethodVisitor
mv
=
classWriter
.
visitMethod
(
0x0
,
METHOD_EVENT_HANDLER_CONSTRUCTOR
.
getName
(),
makeConstructorDescriptor
(),
null
,
null
);
mv
.
visitVarInsn
(
Opcodes
.
ALOAD
,
0
);
// this
mv
.
visitVarInsn
(
Opcodes
.
ILOAD
,
1
);
// registered
mv
.
visitVarInsn
(
Opcodes
.
ALOAD
,
2
);
// event type
mv
.
visitVarInsn
(
Opcodes
.
ALOAD
,
3
);
// event control
mv
.
visitMethodInsn
(
Opcodes
.
INVOKESPECIAL
,
Type
.
getInternalName
(
EventHandler
.
class
),
METHOD_EVENT_HANDLER_CONSTRUCTOR
.
getName
(),
METHOD_EVENT_HANDLER_CONSTRUCTOR
.
getDescriptor
(),
false
);
mv
.
visitInsn
(
Opcodes
.
RETURN
);
mv
.
visitMaxs
(
0
,
0
);
mv
.
visitEnd
();
}
private
static
void
buildClassInfo
()
{
String
internalSuperName
=
ASMToolkit
.
getInternalName
(
EventHandler
.
class
.
getName
());
classWriter
.
visit
(
CLASS_VERSION
,
Opcodes
.
ACC_PUBLIC
+
Opcodes
.
ACC_ABSTRACT
+
Opcodes
.
ACC_SUPER
,
internalClassName
,
null
,
internalSuperName
,
null
);
}
private
static
void
buildTimestampMethod
()
{
MethodVisitor
mv
=
classWriter
.
visitMethod
(
Opcodes
.
ACC_PUBLIC
+
Opcodes
.
ACC_STATIC
,
METHOD_TIME_STAMP
.
getName
(),
METHOD_TIME_STAMP
.
getDescriptor
(),
null
,
null
);
mv
.
visitCode
();
mv
.
visitMethodInsn
(
Opcodes
.
INVOKESTATIC
,
Type
.
getInternalName
(
EventHandler
.
class
),
METHOD_TIME_STAMP
.
getName
(),
METHOD_TIME_STAMP
.
getDescriptor
(),
false
);
mv
.
visitInsn
(
Opcodes
.
LRETURN
);
mv
.
visitMaxs
(
0
,
0
);
mv
.
visitEnd
();
}
private
static
void
buildDurationMethod
()
{
MethodVisitor
mv
=
classWriter
.
visitMethod
(
Opcodes
.
ACC_PUBLIC
+
Opcodes
.
ACC_STATIC
,
METHOD_DURATION
.
getName
(),
METHOD_DURATION
.
getDescriptor
(),
null
,
null
);
mv
.
visitCode
();
mv
.
visitVarInsn
(
Opcodes
.
LLOAD
,
0
);
mv
.
visitMethodInsn
(
Opcodes
.
INVOKESTATIC
,
Type
.
getInternalName
(
EventHandler
.
class
),
METHOD_DURATION
.
getName
(),
METHOD_DURATION
.
getDescriptor
(),
false
);
mv
.
visitInsn
(
Opcodes
.
LRETURN
);
mv
.
visitMaxs
(
0
,
0
);
mv
.
visitEnd
();
}
private
static
String
makeConstructorDescriptor
()
{
StringJoiner
constructordescriptor
=
new
StringJoiner
(
""
,
"("
,
")V"
);
constructordescriptor
.
add
(
Type
.
BOOLEAN_TYPE
.
getDescriptor
());
constructordescriptor
.
add
(
Type
.
getType
(
EventType
.
class
).
getDescriptor
());
constructordescriptor
.
add
(
Type
.
getType
(
EventControl
.
class
).
getDescriptor
());
return
constructordescriptor
.
toString
();
}
}
src/share/classes/jdk/jfr/internal/EventInstrumentation.java
浏览文件 @
bfeb9cc9
...
...
@@ -97,10 +97,11 @@ public final class EventInstrumentation {
static
final
String
FIELD_EVENT_HANDLER
=
"eventHandler"
;
static
final
String
FIELD_START_TIME
=
"startTime"
;
private
static
final
Class
<?
extends
EventHandler
>
eventHandlerProxy
=
EventHandlerProxyCreator
.
proxyClass
;
private
static
final
Type
ANNOTATION_TYPE_NAME
=
Type
.
getType
(
Name
.
class
);
private
static
final
Type
ANNOTATION_TYPE_REGISTERED
=
Type
.
getType
(
Registered
.
class
);
private
static
final
Type
ANNOTATION_TYPE_ENABLED
=
Type
.
getType
(
Enabled
.
class
);
private
static
final
Type
TYPE_EVENT_HANDLER
=
Type
.
getType
(
EventHandler
.
class
);
private
static
final
Type
TYPE_EVENT_HANDLER
=
Type
.
getType
(
eventHandlerProxy
);
private
static
final
Type
TYPE_SETTING_CONTROL
=
Type
.
getType
(
SettingControl
.
class
);
private
static
final
Method
METHOD_COMMIT
=
new
Method
(
"commit"
,
Type
.
VOID_TYPE
,
new
Type
[
0
]);
private
static
final
Method
METHOD_BEGIN
=
new
Method
(
"begin"
,
Type
.
VOID_TYPE
,
new
Type
[
0
]);
...
...
@@ -408,7 +409,7 @@ public final class EventInstrumentation {
// eventHandler.write(...);
// }
methodVisitor
.
visitJumpInsn
(
Opcodes
.
IFEQ
,
end
);
methodVisitor
.
visitFieldInsn
(
Opcodes
.
GETSTATIC
,
getInternalClassName
(),
FIELD_EVENT_HANDLER
,
Type
.
getDescriptor
(
EventHandler
.
class
));
methodVisitor
.
visitFieldInsn
(
Opcodes
.
GETSTATIC
,
getInternalClassName
(),
FIELD_EVENT_HANDLER
,
Type
.
getDescriptor
(
eventHandlerProxy
));
methodVisitor
.
visitTypeInsn
(
Opcodes
.
CHECKCAST
,
eventHandlerXInternalName
);
for
(
FieldInfo
fi
:
fieldInfos
)
{
...
...
@@ -427,7 +428,7 @@ public final class EventInstrumentation {
updateMethod
(
METHOD_EVENT_SHOULD_COMMIT
,
methodVisitor
->
{
Label
fail
=
new
Label
();
// if (!eventHandler.shoouldCommit(duration) goto fail;
methodVisitor
.
visitFieldInsn
(
Opcodes
.
GETSTATIC
,
getInternalClassName
(),
FIELD_EVENT_HANDLER
,
Type
.
getDescriptor
(
EventHandler
.
class
));
methodVisitor
.
visitFieldInsn
(
Opcodes
.
GETSTATIC
,
getInternalClassName
(),
FIELD_EVENT_HANDLER
,
Type
.
getDescriptor
(
eventHandlerProxy
));
methodVisitor
.
visitVarInsn
(
Opcodes
.
ALOAD
,
0
);
methodVisitor
.
visitFieldInsn
(
Opcodes
.
GETFIELD
,
getInternalClassName
(),
FIELD_DURATION
,
"J"
);
ASMToolkit
.
invokeVirtual
(
methodVisitor
,
TYPE_EVENT_HANDLER
.
getInternalName
(),
METHOD_EVENT_HANDLER_SHOULD_COMMIT
);
...
...
@@ -435,7 +436,7 @@ public final class EventInstrumentation {
for
(
SettingInfo
si
:
settingInfos
)
{
// if (!settingsMethod(eventHandler.settingX)) goto fail;
methodVisitor
.
visitIntInsn
(
Opcodes
.
ALOAD
,
0
);
methodVisitor
.
visitFieldInsn
(
Opcodes
.
GETSTATIC
,
getInternalClassName
(),
FIELD_EVENT_HANDLER
,
Type
.
getDescriptor
(
EventHandler
.
class
));
methodVisitor
.
visitFieldInsn
(
Opcodes
.
GETSTATIC
,
getInternalClassName
(),
FIELD_EVENT_HANDLER
,
Type
.
getDescriptor
(
eventHandlerProxy
));
methodVisitor
.
visitTypeInsn
(
Opcodes
.
CHECKCAST
,
eventHandlerXInternalName
);
methodVisitor
.
visitFieldInsn
(
Opcodes
.
GETFIELD
,
eventHandlerXInternalName
,
si
.
fieldName
,
TYPE_SETTING_CONTROL
.
getDescriptor
());
methodVisitor
.
visitTypeInsn
(
Opcodes
.
CHECKCAST
,
si
.
internalSettingName
);
...
...
src/share/classes/jdk/jfr/internal/JVM.java
浏览文件 @
bfeb9cc9
...
...
@@ -54,6 +54,7 @@ public final class JVM {
// subscribeLogLevel(tag, tag.id);
// }
Options
.
ensureInitialized
();
EventHandlerProxyCreator
.
ensureInitialized
();
}
/**
...
...
src/share/classes/jdk/jfr/internal/handlers/EventHandler.java
浏览文件 @
bfeb9cc9
...
...
@@ -45,7 +45,13 @@ public abstract class EventHandler {
private
final
EventControl
eventControl
;
// Accessed by generated sub class
EventHandler
(
boolean
registered
,
EventType
eventType
,
EventControl
eventControl
)
{
protected
EventHandler
(
boolean
registered
,
EventType
eventType
,
EventControl
eventControl
)
{
if
(
System
.
getSecurityManager
()
!=
null
)
{
// Do not allow user subclasses when security is enforced.
if
(
EventHandler
.
class
.
getClassLoader
()
!=
this
.
getClass
().
getClassLoader
())
{
throw
new
SecurityException
(
"Illegal subclass"
);
}
}
this
.
eventType
=
eventType
;
this
.
platformEventType
=
PrivateAccess
.
getInstance
().
getPlatformEventType
(
eventType
);
this
.
eventControl
=
eventControl
;
...
...
src/share/lib/security/java.security-aix
浏览文件 @
bfeb9cc9
...
...
@@ -223,7 +223,10 @@ package.access=sun.,\
jdk.nashorn.internal.,\
jdk.nashorn.tools.,\
jdk.xml.internal.,\
com.sun.activation.registries.
com.sun.activation.registries.,\
jdk.jfr.events.,\
jdk.jfr.internal.,\
jdk.management.jfr.internal.
#
# List of comma-separated packages that start with or equal this string
...
...
src/share/lib/security/java.security-linux
浏览文件 @
bfeb9cc9
...
...
@@ -223,7 +223,10 @@ package.access=sun.,\
jdk.nashorn.internal.,\
jdk.nashorn.tools.,\
jdk.xml.internal.,\
com.sun.activation.registries.
com.sun.activation.registries.,\
jdk.jfr.events.,\
jdk.jfr.internal.,\
jdk.management.jfr.internal.
#
# List of comma-separated packages that start with or equal this string
...
...
src/share/lib/security/java.security-macosx
浏览文件 @
bfeb9cc9
...
...
@@ -225,7 +225,10 @@ package.access=sun.,\
jdk.nashorn.tools.,\
jdk.xml.internal.,\
com.sun.activation.registries.,\
apple.
apple.,\
jdk.jfr.events.,\
jdk.jfr.internal.,\
jdk.management.jfr.internal.
#
# List of comma-separated packages that start with or equal this string
...
...
src/share/lib/security/java.security-solaris
浏览文件 @
bfeb9cc9
...
...
@@ -225,7 +225,10 @@ package.access=sun.,\
jdk.nashorn.internal.,\
jdk.nashorn.tools.,\
jdk.xml.internal.,\
com.sun.activation.registries.
com.sun.activation.registries.,\
jdk.jfr.events.,\
jdk.jfr.internal.,\
jdk.management.jfr.internal.
#
# List of comma-separated packages that start with or equal this string
...
...
src/share/lib/security/java.security-windows
浏览文件 @
bfeb9cc9
...
...
@@ -225,7 +225,10 @@ package.access=sun.,\
jdk.nashorn.tools.,\
jdk.xml.internal.,\
com.sun.activation.registries.,\
com.sun.java.accessibility.
com.sun.java.accessibility.,\
jdk.jfr.events.,\
jdk.jfr.internal.,\
jdk.management.jfr.internal.
#
# List of comma-separated packages that start with or equal this string
...
...
test/jdk/jfr/security/JFRSecurityTestSuite.java
0 → 100644
浏览文件 @
bfeb9cc9
/*
* Copyright (c) 2019, Red Hat, Inc.
*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
import
java.io.File
;
import
java.io.FilePermission
;
import
java.nio.file.Files
;
import
java.nio.file.Path
;
import
java.nio.file.Paths
;
import
java.nio.file.StandardOpenOption
;
import
java.security.AccessControlContext
;
import
java.security.AccessControlException
;
import
java.security.AccessController
;
import
java.security.AllPermission
;
import
java.security.CodeSource
;
import
java.security.Permission
;
import
java.security.PermissionCollection
;
import
java.security.Permissions
;
import
java.security.Policy
;
import
java.security.PrivilegedAction
;
import
java.security.ProtectionDomain
;
import
java.time.Duration
;
import
java.util.ArrayList
;
import
java.util.Comparator
;
import
jdk.jfr.AnnotationElement
;
import
jdk.jfr.Configuration
;
import
jdk.jfr.consumer.RecordedEvent
;
import
jdk.jfr.consumer.RecordingFile
;
import
jdk.jfr.Event
;
import
jdk.jfr.EventFactory
;
import
jdk.jfr.EventType
;
import
jdk.jfr.FlightRecorder
;
import
jdk.jfr.FlightRecorderListener
;
import
jdk.jfr.FlightRecorderPermission
;
import
jdk.jfr.internal.JVM
;
import
jdk.jfr.Label
;
import
jdk.jfr.Name
;
import
jdk.jfr.Recording
;
import
jdk.jfr.ValueDescriptor
;
/*
* @test
* @requires (jdk.version.major >= 8)
* @run main/othervm/timeout=30 -XX:+FlightRecorder -XX:StartFlightRecording JFRSecurityTestSuite
* @author Martin Balao (mbalao@redhat.com)
*/
public
class
JFRSecurityTestSuite
{
private
static
boolean
DEBUG
=
true
;
private
static
SecurityManager
sm
;
private
static
String
failureMessage
=
null
;
private
static
Path
jfrTmpDirPath
=
null
;
private
static
Path
recFilePath
=
null
;
interface
F
{
void
call
()
throws
Exception
;
}
@Label
(
"MyEvent"
)
static
class
MyEvent
extends
Event
{
}
@Label
(
"MyEvent2"
)
static
class
MyEvent2
extends
Event
{
}
@Label
(
"MyEvent3"
)
static
class
MyEvent3
extends
Event
{
}
public
static
class
MyPolicy
extends
Policy
{
public
MyPolicy
()
{
super
();
}
@Override
public
PermissionCollection
getPermissions
(
ProtectionDomain
domain
)
{
PermissionCollection
perms
=
new
Permissions
();
perms
.
add
(
new
AllPermission
());
return
perms
;
}
}
private
static
class
MyProtectionDomain
extends
ProtectionDomain
{
MyProtectionDomain
(
CodeSource
source
,
Permissions
permissions
)
{
super
(
source
,
permissions
);
}
public
boolean
implies
(
Permission
permission
)
{
if
(
DEBUG
)
{
System
.
out
.
println
(
"Permission checked: "
+
permission
);
}
return
super
.
implies
(
permission
);
}
}
private
static
final
Runnable
periodicEvent
=
new
Runnable
()
{
@Override
public
void
run
()
{
if
(
DEBUG
)
{
System
.
out
.
println
(
"Periodic event"
);
}
}
};
private
static
final
FlightRecorderListener
frl
=
new
FlightRecorderListener
()
{
};
public
static
void
main
(
String
[]
args
)
throws
Throwable
{
// Temporary directory for JFR files
jfrTmpDirPath
=
Files
.
createTempDirectory
(
"jfr_test"
);
try
{
File
recFile
=
new
File
(
jfrTmpDirPath
.
toString
(),
"rec"
);
recFile
.
createNewFile
();
recFilePath
=
recFile
.
toPath
();
if
(
DEBUG
)
{
System
.
out
.
println
(
"Test JFR tmp directory: "
+
jfrTmpDirPath
);
}
// Create a SecurityManager with all permissions enabled
Policy
.
setPolicy
(
new
MyPolicy
());
sm
=
new
SecurityManager
();
System
.
setSecurityManager
(
sm
);
CodeSource
source
=
Thread
.
currentThread
().
getClass
().
getProtectionDomain
().
getCodeSource
();
// Create a constrained execution environment
Permissions
noPermissions
=
new
Permissions
();
ProtectionDomain
constrainedPD
=
new
MyProtectionDomain
(
source
,
noPermissions
);
AccessControlContext
constrainedContext
=
new
AccessControlContext
(
new
ProtectionDomain
[]
{
constrainedPD
});
AccessController
.
doPrivileged
(
new
PrivilegedAction
<
Void
>()
{
@Override
public
Void
run
()
{
try
{
doInConstrainedEnvironment
();
}
catch
(
Throwable
t
)
{
if
(
DEBUG
)
{
t
.
printStackTrace
();
}
failureMessage
=
t
.
toString
();
}
return
null
;
}
},
constrainedContext
);
// Create a JFR execution environment
Permissions
JFRPermissions
=
new
Permissions
();
JFRPermissions
.
add
(
new
FilePermission
(
recFilePath
.
toString
(),
"read,write"
));
JFRPermissions
.
add
(
new
FlightRecorderPermission
(
"accessFlightRecorder"
));
JFRPermissions
.
add
(
new
FlightRecorderPermission
(
"registerEvent"
));
JFRPermissions
.
add
(
new
RuntimePermission
(
"accessDeclaredMembers"
));
ProtectionDomain
JFRPD
=
new
MyProtectionDomain
(
source
,
JFRPermissions
);
AccessControlContext
JFRContext
=
new
AccessControlContext
(
new
ProtectionDomain
[]
{
JFRPD
});
AccessController
.
doPrivileged
(
new
PrivilegedAction
<
Void
>()
{
@Override
public
Void
run
()
{
try
{
doInJFREnvironment
();
}
catch
(
Throwable
t
)
{
if
(
DEBUG
)
{
t
.
printStackTrace
();
}
failureMessage
=
t
.
toString
();
}
return
null
;
}
},
JFRContext
);
if
(
failureMessage
!=
null
)
{
throw
new
Exception
(
"TEST FAILED"
+
System
.
lineSeparator
()
+
failureMessage
);
}
System
.
out
.
println
(
"TEST PASS - OK"
);
}
finally
{
Files
.
walk
(
jfrTmpDirPath
)
.
sorted
(
Comparator
.
reverseOrder
())
.
map
(
Path:
:
toFile
)
.
forEach
(
File:
:
delete
);
}
}
private
static
void
doInConstrainedEnvironment
()
throws
Throwable
{
final
String
testPath
=
"/etc"
;
checkNoDirectAccess
();
assertPermission
(()
->
{
FlightRecorder
.
getFlightRecorder
();
},
FlightRecorderPermission
.
class
,
"accessFlightRecorder"
,
false
);
assertPermission
(()
->
{
FlightRecorder
.
register
(
MyEvent
.
class
);
},
FlightRecorderPermission
.
class
,
"registerEvent"
,
false
);
assertPermission
(()
->
{
FlightRecorder
.
unregister
(
MyEvent
.
class
);
},
FlightRecorderPermission
.
class
,
"registerEvent"
,
false
);
assertPermission
(()
->
{
FlightRecorder
.
addPeriodicEvent
(
MyEvent
.
class
,
periodicEvent
);
},
FlightRecorderPermission
.
class
,
"registerEvent"
,
false
);
assertPermission
(()
->
{
FlightRecorder
.
removePeriodicEvent
(
periodicEvent
);
},
FlightRecorderPermission
.
class
,
"registerEvent"
,
false
);
assertPermission
(()
->
{
FlightRecorder
.
addListener
(
frl
);
},
FlightRecorderPermission
.
class
,
"accessFlightRecorder"
,
false
);
assertPermission
(()
->
{
FlightRecorder
.
removeListener
(
frl
);
},
FlightRecorderPermission
.
class
,
"accessFlightRecorder"
,
false
);
assertPermission
(()
->
{
new
MyEvent
().
commit
();
},
FlightRecorderPermission
.
class
,
"registerEvent"
,
true
);
assertPermission
(()
->
{
Configuration
.
create
(
Paths
.
get
(
testPath
));
},
FilePermission
.
class
,
testPath
,
false
);
assertPermission
(()
->
{
EventFactory
.
create
(
new
ArrayList
<
AnnotationElement
>(),
new
ArrayList
<
ValueDescriptor
>());
},
FlightRecorderPermission
.
class
,
"registerEvent"
,
false
);
assertPermission
(()
->
{
new
AnnotationElement
(
Name
.
class
,
"com.example.HelloWorld"
);
},
FlightRecorderPermission
.
class
,
"registerEvent"
,
false
);
assertPermission
(()
->
{
new
ValueDescriptor
(
MyEvent
.
class
,
""
,
new
ArrayList
<
AnnotationElement
>());
},
FlightRecorderPermission
.
class
,
"registerEvent"
,
false
);
assertPermission
(()
->
{
new
Recording
();
},
FlightRecorderPermission
.
class
,
"accessFlightRecorder"
,
false
);
assertPermission
(()
->
{
new
RecordingFile
(
Paths
.
get
(
testPath
));
},
FilePermission
.
class
,
testPath
,
false
);
assertPermission
(()
->
{
RecordingFile
.
readAllEvents
(
Paths
.
get
(
testPath
));
},
FilePermission
.
class
,
testPath
,
false
);
assertPermission
(()
->
{
EventType
.
getEventType
(
MyEvent2
.
class
);
},
FlightRecorderPermission
.
class
,
"registerEvent"
,
true
);
}
private
static
void
doInJFREnvironment
()
throws
Throwable
{
checkNoDirectAccess
();
FlightRecorder
fr
=
FlightRecorder
.
getFlightRecorder
();
Configuration
c
=
Configuration
.
getConfiguration
(
"default"
);
Recording
recordingDefault
=
new
Recording
(
c
);
recordingDefault
.
start
();
FlightRecorder
.
addListener
(
frl
);
FlightRecorder
.
register
(
MyEvent3
.
class
);
FlightRecorder
.
addPeriodicEvent
(
MyEvent3
.
class
,
periodicEvent
);
new
MyEvent3
().
commit
();
FlightRecorder
.
removePeriodicEvent
(
periodicEvent
);
FlightRecorder
.
unregister
(
MyEvent3
.
class
);
FlightRecorder
.
removeListener
(
frl
);
recordingDefault
.
stop
();
try
(
Recording
snapshot
=
fr
.
takeSnapshot
())
{
if
(
snapshot
.
getSize
()
>
0
)
{
snapshot
.
setMaxSize
(
100_000_000
);
snapshot
.
setMaxAge
(
Duration
.
ofMinutes
(
5
));
snapshot
.
dump
(
recFilePath
);
}
}
checkRecording
();
Files
.
write
(
recFilePath
,
new
byte
[
0
],
StandardOpenOption
.
TRUNCATE_EXISTING
);
recordingDefault
.
dump
(
recFilePath
);
checkRecording
();
try
{
class
MyEventHandler
extends
jdk
.
jfr
.
internal
.
handlers
.
EventHandler
{
MyEventHandler
()
{
super
(
true
,
null
,
null
);
}
}
MyEventHandler
myEv
=
new
MyEventHandler
();
throw
new
Exception
(
"EventHandler must not be subclassable"
);
}
catch
(
SecurityException
e
)
{}
}
private
static
void
checkRecording
()
throws
Throwable
{
boolean
myEvent3Found
=
false
;
try
(
RecordingFile
rf
=
new
RecordingFile
(
recFilePath
))
{
while
(
rf
.
hasMoreEvents
())
{
RecordedEvent
event
=
rf
.
readEvent
();
if
(
event
.
getEventType
().
getName
().
equals
(
"JFRSecurityTestSuite$MyEvent3"
))
{
if
(
DEBUG
)
{
System
.
out
.
println
(
"Recording of MyEvent3 event:"
);
System
.
out
.
println
(
event
);
}
myEvent3Found
=
true
;
break
;
}
}
}
if
(!
myEvent3Found
)
{
throw
new
Exception
(
"MyEvent3 event was expected in JFR recording"
);
}
}
private
static
void
checkNoDirectAccess
()
throws
Throwable
{
assertPermission
(()
->
{
sm
.
checkPackageAccess
(
"jdk.jfr.internal"
);
},
RuntimePermission
.
class
,
null
,
false
);
assertPermission
(()
->
{
Class
.
forName
(
"jdk.jfr.internal.JVM"
);
},
RuntimePermission
.
class
,
null
,
false
);
assertPermission
(()
->
{
JVM
.
getJVM
();
},
RuntimePermission
.
class
,
null
,
false
);
assertPermission
(()
->
{
sm
.
checkPackageAccess
(
"jdk.jfr.events"
);
},
RuntimePermission
.
class
,
null
,
false
);
assertPermission
(()
->
{
Class
.
forName
(
"jdk.jfr.events.AbstractJDKEvent"
);
},
RuntimePermission
.
class
,
null
,
false
);
assertPermission
(()
->
{
sm
.
checkPackageAccess
(
"jdk.management.jfr.internal"
);
},
RuntimePermission
.
class
,
null
,
false
);
}
private
static
void
assertPermission
(
F
f
,
Class
<?>
expectedPermClass
,
String
expectedPermName
,
boolean
expectedIsCause
)
throws
Throwable
{
String
exceptionMessage
=
expectedPermClass
.
toString
()
+
(
expectedPermName
!=
null
&&
!
expectedPermName
.
isEmpty
()
?
" "
+
expectedPermName
:
""
)
+
" permission check expected."
;
try
{
f
.
call
();
throw
new
Exception
(
exceptionMessage
);
}
catch
(
Throwable
t
)
{
Throwable
t2
=
null
;
if
(
expectedIsCause
)
{
t2
=
t
.
getCause
();
}
else
{
t2
=
t
;
}
if
(
t2
instanceof
AccessControlException
)
{
AccessControlException
ace
=
(
AccessControlException
)
t2
;
Permission
p
=
ace
.
getPermission
();
if
(!
p
.
getClass
().
equals
(
expectedPermClass
)
||
(
expectedPermName
!=
null
&&
!
expectedPermName
.
isEmpty
()
&&
!
p
.
getName
().
equals
(
expectedPermName
)))
{
throw
new
Exception
(
exceptionMessage
,
ace
);
}
}
else
{
throw
t
;
}
}
}
}
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录