为什么显式模板实例化存在用于访问检查的漏洞? [英] Why does a hole for access checking exist for explicit template instantiations?

查看:29
本文介绍了为什么显式模板实例化存在用于访问检查的漏洞?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

[temp.explicit] 包含以下措辞:

<块引用>

通常的访问检查规则不适用于用于指定显式实例化的名称.[注意:在特别是函数声明器中使用的模板参数和名称(包括参数类型、返回类型和异常规范)可能是私有类型或通常不会的对象可访问,模板可能是成员模板或成员函数,通常不会无障碍.—结束注释]

为什么专门针对这种情况禁用这些规则?在极端情况下,这允许以明确定义的方式任意访问任何类的任何私有成员(演示 - 零警告):

<块引用>

struct A {私人的:国际会员;};template结构罗布{朋友 typename 标签::type get(Tag) {返回 M;}};//用于访问 A::member 的标签结构 A_member {typedef int A::*type;朋友类型 get(A_member);};模板结构 Rob<A_member, &A::member>;int main() {一个;a.*get(A_member()) = 42;//写入 42std::cout <<证明:"<<a.*get(A_member()) <<std::endl;}

这就是这条规则的缺点.有什么好处?为什么我们需要这个洞来避免访问检查?

解决方案

Herb Sutter 的 得到了#76.成员函数应该能够访问类的私有成员.当成员函数是一个模板时,您希望能够专门化这样的模板.这是 C++ 访问控制模型和模板模型之间的冲突,可以通过复杂(已经很复杂)的 C++ 标准来避免.虽然可以通过这种方式绕过 C++ 访问控制并访问私有成员,但强烈建议您不要这样做.

注意:@Xeo 已经在他上面的评论中解释了大部分这些要点.

[temp.explicit] contains this wording:

The usual access checking rules do not apply to names used to specify explicit instantiations. [Note: In particular, the template arguments and names used in the function declarator (including parameter types, return types and exception specifications) may be private types or objects which would normally not be accessible and the template may be a member template or member function which would not normally be accessible. —end note ]

Why are those rules disabled specifically for this case? In the extreme, this allows for arbitrary access of any private member of any class in a well-defined way (demo - zero warnings):

struct A {
private:
  int member;
};

template<typename Tag, typename Tag::type M>
struct Rob { 
  friend typename Tag::type get(Tag) {
    return M;
  }
};

// tag used to access A::member
struct A_member { 
  typedef int A::*type;
  friend type get(A_member);
};

template struct Rob<A_member, &A::member>;

int main() {
  A a;
  a.*get(A_member()) = 42; // write 42 to it
  std::cout << "proof: " << a.*get(A_member()) << std::endl;
}

So that's the downside of this rule. What's the upside? Why do we need this hole to avoid access checking?

解决方案

This question is covered by Herb Sutter's GotW #76. Member functions are expected to be able to access private members of a class. When member function is a template, you would expect to be able to specialize such template. This is a conflict between the C++ access control model and the template model, which could be avoided by complicating (already complex) C++ standard. While it is possible to bypass C++ access controls and access private members in this way, you are strongly advised against doing that.

Note: @Xeo already explained most of these points in his comments above.

这篇关于为什么显式模板实例化存在用于访问检查的漏洞?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆