Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

apparmor: Fix unpack_profile() warn: passing zero to 'ERR_PTR'

unpack_profile() sets a default error on entry but this gets overridden
by error assignment by functions called in its body. If an error
check that was relying on the default value is triggered after one
of these error assignments then zero will be passed to ERR_PTR.

Fix this by setting up a default -EPROTO assignment in the error
path and while we are at it make sure the correct error is returned
in non-default cases.

Fixes: 217af7e2f4de ("apparmor: refactor profile rules and attachments")
Reported-by: kernel test robot <lkp@intel.com>
Signed-off-by: John Johansen <john.johansen@canonical.com>

+16 -5
+16 -5
security/apparmor/policy_unpack.c
··· 851 851 *ns_name = kstrndup(tmpns, ns_len, GFP_KERNEL); 852 852 if (!*ns_name) { 853 853 info = "out of memory"; 854 + error = -ENOMEM; 854 855 goto fail; 855 856 } 856 857 name = tmpname; ··· 883 882 } 884 883 profile->attach.xmatch_len = tmp; 885 884 profile->attach.xmatch.start[AA_CLASS_XMATCH] = DFA_START; 886 - if (aa_compat_map_xmatch(&profile->attach.xmatch)) { 885 + error = aa_compat_map_xmatch(&profile->attach.xmatch); 886 + if (error) { 887 887 info = "failed to convert xmatch permission table"; 888 888 goto fail; 889 889 } ··· 1006 1004 AA_CLASS_FILE); 1007 1005 if (!unpack_nameX(e, AA_STRUCTEND, NULL)) 1008 1006 goto fail; 1009 - if (aa_compat_map_policy(&rules->policy, e->version)) { 1007 + error = aa_compat_map_policy(&rules->policy, e->version); 1008 + if (error) { 1010 1009 info = "failed to remap policydb permission table"; 1011 1010 goto fail; 1012 1011 } ··· 1019 1016 if (error) { 1020 1017 goto fail; 1021 1018 } else if (rules->file.dfa) { 1022 - if (aa_compat_map_file(&rules->file)) { 1019 + error = aa_compat_map_file(&rules->file); 1020 + if (error) { 1023 1021 info = "failed to remap file permission table"; 1024 1022 goto fail; 1025 1023 } ··· 1031 1027 } else 1032 1028 rules->file.dfa = aa_get_dfa(nulldfa); 1033 1029 1030 + error = -EPROTO; 1034 1031 if (unpack_nameX(e, AA_STRUCT, "data")) { 1035 1032 info = "out of memory"; 1036 1033 profile->data = kzalloc(sizeof(*profile->data), GFP_KERNEL); 1037 - if (!profile->data) 1034 + if (!profile->data) { 1035 + error = -ENOMEM; 1038 1036 goto fail; 1039 - 1037 + } 1040 1038 params.nelem_hint = 3; 1041 1039 params.key_len = sizeof(void *); 1042 1040 params.key_offset = offsetof(struct aa_data, key); ··· 1055 1049 data = kzalloc(sizeof(*data), GFP_KERNEL); 1056 1050 if (!data) { 1057 1051 kfree_sensitive(key); 1052 + error = -ENOMEM; 1058 1053 goto fail; 1059 1054 } 1060 1055 ··· 1065 1058 if (data->size && !data->data) { 1066 1059 kfree_sensitive(data->key); 1067 1060 kfree_sensitive(data); 1061 + error = -ENOMEM; 1068 1062 goto fail; 1069 1063 } 1070 1064 ··· 1087 1079 return profile; 1088 1080 1089 1081 fail: 1082 + if (error == 0) 1083 + /* default error covers most cases */ 1084 + error = -EPROTO; 1090 1085 if (profile) 1091 1086 name = NULL; 1092 1087 else if (!name)